假设我在c ++中有以下数字分布(向量):
vector 1 vector 2 vector 3
11 4 65
128 6 66
12 4 64
13 4 62
12 5 65
14 5 63
16 7 190
60 3 210
120 4 220
126 5 242
77 6 231
14 4 210
12 7 222
13 6 260
11 8 300
14 6 233
99 80
15 66
13
我需要为每个向量找到一个阈值。如果它们高于该向量的阈值,我将消除每个中较大(“坏”)的数字。我想重新使用这种方法在将来找到其他类似载体的阈值。这些数字不一定是较小的“好”数字。
理想情况下,阈值只是比大多数较小的“好”数字更大的头发。例如,第一个矢量的理想阈值大约是17或18,第二个大约是8,第三个大约是68-70。
我意识到这可能是简单的数学,但由于我在数学方面很糟糕,我真的很感激如何找到这个神奇的阈值的代码示例,特别是在C ++或Objective-C中,这就是为什么我'我在SO中发布此内容,而不是在Math网站上发布。
我尝试过的一些事情
float threshold = mean_of_vector;
float threshold = mean_of_vector / 1.5f;
float threshold = ((max_of_vector - min_of_vector) / 2.0f) + mean_of_vector;
其中每一个似乎都有自己的问题,例如:一些包括太多的“好”平均数(因此阈值太低),一些不够好的数字(阈值太高),或者不够“坏”数字。有时他们会使用特定的数字向量,例如,如果标准偏差很高,而不是标准偏差较低的其他数据。
我认为该方法会涉及标准偏差和/或某种高斯分布,但我不知道如何将它们拼凑在一起以获得所需的结果。
编辑:我可以对矢量进行重新排序。
答案 0 :(得分:0)
您可以消除90%或95%以上的值。 技术上你计算了数组分布的p = 0.9(或0.95)百分位数。
只需按升序对数组进行排序:
int[] data;
Arrays.sort(data); // or use ArrayList<Integer> which has Collections.sort(dataArrayList),
然后计算百分位数p的位置:
float p = data.length * p; // e.g p = 0.9 for 90% percentile.
// cut of fractional part.
int posInt = (int) p;
// this is the threshold value
int threshold = data[posInt]
现在通过保持所有值&lt;过滤数组或&lt; =阈值。 这保持了90%的最小值。
int i = 0;
while (i < data.length && data[i] <= threshold) {
// output data[i];
}
对于数学上“完美”的结果,您可以搜索“计算离散数组/值的百分位数”。
我记得有两种有效的算法,描述是否必须向下舍入或舍入posInt
。我上面的例子我被截断了。
答案 1 :(得分:0)
一个想法是计算平均值mu
和标准差sigma
(例如使用“Accurately computing running variance”中描述的算法)并使用它们来定义你的门槛。
如果您的数据被假定为高斯数据,则您知道97.5%的数据应低于mu + 2*sigma
,因此这可能是一个很好的阈值。
备注:您可能希望在拒绝极值后重新计算阈值,因为这些值会对均值和标准差产生重大影响。
编辑:
我刚刚使用我提出的方法计算了阈值,并且它看起来并不令人满意:对于第一种情况,阈值大约为130(所以可能需要1.5 sigma可以帮助摆脱最大的条目),对于第二种情况例如,阈值大约为8,而对于第三种情况,阈值大约为262。
实际上,我对这些结果并不感到惊讶:对于你的上一个例子,你想要摆脱超过一半的数据!假设数据是高斯的,只有几个极值,这远远不是你手边的......