如何在 Python 中执行 Grubbs 测试

pythonserver side programmingprogramming

简介

Grubbs 测试是一种统计假设检验方法,用于检测数据集中的异常值。异常值是分散数据分布的观测值,也称为异常。具有异常值的数据集往往比具有正态/高斯分布的数据更容易过度拟合。因此,在机器学习建模之前,有必要解决异常值问题。在处理之前,我们必须检测并定位数据集中的异常值。最流行的异常值检测技术是 QQPlot、四分位距和 Grubbs 统计测试。但是,本文将仅讨论用于检测异常值的 Grubbs 测试。您将了解:什么是 Grubbs 测试以及如何在 Python 中实现它。

什么是异常值?

异常值是与其他数据值在数值上相距甚远的数据观测值。这些值超出了正态分布数据的范围。数据集必须包含 67% 的记录低于第一个标准差、95% 的数据低于第二个标准差,以及 99.7% 的点低于平均值的第三个标准差,才能实现正态分布。换句话说,数据点应位于第一四分位数和第三四分位数之间。我们将低于第一四分位数和高于第三四分位数的记录视为离群值或异常值。

Grubbs 统计假设检验

Grubbs 检验也像任何其他统计假设检验一样,批准或拒绝零假设 (H0) 或备择假设 (H1)。 Grubbs 检验是一种检测数据集中异常值的检验方法。

我们可以通过两种方式执行 Grubbs 检验:单侧检验双侧检验,适用于具有至少七个变量的单变量数据集或近似正态分布的样本。此检验也称为极端学生化偏差检验或最大正态残差检验。

Grubbs 检验使用以下假设 -

  • 零假设 (H0):数据集没有异常值。

  • 替代假设 (H1):数据集只有一个异常值。

Python 中的 Grubbs 检验

Python 拥有庞大的库集合,可以应对任何编程挑战。这些库提供内置方法,可直接用于执行任何操作、统计测试等。类似地,Python 有一个库,其中有执行 Grubbs 测试来检测异常值的方法。但是,我们将探索在 Python 中实现 Grubbs 测试的两种方法:库中的内置函数和从头开始实现公式。

异常值库和 Smirnov_grubbs

让我们首先使用以下命令安装 outlier_utils 库。

!pip install outlier_utils

现在让我们创建一个包含异常值的数据集并执行 Grubbs 测试。

双面 Grubbs 测试

语法

grubbs.test(data, alpha=.05)

参数

data − 数据的数字向量值。

alpha − 测试的显著性水平。

解释

在这种方法中,用户必须使用 outliers 包中的 smirnov_grubbs.test() 函数,并将必要的数据作为输入传递,才能运行 Grubb 测试。

示例

import numpy as np
from outliers import smirnov_grubbs as grubbs

#define data
data = np.array([ 5, 14, 15, 15, 14, 19, 17, 16, 20, 22, 8, 21, 28, 11, 9, 29, 40])

#perform Grubbs'测试
grubbs.test(data, alpha=.05)

输出

array([ 5, 14, 15, 15, 14, 19, 17, 16, 20, 22, 8, 21, 28, 11, 9, 29])

上述代码只是从加载库和数据开始,最后使用"测试"方法对该数据执行 Grubbs 测试。此测试检测两侧、左侧和右侧的异常值,或低于第一四分位数和高于第三四分位数的值。数据只有 1 个异常值 40,使用 Grubbs 测试将其删除。

单侧 Grubbs 测试

Synatx

grubbs.max_test(data, alpha=.05)

解释

在此方法中,用户必须调用 grubbs.min_test() 函数从提供的数据集中获取最小异常值,或调用 grubbs.max_test() 函数从提供的数据集中获取最大异常值,以便获得单侧 Grubb 检验。

示例

import numpy as np
from outliers import smirnov_grubbs as grubbs

#define data
data = np.array([5, 14, 15, 15, 14, 19, 17, 16, 20, 22, 8, 21, 28, 11, 9, 29, 40])

#执行格鲁布斯检验,判断最小值是否为异常值
print(grubbs.min_test(data, alpha=.05))

#执行格鲁布斯检验,判断最小值是否为异常值
grubbs.max_test(data, alpha=.05)

输出

[ 5 14 15 15 14 19 17 16 20 22 8 21 28 11 9 29 40]
array([ 5, 14, 15, 15, 14, 19, 17, 16, 20, 22, 8, 21, 28, 11, 9, 29])

单侧格鲁布斯检验检测出第一四分位数以下或第三四分位数以上的异常值。我们可以看到,min_test 方法从最小侧移除异常值,而 max_test 方法从数据的顶部移除异常值。

公式实现

这里我们将在 Python 中实现以下格鲁布斯检验公式。我们将使用 Numpy 和 Scipy 库来实现。

语法

g_calculated = numerator/sd_x
g_critical = ((n - 1) * np.sqrt(np.square(t_value_1))) / (np.sqrt(n) * np.sqrt(n - 2 + np.square(t_value_1)))

算法

实现步骤如下 −

  • 计算数据集的平均值值。

  • 计算数据集值的标准差。

  • 要实现 Grubbs 检验公式,请通过从数据集的平均值中减去每个值来计算分子。

  • 将分子值除以标准差以获得计算分数。

  • 计算相同值的临界分数。

  • 如果临界值大于计算值,则数据集中没有异常值,否则存在异常值。

示例

import numpy as np
import scipy.stats as stats
## 定义数据
x = np.array([12,13,14,19,21,23])
y = np.array([12,13,14,19,21,23,45])

## 实现 Grubbs 检验
def grubbs_test(x):
   n = len(x)
   mean_x = np.mean(x)
   sd_x = np.std(x)
   numerator = max(abs(x-mean_x))
   g_calculated = numerator/sd_x
   print("格鲁布斯计算值:",g_calculated)
   t_value_1 = stats.t.ppf(1 - 0.05 / (2 * n), n - 2)
   g_critical = ((n - 1) * np.sqrt(np.square(t_value_1))) / (np.sqrt(n) * np.sqrt(n - 2 + np.square(t_value_1)))
   print("格鲁布斯临界值:",g_critical)
   if g_critical > g_calculated:
      print("从格鲁布斯检验中我们可以看出,计算值小于临界值。承认零假设,并得出结论,没有异常值\n")
else:
    print("从格鲁布斯检验中我们可以看出,估计值超过了临界值。拒绝零假设,并得出结论,存在异常值\n")
grubbs_test(x)
grubbs_test(y)

输出

格鲁布斯计算值:1.4274928542926593
格鲁布斯临界值:1.887145117792422
从格鲁布斯检验中我们可以看出,计算值小于临界值。承认零假设,得出没有异常值的结论

Grubbs 计算值:2.2765147221587774
Grubbs 临界值:2.019968507680656
从 Grubbs 检验中我们可以看出估计值超过了临界值。拒绝零假设,得出存在异常值的结论

Grubb 检验的结果表明数组 x 没有任何异常值,但 y 有 1 个异常值。

结论

我们在本文中了解了 Python 中的异常值和 Grubbs 检验。让我们用几个要点来总结一下这篇文章。

  • 异常值是四分位数范围之外的记录。

  • 异常值不在数据集的正态分布中。

  • 我们可以使用 Grubbs 假设统计检验来检测异常值。

  • 我们可以使用 outlier_utils 库中提供的内置方法执行 Grubbs 检验。

  • 双侧 Grubbs 检验可检测并删除左侧和右侧的异常值。

  • 但是单侧 Grubbs 检验将检测任一侧的异常值。


相关文章