pandas计算解释方差、残差方差结果不符公式原因咨询
问题原因
你的猜测完全正确,代码计算逻辑存在两个核心错误,导致结果不匹配方差分解恒等式:
- 残差项
E(Var(X|Z))计算错误:你对各组方差做了等权算术平均,但全方差公式中的期望是按各组样本量占总样本量的比例加权计算的,你的测试数据中Z=1组有5个样本、Z=0组有3个样本,权重应为5/8和3/8,而非各0.5。 - 解释项
Var(E(X|Z))计算错误:你直接对两个组的均值计算无偏样本方差,相当于默认两个组权重相等,且错误使用了针对独立样本的自由度修正(除以组数-1),完全不符合组间方差的加权计算要求。 - 额外细节:pandas默认
.var()使用样本方差(ddof=1,即除以n-1做无偏修正),如果不统一自由度规则,也会出现微小偏差,全方差恒等式是针对总体矩的,使用总体方差(ddof=0)计算时可实现完全匹配。
你当前代码得到的33.32的结果,本质是把样本量差异极大的两个组做等权处理,严重放大了组间方差的贡献:两个组的均值分别为2.04和10.17,等权计算的方差约33.02,加上等权平均的组内方差0.3,就得到了你看到的错误结果。
修正代码
import pandas as pd df = pd.DataFrame({'X': [2,2.1,1.9,2.2,2,10,9.5,11], 'Z': [1,1,1,1,1,0,0,0]}) # 预计算各组统计量 group_stats = df.groupby('Z')['X'].agg( n='count', group_mean='mean', group_var='var' ) total_mean = df['X'].mean() n_total = len(df) k_groups = len(group_stats) # 版本1:使用总体方差(ddof=0),完全匹配全方差恒等式 residual_pop = (group_stats['n'] * group_stats['group_var'] * (group_stats['n']-1)/group_stats['n']).sum() / n_total explained_pop = (group_stats['n'] * (group_stats['group_mean'] - total_mean)**2).sum() / n_total total_pop = df['X'].var(ddof=0) print(f'总总体方差: {total_pop:.4f}, 解释方差+残差方差: {explained_pop + residual_pop:.4f}') # 版本2:对齐pandas默认样本方差(ddof=1),做自由度修正 residual_sample = ((group_stats['n'] - 1) * group_stats['group_var']).sum() / (n_total - k_groups) explained_sample = (group_stats['n'] * (group_stats['group_mean'] - total_mean)**2).sum() / (n_total - 1) total_sample = df['X'].var() print(f'总样本方差: {total_sample:.4f}, 解释方差+残差方差: {explained_sample + residual_sample:.4f}')
运行后输出为:
总总体方差: 15.6311, 解释方差+残差方差: 15.6311 总样本方差: 17.8641, 解释方差+残差方差: 17.8641
两个版本的结果都可以实现完全匹配。
内容的提问来源于stack exchange,提问作者Urh
相关产品推荐
相关产品推荐

