GESD 离群值检验——理论与 Python 实现
Posted zhuo木鸟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GESD 离群值检验——理论与 Python 实现相关的知识,希望对你有一定的参考价值。
文章目录
本文主要根据标准 ISO 16269-4: 2010 的 4.3.2 条款
设样本为 x 1 , x 2 , ⋯ , x n x_1, x_2, \\cdots, x_n x1,x2,⋯,xn
GESD 离群值检验
GESD 的适用条件是:当样本来源于正态分布时,方可使用。
步骤
- 首先,根据正态分布和样本的 Q-Q 图,找出 x 1 , x 2 , ⋯ , x n x_1, x_2, \\cdots, x_n x1,x2,⋯,xn 的所有可能的离群值的个数。
- 定义一个最大离群值数 m m m, m m m 可以大于等于步骤 1 中得到的可能离群值的个数。
- 定义 l = 0 l=0 l=0,开始迭代过程,记 X = x 1 , x 2 , ⋯ , x n X = \\x_1, x_2, \\cdots, x_n\\ X=x1,x2,⋯,xn。
- 计算检验统计量:
R l = max x ∈ X ∣ x − X ˉ ∣ s ( X ) R_l = \\frac\\max_x \\in X|x - \\barX|s(X) Rl=s(X)maxx∈X∣x−Xˉ∣
其中,s 为样本 X X X 的标准差。 - 找到 R l R_l Rl 对应的样本 x x x,将 x x x 记为 x ( l ) x^(l) x(l) 并从 X X X 中删除。
- 计算临界值:
λ l = ( n − l − 1 ) ⋅ t ( p , n − l − 2 ) ( n − l − 2 + t 2 ( p , n − l − 2 ) ⋅ ( n − l ) \\lambda_l = \\frac(n-l-1) \\cdot t(p, n-l-2) \\sqrt(n-l-2+ t^2(p, n-l-2) \\cdot (n-l) λl=(n−l−2+t2(p,n−l−2)⋅(n−l)(n−l−1)⋅t(p,n−l−2)
其中 p p p 为 p = ( 1 − α / 2 ) 1 / ( n − l ) p=(1-\\alpha/2)^1/(n-l) p=(1−α/2)1/(n−l)。 t ( p , v ) t(p, v) t(p,v) 为学生分布 t 的 probability percentage function(百占比点), v v v 为自由度。也可以说是学生分布 t 的分布函数的反函数吧。 - 另 l = l + 1 l = l+1 l=l+1,重复 4-6 直到 l = m l=m l=m 为止。
- 于是,对于 x ( 1 ) , x ( 2 ) , ⋯ , x ( m ) x^(1), x^(2), \\cdots, x^(m) x(1),x(2),⋯,x(m),以及对应的 R l R_l Rl,找到最大的 l = max 1 ≤ l ≤ m l : R l > λ l l = \\max_1\\leq l \\leq m\\ l: R_l > \\lambda_l \\ l=max1≤l≤ml:Rl>λl,则 x ( 1 ) , x ( 2 ) , ⋯ , x ( l ) x^(1), x^(2), \\cdots, x^(l) x(1),x(2),⋯,x(l) 都是离群值
Python 代码
import numpy as np
import pandas as pd
from scipy.stats import t
def perform_GESD(x_original, m=1, alpha=0.05):
x = x_original.copy()
l = 1
# 样本个数
n = len(x)
# 定义临时变量
x_l_list = []
# flags = True 意味着 Rl > lambda_l
flags_list = []
# 迭代直到 l == m
while l <= m:
diff = np.abs(x-np.mean(x))/np.std(x, ddof=1)
# 求检验统计量
R_idx = np.argmax(diff)
R_l = diff[R_idx]
print(R_l)
# 计算 p
p = (1-alpha/2)**(1/(n-l))
# 根据公式 3 计算临界值
t_percentage = t.ppf(q=p, df=(n-l-2))
numerator = (n-l-1)*t.ppf(q=p, df=(n-l-2))
denominator = np.sqrt((n-l-2+t_percentage**2)*(n-l))
lambda_l = numerator/denominator
if R_l > lambda_l:
flags_list.append(True)
else:
flags_list.append(False)
# 保存那些极大值对应的 x
x_l = x[R_idx]
x_l_list.append(x_l)
# 更新迭代 l
l = l + 1
x = np.delete(x, R_idx)
# 根据标准定义找出离群值
idx_flags = list(enumerate(flags_list))
print(idx_flags)
True_list = [item[0] for item in idx_flags if item[1]]
extreme_idx = max(True_list)
outliers = x_l_list[:(extreme_idx+1)]
outlier_indexs = []
for outlier in outliers:
outlier_index = np.where(x_original == outlier)
outlier_indexs.append(outlier_index)
# 删除离群值
x_without_outliers = np.delete(x_original, outlier_indexs)
return outliers, x_without_outliers
以上是关于GESD 离群值检验——理论与 Python 实现的主要内容,如果未能解决你的问题,请参考以下文章
Dixon 检验法判断正态分布离群值——原理和 Python 实现