格拉布斯离群值检验——理论与 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=smaxxixˉ
其中 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=n1i=1n(xixˉ)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)}} Gn n1×n2+t(1α)/2n2(n2)t(1α)/2n2(n2)
取显著水平为 α = 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>n n1×n2+t(1α)/2n2(n2)t(1α)/2n2(n2)
拒绝原假设,意味着样本中存在离群值,而离群值就是那个离 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

  1. 这里介绍的方法是双边(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 (xmaxxˉ)/s ( x ˉ − x m i n ) / s (\\bar{x}-x_{min})/s (xˉxmin)/s 即可。 ↩︎

以上是关于格拉布斯离群值检验——理论与 Python 实现的主要内容,如果未能解决你的问题,请参考以下文章

GESD 离群值检验——理论与 Python 实现

GESD 离群值检验——理论与 Python 实现

Dixon 检验法判断正态分布离群值——原理和 Python 实现

Dixon 检验法判断正态分布离群值——原理和 Python 实现

正态分布离群值检验——偏度与峰度方法

正态分布离群值检验——偏度与峰度方法