在statsmodels中如何获取无截距的全对比效应结果?
问题描述
考虑以下简单示例:
import pandas as pd from statsmodels.formula.api import ols url = "https://stats.idre.ucla.edu/stat/data/hsb2.csv" hsb2 = pd.read_table(url, delimiter=",") hsb2.head() # 输出示例: # id female race ses schtyp prog read write math science socst # 0 70 0 4 1 1 1 57 52 41 47 57 # 1 121 1 4 2 1 3 68 59 53 63 61
我有两个感兴趣的分类变量(race和female),希望计算这两个变量所有可能组合对应的read分数均值的t统计量。目前可以通过statsmodels中的C()符号,将write对这两个分类变量的全交互项进行回归,间接获取该信息:
mod = ols("write ~ C(race)*C(female)", data=hsb2) res = mod.fit() print(res.summary())
回归输出如下:
OLS Regression Results ============================================================================== Dep. Variable: write R-squared: 0.171 Model: OLS Adj. R-squared: 0.140 Method: Least Squares F-statistic: 5.642 Date: Fri, 25 Aug 2023 Prob (F-statistic): 6.16e-06 Time: 11:02:32 Log-Likelihood: -714.39 No. Observations: 200 AIC: 1445. Df Residuals: 192 BIC: 1471. Df Model: 7 Covariance Type: nonrobust =============================================================================================== coef std err t P>|t| [0.025 0.975] ----------------------------------------------------------------------------------------------- Intercept 44.3846 2.437 18.210 0.000 39.577 49.192 C(race)[T.2] 11.2821 5.629 2.004 0.046 0.180 22.385 C(race)[T.3] 2.6154 4.120 0.635 0.526 -5.511 10.742 C(race)[T.4] 6.9095 2.660 2.597 0.010 1.663 12.156 C(female)[T.1] 4.5245 3.600 1.257 0.210 -2.577 11.626 C(race)[T.2]:C(female)[T.1] -1.3161 6.954 -0.189 0.850 -15.032 12.400 C(race)[T.3]:C(female)[T.1] -2.6783 5.471 -0.490 0.625 -13.470 8.113 C(race)[T.4]:C(female)[T.1] 0.6749 3.886 0.174 0.862 -6.990 8.340 ============================================================================== Omnibus: 6.095 Durbin-Watson: 1.906 Prob(Omnibus): 0.047 Jarque-Bera (JB): 5.710 Skew: -0.356 Prob(JB): 0.0576 Kurtosis: 2.578 Cond. No. 23.2 ============================================================================== Notes: [1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
但我希望在回归输出中查看全对比效应(无截距项),即无需手动累加主效应和交互项,直接得到female和race每个组合的平均得分。能否在statsmodels中实现这一需求?
解决方案
完全可以实现,以下两种方式可直接获取分类变量组合的均值及对应的t统计量:
方法1:无截距项的全交叉项模型
在公式中添加0 +或-1去掉截距,同时用C(race):C(female)表示两个变量的全交叉组合(等价于C(race)*C(female) - C(race) - C(female)),回归系数将直接对应每个组合的均值:
mod = ols("write ~ 0 + C(race):C(female)", data=hsb2) res = mod.fit() print(res.summary())
输出的每个系数就是race和female对应组合的write分数均值,同时附带标准误、t值和p值。
方法2:生成组合变量后回归
先将两个分类变量合并为一个新的组合变量,再用无截距模型回归,变量名会更直观:
# 生成组合变量 hsb2['race_female'] = hsb2.apply(lambda x: f"race_{x['race']}_female_{x['female']}", axis=1) # 无截距回归 mod = ols("write ~ 0 + C(race_female)", data=hsb2) res = mod.fit() print(res.summary())
结果验证
可以通过分组均值验证回归系数的准确性:
print(hsb2.groupby(['race', 'female'])['write'].mean())
输出的分组均值会和回归系数完全一致。
内容的提问来源于stack exchange,提问作者ℕʘʘḆḽḘ
相关产品推荐
相关产品推荐

