scipy.stats.

bartlett#

scipy.stats.bartlett(*samples, axis=0, nan_policy='propagate', keepdims=False)[源代码]#

执行 Bartlett 的方差相等检验。

Bartlett 的检验针对所有输入样本来自方差相等的总体这一零假设进行检验。对于来自显著非正态总体的样本,Levene 的检验 levene 更加稳健。

参数:
sample1, sample2, …array_like

样本数据的数组。仅接受 1d 数组,它们可能具有不同的长度。

axisint 或 None,默认值:0

如果为 int,则为计算统计量时输入的轴。输入的每个轴切片(例如行)的统计量将显示在输出的相应元素中。如果 None,则在计算统计量之前将对输入进行拉伸。

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

定义如何处理输入 NaN。

  • 传播:如果在统计数据计算的轴切片(例如行)中存在 NaN,输出的相应条目将为 NaN。

  • 忽略:执行计算时,将忽略 NaN。如果沿统计数据计算的轴切片中的数据量不足,输出的相应条目将为 NaN。

  • 提升:如果存在 NaN,则将提升一个 ValueError

保持维度布尔值,默认值:False

如果将此项设置为 True,则被减少的轴将以大小为一的维度保留在结果中。通过这个选项,结果将针对输入数组正确广播。

返回:
统计数据浮点数

检验统计数据。

p 值浮点数

检验的 p 值。

请参见

fligner

k 个方差相等的非参数检验

levene

k 个方差相等的稳健参数检验

备注

Conover 等人 (1981) 广泛模拟来检验现有的许多参数检验和非参数检验,得出的结论是 Fligner 和 Killeen (1976) 和 Levene (1960) 提出的检验在鲁棒性离散正态性和威力方面似乎很出色([3])。

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

参考资料

[2]

Snedecor, George W. 和 Cochran, William G. (1989),统计方法,第八版,爱荷华州立大学出版社。

[3]

Park, C. 和 Lindsay, B. G. (1999)。基于二次推理函数的稳健尺度估计和假设检验。技术报告 99-03,似然研究中心,宾夕法尼亚州立大学。

[4]

Bartlett, M. S. (1937)。充分性和统计检验的属性。伦敦皇家学会学报。系列 A,数学和物理科学,卷。160,901 期,第 268-282 页。

[5]

C.I. BLISS (1952),生物测定的统计学:特别参考维生素,第 499-503 页,DOI:10.1016/C2013-0-12584-6

[6]

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

[7]

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

示例

[5] 中,研究了维生素 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
... ])

bartlett 统计信息对样本间方差的差异很敏感。

>>> from scipy import stats
>>> res = stats.bartlett(small_dose, medium_dose, large_dose)
>>> res.statistic
0.6654670663030519

当方差存在较大差异时,统计信息的值往往较高。

我们可以通过将统计信息的观察值与此分布进行比较,来检验组间方差是否相等:这一分布是在零假设(三组的总体方差相等)下得出的统计信息值分布。

对于此项检验,零假设分布遵循如下所示的卡方分布。

>>> import matplotlib.pyplot as plt
>>> k = 3  # number of samples
>>> dist = stats.chi2(df=k-1)
>>> 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("Bartlett 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-bartlett-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-bartlett-1_01_00.png
>>> res.pvalue
0.71696121509966

如果 p 值“小” - 也就是说,如果从具有相同方差的分布中抽样数据的概率很低,并且产生了如此极端的统计信息值 - 这可作为反对零假设、支持备择假设(组的方差不相等)的证据。请注意

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

  • 被认为“小”的值的门槛是一个应在分析数据之前做出[6]的选择,并考虑假阳性(错误地拒绝零假设)和假阴性(未能拒绝错误的零假设)的风险。

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

请注意,卡方分布提供了观测值呈正态分布时的零分布。对于从非正态总体抽取的小样本,执行置换检验可能更合适:在所有三个样本均从同一总体抽取的零假设下,在三个样本中的任何一个样本中观测到每个测量值的可能性都相等。因此,我们可以通过计算观测值随机分区到三个样本的许多随机生成分区下的统计数据,来形成随机的零分布。

>>> def statistic(*samples):
...     return stats.bartlett(*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-bartlett-1_02_00.png
>>> ref.pvalue  # randomized test p-value
0.5387  # may vary

请注意,此处计算的 p 值与 bartlett 返回的渐近近似值之间存在显著分歧。可以严格从置换检验中得出统计推论是有限的;尽管如此,在许多情况下它们可能是首选方法 [7]

接下来是另一个将拒绝零假设的通用示例。

检验列表 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.bartlett(a, b, c)
>>> p
1.1254782518834628e-05

极小的 p 值表明这些总体方差不相等。

这并不令人意外,因为 b 的样本方差远大于 ac 的方差

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