找到'异常值'在数字数据集中

时间:2015-01-14 22:35:57

标签: algorithm statistics median standard-deviation outliers

我想比较(排序)增长率和不利的高利率和非常低的起始价值。

示例:

1。 开始:1.000.000 结束:1.100.000 增长:+ 10%

  1. 开始时间:100.000 结束:120.000 增长:+ 20%
  2. 3。 开始:1 结束:10 增长:+ 900%

    1. 开始:10 结束:15 增长:+ 50%
    2. 按增长排序,下降将导致:900%(3。),50%(4。),20%(2。),10%(1。)

      但我希望:20%(2。),10%(1。),900%(3。),50%(4。),因为在我的情况下,机会很高,即3。 4.是统计异常值。

      解决此问题的最佳方法是什么?我是否要定义起始值的阈值?

      谢谢!

2 个答案:

答案 0 :(得分:2)

根据您提供的说明,问题可分为2:

  1. 在数据集中查找并排除Statistical Outliers
  2. 按降序(或任何)顺序对结果值进行排序
  3. 使用Microsoft Excel的第一个问题和示例的一般解决方案描述于: Microsoft Excel工作表中的统计异常值检测http://www.codeproject.com/Tips/214330/Statistical-Outliers-detection)。以下是一些理论和与您的案例相关的样本。

    在数据集中查找“异常值”可以通过计算每个数字的偏差来完成,表示为“Z分数”或“修改的Z分数”并针对某个预定阈值进行测试。 Z分数通常是指相对于统计平均值的标准偏差的数量(换句话说,它以“Sigmas”测量)。修正的Z分数应用中值计算技术来测量偏差,并且在许多情况下提供更强大的异常值统计检测。数学上可以编写修改后的Z分数(如 Iglewicz Hoaglin 所示 - 参见参考文章):

    Mi = 0.6745 * (Xi - Median(Xi)) / MAD,
    

    其中MAD代表中位数绝对偏差。具有超过3.5的修正Z分数的绝对值的数据集中的任何数字被认为是“异常值”。修改后的Z分数可用于检测与您的案例相关的Microsoft Excel工作表中的异常值,如下所述。

    步骤1.打开Microsoft Excel工作表,在单元格A1,A2,A3和A4中输入值:900%,50%20%和10%,相应的。

    步骤2.在C1中输入公式:=MEDIAN(A1:A4)。此单元格中的值对应于在步骤1中输入的数据集计算的中值。

    步骤3.在C2中输入数组公式:{=MEDIAN(ABS(MEDIAN(A1:A4)-A1:A4))}。提醒一下,为了输入数组公式,选择单元格,在Excel公式栏中键入公式,然后单击组合:CTRL-SHIFT-ENTER(注意表达式周围的花括号,表示数组公式) 。该单元格(C2)中的值对应于MAD。

    步骤4.在B列的第一行输入公式:=IF((0.6745*ABS(C$1-A1)>3.5*C$2), "OUTLIER", "NORMAL")并将其向下延伸到第4行。 “异常检测”的最终结果应出现在B栏中。

    A       B           C
    900%    OUTLIER     35%
    50%     NORMAL      0.35
    20%     NORMAL  
    10%     NORMAL  
    

    因此,900%的值被发现为“异常值”,而其他值则可以。对结果集进行排序只是一项微不足道的任务。

    包含Excel工作表示例以便于解释清晰。算法本身可以用任何编程语言(VBA,C#,Java等)实现。希望这会有所帮助。

答案 1 :(得分:2)

我的决心

private static List<double> StatisticalOutLierAnalysis(List<double> allNumbers)
{
    List<double> normalNumbers = new List<double>();
    List<double> outLierNumbers = new List<double>(); 
    double avg = allNumbers.Average();
    double standardDeviation = Math.Sqrt(allNumbers.Average(v => Math.Pow(v - avg, 2)));
    foreach (double number in allNumbers)
    {
        if ((Math.Abs(number - avg)) > (2 * standardDeviation))
            outLierNumbers.Add(number);
        else
            normalNumbers.Add(number);
    }

    return normalNumbers;
}