格拉布斯离群值检验——理论与 Python 实现
Posted zhuo木鸟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了格拉布斯离群值检验——理论与 Python 实现相关的知识,希望对你有一定的参考价值。
参考文章: https://en.wikipedia.org/wiki/Grubbs%27s_test
原理
格拉布斯检验1是一种假设检验方法(显著检验法),其原假设为:
H
0
:
H_0:
H0: 数据集中没有离群值
H
1
:
H_1:
H1: 数据集中存在离群值
设数据集为:
x
1
,
x
2
,
⋯
,
x
n
x_1, x_2, \\cdots, x_n
x1,x2,⋯,xn计算 Grubbs 检验的检验统计量如下:
G
=
max
∣
x
i
−
x
ˉ
∣
s
G=\\frac{\\max |x_i-\\bar{x}|}{s}
G=smax∣xi−xˉ∣
其中
s
s
s 为样本的标准差:
s
=
∑
i
=
1
n
(
x
i
−
x
ˉ
)
2
n
−
1
s=\\sqrt{\\frac{\\sum_{i=1}^{n} (x_i-\\bar{x})^2}{n-1}}
s=n−1∑i=1n(xi−xˉ)2
其中检验统计量 G 服从:
G
∼
n
−
1
n
×
t
(
1
−
α
)
/
2
n
2
(
n
−
2
)
n
−
2
+
t
(
1
−
α
)
/
2
n
2
(
n
−
2
)
G\\sim \\frac{n-1}{\\sqrt{n}} \\times \\sqrt{\\frac{t^2_{(1-\\alpha)/2n}(n-2)}{n-2+t^2_{(1-\\alpha)/2n}(n-2)}}
G∼nn−1×n−2+t(1−α)/2n2(n−2)t(1−α)/2n2(n−2)
取显著水平为
α
=
0.95
\\alpha=0.95
α=0.95,若:
G
>
n
−
1
n
×
t
(
1
−
α
)
/
2
n
2
(
n
−
2
)
n
−
2
+
t
(
1
−
α
)
/
2
n
2
(
n
−
2
)
G > \\frac{n-1}{\\sqrt{n}} \\times \\sqrt{\\frac{t^2_{(1-\\alpha)/2n}(n-2)}{n-2+t^2_{(1-\\alpha)/2n}(n-2)}}
G>nn−1×n−2+t(1−α)/2n2(n−2)t(1−α)/2n2(n−2)
则拒绝原假设,意味着样本中存在离群值,而离群值就是那个离
x
ˉ
\\bar{x}
xˉ 最远的样本,一般只要将其从样本中删除即可。
于是,对样本 x 1 , x 2 , ⋯ , x n x_1, x_2, \\cdots, x_n x1,x2,⋯,xn,重复上述过程,直到 格拉布斯 检验无法检验的离群值为止。
Python 代码
def grubbs_test(x, alpha=0.95):
'''
格拉布斯检验
Parameters
----------
x : array, series
样本.
alpha : float, optional
置信水平. The default is 0.95.
Returns
-------
x : np.array
移除了 outliers 后的样本.
'''
# https://en.wikipedia.org/wiki/Grubbs%27s_test
if isinstance(x, pd.Series) or isinstance(x, pd.DataFrame):
x = x.astype('float').values
elif isinstance(x, list):
x = np.array(x)
# 样本个数
p = len(x)
beta = 1-alpha
while True:
# 格拉布斯法算出离群值
if p > 2:
# 求均值和方差
mean, std, _ = mean_standard(x)
G_arr = np.abs(x-mean)/std
# 最有可能是离群值的样本的 index
G_idx = G_arr.argmax()
# 求出 Grubbs test 的能力统计量 G
G = G_arr[G_idx]
t_crital = t.ppf(beta/(2*p), p-2)
# 求检验统计量在显著性水平中的临界值
criteria = (p-1)/np.sqrt(p)*np.sqrt(t_crital**2/(p-2+t_crital**2))
if G > criteria:
# 若样本中有离群值, 删除离群值
x = np.delete(x, G_idx)
# 重新求取参加者个数
p = len(x)
else:
# 若样本中没有离群值,则返回
return x
else:
return x
这里介绍的方法是双边(two-sides)格拉布斯检验法。也即同时检验两个方向的离群值,若需要单边,则只需把 ( 1 − α ) / 2 n (1-\\alpha)/2n (1−α)/2n 换做 ( 1 − α ) / n (1-\\alpha)/n (1−α)/n,把 G 换成 ( x m a x − x ˉ ) / s (x_{max}-\\bar{x})/s (xmax−xˉ)/s 或 ( x ˉ − x m i n ) / s (\\bar{x}-x_{min})/s (xˉ−xmin)/s 即可。 ↩︎
以上是关于格拉布斯离群值检验——理论与 Python 实现的主要内容,如果未能解决你的问题,请参考以下文章
Dixon 检验法判断正态分布离群值——原理和 Python 实现