python - scipy.stats 中 ttest 的两种实现的不同结果

标签 python python-3.x scipy statistics

这里有两种在 scipy 中进行独立 t 检验(welch 版本)的方法。两者对计算的 p 值以及 t 统计量本身给出了不同的结果?为什么会这样?

import scipy
print(scipy.__version__)
# 1.4.1
from scipy.stats import ttest_ind, ttest_ind_from_stats
x1_a = [19.0924, 19.1055, 19.1192, 19.1431, 19.0970]
x1_b = [20.3323, 20.3472, 20.3417, 20.3408, 20.2849]
x1_c = [19.0448, 18.9576, 19.0171, 19.0184, 18.9534]
ttest_ind(x1_a, x1_c, equal_var=False)
# Ttest_indResult(statistic=5.568858312509857, pvalue=0.0014998806395224108)
ttest_ind_from_stats(np.mean(x1_a), np.std(x1_a), 5, np.mean(x1_c), np.std(x1_c), 5, equal_var=False)
# Ttest_indResult(statistic=6.226172871918404, pvalue=0.000844418100098984)
ttest_ind(x1_a, x1_b, equal_var=False)
# Ttest_indResult(statistic=-83.49461195258749, pvalue=1.3516515130741807e-12)
ttest_ind_from_stats(np.mean(x1_a), np.std(x1_a), 5, np.mean(x1_b), np.std(x1_b), 5, equal_var=False)
# Ttest_indResult(statistic=-93.34981404047603, pvalue=5.764760941006529e-13)

我试图排除可能的原因,包括通过输入np.sqrt(np.var(x))而不是np.std(x)来检查可能的舍入问题)),使用维基百科解释编写自定义测试函数,该函数给出类似于 ttest_ind_from_stats 的结果,尝试多个值,手动计算 sds 以避免 n-1 code>/n 问题并尝试阅读源代码文档,但似乎 ttest_ind 在内部使用 _ttest_ind_from_stats 这引起了我的困惑。这是我的自定义函数:

from scipy.stats import t as tdist
def welch_ttest(m1, m2, s1, s2, n1, n2):
    numerator = m1 - m2
    denominator = np.sqrt((s1 ** 2) / n1 + (s2 ** 2) / n2)
    t = numerator / denominator
    dof_numerator = ((s1 ** 2) / n1 + (s2 ** 2) / n2) ** 2
    dof_denominator = ((s1 ** 4) / (n1 ** 2) / (n1 - 1) + (s2 ** 4) / (n2 ** 2) / (n2 - 1))
    dof = dof_numerator / dof_denominator
    p_half = tdist.cdf(t, dof)
    if p_half > 0.5:
        p_final = 2 * (1 - p_half)
    else:
        p_final = 2 * p_half
    return t, p_final  # returning t to check the validity of the function

最佳答案

np.std 不执行 Bessel's correction 。如果替换为 pandas 版本的 std,则结果匹配:

ttest_ind(x1_a, x1_c, equal_var=False)                                                             
# Ttest_indResult(statistic=5.568858312509857, pvalue=0.0014998806395224108)

ttest_ind_from_stats(np.mean(x1_a), pd.Series(x1_a).std(), 5, np.mean(x1_c), pd.Series(x1_c).std(), 5, equal_var=False)                                                                               
# Ttest_indResult(statistic=5.568858312509857, pvalue=0.0014998806395224108)

或者,如果您不需要额外的导入,只需将 std 乘以 sqrt(n/n-1)

关于python - scipy.stats 中 ttest 的两种实现的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64199528/

相关文章:

python - 在 Scikit-image 中移动图像 [Python]

python - 从另一个模型向序列化器添加额外的字段

python - 使用 scipy.optimize.curve_fit

python - 使用 SciPy 对 3d 数据进行插值时如何提高性能

python - 如何使用 Scipy 和一维数组正确 reshape N 维插值的值?

python - 如何构建一个使用多个属性的基于内容的推荐系统?

Python - 我如何知道何时按下表单按钮? (登出)

python - 解码 JSON 字符串中的 UTF-8 编码

python - set_column 未将颜色格式应用于大型 Excel 文件的列

python - KFold 交叉验证无法修复过度拟合