r2_score返回负值表示模型在测试集上的预测效果比直接用训练集目标变量均值预测更差,其公式为1-(SS_res/SS_tot),当残差平方和SS_res大于总离差平方和SS_tot时即为负;常见原因包括数据分布偏移、训练/测试集不一致、特征未标准化、异常值干扰或模型过于简单。

为什么 r2_score 会返回负值?
r2_score 的负值不是报错,而是明确告诉你:模型在测试集上的表现比直接用训练集均值预测还要差。它的计算公式是 1 - (SS_res / SS_tot),当残差平方和 SS_res 大于总离差平方和 SS_tot(即模型预测比“全用均值”还烂),结果就为负。
常见诱因包括:数据分布严重偏移、训练/测试集不一致(比如时间序列混洗)、特征未标准化导致线性模型失效、目标变量存在强异常值、或模型本身过简(如用线性回归拟合明显非线性关系)。
检查训练集和测试集是否「同分布」
尤其要注意时间序列、地理数据或分组数据——盲目用 train_test_split 随机切分会导致信息泄露或分布断裂。
- 用
plt.hist(y_train, alpha=0.5); plt.hist(y_test, alpha=0.5)对比目标变量分布 - 对时间序列,改用
TimeSeriesSplit或手动按时间顺序切分:X_train, X_test = X[:split_idx], X[split_idx:] - 对分组数据(如用户ID),确保同一组样本不被拆到训练/测试两边,用
GroupShuffleSplit并传入groups=user_id
线性模型前必须做特征缩放吗?
对 LinearRegression 本身,缩放不影响最终预测结果(数学等价),但极大影响数值稳定性与收敛性;而对 Ridge、Lasso、SGDRegressor 等带正则或梯度下降的模型,**不做缩放会导致系数严重偏向量纲大的特征,R² 显著恶化甚至为负**。
立即学习“Python免费学习笔记(深入)”;
- 统一用
StandardScaler:先scaler.fit_transform(X_train),再scaler.transform(X_test) - 避免用
fit_transform分别处理训练/测试集——这会造成数据泄露和尺度不一致 - 对含类别型特征的管道,确保
OneHotEncoder在StandardScaler前,且只对数值列缩放
用 cross_val_score 替代单次 train_test_split 评估
单次随机划分的 R² 波动大,可能偶然得负分,掩盖模型真实能力。交叉验证能暴露模型稳定性问题。
- 用
cross_val_score(model, X, y, cv=5, scoring='r2')查看五折 R² 分布 - 若某折 R² 极低(如 -5.0),说明该折数据有异常,需检查对应样本的
y值或特征缺失模式 - 配合
cv=RepeatedKFold(n_splits=5, n_repeats=3)进一步降低随机性影响
负 R² 往往不是模型写错了,而是数据和评估方式没对齐。最常被跳过的步骤是:检查测试集 y 是否真在训练集 y 的合理外延范围内,以及是否误把未清洗的原始特征直接喂给了敏感模型。


















