同一数据集下R与Python的OLS回归调整R²结果差异悬殊的原因
Python与R中OLS回归调整R²差异的原因
问题描述
我在Python中运行OLS回归得到了极高的调整R²值(约0.94),由于我通常在R中进行统计分析,于是也在R中运行了该回归,但奇怪的是得到了正常的调整R²值(约0.05)。为何两段代码会产生如此大的结果差异?
数据包含avg_ambiguous_score、crttotal、nfcc_mean、bficonmean、bfiopmean等字段。
代码对比
R代码
tlm <- lm(avg_ambiguous_score ~ crttotal + nfcc_mean + bficonmean+bfiopmean, data = test) summary(tlm)
Python代码
import statsmodels.api as sm X = df[['crttotal','nfcc_mean', 'bficonmean', 'bfiopmean']] Y = df['avg_ambiguous_score'] model = sm.OLS(Y, X).fit() model.summary()
结果截图
R中OLS输出:

Python中OLS输出:

差异原因与解决方法
核心原因
statsmodels的OLS默认不包含截距项,而R的lm()函数默认会自动添加截距项:
- R的
lm()函数使用的公式avg_ambiguous_score ~ crttotal + ...等价于avg_ambiguous_score ~ 1 + crttotal + ...,其中1代表模型截距,这是标准的OLS回归设定。 - Python的
sm.OLS(Y, X)直接传入自变量矩阵X,没有添加截距列,模型会被强制拟合过原点的回归。这种情况下,R²的计算逻辑被改变:总平方和不再是Y与均值的偏差平方和,而是Y与0的偏差平方和,从而导致R²被异常拉高。
解决方法
在Python代码中给自变量矩阵添加截距项,修改后的代码如下:
import statsmodels.api as sm X = df[['crttotal','nfcc_mean', 'bficonmean', 'bfiopmean']] X = sm.add_constant(X) # 添加截距项 Y = df['avg_ambiguous_score'] model = sm.OLS(Y, X).fit() model.summary()
修改后重新运行,Python的调整R²结果就会和R的结果保持一致。
内容的提问来源于stack exchange,提问作者MartyMcFly
相关产品推荐
相关产品推荐

