直接调用 sklearn.metrics 中的 mean_squared_error 和 r2_score 即可计算 mse 和 r²,注意 y_true 与 y_pred 同形、避免传反,mse 非 rmse,r² 可为负值,二者互补不可偏废。

怎么用 sklearn.metrics 算 MSE 和 R²
直接调 mean_squared_error 和 r2_score 就行,别自己手写公式——容易漏开方、搞反真值预测顺序,还可能忽略多维数组的 axis 问题。
常见错误现象:mean_squared_error(y_true, y_pred) 返回一个标量,但有人误以为要手动除以样本数;r2_score 在 y_true 全相等时会返回负无穷(不是报错),这点常被忽略。
-
y_true和y_pred必须是同 shape 的一维数组或列向量,传入 DataFrame 列时建议显式用.values.ravel()降维 - 默认
mean_squared_error是 MSE,不是 RMSE;要 RMSE 就得套np.sqrt() -
r2_score的基准线是用 y_true 均值作预测,所以它可小于 0 —— 模型比“全猜均值”还差时就会这样
MSE 和 R² 值对不上,是不是代码写错了
大概率不是代码错,而是指标本身性质不同:MSE 敏感于异常值,R² 关注解释方差比例。同一个模型在不同数据子集上,两个指标变化方向可能相反。
使用场景差异明显:做超参搜索时,GridSearchCV 默认用 scoring='neg_mean_squared_error'(注意负号!),但你手动算 r2_score 得到的是正数,别拿它们直接比大小。
- 验证集里有离群点?MSE 会突然变大,R² 可能只轻微下降
- 目标变量量纲大(比如房价单位是元)?MSE 数值巨大,但 R² 不受量纲影响
- 用
LinearRegression拟合后 R² ≈ 0.95,但 MSE = 120000 —— 这不矛盾,只是说明残差平方平均是 12 万(单位是元²)
为什么测试集 R² 是负数
R² 负了,说明模型在测试集上的 SSE(残差平方和)比 SST(总平方和)还大,即模型预测还不如直接输出训练集 y_train.mean()。
这不是数值计算错误,而是模型泛化失败的明确信号。重点查三件事:
- 是否在训练集上过拟合?比如特征太多、没做正则,而测试集分布偏移
- 是否误用了训练集 mean 去中心化测试集?
r2_score内部用的是y_true自身均值,不是训练集均值 - 是否把
y_true和y_pred传反了?传反会导致 R² 计算逻辑崩坏,可能出负值甚至 NaN
要不要同时看 MSE 和 R²,还是只盯一个
必须同时看。MSE 告诉你误差绝对大小,R² 告诉你相对基准线的表现。单独看哪个都容易误判。
比如某次实验 MSE 从 850 降到 790,看着改善不大;但 R² 从 0.81 升到 0.87 —— 实际提升明显,尤其当目标变量标准差大时,MSE 的绝对变化会被掩盖。
- 部署前必须检查测试集 MSE 是否在业务可接受范围内(比如预测误差不能超 ±5%)
- R² 接近 1 不代表模型好,可能是数据泄露或时间序列中用了未来信息
- 跨项目比较时,R² 更稳定;同一项目迭代时,MSE 更敏感——尤其当目标变量范围缩放后(如从万元改回元)
最麻烦的是 R² 在小样本或高噪声数据里波动剧烈,这时候 MSE 的变化趋势反而更可信。别光盯着数字,得结合残差图一起看。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











