跳到主要内容

从直线拟合到给旋钮上枷锁 — 让分数最小,以及它的副作用

这一章讲两件事: 最基础的「拿直线套数据」(行话叫线性回归)怎么从数据里学出一条直线; 以及学到一半发现的坏消息——学得太好反而是病,和它的解药「正则化」。 原书有句话值得先放在这:「根据训练数据,算出让评分最小的那组可调的数」这个做法, 是所有有监督学习算法的共同之处1。这一章讲的就是这颗共同的内核。

1. 顶层全景:一条因果链

想预测连续数字(回归问题)
↓ 最简单的假设:线性关系 y = w0 + w1x
可直线有无数条,哪条算「学得好」?
↓ 定一个损失函数:预测差多远,罚多少分
怎么找到罚分最少的那条直线?
↓ 在所有参数组合里挑损失最小的(第 4 节走查)
── 但训练误差最小 ≠ 模型好 ──
↓ 模型太复杂会过拟合:训练误差 0.024,验证误差 3.472
解药:往损失里加惩罚项,参数越大罚越重(正则化)
↓ 同样的六次曲线,验证误差从 3.472 压回 0.331

2. 线性回归:从「画一条直线」开始

回归问题要预测的是连续数字。最简单的猜法是拿一条直线去套数据——这种直线思路行话叫线性,对应的做法叫线性回归。它对「目标变量随某个特征值的增大而增大(或减小)」这种关联建模2。最简单的样子是中学的一次函数:

y = w0 + w1x

w1 是斜率,w0 是截距。原书特意指出:w1 还有个名字叫权重——后面所有算法里「权重」都是这个角色:特征值前面的倍率,由算法从数据里学出来3

麻烦在于:数据点通常不在一条直线上。四个点,可以画出无数条直线,哪条最「贴合」?线性回归的回答分两步:先定什么叫贴合,再找最贴合的那条。

主走查(上半场):四条数据,两条直线,一个 2.89 一个 5.83

原书造了一组最小教学数据:四个点 (2,1)、(3,5)、(6,3)、(7,7)4。考察两条候选直线:

候选直线 a:y = 0.706x + 0.823
候选直线 b:y = −0.125x + 4.5

逐点量「真实值 − 直线预测值」的差,平方,取平均(=均方误差):

直线 a:点 (2,1) 预测 2.235,差 −1.235;点 (3,5) 预测 2.941,差 2.059;…
四个差的平方平均 → 均方误差 ≈ 2.89
直线 b:点 (2,1) 预测 4.25,差 −3.25;点 (3,5) 预测 4.125,差 0.875;…
四个差的平方平均 → 均方误差 ≈ 5.83

2.89 < 5.83 → 直线 a 更好。

图说:数据与两直线均取自原书;「差」的逐点数值是为演示补算的,
均方误差 2.89 与 5.83 是原书给出的。

均方误差的定义就藏在上面那句话里:目标变量和直线预测值之差的平方的平均值5。为什么先平方再平均?因为不平方的话,「偏高 3」和「偏低 3」会互相抵消,看起来误差为零;平方把所有偏差都变成正数,躲不掉。原书用两个数一锤定音:直线 a 的 2.89 小于直线 b 的 5.83,a 更好6

损失函数:把「哪条线好」变成一个可以求最小的数

到这里,「贴合程度」已经变成一个数。原书接着给出全章(也是全书)最重要的一步抽象:猜得离谱的程度,有个名字叫损失;误差随参数 w0、w1 变化而变化,把这个关系写成一个函数,它叫误差函数(或损失函数)7

把四个点代进去,均方误差就成了只含 w0、w1 的式子——一个二次函数,画出图来是一个碗状曲面:碗底就是损失最小的参数组合。原书核对过:直线 a 的参数恰好落在碗底,所以它不只是比 b 好,它就是这组数据下的最佳参数8

「找出让损失最小的参数」这个思路,原书明说是所有有监督学习算法通用9。第 03~07 章的每个算法,区别只在两处:模型长什么样、损失函数怎么定。

安斯库姆四重奏:直接跑回归是会出事的

主走查上半场用的数据其实是统计学家安斯库姆故意造的四组数据之一。四组数据的均值、方差(数据的波动幅度)、相关系数几乎相同,线性回归算出的参数也完全相同——但画出散点图一看,只有第一组真是一条直线带:第二组是明显的曲线,第三组被一个离群值(严重偏离群体的点)带偏了直线,第四组里所有点只由一个离群值撑起关联10

原书由此立了条工作规矩:拿到数据,先可视化,再决定要不要线性回归11。这也是全书第一次演示「同一个数字分数,可能对应完全不同的数据形状」。

3. 坏消息:训练误差最小,不等于模型好

主走查(下半场):0.024 对 3.472

现在把线性回归推到复杂的一侧。原书拿一条正弦曲线 y = sin(2πx) 加上随机噪声(叠加在规律上的随机干扰)造数据,20 条做训练、12 条做验证,然后逐级提高多项式次数(一次、二次……六次),分别看两种误差12:

次数训练误差验证误差
10.4120.618
20.1760.193
30.0810.492
60.024(最小)3.472(爆炸)

六次曲线在训练数据上几乎完美——但一到没见过的验证数据,误差是训练的 140 多倍。原书的判词:训练误差渐变小、验证误差反而大得多,这个现象就是过拟合;根源之一是模型过于复杂13

复杂模型坏在哪:看一眼参数就知道了

对比两个版本的六次曲线学出的参数,病灶一目了然14:

不用正则化:d=6 时 w = (1.080, −26.324, 287.431, −1034.141,
1611.144, −1147.946, 308.643)
用了正则化:d=6 时 w = (0.191, −0.751, −0.497, −0.182,
0.109, 0.370, 0.607)

图说:数字均取自原书表 2-7 与表 2-8。
上排参数大起大落到上千,曲线为了迁就每个训练点疯狂扭曲;
下排全部压在 ±1 以内,曲线自然平滑。

原书点破:复杂模型过拟合的一个原因,是学习参数的绝对值太大;次数越高,参数越膨胀15

4. 正则化:往损失里加一个「罚款项」

机制:三行讲完

正则化做的事只有一件:向损失函数增加一个惩罚项,给模型加上制约,从而抑制过拟合16。以二次曲线为例,新损失函数长这样:

R(w) = Σ(预测与真实之差的平方) + α(w1² + w2²)

前半段还是老损失(拟合得差就罚);后半段是新加的惩罚项——所有学习参数的平方和(截距一般不算在内)17。它传递的规则很直白:参数绝对值越大,罚款越重;想少交罚款,就把参数压小18

效果看下半场走查的表:同样六次曲线,加了正则化之后,训练误差 0.159、验证误差 0.331——训练误差比裸奔版(0.024)大了,验证误差却从 3.472 掉回 0.331,过拟合消失了19。这就是正则化的交易:用训练时的「不完美」换没见过的数据上的「靠得住」,而模型对没见过的数据的预测能力,第 01 章已经给它起过名字:泛化(对没见过的数据管不管用)能力。

α:一个必须人来定的旋钮

惩罚项前面的 α 控制正则化强度,原书把它讲得很清楚:α 越大,对参数的抑制越强;α 越小,越容易过拟合;α = 0 时惩罚项恒为 0,等于没有正则化20

这里埋了全书的一个重要区分。w 这类由算法从数据里学出来的数,叫学习参数;α 这类学习开始前就得由人给定的数,叫超参数——「超」不是说它更大,是说它在训练之上,算法碰不到它21。α 怎么定?原书的答案朴素得可爱:一边看验证误差一边调22。怎么系统地调,第 11 章的网格搜索接手。

5. 岭回归与 Lasso:同一服药,两种药方

把「平方和」当惩罚项的回归叫岭回归;把惩罚项换成「绝对值之和」,就得到 Lasso 回归23。差一个平方,行为差很多:

惩罚项参数被压成什么形状附赠能力
岭回归参数的平方和整体变小,但很少恰好为 0
Lasso 回归参数的绝对值之和容易恰好压到 0顺带做特征选择

原书用几何讲清了 Lasso 为什么会把参数压成 0:平方和的等高线是个圆,绝对值和的等高线是个四边形(有棱角);损失函数的最优解落在「碗」与「惩罚图形」的交点上,圆和碗多半交在弧面上,而四边形的棱角恰好长在坐标轴上——交到角上,落在轴上的那个参数就等于 0。原书的实验里,Lasso 学出的 w2 正好是 024

参数为 0 意味着对应的特征被踢出模型。原书指出这等于用 Lasso 顺带做了特征筛选——模型更简单,人也更容易解释25。至于「该用哪个」,原书没有下结论,只并列给出;我们的判断放在第 7 节。

6. 作者的判断与证据

说法性质依据
均方误差 2.89 < 5.83,直线 a 更好;且 a 即最优参数书内给出计算结果数值都在正文里68
「损失最小的参数」是一切有监督学习的共同思路作者的方法论断言,全书以此展开书内明说「通用」9
过拟合的一个原因是参数绝对值太大书内给出参数表作证据(1611 对 0.6)表 2-7/2-8 对照14
Lasso 交点在棱角处、参数易为 0书内给出几何示意 + 一次实验(w2=0)图示论证24
该选岭回归还是 Lasso书内未裁决——只并列介绍,没有给选择标准原书并列陈述23

判断(我们的,不是书里的): 实践里的默认起点是岭回归:特征都还有点用、只想压过拟合,用它;只有当你怀疑一堆特征是凑数的、想要一份「被归零」的清单时,才换 Lasso。理由:归零是不可逆的删除,Lasso 的特征筛选在数据条数少、干扰多的场合并不总是可靠。 如果错,会错在: 若某些数据里「大量参数恰好压成 0」的解本身就是主要收益(比如特征上万个、必须砍),只用岭回归就会错过;此时应以 Lasso 或其变体为默认。

7. 边界与局限

  • 全章的「最优参数」都建立在均方误差这个损失上。损失换个样子(比如第 03 章的逻辑损失),「式子变形直接解」的路子就走不通了,得换数值逼近——那是下一章开头的事。
  • 正则化只压参数大小,不解决「特征选错了」「数据本身有偏」的问题。安斯库姆第三组那个离群值,加了正则化照样把直线拽歪;原书给的方子是预处理(去离群值)或换方法10
  • 原书没有讲「多项式次数 d」本身也是一个超参数,和 α 一样需要验证着调——它只在例子里换了 d,没有给选 d 的流程。这是原书的省略,我们补在这里。
  • 版本提示:原书代码用 Ridge(alpha=1.0),输出训练误差 0.159、验证误差 0.33126;scikit-learn 新版本里类名与参数名未变,可照跑。

8. 可带走的

  1. 有监督学习的共同内核:定损失函数 → 找让损失最小的参数;换算法=换模型形状或换损失;
  2. 均方误差先平方再平均,是为了不让正负偏差互相抵消;
  3. 训练误差会撒谎:0.024 的训练误差配上 3.472 的验证误差,是过拟合的标准长相;
  4. 看到参数表里出现 1611、−1147 这种量级,基本可以断定模型在硬拗;
  5. 正则化 = 损失 + 惩罚项(参数平方和或绝对值和),参数越大罚越重;
  6. α 是超参数:训练前人给,α=0 等于关掉正则化;调法是盯验证误差;
  7. Lasso 把参数压到 0 的几何原因:绝对值和的等高线有棱角,角长在坐标轴上;
  8. 参数被压成 0 = 特征被删除,Lasso 白送特征筛选;
  9. 拿到数据先画散点图——四组统计量相同的数据,可以长四种完全不同的样子(安斯库姆四重奏);
  10. 「线性」说的是参数,不是特征:含 x² 项的回归,只要对参数是线性的,仍然叫线性回归27

9. 原文地图

主题原书章原文位置
损失最小化是共同之处2.1 算法1:线性回归text/06-ch02-01-2-1-1.txt:3(搜「共同之处」)
y=w0+w1x、斜率与截距2.1 算法1:线性回归text/06-ch02-01-2-1-1.txt:39(搜「中学阶段学过的一次函数」)
表 2-2 四点数据与两条直线2.1 算法1:线性回归text/06-ch02-01-2-1-1.txt:53(搜「数据介绍学习参数的求法」) · text/06-ch02-01-2-1-1.txt:55(搜「0.706x + 0.823」)
均方误差定义2.1 算法1:线性回归text/06-ch02-01-2-1-1.txt:57(搜「均方误差指的是目标变量和直线的差」)
2.89 与 5.832.1 算法1:线性回归text/06-ch02-01-2-1-1.txt:66(搜「约为 2.89」)
误差函数(损失函数)定义2.1 算法1:线性回归text/06-ch02-01-2-1-1.txt:75(搜「叫作误差函数」)
通用思路2.1 算法1:线性回归text/06-ch02-01-2-1-1.txt:77(搜「使误差函数值最小的参数的思路」)
损失=参数的函数、碗底2.1 算法1:线性回归text/06-ch02-01-2-1-1.txt:143(搜「学习参数的函数表示」) · text/06-ch02-01-2-1-1.txt:155(搜「二次函数」) · text/06-ch02-01-2-1-1.txt:157(搜「最佳学习参数」)
安斯库姆四重奏2.1 算法1:线性回归text/06-ch02-01-2-1-1.txt:109(搜「可视化的重要性」) · text/06-ch02-01-2-1-1.txt:112(搜「却相同」)
一元/多元/多项式回归2.1 算法1:线性回归text/06-ch02-01-2-1-1.txt:165(搜「独立特征变量只有一个」) · text/06-ch02-01-2-1-1.txt:171(搜「才称为线性回归」)
过拟合定义(验证误差远大)2.2 算法2:正则化text/07-ch02-02-2-2-2.txt:10(搜「大得多的现象」)
sin 数据、20/12 条2.2 算法2:正则化text/07-ch02-02-2-2-2.txt:14(搜「添加了遵循高斯分布」)
0.024 对 3.4722.2 算法2:正则化text/07-ch02-02-2-2-2.txt:39(搜「0.024 是最小的」) · text/07-ch02-02-2-2-2.txt:40(搜「比训练误差大了很多」)
参数膨胀与压平对照2.2 算法2:正则化text/07-ch02-02-2-2-2.txt:92(搜「绝对值变大」) · text/07-ch02-02-2-2-2.txt:104(搜「1611.144」) · text/07-ch02-02-2-2-2.txt:115(搜「-0.751」)
正则化定义与效果2.2 算法2:正则化text/07-ch02-02-2-2-2.txt:4(搜「向损失函数增加惩罚项」) · text/07-ch02-02-2-2-2.txt:59(搜「防止了过拟合的出现」)
惩罚项、α、机制2.2 算法2:正则化text/07-ch02-02-2-2-2.txt:129(搜「惩罚项(或者正则化项)」) · text/07-ch02-02-2-2-2.txt:132(搜「控制正则化强度的参数」) · text/07-ch02-02-2-2-2.txt:140(搜「给予损失变大」)
α=0 等于关闭2.2 算法2:正则化text/07-ch02-02-2-2-2.txt:178(搜「等同于不使用正」)
岭回归与 Lasso、特征选择2.2 算法2:正则化text/07-ch02-02-2-2-2.txt:194(搜「Lasso 回归的误差函数如下」) · text/07-ch02-02-2-2-2.txt:202(搜「绝对值之和」) · text/07-ch02-02-2-2-2.txt:216(搜「w2 变为了 0」) · text/07-ch02-02-2-2-2.txt:218(搜「选择特征」)
示例代码输出 0.159/0.3312.2 算法2:正则化text/07-ch02-02-2-2-2.txt:170(搜「0.15917213」) · text/07-ch02-02-2-2-2.txt:172(搜「0.33133271」)

Footnotes

  1. 出处:「2.1 算法1:线性回归」第 3 段(text/06-ch02-01-2-1-1.txt:3,搜「共同之处」)。原文:「根据训练数据计算使损失最小的参数的做法是有监督学习算法的共同之处」。

  2. 出处:「2.1 算法1:线性回归」第 8 段(text/06-ch02-01-2-1-1.txt:8,搜「这种关联性建模」)。

  3. 出处:「2.1 算法1:线性回归」第 39 段(text/06-ch02-01-2-1-1.txt:39,搜「中学阶段学过的一次函数」)。原文:w1 是斜率(或者叫权重),w0 相当于在 y 轴上的截距,二者由有监督学习算法学得,称为学习参数。

  4. 出处:「2.1 算法1:线性回归」第 52 段(text/06-ch02-01-2-1-1.txt:52,搜「不在一条直线上的点」);数据表在第 52~55 段。

  5. 出处:「2.1 算法1:线性回归」第 57 段(text/06-ch02-01-2-1-1.txt:57,搜「均方误差指的是目标变量和直线的差」)。「先平方防抵消」是这条定义的直接推论,书内未展开,来自通用知识。

  6. 出处:「2.1 算法1:线性回归」第 66 段(text/06-ch02-01-2-1-1.txt:66,搜「约为 2.89」)。 2

  7. 出处:「2.1 算法1:线性回归」第 75 段(text/06-ch02-01-2-1-1.txt:75,搜「叫作误差函数」)。

  8. 出处:「2.1 算法1:线性回归」第 157 段(text/06-ch02-01-2-1-1.txt:157,搜「最佳学习参数」)。 2

  9. 出处:「2.1 算法1:线性回归」第 77 段(text/06-ch02-01-2-1-1.txt:77,搜「使误差函数值最小的参数的思路」)。 2

  10. 出处:「2.1 算法1:线性回归」第 109 段(text/06-ch02-01-2-1-1.txt:109,搜「可视化的重要性」)与第 112 段(text/06-ch02-01-2-1-1.txt:112,搜「却相同」)。四组形状的逐图解说在第 122~126 段。 2

  11. 出处:「2.1 算法1:线性回归」第 126 段(text/06-ch02-01-2-1-1.txt:126,搜「首先应该进行可视化」)。

  12. 出处:「2.2 算法2:正则化」第 14 段(text/07-ch02-02-2-2-2.txt:14,搜「添加了遵循高斯分布」);数据条数见示例代码第 153154 段(text/07-ch02-02-2-2-2.txt:153,搜「train_size = 20」)。误差表在第 4354 段。

  13. 出处:「2.2 算法2:正则化」第 10 段(text/07-ch02-02-2-2-2.txt:10,搜「大得多的现象」)与第 40~42 段(搜「泛化能力很低」)。

  14. 出处:「2.2 算法2:正则化」第 104 段(text/07-ch02-02-2-2-2.txt:104,搜「1611.144」)与第 115 段(text/07-ch02-02-2-2-2.txt:115,搜「-0.751」)。 2

  15. 出处:「2.2 算法2:正则化」第 90~91 段(text/07-ch02-02-2-2-2.txt:91,搜「值太大(或太小)」;text/07-ch02-02-2-2-2.txt:92,搜「绝对值变大」)。

  16. 出处:「2.2 算法2:正则化」第 4 段(text/07-ch02-02-2-2-2.txt:4,搜「向损失函数增加惩罚项」)。

  17. 出处:「2.2 算法2:正则化」第 129 段(text/07-ch02-02-2-2-2.txt:129,搜「惩罚项(或者正则化项)」)。

  18. 出处:「2.2 算法2:正则化」第 140 段(text/07-ch02-02-2-2-2.txt:140,搜「给予损失变大」)。

  19. 出处:「2.2 算法2:正则化」第 81 段(text/07-ch02-02-2-2-2.txt:81,搜「0.159」)与第 59 段(搜「防止了过拟合的出现」)。

  20. 出处:「2.2 算法2:正则化」第 132 段(text/07-ch02-02-2-2-2.txt:132,搜「控制正则化强度的参数」)与第 178 段(搜「等同于不使用正」)。

  21. 超参数与学习参数的区分,原书在附录名词表里给了正式定义:「不能从数据中学习,所以必须事先指定的机器学习模型的参数」(「附录」第 404 段,text/27-apx.txt:404,搜「必须事先指定」)。

  22. 出处:「2.2 算法2:正则化」第 179 段(text/07-ch02-02-2-2-2.txt:179,搜「一边验证误差一边对 α」)。

  23. 出处:「2.2 算法2:正则化」第 194 段(text/07-ch02-02-2-2-2.txt:194,搜「Lasso 回归的误差函数如下」)与第 202 段(text/07-ch02-02-2-2-2.txt:202,搜「绝对值之和」)。 2

  24. 出处:「2.2 算法2:正则化」第 213 段(text/07-ch02-02-2-2-2.txt:213,搜「圆形」)与第 216 段(text/07-ch02-02-2-2-2.txt:216,搜「w2 变为了 0」)。「棱角长在坐标轴上」是原书图 2-11 几何直观的文字转述。 2

  25. 出处:「2.2 算法2:正则化」第 218 段(text/07-ch02-02-2-2-2.txt:218,搜「选择特征」)与第 218 段(搜「使模型的解释变容易」)。

  26. 出处:「2.2 算法2:正则化」第 162 段(text/07-ch02-02-2-2-2.txt:162,搜「Ridge(alpha=1.0)」);输出在第 170、172 段。

  27. 出处:「2.1 算法1:线性回归」第 171 段(text/06-ch02-01-2-1-1.txt:171,搜「才称为线性回归」)。