我想使用基于置换的替代scipy.stats.ttest_1samp
来检验我观察到的平均值是否明显大于零。我偶然发现了scipy.stats.permutation_test
,但我不确定这是否也可以用于我的情况?我还偶然发现了mne.stats.permutation_t_test
,它似乎能做我想做的事情,但如果可以的话,我想坚持使用scipy
。
示例:
import numpy as np
from scipy import stats
# create data
np.random.seed(42)
rvs = np.random.normal(loc=5,scale=5,size=100)
# compute one-sample t-test
t,p = stats.ttest_1samp(rvs,popmean=0,alternative='greater')
发布于 2022-09-06 02:16:51
这个测试可以用permutation_test
执行。使用permutation_type='samples'
,它“改变”了观察的迹象。假设数据已按上述方式生成,则测试可以执行如下
from scipy import stats
def t_statistic(x, axis=-1):
return stats.ttest_1samp(x, popmean=0, axis=axis).statistic
res = stats.permutation_test((rvs,), t_statistic, permutation_type='samples')
print(res.pvalue)
如果您只关心p值,您可以使用np.mean
而不是t_statistic
获得相同的结果。
诚然,对于只有一个示例的permutation_type='samples'
来说,这种行为在文档中有点隐藏。
因此,如果数据只包含一个样本,则通过独立地更改每个观察的符号来形成空分布。
但是产生相同p值的测试也可以作为两个样本进行,其中第二个样本是数据的负值。为了避免特殊情况,这实际上是permutation_test
在幕后所做的事情。
在本例中,上面的示例代码现在比permutation_test
快得多。不过,我将尝试对SciPy 1.10进行改进。
发布于 2022-09-02 08:07:58
基于当前的文档,似乎不能用permutation_test
函数实现一个样本t检验的等效值。但是可以使用numpy
实现它,如下所示。这是基于R实现(发现的这里)和交叉验证上的这线程,可以选择执行单边测试和针对特定均值的测试。
import numpy as np
def permutation_ttest_1samp(
data, popmean, n_resamples, alternative='two-sided', random_state=None
):
assert alternative in ('two-sided', 'less', 'greater'), (
"Unrecognized alternative hypothesis"
)
n = len(data)
data = np.asarray(data) - popmean
dbar = np.mean(data)
absx = np.abs(data)
z = []
rng = np.random.RandomState(random_state)
for _ in range(n_resamples):
mn = rng.choice((-1,1), n, replace=True)
xbardash = np.mean(mn * absx)
z.append(xbardash)
z = np.array(z)
if alternative == 'greater':
return 1 - (np.sum(z <= -np.abs(dbar)) / n_resamples)
elif alternative == 'less':
return np.sum(z <= -np.abs(dbar)) / n_resamples
return (
(np.sum(z >= np.abs(dbar)) + np.sum(z <= -np.abs(dbar))) / n_resamples
)
示例1(对均值为0的空假设进行的双边检验):
rng = np.random.RandomState(42)
rvs = rng.normal(loc=0, scale=0.01, size=1000)
pval = permutation_ttest_1samp(rvs, 0, 100_000, alternative='two-sided', random_state=42)
print(pval)
# 0.53206
与参数化t检验相比:
from scipy.stats import ttest_1samp
stat, pval = ttest_1samp(rvs, popmean=0, alternative='two-sided')
print(pval)
# 0.5325672436623021
例2(对非零均值零假设的单边检验)
rng = np.random.RandomState(42)
rvs = rng.normal(loc=0, scale=3, size=1000)
pval = permutation_ttest_1samp(rvs, 0.1, 100_000, alternative='greater', random_state=42)
print(pval)
# 0.6731
与参数化t检验相比:
from scipy.stats import ttest_1samp
stat, pval = ttest_1samp(rvs, popmean=0.1, alternative='greater')
print(pval)
# 0.6743729530216749
https://stackoverflow.com/questions/73569894
复制相似问题