【问题标题】:Finding outliers in a data set查找数据集中的异常值
【发布时间】:2011-01-05 16:09:43
【问题描述】:

我有一个 python 脚本,它创建服务器正常运行时间和性能数据列表,其中每个子列表(或“行”)包含特定集群的统计信息。例如,格式良好的它看起来像这样:

-------  -------------  ------------  ----------  -------------------
Cluster  %Availability  Requests/Sec  Errors/Sec  %Memory_Utilization
-------  -------------  ------------  ----------  -------------------
ams-a    98.099          1012         678          91
bos-a    98.099          1111         12           91
bos-b    55.123          1513         576          22
lax-a    99.110          988          10           89
pdx-a    98.123          1121         11           90
ord-b    75.005          1301         123          100
sjc-a    99.020          1000         10           88
...(so on)...

所以在列表形式中,它可能看起来像:

[[ams-a,98.099,1012,678,91],[bos-a,98.099,1111,12,91],...]

我的问题:确定每列中的异常值的最佳方法是什么?或者异常值不一定是解决“坏处”问题的最佳方法?在上面的数据中,我肯定想知道 bos-b 和 ord-b,还有 ams-a,因为它的错误率很高,但其他的可以丢弃。取决于列,因为更高不一定更糟,也不一定更低,我试图找出最有效的方法来做到这一点。似乎 numpy 在这类东西中被提及了很多,但不知道从哪里开始(遗憾的是,我更像是系统管理员而不是统计学家......)。

提前致谢!

【问题讨论】:

标签: python statistics


【解决方案1】:

视觉识别异常值的一个好方法是制作箱线图(或箱须图),它将显示中位数、中位数上方和下方的几个四分位数以及位于“远”的点从此框(参见维基百科条目http://en.wikipedia.org/wiki/Box_plot)。在 R 中,有一个 boxplot 函数可以做到这一点。

以编程方式丢弃/识别异常值的一种方法是使用 MAD 或 Median Absolute Deviation。与标准差不同,MAD 对异常值不敏感。我有时会使用经验法则将距离中位数超过 5*MAD 的所有点视为异常值。

【讨论】:

    【解决方案2】:

    您声明的“发现不良”目标意味着您要查找的不是异常值,而是高于或低于某个阈值的观察值,我认为该阈值会随着时间的推移保持不变。

    p>

    例如,如果您的所有服务器的可用性为 98 ± 0.1 %,那么可用性为 100% 的服务器将是一个异常值,而可用性为 97.6% 的服务器也是如此。但这些可能在您想要的范围内。

    另一方面,可能有充分的先验理由希望在可用性低于 95% 的情况下收到任何服务器的通知,无论是否有一台或多台服务器低于此阈值。

    因此,对异常值的搜索可能无法提供您感兴趣的信息。阈值可以根据历史数据进行统计确定,例如通过将错误率建模为泊松或可用性百分比作为 beta 变量。在应用设置中,这些阈值可能会根据性能要求来确定。

    【讨论】:

    • 虽然这里有很多很好的答案(特别针对我关于异常值的问题),但从统计的角度来看,@David 似乎是最好的。标记为已回答,尽管我还没有机会实现它。
    【解决方案3】:

    我认为最好的办法是查看scipyscoreatpercentile 函数。因此,例如,您可以尝试排除所有高于 99 个百分位的值。

    如果没有正态分布,均值和标准差就不好。

    一般来说,对您的数据的外观有一个粗略的视觉概念是很好的。有matplotlib;我建议您在决定计划之前用它绘制一些数据图。

    【讨论】:

    • 如果您只是不经常进行这种分析,我发现 R (r-project.org) 更容易用于数据的交互式探索。即使您最终使用 scipy/numpy 作为最终解决方案,也可能值得先使用 R 中的数据。
    • 好建议,我去看看 scoreatpercentile。
    【解决方案4】:

    您需要计算列的平均值(平均值)和标准偏差。标准差有点混乱,但重要的事实是 2/3 的数据在

    平均值 +/- 标准偏差

    通常平均值 +/- 2 * StandardDeviation 之外的任何值都是异常值,但您可以调整乘数。

    http://en.wikipedia.org/wiki/Standard_deviation

    为了清楚起见,您希望将数据转换为均值的标准差。

    def getdeviations(x, mean, stddev):
       return math.abs(x - mean) / stddev
    

    Numpy 有这方面的功能。

    【讨论】:

    • 如果您假设这些值来自正态分布,这只是一种有效的方法。
    • 正常的替代方案将包括泊松的错误率和 beta 分布的可用性百分比
    猜你喜欢
    • 2015-03-13
    • 2016-12-16
    • 2021-12-05
    • 1970-01-01
    • 2016-08-17
    • 2020-02-16
    • 2020-01-17
    • 1970-01-01
    • 2020-04-27
    相关资源
    最近更新 更多