Objective c 尖峰去除算法

Objective c 尖峰去除算法,objective-c,c,algorithm,Objective C,C,Algorithm,我有一个从30到300的值数组。我想做一个加权平均,如果我有5个值,其中一个值比其他值大很多(峰值),它不会像我简单地做算术平均那样影响平均值:例如:(n1+n2+n3+n4+n5)/5 有没有人知道如何制作一个简单的算法来实现这一点,或者去哪里寻找呢?你可以尝试一个而不是一个平均值过滤器。在图像处理中经常使用它来减少伪像素值(与白噪声相反)。正如您所注意到的,平均值容易受到尖峰的影响。也许中位数或模式可能是一个更好的统计数据,因为它们往往不那么偏斜 这应该是一个评论,但js似乎对我来说是不正确

我有一个从30到300的值数组。我想做一个加权平均,如果我有5个值,其中一个值比其他值大很多(峰值),它不会像我简单地做算术平均那样影响平均值:例如:
(n1+n2+n3+n4+n5)/5


有没有人知道如何制作一个简单的算法来实现这一点,或者去哪里寻找呢?

你可以尝试一个而不是一个平均值过滤器。在图像处理中经常使用它来减少伪像素值(与白噪声相反)。

正如您所注意到的,平均值容易受到尖峰的影响。也许中位数或模式可能是一个更好的统计数据,因为它们往往不那么偏斜

这应该是一个评论,但js似乎对我来说是不正确的:不太清楚你是在寻找一个数组特征的单个数字(即平均值),还是一个去掉尖峰的新数组(中值滤波器)


对此,我建议你们首先看看中位数或模式是否更适合作为一种统计。如果没有,则应用中值滤波器(非常擅长消除尖峰),然后平均值听起来像是要丢弃超出指定参数范围的数据。你可以通过计算中位数/模式,并在计算平均值时忽略此范围之外的值来实现。当然,您必须相应地调整除数,以考虑丢弃值的数量。这个“可容忍”范围应该是什么最终由您决定,并且可能取决于您的特定应用程序需求

或者,你可以尝试一些类似的方法,比如将项目从你的总平均值范围内剔除r%。类似这样的内容(在javascript中):

功能范围平均值(arr,r)
{
x=平均值(arr);
//现在消除超出范围r%的项目
对于(var i=0;i(x*(1+r)))
阵列拼接(i,1);
x=平均值(arr);//计算新的平均值
返回x;
}

A通常用于类似的应用中。我不知道它是否符合“简单”的条件,但它很健壮并且众所周知。

实现这一点的方法很多:您可以实现


或者,如果您只关心从统计摘要中删除异常值,您可以在平均之前从数据集中删除数据值的最高和最低N%。

将您带入文献的搜索词是“稳健统计”。卡尔曼滤波器的一个优点是,您对数据的可变性有一个连续的估计,这允许您最终“放弃超过x%的可能是虚假的观测值,考虑到目前为止的整套观测值”

嗯<代码>(N1+N2+N3+N4+N5-MN5(N1,N2,N3,N4,N5)-Max 5(N1,N2,N3,N4,N5))/ 3</代码>???也可以考虑使用几何平均值。然而,这将对“反向峰值”(低得多的值)敏感。这只是去除峰值,它在平均值中没有权重,就像:(n1+n2+n3)/3,其中n4和n5是最小值和最大值。我想找到一些即使是尖峰也有平均重量的东西,很小的一个,但是如果我在100个值中有7个尖峰,应该会影响它一点。有意义吗?我想知道StackOverflow用户和James Taranto阅读器的交集有多大。显然,该集合至少有2个成员。我只需要一个数字,这是我数组的特征;)谢谢你的链接,我会看看,我真的不知道如何搜索它。移动平均是一个低通数字滤波器。你真的需要非线性处理来消除虚假的尖峰。卡尔曼滤波器需要对数据进行大量假设,其中大多数假设与大尖峰不兼容。卡尔曼滤波器将“跟踪”尖峰,而不是消除它们。同意。卡尔曼滤波器在这里听起来不合适;它不仅需要底层过程的精确模型,更重要的是,它用于从高斯白(或彩色)噪声中恢复过程,而不是伪尖峰。这看起来很棒,而且对于预期用途来说足够简单。我马上就去试试!对我的代码注释稍加修改,r应该在0和1之间。@mindnoise我不明白。你说你想让那些“钉子”还能算一点。在这种情况下,你还在扔钉子?你可能会说尖峰有助于确定我们用来确定要消除哪些的平均值,但你确定这就是你想要的吗?事实是我对代码做了一些修改,但这是基本代码,所以我选择它作为正确答案。对不起,我没提。我没有删除尖峰,而是根据它们超出图表的程度对它们进行“平均”(如果超过某个值,则将它们永久删除)。您可以将代码发布给您。我看不出上面的解决方案如何适用于1,1,1200这样的数据集,因为它将在进行最终平均之前消除所有值
function RangedAverage(arr, r)
{
    x = Average(arr);
    //now eliminate items r% out of range
    for(var i=0; i<arr.length; i++)
        if(arr[i] < (x/r) || arr[i]>(x*(1+r)))
            arr.splice(i,1);
    x = Average(arr); //compute new average
    return x;
}