提问人:root66 提问时间:1/15/2015 最后编辑:Alexander Bellroot66 更新时间:6/6/2018 访问量:7702
在数值数据集中查找“异常值”
Finding the 'Outliers' in numeric data set
问:
我想比较(按)增长率和低起始值的高增长率。
例:
1. 开始: 1.000.000 结束: 1.100.000 增长:+10%
- 开始: 100.000 结束: 120.000 增长:+20%
3. 开始: 1 结束: 10 成长:+900%
- 开始: 10 结束: 15 增长:+50%
仅按增长排序,降序将导致:900% (3.)、50% (4.)、20% (2.)、10% (1.)
但我想要:20% (2.)、10% (1.)、900% (3.)、50% (4.),因为在我的情况下,机会很高,即 3.和 4.是统计异常值。
解决此问题的最佳方法是什么,我是否必须为起始值定义阈值?
谢谢!
答:
根据您提供的描述,问题可以分为 2 个:
- 查找数据集并从中排除
Statistical Outliers
- 按降序(或仅按任意)顺序对结果值进行排序
使用 Excel 的第一个问题和示例的一般解决方案Microsoft请参阅:Excel 工作表Microsoft中的统计异常值检测 (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 代表中位数绝对偏差。数据集中修改后的 Z 分数绝对值超过 3.5 的任何数字都被视为“异常值”。修改后的 Z 分数可用于检测 Microsoft Excel 工作表中与您的案例相关的异常值,如下所述。
步骤 1。打开 Microsoft Excel 工作表,然后在单元格 A1、A2、A3 和 A4 中相应地输入值:900%、50%、20% 和 10%。
第2步。在 C1 中输入公式:。此单元格中的值对应于在步骤 1 中输入的数据集计算的中位数。=MEDIAN(A1:A4)
第 3 步。在 C2 中输入数组公式:。提醒一下,要输入数组公式,请选择单元格,在Excel公式栏中键入公式,然后单击组合:CTRL-SHIFT-ENTER(注意表达式周围的大括号,表示数组公式)。此单元格中的值 (C2) 对应于 MAD。{=MEDIAN(ABS(MEDIAN(A1:A4)-A1:A4))}
第 4 步。在 B 列的第一行中输入公式:并将其向下扩展到第 4 行。“异常值检测”的最终结果应显示在 B 列中。=IF((0.6745*ABS(C$1-A1)>3.5*C$2), "OUTLIER", "NORMAL")
A B C
900% OUTLIER 35%
50% NORMAL 0.35
20% NORMAL
10% NORMAL
因此,值 900% 被发现为“异常值”,而其他值则正常。 对结果集进行排序将只是一项微不足道的任务。
为了便于解释,包括了 Excel 工作表示例。该算法本身可以用任何编程语言(VBA、C#、Java 等)实现。希望这会有所帮助。
评论
我的 solition
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;
}
评论