1.1 从预测误差说起:机器学习基础与残差


文档摘要

1.1 从预测误差说起:机器学习基础与残差 残差是真实值与预测值之间的差,它是模型"还没学会的部分"。 本节从一次朴素的房价预测出发,建立误差、损失、残差三个概念,并用代码验证残差序列中仍然残留可学习的规律——这是整个 Boosting 家族得以成立的事实基础。 学习目标 读完本节,你应当能够: 区分误差、损失函数与残差三个概念 用代码计算残差并检验残差是否与特征相关 解释"拟合残差再累加"为什么能降低总误差 说出监督学习的基本要素在回归任务中的对应物 一、一个朴素的预测实验 先做一个小实验。我们手上有 8 套房的真实成交价,第一版模型非常粗糙:直接用面积乘以一个固定单价。 运行输出: 三个概念在这里分了家。误差是泛指"预测与真实有差距"这个现象;

1.1 从预测误差说起:机器学习基础与残差

残差是真实值与预测值之间的差,它是模型"还没学会的部分"。 本节从一次朴素的房价预测出发,建立误差、损失、残差三个概念,并用代码验证残差序列中仍然残留可学习的规律——这是整个 Boosting 家族得以成立的事实基础。

学习目标

读完本节,你应当能够:

  1. 区分误差、损失函数与残差三个概念
  2. 用代码计算残差并检验残差是否与特征相关
  3. 解释"拟合残差再累加"为什么能降低总误差
  4. 说出监督学习的基本要素在回归任务中的对应物

一、一个朴素的预测实验

先做一个小实验。我们手上有 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 的每一步都在燃烧这份燃料,直到它稀薄得只剩噪声。

本节要点回顾

  • 残差 = 真实值 − 预测值,逐样本保留符号与大小,是损失函数的原料
  • 残差与特征显著相关,说明信息未榨干,可以再学
  • "拟合残差再累加"手工复现了梯度提升的一轮迭代
  • 收敛曲线先陡后平,趋平处即应停下的位置
  • 监督学习三要素在 Boosting 中被改写为"简单模型的可累加序列"

下一节讨论把多个模型组织起来的两条路线——平均与累加各有什么代价,这正是 Bagging 与 Boosting 的分水岭。

常见问答

残差和误差是一回事吗

不是。误差是笼统的现象描述,残差是逐样本的带符号数值。损失函数把残差加工成一个标量(比如平方平均),用于优化;而残差本身保留了"每个样本各自错了多少、往哪个方向错"的完整信息。Boosting 依赖的正是这份逐样本信息,所以本节反复强调别把残差当垃圾丢掉。

残差什么时候算学不动了

看两个信号:残差与所有特征的相关性都接近零,说明特征里已没有可解释剩余误差的信息;残差平方和每轮下降不足千分之一,说明继续训练的边际收益趋近于零。两个信号指向同一件事——剩下的基本是噪声,残差收敛之路走到了终点,该停了。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U