【问题标题】:How to compute a threshold for a given vector/array of float numbers如何计算给定向量/浮点数数组的阈值
【发布时间】:2013-01-08 14:08:16
【问题描述】:

假设我在 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

我需要为每个向量找到一个阈值。如果它们高于该向量的阈值,我将消除每个中较大的(“坏”)数字。我想在将来重新使用这种方法来找到其他类似向量的阈值。这些数字不一定是较小的“好”数字。

理想情况下,阈值只是比大多数较小的“好”数字大一点。例如,第一个 vetor 的理想阈值在 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;

这些似乎都有自己的问题,例如:有些包含太多的“好”平均数(因此阈值太低),有些没有足够的好数(阈值太高),或者不够“坏”的数字。有时他们会使用特定的数字向量,例如,如果标准差较高,但在标准差较低的情况下则不然。

我认为该方法将涉及标准偏差和/或某种高斯分布,但我不知道如何将它们拼凑在一起以获得所需的结果。

编辑:我可以重新排序向量。

【问题讨论】:

    标签: math numbers gaussian threshold standard-deviation


    【解决方案1】:

    一个想法是计算平均值mu 和标准差sigma(例如使用“Accurately computing running variance”中描述的算法),并使用它们来定义阈值。

    如果假设您的数据是高斯分布的,那么您知道 97.5% 的数据应该低于 mu + 2*sigma,因此这是一个很好的阈值。

    备注:您可能希望在拒绝极值后重新计算阈值,因为这些值会对均值和标准差产生重大影响。

    编辑:

    我刚刚使用我提出的方法计算了阈值,但您看起来并不满意:对于第一种情况,阈值约为 130(因此,取 1.5 sigma 可能有助于消除最大的条目),对于第二种情况情况,阈值约为 8,第三种情况,阈值约为 262。

    实际上,我对这些结果并不感到惊讶:对于您的最后一个示例,您想要删除一半以上的数据!假设数据是只有几个极值的高斯数据,这与您手头的数据相差甚远...

    【讨论】:

      【解决方案2】:

      您可以消除高于 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]
      

      现在通过保留所有值

      int i = 0;
      while (i < data.length && data[i] <= threshold) {
        // output data[i];
      }
      

      对于数学上“完美”的结果,您可以搜索“计算离散数组/值的百分位”。 我记得有两种有效的算法,描述是否必须向下舍入或向上舍入posInt。我上面的例子我只是截断了。

      【讨论】:

      • 感谢您的回答 - 这种方法不是假设 90% 的值将是更大的数字吗?抱歉,数组可能是大/小数字的一半。我应该更新我的例子。
      • 不,它会删除 10% 的最大值。 (使用 p=90% 或 (5% ,如果 p = 95%)。当数组的所有值都相同时,可能会有特殊情况,但没关系。
      猜你喜欢
      • 1970-01-01
      • 2018-07-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-30
      • 2013-01-31
      • 1970-01-01
      • 2014-08-16
      相关资源
      最近更新 更多