什么是Sigma Clipping?何时应用它?

6

我正在阅读一本关于Python数据科学的书籍,作者应用“sigma-clipping操作”来消除由于打字错误而产生的异常值。然而,这个过程并没有被解释。

什么是sigma-clipping?它只适用于特定的数据吗(例如,在该书中,它用于美国的出生率)?

根据文本所述:

quartiles = np.percentile(births['births'], [25, 50, 75]) #so we find the 25th, 50th, and 75th percentiles
mu = quartiles[1] #we set mu = 50th percentile
sig = 0.74 * (quartiles[2] - quartiles[0]) #???

This final line is a robust estimate of the sample mean, where the 0.74 comes 
from the interquartile range of a Gaussian distribution.

为什么是0.74?这个数字有没有证明?

2
https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.stats.sigmaclip.html - DYZ
1
你的回答没有任何帮助。 你有看过上面的问题吗? - NRH
2
你混淆了截然不同的问题。上面的链接已经完美地回答了“什么是sigma剪裁?”。“为什么是0.74?”和引用的书籍内容与sigma剪裁毫无关系,下面会有答案。 - MB-F
为什么是0.74的值?正态分布的一个基本属性是50%的值在距离平均值最大为0.67σ的距离内(四分位差,参见这篇文章中的这个图像). 0.74 = 1 / (2x0.67)。 "健壮"意味着不受异常极端值的影响(离群点在IQR之外,因此不能用来估计σ)。 - mins
4个回答

11

这个最终值是样本均值的一个鲁棒估计,其中0.74来自于高斯分布的四分位距

就是这样,真的很简单...

该代码尝试使用四分位距来估计标准差,以使其对离群值具有鲁棒性。 0.74是一个修正因子。以下是如何计算它:

p1 = sp.stats.norm.ppf(0.25)  # first quartile of standard normal distribution
p2 = sp.stats.norm.ppf(0.75)  # third quartile
print(p2 - p1)  # 1.3489795003921634

sig = 1  # standard deviation of the standard normal distribution  
factor = sig / (p2 - p1)
print(factor)  # 0.74130110925280102

在标准正态分布中,sig==1,四分位距为1.35。因此,0.74是将四分位距转换为σ的校正因子。当然,这仅适用于正态分布。


IQR = Q3 - Q1 = (mu + .6745 * sig) - (mu - .6745 * sig) = 2 * .6745 * sig,因此 sig = IQR / (2 * .6745) = 0.74 * IQR。 - Xopi García

10
假设你有一组数据。计算它的中位数m和标准差sigma。仅保留落在范围(m-a*sigma, m+a*sigma)内的数据,其中a是某个值,并且丢弃其他所有数据。这是sigma剪辑的一次迭代。继续迭代预定次数,或当sigma的相对减少量很小时停止。
Sigma剪辑旨在消除异常值,以便更稳健(即对异常值有抵抗力)地估计分布的平均值等内容。因此,它适用于预期存在异常值的数据。
至于0.74,它来自高斯分布的四分位距,就像文本所述。

3
这里的答案准确合理,但并没有完全回答你的问题:
“什么是sigma剪辑?它是否只适用于某些数据?”
如果我们想使用均值(mu)和标准差(sigma)来确定阈值,以便在我们有理由怀疑那些极端值是错误时将其排除在外(而不仅仅是非常高/低的值),我们不希望使用包括这些错误的数据集来计算mu/sigma。
样本问题:您需要计算温度传感器的阈值,以指示温度何时“高”-但有时传感器会给出不可能的读数,如“太阳表面”高。
想象一下一个看起来像这样的系列:
thisSeries = np.array([1,2,3,4,1,2,3,4,5,3,4,5,3, 500, 1000])
最后两个值看起来像明显的错误-但如果我们使用典型的统计函数(如正态PPF),它将默认假定这些异常值属于分布,并相应地执行其计算:st.norm.ppf(.975,thisSeries.mean(),thisSeries.std())。

631.5029013468446

使用双侧5%的异常值阈值(意味着我们将拒绝下限和上限的2.5%),它告诉我500不是异常值。即使我使用单侧阈值为0.95(拒绝上限5%),它也会给出546作为异常值限制,因此500被认为是非异常值。
Sigma-clipping通过专注于四分位距并使用中位数而不是平均值来工作,因此阈值不会在极端值的影响下计算。
thisDF = pd.DataFrame(thisSeries, columns=["value"])
intermed="value"
factor=5
quartiles = np.percentile(thisSeries, [25, 50, 75])
mu, sig = quartiles[1], 0.74 * (quartiles[2] - quartiles[0])
queryString = '({} < @mu - {} * @sig) | ({} > @mu + {} * @sig)'.format(intermed, factor, intermed, factor)
print(mu + 5 * sig)
  10.4

print(thisDF.query(queryString))
 500
1000

在因子为5的情况下,两个离群值都被正确地隔离出来,并且阈值在合理的10.4处 - 合理之处在于系列的“干净”部分是[1,2,3,4,1,2,3,4,5,3,4,5,3]。(此处的“factor”是应用于阈值的标量)
因此,sigma截断是一种识别离群值的方法,它不受离群值本身变形影响,并且虽然它可以在许多情况下使用,但它在你怀疑极端值不仅仅是应该被视为数据集一部分的高/低值,而是错误时表现得非常出色。
以下是极端值是分布的一部分和可能是错误或者是如此极端以至于会影响其余数据分析的差异的说明。

Normally distributed data has extreme values that do not deform analysis of the rest of the data

以上数据是合成的,但您可以看到在此数据集中最高的值并没有扭曲统计数据。

现在这里有一个以相同方式生成的数据集,但是这次注入了一些人为的异常值(大于40):

enter image description here

如果我使用sigma-clip,我可以回到原始的直方图和统计数据,并将它们有用地应用于数据集。但是,sigma-clipping真正发挥作用的地方是在现实世界的场景中,其中错误数据很常见。这里有一个使用真实数据的例子——我的心率监测器的历史观测记录。让我们先看一下没有进行sigma-clipping的直方图:

enter image description here

我是一个相当冷静的人,但我知道我的心率从来不会降到零。Sigma-clipping轻松处理这个问题,现在我们可以查看心率观察的真实分布:

enter image description here

现在,您可能具备某些领域知识,使您能够手动确定异常值阈值或过滤器。这就是我们为什么可能使用sigma-clipping的最后一个微妙之处 - 在完全由自动化处理数据的情况下,或者我们没有与测量或采取方式相关的领域知识时,我们就没有任何有根据的基础来进行过滤器或阈值语句。

很容易说心率为0不是有效的测量结果 - 但是10呢?200呢?如果心率是我们正在进行的数千种不同测量中的一种,那该怎么办?在这种情况下,维护一组手动定义的阈值和过滤器将会过于繁琐。


0

我认为这句话中有一个小错别字,应该是“这个最终结果是样本平均数的强估计”。根据之前的证明,如果遵循正态分布,我认为最后一行是对出生率1 Sigma的可靠估计。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接