You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中均值差T统计量计算结果差异的原因咨询

合并方差T检验手动实现与scipy结果差异的原因分析

我重学基础统计学时,尝试用两种方式计算均值差的T统计量和p值:一是手动编写合并方差T检验公式的Python函数,二是生成符合指定参数的正态分布数据后用scipy.stats.ttest_ind计算,但两者结果差异明显,手动实现的结果更接近参考示例,我疑惑大样本近似正态分布的情况下为何偏差这么大,以下是具体分析:

两种实现的代码与结果

生成分布法(基于随机样本)

from numpy.random import normal
from scipy import stats
import math

# 生成符合指定参数的正态分布样本
data1 = normal(loc=65.2, scale=7.8, size=30)
data2 = normal(loc=70.3, scale=8.4, size=30)

# 执行独立样本T检验
stats.ttest_ind(a=data1, b=data2)

结果:T统计量约为-2.0298,p值约为0.0470

手动实现(基于给定总体参数)

import math
from scipy import stats

def pop_2_mean_pooled_t(mean1, mean2, s1, s2, n1, n2):
    dof = (n1+n2)-2
    mean_diff = mean1 - mean2
    # 计算标准误的样本量部分
    right_n = math.sqrt((1/n1) + (1/n2))
    # 计算合并方差的平方根Sp
    sp_num_left = ((n1-1)*(s1**2))
    sp_num_right = ((n2-1)*(s2**2))
    sp = math.sqrt((sp_num_left + sp_num_right)/(dof))
    # 计算标准误
    pooled_se = sp * right_n
    # 计算T统计量
    t = mean_diff / pooled_se
    # 计算单侧p值
    p = stats.t.cdf(t, dof)
    print(f"T is {t}")
    print(f"p is {p}")
    return t, p

# 代入给定的总体参数计算
pop_2_mean_pooled_t(65.2, 70.3, 7.8, 8.4, 30, 30)

结果:T统计量约为-2.4369,p值约为0.0090

差异产生的核心原因

  1. 计算依据不同:

    • 手动实现直接使用给定的总体均值、总体标准差进行计算,得到的是理论上的T统计量和p值,这也是参考示例的计算逻辑。
    • 生成分布法中,normal()生成的是随机样本,样本的均值、标准差会和设定的loc(总体均值)、scale(总体标准差)存在抽样误差——哪怕是30个样本的大样本,抽样变异依然存在。scipy.stats.ttest_ind是基于这些样本统计量计算的,结果自然会和理论值有偏差。
  2. 随机样本的波动性:
    如果你多次运行生成分布法的代码,会发现每次得到的T统计量和p值都不一样,这是因为每次生成的随机样本都有差异。而手动实现的结果是固定的,因为它用的是固定的总体参数。

  3. 验证方式:
    如果想让scipy.stats.ttest_ind的结果接近手动值,可以构造严格符合总体参数的数据集(比如让样本均值恰好等于65.2和70.3,样本标准差恰好等于7.8和8.4),或者直接用手动计算中的统计量代入公式,此时两者结果会一致。

内容的提问来源于stack exchange,提问作者a0a912

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 17:40:39