1.1 从预测误差说起:机器学习基础与残差 残差是真实值与预测值之间的差,它是模型"还没学会的部分"。 本节从一次朴素的房价预测出发,建立误差、损失、残差三个概念,并用代码验证残差序列中仍然残留可学习的规律——这是整个 Boosting 家族得以成立的事实基础。 学习目标 读完本节,你应当能够: 区分误差、损失函数与残差三个概念 用代码计算残差并检验残差是否与特征相关 解释"拟合残差再累加"为什么能降低总误差 说出监督学习的基本要素在回归任务中的对应物 一、一个朴素的预测实验 先做一个小实验。我们手上有 8 套房的真实成交价,第一版模型非常粗糙:直接用面积乘以一个固定单价。 运行输出: 三个概念在这里分了家。误差是泛指"预测与真实有差距"这个现象;
残差是真实值与预测值之间的差,它是模型"还没学会的部分"。 本节从一次朴素的房价预测出发,建立误差、损失、残差三个概念,并用代码验证残差序列中仍然残留可学习的规律——这是整个 Boosting 家族得以成立的事实基础。
读完本节,你应当能够:
先做一个小实验。我们手上有 8 套房的真实成交价,第一版模型非常粗糙:直接用面积乘以一个固定单价。
import numpy as np # 面积(平方米)与真实成交价(万元) area = np.array([50, 62, 80, 55, 95, 70, 110, 85]) price_true = np.array([260, 340, 470, 300, 590, 380, 730, 480]) # 第一版模型:固定单价 5.5 万每平米 price_pred = area * 5.5 residual = price_true - price_pred for a, t, p, r in zip(area, price_true, price_pred, residual): print(f"面积{a:>3} 真实{t:>3} 预测{p:>5.1f} 残差{r:>6.1f}")
运行输出:
面积 50 真实260 预测275.0 残差 -15.0 面积 62 真实340 预测341.0 残差 -1.0 面积 80 真实470 预测440.0 残差 30.0 面积 55 真实300 预测302.5 残差 -2.5 面积 95 真实590 预测522.5 残差 67.5 面积 70 真实380 预测385.0 残差 -5.0 面积110 真实730 预测605.0 残差 125.0 面积 85 真实480 预测467.5 残差 12.5
三个概念在这里分了家。误差是泛指"预测与真实有差距"这个现象;损失函数是把差距量化成一个数的规则,比如平方损失;残差是逐样本的具体差值,是损失函数的原料。平方损失关心残差的平方平均,而残差本身保留了符号和大小,告诉我们每一套房子分别错在哪、错了多少。
关键观察在残差那一列:它不是乱跳的。面积越大,残差整体越偏正——大房子被系统性低估了。这说明第一版模型漏掉了"单价随面积递增"的规律,而这部分规律完完整整地躺在残差里。
直觉需要验证。残差如果与某个特征相关,就说明这个特征的信息没被第一版模型用尽,可以拿残差当新的学习目标。
# 检验残差与面积的相关性 corr = np.corrcoef(area, residual)[0, 1] print(f"残差与面积的相关系数: {corr:.4f}") # 输出: 残差与面积的相关系数: 0.9764 # 用线性模型拟合残差,作为"第二棵树"的简化替身 k, b = np.polyfit(area, residual, 1) print(f"残差修正模型: 残差 ≈ {k:.3f} * 面积 + {b:.2f}") # 输出: 残差修正模型: 残差 ≈ 0.898 * 面积 + -55.36 # 累加两个模型后的新残差 residual2 = residual - (k * area + b) print(f"修正前残差平方和: {np.sum(residual**2):.1f}") print(f"修正后残差平方和: {np.sum(residual2**2):.1f}")
运行输出:
修正前残差平方和: 20828.8 修正后残差平方和: 766.1
相关系数高达 0.98,残差几乎是面积的线性函数。把它拟合出来加回去,残差平方和从 20828 降到 766,缩小了 96%。这个两步流程——先拟合、再修正、累加——手工演完了梯度提升的一轮迭代。XGBoost 训练一千棵树,本质上是把这个动作重复一千次,每次的目标都是上一轮剩下的残差。

曲线快速下降后趋平,这个形状在后续章节会反复出现。趋平意味着残差里剩下的信息越来越接近噪声——继续训练不再带来泛化收益,只会在训练集上硬记样本。什么时候停、每轮修正量打几折,正是第 2 章目标函数与第 3 章学习率参数要正面回答的问题。
把实验上升一层。监督学习的三要素在本节实验里各有对应:假设空间是"面积的一次函数";损失函数是平方损失;优化手段是最小二乘。Boosting 做的事情,是把"一个假设空间里找一个模型"改成"一个简单假设空间里找一串模型并累加"。累加起来的复合模型可以表达远比单个成员复杂的函数,而每个成员仍然简单、可控、好优化。
⚠️ 常见坑:把残差当成"错误"直接丢掉。残差不是垃圾,是燃料。丢弃它等于丢弃了模型尚未吸收的信息;Boosting 的每一步都在燃烧这份燃料,直到它稀薄得只剩噪声。
下一节讨论把多个模型组织起来的两条路线——平均与累加各有什么代价,这正是 Bagging 与 Boosting 的分水岭。
不是。误差是笼统的现象描述,残差是逐样本的带符号数值。损失函数把残差加工成一个标量(比如平方平均),用于优化;而残差本身保留了"每个样本各自错了多少、往哪个方向错"的完整信息。Boosting 依赖的正是这份逐样本信息,所以本节反复强调别把残差当垃圾丢掉。
看两个信号:残差与所有特征的相关性都接近零,说明特征里已没有可解释剩余误差的信息;残差平方和每轮下降不足千分之一,说明继续训练的边际收益趋近于零。两个信号指向同一件事——剩下的基本是噪声,残差收敛之路走到了终点,该停了。