为什么设置fit_intercept=False时Sklearn与statsmodels的R²结果不一致?
现象成因
两个库的R²计算逻辑核心差异来自总平方和(SS_tot)的基准选择不同,二者的残差平方和(SS_res)计算逻辑完全一致,所以回归系数相同,但R²结果出现差异:
- statsmodels的OLS默认会自动判断模型是否包含截距项:
当模型无截距时,SS_tot采用非中心化计算方式,即SS_tot = sum(y²),基准对比线是y=0,对应无截距模型的拟合目标,计算得到的R²是模型相对0基准的解释能力。 - Sklearn的
LinearRegression.score()方法不判断是否拟合截距:
永远采用中心化计算方式计算SS_tot,即SS_tot = sum((y - y.mean())²),基准对比线是y的均值,当无截距模型的拟合效果差于直接用y均值预测时,就会出现负R²的结果。
Sklearn无截距回归的适配方案
1. 如需获取和statsmodels一致的无截距R²
手动实现非中心化R²的计算即可,示例代码如下:
def calculate_uncentered_r2(y_true, y_pred): ss_res = ((y_true - y_pred) ** 2).sum() ss_tot = (y_true ** 2).sum() return 1 - ss_res / ss_tot # 调用示例 y_pred = lr.predict(X) print(calculate_uncentered_r2(y, y_pred)) # 输出结果和statsmodels的rsquared一致:0.8058035714285714
2. 特殊场景适配建议
如果你的业务场景本身要求回归必须过原点(例如输入为0时输出天然为0的物理、计量场景),不要直接使用Sklearn默认的score()结果作为模型评估指标,中心化R²在无截距场景下没有实际参考价值,优先使用非中心化R²或者MAE、MSE等不受基准选择影响的回归指标。
内容的提问来源于stack exchange,提问作者yoon
相关产品推荐
相关产品推荐

