scipy.stats.

levene#

scipy.stats.levene(*samples, center='median', proportiontocut=0.05, axis=0, nan_policy='propagate', keepdims=False)[源代码]#

执行勒维涅检验,检验方差相等。

勒维涅检验检验了以下原假设:所有输入样本都来自具有相等方差的总体。在存在显著偏离正态分布的情况下,勒维涅检验是巴特利特检验 bartlett 的替代检验。

参数:
sample1,sample2,…array_like

样本数据,可能具有不同的长度。仅接受一维样本。

中心{‘mean’, ‘median’, ‘trimmed’}, 可选

在检验中使用数据的哪个函数。默认值为“中位数”。

proportiontocutfloat,可选

center 为‘trimmed’时,这给出了要从每端去掉的数据点的比例。(请参阅scipy.stats.trim_mean。)默认为 0.05。

axisint 或 None,默认为: 0

如果为 int,则此为输入计算统计信息的轴,输入的各个轴片(例如行)的统计信息将显示在输出的对应元素中。如果None,那么在计算统计信息之前,输入将被展开。

nan_policy{‘propagate’, ‘omit’, ‘raise’}

定义如何处理输入 NaN。

  • propagate:如果在计算统计信息时轴片(例如行)内存在 NaN,则输出的对应项将为 NaN。

  • omit:在执行计算时,将忽略 NaN。如果计算统计信息的轴片中没有足够的数据,则输出的对应项将为 NaN。

  • raise:如果出现 NaN,则将引发ValueError

keepdimsbool,默认为: False

如果设置为 True,则降维的轴仍以尺寸为 1 的维度的形式保留在结果中。如果使用此选项,则结果将针对输入数组正确广播。

返回:
statisticfloat

检验统计信息。

pvaluefloat

检验的p值。

另请参阅

fligner

k个方差的齐性检验的非参数测试

bartlett

k个方差在正态样本中的相等性检验

备注

Levene检验有三种形式,可推荐使用以下三种方法:

  • ‘median’ : 推荐用于偏斜(非正态)分布>。

  • ‘mean’ : 推荐对称、中等方差分布。

  • ‘trimmed’ : 推荐用于重尾分布。

使用均值的检验形式是在Levene最初的文章 ([2]) 中提出的,而中值和修剪均值已由 Brown 和 Forsythe ([3]) 研究,有时也称为 Brown-Forsythe 检验。

从 SciPy 1.9 开始,np.matrix 输入(不建议用于新代码)在计算执行之前被转换为 np.ndarray。在这种情况下,输出将是标量或形状合适的 np.ndarray,而不是 2D np.matrix。同样,虽然掩码数组的掩码元素会被忽略,但输出将是标量或 np.ndarray,而不是掩码为 mask=False 的掩码数组。

参考资料

[2]

Levene, H. (1960)。在对概率和统计学的贡献中:致哈罗德·霍特林的论文集,I. Olkin 等编辑,斯坦福大学出版社,第 278-292 页。

[3]

Brown, M. B. 和 Forsythe, A. B. (1974),美国统计协会杂志,69,364-367

[4]

C.I. BLISS (1952),生物测定的统计:对维生素的专门研究,第 499-503 页,DOI:10.1016/C2013-0-12584-6

[5]

B. Phipson 和 G. K. Smyth。“排列 P 值绝不应为零:当排列随机抽取时计算精确 P 值。”统计应用于遗传学和分子生物学 9.1 (2010)。

[6]

Ludbrook, J., & Dudley, H. (1998)。为什么排列检验优于生物医学研究中的 t 和 f 检验。美国统计学家 52(2),127-132。

示例

[4] 中,研究了维生素 C 对豚鼠牙齿生长的影响。在一项对照研究中,60 个受试者被分为小剂量、中剂量和大剂量组,分别接受每天 0.5、1.0 和 2.0 毫克的维生素 C。42 天后测量牙齿生长情况。

下面的 small_dosemedium_doselarge_dose 数组记录了三组牙齿生长的测量值(以微米为单位)。

>>> import numpy as np
>>> small_dose = np.array([
...     4.2, 11.5, 7.3, 5.8, 6.4, 10, 11.2, 11.2, 5.2, 7,
...     15.2, 21.5, 17.6, 9.7, 14.5, 10, 8.2, 9.4, 16.5, 9.7
... ])
>>> medium_dose = np.array([
...     16.5, 16.5, 15.2, 17.3, 22.5, 17.3, 13.6, 14.5, 18.8, 15.5,
...     19.7, 23.3, 23.6, 26.4, 20, 25.2, 25.8, 21.2, 14.5, 27.3
... ])
>>> large_dose = np.array([
...     23.6, 18.5, 33.9, 25.5, 26.4, 32.5, 26.7, 21.5, 23.3, 29.5,
...     25.5, 26.4, 22.4, 24.5, 24.8, 30.9, 26.4, 27.3, 29.4, 23
... ])

levene 统计量对样本之间的方差差异很敏感。

>>> from scipy import stats
>>> res = stats.levene(small_dose, medium_dose, large_dose)
>>> res.statistic
0.6457341109631506

当方差差异很大时,该统计量倾向于很高。

我们可以通过比较统计量的观察值与零分布(即在三个群体的总体方差相等的零假设下推导出的统计量值分布)来检验这些组之间的方差是否不相等。

对于此检验,零分布服从如下所示的 F 分布。

>>> import matplotlib.pyplot as plt
>>> k, n = 3, 60   # number of samples, total number of observations
>>> dist = stats.f(dfn=k-1, dfd=n-k)
>>> val = np.linspace(0, 5, 100)
>>> pdf = dist.pdf(val)
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> def plot(ax):  # we'll reuse this
...     ax.plot(val, pdf, color='C0')
...     ax.set_title("Levene Test Null Distribution")
...     ax.set_xlabel("statistic")
...     ax.set_ylabel("probability density")
...     ax.set_xlim(0, 5)
...     ax.set_ylim(0, 1)
>>> plot(ax)
>>> plt.show()
../../_images/scipy-stats-levene-1_00_00.png

比较通过 p 值量化:在空值分布中大于或等于统计值观测值的比例。

>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> plot(ax)
>>> pvalue = dist.sf(res.statistic)
>>> annotation = (f'p-value={pvalue:.3f}\n(shaded area)')
>>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
>>> _ = ax.annotate(annotation, (1.5, 0.22), (2.25, 0.3), arrowprops=props)
>>> i = val >= res.statistic
>>> ax.fill_between(val[i], y1=0, y2=pdf[i], color='C0')
>>> plt.show()
../../_images/scipy-stats-levene-1_01_00.png
>>> res.pvalue
0.5280694573759905

如果 p 值“小” - 即,从具有相等方差的分布中抽样数据而产生如此极端统计值的概率很低 - 这可以作为证据驳斥空假设,支持备择假设:组的方差不相等。请注意

  • 反之不然;也就是说,该检验不用于为支持空假设提供证据。

  • 将被视为“小”的值的阈值是一个选择,应当在分析数据之前做出 [5],同时要考虑假阳性(不正确地拒绝空假设)和假阴性(未能拒绝错误的空假设)的风险。

  • 小 p 值并不是作用的证据;相反,它们只能为“显着”作用提供证据,这意味着它们在空假设下不太可能发生。

请注意,F 分布提供了空值分布的渐近近似值。对于小样本,执行置换检验可能更合适:根据所有三个样本都从同一总体中抽取的空假设,每个测量值在三个样本中的任何一个中观测到的可能性均相等。因此,我们可以通过计算观察值随机划分为这三个样本的许多随机生成划分下的统计值来形成随机空值分布。

>>> def statistic(*samples):
...     return stats.levene(*samples).statistic
>>> ref = stats.permutation_test(
...     (small_dose, medium_dose, large_dose), statistic,
...     permutation_type='independent', alternative='greater'
... )
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> plot(ax)
>>> bins = np.linspace(0, 5, 25)
>>> ax.hist(
...     ref.null_distribution, bins=bins, density=True, facecolor="C1"
... )
>>> ax.legend(['aymptotic approximation\n(many observations)',
...            'randomized null distribution'])
>>> plot(ax)
>>> plt.show()
../../_images/scipy-stats-levene-1_02_00.png
>>> ref.pvalue  # randomized test p-value
0.4559  # may vary

请注意,这里计算的 p 值与上述 levene 返回的渐近近似值之间存在显着差异。可以通过置换检验严格得出的统计推论是有限的;然而,在许多情况下它们可能仍是首选方法 [6]

以下是空假设将被拒绝的另一个通用示例。

检验列表 abc 是否来自方差相等的总体。

>>> a = [8.88, 9.12, 9.04, 8.98, 9.00, 9.08, 9.01, 8.85, 9.06, 8.99]
>>> b = [8.88, 8.95, 9.29, 9.44, 9.15, 9.58, 8.36, 9.18, 8.67, 9.05]
>>> c = [8.95, 9.12, 8.95, 8.85, 9.03, 8.84, 9.07, 8.98, 8.86, 8.98]
>>> stat, p = stats.levene(a, b, c)
>>> p
0.002431505967249681

小 p 值表明这些总体没有相等的方差。

这并不奇怪,因为b 的样本方差远大于ac

>>> [np.var(x, ddof=1) for x in [a, b, c]]
[0.007054444444444413, 0.13073888888888888, 0.008890000000000002]