使用修改后的 z 分数进行 Iglewicz 和 Hoaglin 异常值测试 - 如果 MAD 变为 0,我该怎么办?

机器算法验证 异常值 强大的
2022-03-13 12:49:10

我是一个有少量统计背景的程序员,我需要在一小部分整数和浮点数列表中找到异常值。

在 google 上进行一些搜索后,我发现了Iglewicz 和 Hoaglin 异常值测试,它为列表中的每个值创建了一个修改后的 z-score M i并根据阈值(通常为3.5)检查它。

Mi=0.6745(xix~)MAD

我写了一个小python脚本来测试它。起初它工作得很好,但经过几次测试后我发现了一个错误。

如果您尝试在具有许多相同值和一个异常值的列表中查找异常值(使用我的脚本),例如data = [10, 10, 10, 10, 10, 10, 10, 100]变为MAD(median absolute deviation)0这将导致我的问题:“如果MAD变为,我该怎么办0?”。

我的第一个想法是将 设置MAD,但这会导致脚本找不到异常值。

我的第二个想法是向值添加非常小的偏移量以使它们独一无二,例如data = [10.0, 10.00000001, 10.00000002, 10.00000003, 10.00000004, 10.00000004, 10.00000005, 100]这种方式MAD不能成为0,我的脚本能够检测到异常值 100。

有人有更好的想法吗?

难道我做错了什么?

2个回答

三个事实将在这里为您提供帮助。

  • 您发现的称为精确拟合属性。如果的观测值具有相同的值,则样本的 mad 将为 0。α>0.5
  • 这不是疯子的特性,而是所有强大的规模估计器的特性。更准确地说:任何分解点的稳健规模估计量都 水平的精确拟合属性(参见 Croux 等人的第 3 节,2006,[0],对于例子)。0<α<0.51α
  • 您的第一个建议相当于在完全拟合的情况下用任意数字的值(在前者中和M_i是您扰乱数据的量——在后者中)。 MiMi=0Mi=O(1/σ)σ

您提出的问题解决方案(第 3 点)不是正确的解决方案。

事实上,您的问题的正确解决方案要简单得多。保持 MAD,保持异常值拒绝规则。您需要做的就是 在计算异常值检测规则此约定在精确匹配情况之外没有影响。然后,无论 MAD 是否严格为正,您都可以使用该规则。0/0:=0

这是因为:

在完全拟合的情况下,一半或更多的数据与任意值不同的所有观测值都是严重异常值xx

在这种情况下,样本中与不同的所有观测值毕竟与大量数据的模式存在无限差异。然后,采用将为那些等于 ( ) 和那些不同于 ( ) 的观察分配正确的离群分数。 x0/0:=0xMi=0xMi=

您可以使用此约定的原因是因为精确拟合属性是双射的:

Mad = 0超过一半的样本与相同的值相关联。

  • 投影追踪稳健主成分分析的算法。(2006 年)。Croux, C. Filzmoser, P. 和 Oliveira, MR

1. 一个实用的建议。

更改这部分代码

    if mad == 0:
        mad = 9223372036854775807 # maxint

    if mad == 0:
        mad = 2.2250738585072014e-308 # sys.float_info.min

它成功了。除以这个数字会炸毁 Iglewicz-Hoaglin 测试统计数据 - 完全符合预期。也就是说,将严重偏差的观察标记为异常值。


2.以前的实用建议。

您可以做的是检查它是否与平均绝对误差( MAE ) 的密切相关定义一起使用:

MAE=1ni=1n|ximedian(x)|,

错误(更好:残差偏差)。ei=ximedian(x)

IBM使用此变体:

Mi=ximedian(x)1.253314MAE

对于这个if MAD == 0案子。


3. 这里发生了什么?(从编程的角度来看)

考虑以下两种情况:

  1. 0/0 ,
  2. x/0对于x0

科学编程语言 R、Matlab 和 Julia 具有以下行为:

  1. 0/0返回NaN
  2. 90/0返回Inf

另一方面,PythonZeroDivisionError在这两种情况下都会抛出 a 。

实用建议一规避了这两种零分割处理的两种情况。