scipy.stats.

fisher_exact#

scipy.stats.fisher_exact(table, alternative=None, *, method=None)[源代码]#

对列联表执行费舍尔精确检验。

对于 2x2 表,零假设是观测值背后的人群的真实比值比为 1,并且观测值是在一个条件下从这些人总体中采样的:所得表的边际值必须等于观察到的表的边际值。统计量是比值比的无条件最大似然估计,p 值是在零假设下获得至少与实际观察到的表一样极端的表的概率。

对于其他表大小,或者如果提供了 method,则零假设是表的行和列具有固定的总和并且是独立的;即,该表是从具有观测到的边际值的 scipy.stats.random_table 分布中采样的。统计量是此分布在 table 处评估的概率质量,p 值是统计量至少与 table 的统计量一样极端(小)的表总体中的百分比。只有一个备择假设可用:行和列不是独立的。

费舍尔精确检验还有其他可能的统计量选择和双边 p 值定义;请参阅注释以获取更多信息。

参数:
table整数数组类

列联表。元素必须是非负整数。

alternative{‘双边’, ‘小于’, ‘大于’}, 可选

为 2x2 表定义备择假设;对于其他表大小不使用。以下选项可用(默认为“双边”)

  • “双边”:潜在人群的比值比不为 1

  • “小于”:潜在人群的比值比小于 1

  • “大于”:潜在人群的比值比大于 1

有关更多详细信息,请参阅注释。

methodResamplingMethod, 可选

定义用于计算 p 值的方法。如果 methodPermutationMethod/MonteCarloMethod 的实例,则使用 scipy.stats.permutation_test/scipy.stats.monte_carlo_test 以及提供的配置选项和其他适当的设置来计算 p 值。请注意,如果 methodMonteCarloMethod 的实例,则必须将 rvs 属性保留为未指定;始终使用 scipy.stats.random_tablervs 方法绘制蒙特卡罗样本。否则,p 值的计算方法如注释中所述。

在版本 1.15.0 中新增。

返回:
resSignificanceResult

包含属性的对象

statisticfloat

对于具有默认 method 的 2x2 表,这是比值比 - 先验比值比而不是后验估计。在所有其他情况下,这是在零假设下获得观测表且边际值固定时观测表的概率密度。

pvaluefloat

在零假设下获得至少与实际观察到的表一样极端的表的概率。

引发:
ValueError

如果 table 不是二维的或具有负条目。

另请参阅

chi2_contingency

列联表中变量的独立性卡方检验。当表中的数字很大时,可以使用它作为 fisher_exact 的替代方法。

contingency.odds_ratio

计算 2x2 列联表的比值比(样本或条件 MLE)。

barnard_exact

巴纳德精确检验,它比 2x2 列联表的费舍尔精确检验更强大。

boschloo_exact

博什卢精确检验,它比 2x2 列联表的费舍尔精确检验更强大。

费舍尔精确检验

扩展示例

注释

零假设和 p 值

零假设是观测值背后的人群的真实比值比为 1,并且观测值是在一个条件下从这些人总体中随机采样的:所得表的边际值必须等于观察到的表的边际值。等效地,零假设是输入表来自具有参数(如在 hypergeom 中使用的)M = a + b + c + dn = a + bN = a + c 的超几何分布,其中输入表为 [[a, b], [c, d]]。此分布具有支撑 max(0, N + n - M) <= x <= min(N, n),或者,根据输入表中的值,min(0, a - d) <= x <= a + min(b, c)x 可以解释为 2x2 表的左上元素,因此分布中的表具有以下形式

[  x           n - x     ]
[N - x    M - (n + N) + x]

例如,如果

table = [6  2]
        [1  4]

则支撑为 2 <= x <= 7,并且分布中的表为

[2 6]   [3 5]   [4 4]   [5 3]   [6 2]  [7 1]
[5 0]   [4 1]   [3 2]   [2 3]   [1 4]  [0 5]

每个表的概率由超几何分布 hypergeom.pmf(x, M, n, N) 给出。对于此示例,这些为(四舍五入到三位有效数字)

x       2      3      4      5       6        7
p  0.0163  0.163  0.408  0.326  0.0816  0.00466

可以使用以下方法计算这些

>>> import numpy as np
>>> from scipy.stats import hypergeom
>>> table = np.array([[6, 2], [1, 4]])
>>> M = table.sum()
>>> n = table[0].sum()
>>> N = table[:, 0].sum()
>>> start, end = hypergeom.support(M, n, N)
>>> hypergeom.pmf(np.arange(start, end+1), M, n, N)
array([0.01631702, 0.16317016, 0.40792541, 0.32634033, 0.08158508,
       0.004662  ])

双边 p 值是根据零假设,随机表的概率等于或小于输入表的概率的概率。对于我们的示例,输入表(其中 x = 6)的概率为 0.0816。概率不超过此值的 x 值为 2、6 和 7,因此双边 p 值为 0.0163 + 0.0816 + 0.00466 ~= 0.10256

>>> from scipy.stats import fisher_exact
>>> res = fisher_exact(table, alternative='two-sided')
>>> res.pvalue
0.10256410256410257

alternative='greater' 的单边 p 值是随机表具有 x >= a 的概率,在我们的示例中为 x >= 6,或 0.0816 + 0.00466 ~= 0.08626

>>> res = fisher_exact(table, alternative='greater')
>>> res.pvalue
0.08624708624708627

这等效于在 x = 5 处计算分布的生存函数(比输入表中的 x 小 1,因为我们希望在总和中包括 x = 6 的概率)

>>> hypergeom.sf(5, M, n, N)
0.08624708624708627

对于 alternative='less',单侧 p 值是随机表具有 x <= a 的概率(即,在我们的示例中 x <= 6),或者 0.0163 + 0.163 + 0.408 + 0.326 + 0.0816 ~= 0.9949

>>> res = fisher_exact(table, alternative='less')
>>> res.pvalue
0.9953379953379957

这等价于计算分布在 x = 6 处的累积分布函数。

>>> hypergeom.cdf(6, M, n, N)
0.9953379953379957

优势比

计算出的优势比与 R 函数 fisher.test 计算的值不同。此实现返回“样本”或“无条件”最大似然估计,而 R 中的 fisher.test 使用条件最大似然估计。要计算优势比的条件最大似然估计,请使用 scipy.stats.contingency.odds_ratio

参考文献

[1]

Fisher, Sir Ronald A, “The Design of Experiments: Mathematics of a Lady Tasting Tea.” ISBN 978-0-486-41151-4, 1935.

[2]

“费舍尔精确检验”,https://en.wikipedia.org/wiki/Fisher's_exact_test

示例

>>> from scipy.stats import fisher_exact
>>> res = fisher_exact([[8, 2], [1, 5]])
>>> res.statistic
20.0
>>> res.pvalue
0.034965034965034975

对于形状不是 (2, 2) 的表格,请为 method 参数提供 scipy.stats.MonteCarloMethodscipy.stats.PermutationMethod 的实例。

>>> import numpy as np
>>> from scipy.stats import MonteCarloMethod
>>> rng = np.random.default_rng()
>>> method = MonteCarloMethod(rng=rng)
>>> fisher_exact([[8, 2, 3], [1, 5, 4]], method=method)
SignificanceResult(statistic=np.float64(0.005782), pvalue=np.float64(0.0603))

有关更详细的示例,请参阅 费舍尔精确检验