power#
- scipy.stats.power(test, rvs, n_observations, *, significance=0.01, vectorized=None, n_resamples=10000, batch=None, kwargs=None)[source]#
模拟在备择假设下假设检验的功效。
- 参数:
- testcallable
要模拟功效的假设检验。
test
必须是可调用对象,它接受一个样本(例如test(sample)
)或len(rvs)
个单独的样本(例如,如果 *rvs* 包含两个可调用对象且 *n_observations* 包含两个值,则test(samples1, sample2)
),并返回检验的 p 值。如果 *vectorized* 设置为True
,test
还必须接受一个关键字参数 *axis*,并且必须进行向量化以沿样本的提供的 *axis* 执行检验。scipy.stats
中任何具有 *axis* 参数且返回带有 *pvalue* 属性的对象的任何可调用对象也是可接受的。- rvscallable 或可调用对象元组
一个可调用对象或可调用对象序列,用于在备择假设下生成随机变量。*rvs* 的每个元素都必须接受关键字参数
size
(例如rvs(size=(m, n))
)并返回该形状的 N 维数组。如果 *rvs* 是一个序列,则 *rvs* 中可调用对象的数量必须与 *n_observations* 的元素数量匹配,即len(rvs) == len(n_observations)
。如果 *rvs* 是单个可调用对象,则 *n_observations* 被视为单个元素。- n_observations整数元组或整数数组元组
如果是整数序列,则每个整数是要传递给
test
的样本的大小。如果是整数数组序列,则模拟每组相应样本大小的功效。请参见示例。- significancefloat 或类数组 float,默认值:0.01
显著性阈值;即,p 值低于该阈值时,假设检验结果将被视为反对原假设的证据。等效地,原假设下可接受的 I 类错误率。如果是数组,则模拟每个显著性阈值的功效。
- kwargsdict,可选
要传递给 *rvs* 和/或
test
可调用对象的关键字参数。使用内省来确定可以将哪些关键字参数传递给每个可调用对象。与每个关键字对应的值必须是一个数组。数组必须可以彼此广播,并且可以与 *n_observations* 中的每个数组广播。模拟每组相应样本大小和参数的功效。请参见示例。- vectorizedbool,可选
如果 *vectorized* 设置为
False
,则不会将关键字参数 *axis* 传递给test
,并且期望仅对一维样本执行检验。如果是True
,则会将关键字参数 *axis* 传递给test
,并且期望在传递 N 维样本数组时沿 *axis* 执行检验。如果None
(默认),则如果axis
是test
的参数,则将 *vectorized* 设置为True
。使用向量化检验通常可以减少计算时间。- n_resamplesint,默认值:10000
从 *rvs* 的每个可调用对象中提取的样本数量。等效地,在备择假设下执行的检验的数量,以近似功效。
- batchint,可选
每次调用
test
时要处理的样本数量。内存使用量与 *batch* 和最大样本大小的乘积成正比。默认值为None
,在这种情况下,*batch* 等于 *n_resamples*。
- 返回:
- resPowerResult
具有属性的对象
- powerfloat 或 ndarray
针对备择假设的估计功效。
- pvaluesndarray
在备择假设下观察到的 p 值。
备注
功效模拟如下
在 *rvs* 指定的备择假设下,抽取多个随机样本(或样本集),每个样本的大小由 *n_observations* 指定。
对于每个样本(或样本集),根据
test
计算 p 值。这些 p 值记录在结果对象的pvalues
属性中。计算小于 *significance* 水平的 p 值比例。这是记录在结果对象的
power
属性中的功效。
假设 *significance* 是一个形状为
shape1
的数组,*kwargs* 和 *n_observations* 的元素可以相互广播到形状shape2
,并且test
返回形状为shape3
的 p 值数组。那么结果对象power
属性的形状将为shape1 + shape2 + shape3
,并且pvalues
属性的形状将为shape2 + shape3 + (n_resamples,)
。示例
假设我们希望在以下条件下模拟独立样本 t 检验的功效
第一个样本有 10 个观测值,这些观测值是从均值为 0 的正态分布中抽取的。
第二个样本有 12 个观测值,这些观测值是从均值为 1.0 的正态分布中抽取的。
显著性的 p 值阈值为 0.05。
>>> import numpy as np >>> from scipy import stats >>> rng = np.random.default_rng() >>> >>> test = stats.ttest_ind >>> n_observations = (10, 12) >>> rvs1 = rng.normal >>> rvs2 = lambda size: rng.normal(loc=1, size=size) >>> rvs = (rvs1, rvs2) >>> res = stats.power(test, rvs, n_observations, significance=0.05) >>> res.power 0.6116
对于大小分别为 10 和 12 的样本,在所选备择假设下,t 检验的功效(显著性阈值为 0.05)约为 60%。我们可以通过传递样本大小数组来研究样本大小对功效的影响。
>>> import matplotlib.pyplot as plt >>> nobs_x = np.arange(5, 21) >>> nobs_y = nobs_x >>> n_observations = (nobs_x, nobs_y) >>> res = stats.power(test, rvs, n_observations, significance=0.05) >>> ax = plt.subplot() >>> ax.plot(nobs_x, res.power) >>> ax.set_xlabel('Sample Size') >>> ax.set_ylabel('Simulated Power') >>> ax.set_title('Simulated Power of `ttest_ind` with Equal Sample Sizes') >>> plt.show()
或者,我们可以研究效应量对功效的影响。在这种情况下,效应量是第二个样本的基础分布的位置。
>>> n_observations = (10, 12) >>> loc = np.linspace(0, 1, 20) >>> rvs2 = lambda size, loc: rng.normal(loc=loc, size=size) >>> rvs = (rvs1, rvs2) >>> res = stats.power(test, rvs, n_observations, significance=0.05, ... kwargs={'loc': loc}) >>> ax = plt.subplot() >>> ax.plot(loc, res.power) >>> ax.set_xlabel('Effect Size') >>> ax.set_ylabel('Simulated Power') >>> ax.set_title('Simulated Power of `ttest_ind`, Varying Effect Size') >>> plt.show()
我们还可以使用
power
来估计检验的 I 类错误率(也称为歧义词“大小”),并评估其是否与标称水平匹配。例如,jarque_bera
的原假设是,样本是从具有与正态分布相同的偏度和峰度的分布中抽取的。为了估计 I 类错误率,我们可以将原假设视为真实的_备择_假设并计算功效。>>> test = stats.jarque_bera >>> n_observations = 10 >>> rvs = rng.normal >>> significance = np.linspace(0.0001, 0.1, 1000) >>> res = stats.power(test, rvs, n_observations, significance=significance) >>> size = res.power
如下所示,正如其文档中所提到的,对于如此小的样本,检验的 I 类错误率远低于标称水平。
>>> ax = plt.subplot() >>> ax.plot(significance, size) >>> ax.plot([0, 0.1], [0, 0.1], '--') >>> ax.set_xlabel('nominal significance level') >>> ax.set_ylabel('estimated test size (Type I error rate)') >>> ax.set_title('Estimated test size vs nominal significance level') >>> ax.set_aspect('equal', 'box') >>> ax.legend(('`ttest_1samp`', 'ideal test')) >>> plt.show()
正如人们可能从这种保守检验中预期的那样,对于某些备择假设,功效非常低。例如,在样本是从拉普拉斯分布中抽取的备择假设下,检验的功效可能不会比 I 类错误率大多少。
>>> rvs = rng.laplace >>> significance = np.linspace(0.0001, 0.1, 1000) >>> res = stats.power(test, rvs, n_observations, significance=0.05) >>> print(res.power) 0.0587
这不是 SciPy 实现中的错误;这仅仅是因为检验统计量的原分布是在假设样本大小很大(即接近无穷大)的情况下推导出来的,并且这种渐近近似对于小样本是不准确的。在这种情况下,重采样和蒙特卡罗方法(例如
permutation_test
、goodness_of_fit
、monte_carlo_test
)可能更合适。