如何在 Python 中执行双样本单尾 t 检验
How to perform two-sample, one-tailed t-test in Python
我想执行双样本单尾 t 检验来比较两种均值。对于我正在寻找的具体问题,我希望比较只在一个方向上。我希望原假设是 mu_2 > mu_1
,备择假设是 mu_1 <= mu_2
。或者原假设仍然是 mu_1 - mu_2 = 0
,即使是单尾情况?
我正在处理一个大型数据集,但如果我要提取和舍入参数,data_1 是 mu_1 = 4.3, s_1 = 4.8, and n_1 = 40000
,data_2 是 mu_2 = 4.9, s_2 = 4.4, n_2 = 30000
.我正在使用 scipy 执行双样本 t 检验:
stats.ttest_ind(data1,
data2,
equal_var = False)
鉴于 scipy 仅考虑双尾测试,我不确定如何解释这些值。 Ttest_indResult(statistic=-19.51646312898464, pvalue=1.3452106729078845e-84)
。 alpha 值为 0.05,p 值远小于原假设被拒绝的值。然而,我的直觉告诉我不应拒绝零假设,因为 mu_2 明显大于 mu_1(至少我希望 p 值更大)。因此,我觉得我要么错误地解释了结果,要么需要额外的计算才能得到正确的答案。
如果有任何额外的帮助和指导,我将不胜感激。谢谢!
你是对的,如果你做的是单侧检验,它应该有一个大的 p 值。 ttest_ind
执行双侧检验,它给出了您观察到比 t 统计量的绝对值更极端的东西的概率。
要进行单边 t 检验,您可以使用 cdf,它是 t 统计量的概率总和。
稍微修改this code:
def welch_ttest(x1, x2,alternative):
n1 = x1.size
n2 = x2.size
m1 = np.mean(x1)
m2 = np.mean(x2)
v1 = np.var(x1, ddof=1)
v2 = np.var(x2, ddof=1)
tstat = (m1 - m2) / np.sqrt(v1 / n1 + v2 / n2)
df = (v1 / n1 + v2 / n2)**2 / (v1**2 / (n1**2 * (n1 - 1)) + v2**2 / (n2**2 * (n2 - 1)))
if alternative == "equal":
p = 2 * t.cdf(-abs(tstat), df)
if alternative == "lesser":
p = t.cdf(tstat, df)
if alternative == "greater":
p = 1-t.cdf(tstat, df)
return tstat, df, p
我模拟了一些数据:
import numpy as np
from scipy.stats import ttest_ind
from scipy.stats import t
np.random.seed(seed=123)
data1 = np.random.normal(4.3,4.8,size=40000)
np.random.seed(seed=123)
data2 = np.random.normal(4.9,4.4,size=30000)
ndf = len(data1) +len(data2) - 2
ttest_ind(data1,data2,equal_var = False)
Ttest_indResult(statistic=-16.945279258324227, pvalue=2.8364816571790452e-64)
你会得到类似于你的结果,我们可以测试上面的代码是否有替代 == "equal",这是一个双向测试:
welch_ttest(data1,data2,"equal")
(<scipy.stats._continuous_distns.t_gen at 0x12472b128>,
67287.08544468222,
2.8364816571790452e-64)
您可以使用与 scipy 2 侧 t 检验相同的 p 值,现在我们进行您需要的单侧检验:
welch_ttest(data1,data2,"greater")
(<scipy.stats._continuous_distns.t_gen at 0x12472b128>, 67287.08544468222, 1.0)
我为 t 检验 p 值计算提供了另一种解决方案。
from scipy.stats import ttest_ind
def t_test(x,y,alternative='both-sided'):
_, double_p = ttest_ind(x,y,equal_var = False)
if alternative == 'both-sided':
pval = double_p
elif alternative == 'greater':
if np.mean(x) > np.mean(y):
pval = double_p/2.
else:
pval = 1.0 - double_p/2.
elif alternative == 'less':
if np.mean(x) < np.mean(y):
pval = double_p/2.
else:
pval = 1.0 - double_p/2.
return pval
SciPy >= 1.6
您现在可以根据文档使用“替代”参数进行双样本单尾测试。在下面的示例中,我使用的是“less”,但这些是替代选项{‘two-sided’, ‘less’, ‘greater’}
https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ttest_ind.html
from scipy.stats import ttest_ind
ttest, pval = ttest_ind(data1, data2, alternative="less")
print("t-test", '{0:.10f}'.format(ttest[0]))
print("p-value", '{0:.10f}'.format(pval[0]))
if pval <0.05:
print("we reject null hypothesis")
else:
print("we accept null hypothesis")
我想执行双样本单尾 t 检验来比较两种均值。对于我正在寻找的具体问题,我希望比较只在一个方向上。我希望原假设是 mu_2 > mu_1
,备择假设是 mu_1 <= mu_2
。或者原假设仍然是 mu_1 - mu_2 = 0
,即使是单尾情况?
我正在处理一个大型数据集,但如果我要提取和舍入参数,data_1 是 mu_1 = 4.3, s_1 = 4.8, and n_1 = 40000
,data_2 是 mu_2 = 4.9, s_2 = 4.4, n_2 = 30000
.我正在使用 scipy 执行双样本 t 检验:
stats.ttest_ind(data1,
data2,
equal_var = False)
鉴于 scipy 仅考虑双尾测试,我不确定如何解释这些值。 Ttest_indResult(statistic=-19.51646312898464, pvalue=1.3452106729078845e-84)
。 alpha 值为 0.05,p 值远小于原假设被拒绝的值。然而,我的直觉告诉我不应拒绝零假设,因为 mu_2 明显大于 mu_1(至少我希望 p 值更大)。因此,我觉得我要么错误地解释了结果,要么需要额外的计算才能得到正确的答案。
如果有任何额外的帮助和指导,我将不胜感激。谢谢!
你是对的,如果你做的是单侧检验,它应该有一个大的 p 值。 ttest_ind
执行双侧检验,它给出了您观察到比 t 统计量的绝对值更极端的东西的概率。
要进行单边 t 检验,您可以使用 cdf,它是 t 统计量的概率总和。
稍微修改this code:
def welch_ttest(x1, x2,alternative):
n1 = x1.size
n2 = x2.size
m1 = np.mean(x1)
m2 = np.mean(x2)
v1 = np.var(x1, ddof=1)
v2 = np.var(x2, ddof=1)
tstat = (m1 - m2) / np.sqrt(v1 / n1 + v2 / n2)
df = (v1 / n1 + v2 / n2)**2 / (v1**2 / (n1**2 * (n1 - 1)) + v2**2 / (n2**2 * (n2 - 1)))
if alternative == "equal":
p = 2 * t.cdf(-abs(tstat), df)
if alternative == "lesser":
p = t.cdf(tstat, df)
if alternative == "greater":
p = 1-t.cdf(tstat, df)
return tstat, df, p
我模拟了一些数据:
import numpy as np
from scipy.stats import ttest_ind
from scipy.stats import t
np.random.seed(seed=123)
data1 = np.random.normal(4.3,4.8,size=40000)
np.random.seed(seed=123)
data2 = np.random.normal(4.9,4.4,size=30000)
ndf = len(data1) +len(data2) - 2
ttest_ind(data1,data2,equal_var = False)
Ttest_indResult(statistic=-16.945279258324227, pvalue=2.8364816571790452e-64)
你会得到类似于你的结果,我们可以测试上面的代码是否有替代 == "equal",这是一个双向测试:
welch_ttest(data1,data2,"equal")
(<scipy.stats._continuous_distns.t_gen at 0x12472b128>,
67287.08544468222,
2.8364816571790452e-64)
您可以使用与 scipy 2 侧 t 检验相同的 p 值,现在我们进行您需要的单侧检验:
welch_ttest(data1,data2,"greater")
(<scipy.stats._continuous_distns.t_gen at 0x12472b128>, 67287.08544468222, 1.0)
我为 t 检验 p 值计算提供了另一种解决方案。
from scipy.stats import ttest_ind
def t_test(x,y,alternative='both-sided'):
_, double_p = ttest_ind(x,y,equal_var = False)
if alternative == 'both-sided':
pval = double_p
elif alternative == 'greater':
if np.mean(x) > np.mean(y):
pval = double_p/2.
else:
pval = 1.0 - double_p/2.
elif alternative == 'less':
if np.mean(x) < np.mean(y):
pval = double_p/2.
else:
pval = 1.0 - double_p/2.
return pval
SciPy >= 1.6
您现在可以根据文档使用“替代”参数进行双样本单尾测试。在下面的示例中,我使用的是“less”,但这些是替代选项{‘two-sided’, ‘less’, ‘greater’}
https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ttest_ind.html
from scipy.stats import ttest_ind
ttest, pval = ttest_ind(data1, data2, alternative="less")
print("t-test", '{0:.10f}'.format(ttest[0]))
print("p-value", '{0:.10f}'.format(pval[0]))
if pval <0.05:
print("we reject null hypothesis")
else:
print("we accept null hypothesis")