识别数据集中的异常值
我有一个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在这方面经常被提到,但我不知道从哪里开始(可惜我更像是系统管理员,而不是统计学家……)。
提前谢谢你!
4 个回答
我觉得你可以看看 scipy 里的 scoreatpercentile 函数。比如说,你可以试着排除掉那些超过99百分位的值。
如果你的数据不是正态分布,平均值和标准差就没什么用。
一般来说,先大致了解一下你的数据长什么样是很有帮助的。可以使用 matplotlib 来画一些图,这样在决定下一步计划之前,你能更清楚地看到数据的情况。
一种很好的视觉识别异常值的方法是制作箱线图(也叫箱须图)。这个图能显示出中位数,以及中位数上下的几个四分位数,还有那些离这个箱子“远”的点(你可以在维基百科上查看相关内容 http://en.wikipedia.org/wiki/Box_plot)。在R语言中,有一个 boxplot
函数可以用来制作这样的图。
如果想通过编程来识别或剔除异常值,可以使用MAD,也就是中位数绝对偏差。MAD对异常值不敏感,这和标准差不同。我有时会用一个简单的规则,认为所有距离中位数超过5倍MAD的点都是异常值。
你提到的“寻找坏情况”意味着你不是在找那些极端的例子,而是想找一些超过或低于某个标准的情况。我猜这个标准应该是固定的,不会随时间变化。
举个例子,如果你所有的服务器都保持在98 ± 0.1%的可用性,那么一台100%可用的服务器就算是个极端值,97.6%可用的服务器也是。但这两台服务器可能还是在你能接受的范围内。
另一方面,可能有很好的理由让你想要被通知任何可用性低于95%的服务器,无论是有一台还是多台服务器低于这个标准。
因此,寻找极端值可能无法提供你真正关心的信息。这个标准可以根据历史数据进行统计分析来确定,比如用泊松分布来建模错误率,或者用贝塔分布来建模可用性。在实际应用中,这些标准可能会根据性能要求来确定。