Python实战:用R²评估你的回归模型到底靠不靠谱(附完整代码)
当你第一次训练出一个线性回归模型,看着那条拟合的直线穿过数据点,心里难免会涌起一丝成就感。但紧接着,一个更实际的问题就会浮现:这个模型到底有多“好”?仅仅看预测值和真实值之间的差距(比如MSE、MAE)够吗?如果你尝试过将同一个模型应用到不同量纲的数据集上——比如预测房价(单位是万元)和预测考试分数(单位是分)——你就会发现,单纯比较误差的绝对值是毫无意义的。一个误差5万元的房价模型和一个误差10分的分数模型,孰优孰劣?这就像比较苹果和橙子。这正是我们需要一个标准化、无量纲的评估指标的原因,而R²(R Square,决定系数) 正是解决这一痛点的关键。它不仅能告诉你模型拟合得“好不好”,更能告诉你它比一个最简单的“基准模型”好多少,其值域在0到1之间(也可能为负),提供了一个清晰、可比的衡量标尺。本文将从零开始,手把手带你用Python实现R²的计算,深入理解其统计含义,并通过可视化对比,让你直观地判断:你的回归模型,到底靠不靠谱。
1. 为什么是R²?超越MSE和MAE的局限性
在深入代码之前,我们必须先理解为什么R²比均方误差(MSE)或平均绝对误差(MAE)更适合作为模型间的比较标准。假设你为两个项目构建了回归模型:
- 项目A:预测波士顿郊区房价。你的模型预测误差(RMSE)是5万美元。
- 项目B:预测学生期末考试成绩。你的模型预测误差(RMSE)是15分。
哪个模型更优秀?你无法直接回答,因为5万美元和15分处于完全不同的量纲和数值尺度上。MSE、RMSE和MAE都是有量纲的指标,其数值大小严重依赖于目标变量y本身的量纲(是万元、公里还是摄氏度)。这使得跨数据集、跨问题的模型性能对比变得异常困难。
R²巧妙地解决了这个问题。它的核心思想不是直接衡量“误差有多大”,而是衡量你的模型相比一个最朴素的基准模型,将误差减少了多少比例。这个基准模型通常被定义为使用目标变量y的均值(ȳ)作为所有样本的预测值。想想看,如果你对任何输入都只预测一个平均值,这无疑是性能的底线。
R²的计算公式清晰地体现了这一比较:
R² = 1 - (SS_residual / SS_total)
其中:
SS_residual(残差平方和):你的模型预测值与真实值之差的平方和。Σ(y_i - ŷ_i)²。这代表了模型未能解释的误差。SS_total(总平方和):基准模型(预测值全为ȳ)的预测值与真实值之差的平方和。Σ(y_i - ȳ)²。这代表了数据自身的总波动。
因此,R²的实际意义是:你的模型解释了目标变量y的总波动(方差)的百分比。
让我们通过一个表格来直观感受R²取值的含义:
| R² 值范围 | 统计学含义 | 模型性能解读 |
|---|---|---|
| R² = 1 | SS_residual = 0 |
完美拟合。模型解释了数据100%的波动。在实践中几乎不可能出现。 |
| 0 < R² < 1 | SS_residual < SS_total |
模型有效。这是最常见的情况。例如R²=0.85,意味着模型解释了目标变量85%的方差。 |
| R² = 0 | SS_residual = SS_total |
模型等于基准模型。你的复杂模型并不比简单粗暴地预测平均值更好。 |
| R² < 0 | SS_residual > SS_total |
模型比基准模型还差。这通常意味着数据可能根本不存在线性关系,或者模型严重过拟合/欠拟合。 |
注意:R²小于0是一个强烈的警告信号。它提示你当前使用的模型(特别是线性模型)可能完全不适合你的数据,需要重新检查数据特征、模型假设或尝试非线性模型。
理解了R²“为什么好”,我们就能带着明确的目的去实现它:不仅要会算,更要能从结果中读出模型的真实故事。
2. 从公式到代码:手撕R²计算函数
现在,我们抛开sklearn的r2_score,亲自从零实现一个R²计算函数。这能让你对公式的每一个组成部分都了如指掌。我们将创建一个名为

&spm=1001.2101.3001.5002&articleId=151131351&d=1&t=3&u=52796f4ad5334d0bb1ce0651c504c0e6)
1235

被折叠的 条评论
为什么被折叠?



