2.2 线性回归与正则化(岭回归与Lasso)

1.从2.1 节的线性回归说起:特征一多,麻烦也就来了

说起来,2.1 节里我们已经把线性回归讲得差不多了。线性回归做的事其实很朴素,就是给一堆特征配上一组权重,再加一个偏置,凑成一条用来预测的直线(或者超平面)。我们当时推导过普通最小二乘法(Ordinary Least Squares,习惯上简称OLS),它的目标很直接,就是让预测值和真实值之间的误差平方和尽量小。

我们不妨把这套记法重新摆一摆。设一共有 nn 个样本,每个样本有 dd 个特征,把所有样本的特征排成一个大矩阵 XX,它是一个 nndd 列的矩阵,每一行对应一个样本。把所有样本要预测的真实值排成一个列向量 yy,长度为 nn。把权重排成一个列向量 ww,长度为 dd。那么最小二乘想要最小化的损失就是 yXw22\|y - Xw\|_2^2,这里 2\|\cdot\|_2 表示向量的L2范数(也就是平时说的长度),yXw22\|y - Xw\|_2^2 就是预测残差向量的长度的平方。

OLS 闭式解的完整推导。 这套损失怎么求出最优权重,2.1 节我们只给了结论,这里把推导走完。先把损失展开,注意 v22=vv\|v\|_2^2=v^\top v

J(w)=yXw22=(yXw)(yXw)=yy2yXw+wXXwJ(w)=\|y-Xw\|_2^2=(y-Xw)^\top(y-Xw)=y^\top y-2y^\top Xw+w^\top X^\top Xw

(展开时用到 (Xw)=wX(Xw)^\top=w^\top X^\top,以及 yXwy^\top Xw 是标量、等于它的转置 wXyw^\top X^\top y,两项合并成 2yXw2y^\top Xw。)现在对 ww 求梯度,用到两条矩阵求导法则:w(aw)=a\nabla_w(a^\top w)=aw(wAw)=2Aw\nabla_w(w^\top A w)=2AwAA 对称时):

wJ=2Xy+2XXw\nabla_w J=-2X^\top y+2X^\top Xw

令梯度为零解出 ww

XXw=Xy    w^=(XX)1XyX^\top Xw=X^\top y\;\Longrightarrow\;\hat{w}=(X^\top X)^{-1}X^\top y

这里头几个符号都得说清楚。XX^\top 表示矩阵 XX 的转置(行变列、列变行),(XX)1(X^\top X)^{-1} 表示矩阵 XXX^\top X 的逆矩阵(逆矩阵的意思是原矩阵乘上它正好等于单位阵),w^\hat{w} 上头那个小帽子表示这是估计出来的权重,用来区别于未知的真实权重。这套解析解看起来干净漂亮,2.1 节我们就是靠它入门的。

可问题也正藏在这套漂亮解里。XTXX^T X 必须可逆,这个解才成立。要是特征之间高度相关,比方说建筑面积和使用面积这两个特征几乎是一回事,一个变大另一个也跟着变大,那么 XTXX^T X 这么一乘,就接近一个不可逆的矩阵(专业上叫奇异矩阵)。这时候 XTXX^T X 里有些特征值会小到接近零(特征值的概念我们在1.3 节讲PCA的时候详细说过),求逆的时候这些小特征值被翻成巨大的数,权重 ww 的数值就被撑得离谱。

我之前看过一本讲统计学习的书,里头把这个现象比作在一条窄巷子里推车,巷子越窄,稍微一偏就要撞墙,权重的取值就在两个极端之间来回跳。说穿了,这就是过拟合的一种典型症状。还有一种更常见的情形,特征数 dd 比样本数 nn 还多的时候,XTXX^T X 必定不可逆,方程有无数组解,模型大可以挑一组把训练数据拟合得分毫不差,可对新数据几乎没什么预测能力。这种模型我们通常说它记住了数据,却没学到规律。

2.岭回归:给权重套上一条软绳(Ridge,L2正则)

要稳住这匹撒野的马,办法说起来倒也简单,就是在原来的损失里再加一项,专门用来约束权重的大小,这一项叫做正则化项。岭回归(Ridge回归)用的是L2正则化,它把损失改写成这个样子:

J(w)=yXw22+λw22J(w) = \|y - Xw\|_2^2 + \lambda \|w\|_2^2

这里 J(w)J(w) 是加上正则项之后的总损失。w2\|w\|_2 是权重向量 ww 的L2范数,定义为 w2=w12+w22++wd2\|w\|_2 = \sqrt{w_1^2 + w_2^2 + \cdots + w_d^2},也就是所有权重平方和再开根号,w22\|w\|_2^2 就是这个平方和本身。λ\lambda 是一个我们手动设定的非负数,叫正则化强度,它决定了正则项有多重。λ\lambda 越大,正则项压得越狠,权重就被整体往小里挤。λ\lambda 等于零的时候,正则项没了,岭回归也就退化回普通最小二乘。

加了这个正则项之后,最优解的解析形式变成:

w^=(XTX+λI)1XTy\hat{w} = (X^T X + \lambda I)^{-1} X^T y

岭回归解析解的推导。 这套解也是求梯度令其为零得来的。损失 J(w)=yXw22+λw22J(w)=\|y-Xw\|_2^2+\lambda\|w\|_2^2,第一项的梯度上面已经算过是 2Xy+2XXw-2X^\top y+2X^\top Xw,第二项 λww\lambda w^\top w 的梯度是 2λw2\lambda w。合起来:

wJ=2Xy+2XXw+2λw=0\nabla_w J=-2X^\top y+2X^\top Xw+2\lambda w=0

把含 ww 的项合并,注意 λw=λIw\lambda w=\lambda I wII 是单位阵):

(XX+λI)w=Xy    w^=(XX+λI)1Xy(X^\top X+\lambda I)w=X^\top y\;\Longrightarrow\;\hat{w}=(X^\top X+\lambda I)^{-1}X^\top y

这里多出来的 II 是单位阵(对角线上全是 11、其余位置全是 00 的方阵),λI\lambda I 就是把单位阵乘上 λ\lambda。这个改动看着小,作用却实在。原本的 XTXX^T X 可能不可逆,可一旦加上 λI\lambda I,相当于给它的每个特征值都额外添了一个 λ\lambda(这部分和1.3 节讲的特征值分解是同一套数学),只要 λ\lambda 大于零,XTX+λIX^T X + \lambda I 就必定可逆。这一下从根上解决了 XTXX^T X 不可逆的麻烦。

我们再从直觉上感受一下 λ\lambda 在做什么。不妨设想一个最简单的情形,权重只有一个数 ww,训练数据希望它往 1010 这个方向靠。要是 λ\lambda 很小,比方 0.010.01,那么 ww 的最终取值大概在 9.99.9 附近,几乎没怎么缩。要是 λ\lambda 取到 11ww 大概会被拉到 55 左右。要是 λ\lambda 大到 100100ww 就几乎贴着零了。这就好像家长拽着孩子的手,拽得轻孩子还能到处跑,拽得紧孩子就只能乖乖跟在身边。岭回归始终把所有权重按比例一起压小,却不会把任何一个权重压到精确的零,所以岭回归擅长缓解过拟合,却不擅长做特征选择(也就是挑出哪些特征有用、哪些没用)。

3.Lasso:让一部分权重直接归零(L1正则)

既然提到特征选择,就该Lasso登场了。Lasso这个词是least absolute shrinkage and selection operator的缩写,名字里那个selection已经把它的看家本领说出来了。Lasso把正则项换成了L1范数,损失写成:

J(w)=yXw22+λw1J(w) = \|y - Xw\|_2^2 + \lambda \|w\|_1

这里 w1\|w\|_1 是权重向量 ww 的L1范数,定义是所有权重绝对值之和,w1=w1+w2++wd\|w\|_1 = |w_1| + |w_2| + \cdots + |w_d|。和L2范数相比,L1范数用的是绝对值而不是平方。

换上L1范数之后,发生了一件非常奇妙的事,就是很多权重会被直接压成精确的零。权重一旦是零,对应的特征对预测就完全没有贡献了,相当于这个特征被自动剔除了。这恰恰是Lasso最讨人喜欢的地方,它在拟合数据的同时顺手做了一轮特征选择,把那些可有可无的特征踢出去,留下的都是真正管事的。

我记得有个在金融行业做风控的朋友讲过一桩事,他们要预测某个客户下个月的违约概率分,手头能拿到的特征有上百个,什么最近三个月的消费金额、最近一次还款距今天数、授信额度使用率、历史逾期次数、住址变更次数,林林总总。直接用普通最小二乘,模型表现乱七八糟,好几个特征之间还高度相关。后来改用Lasso,一跑下来一半以上的权重直接归零,留下来的十几个特征个个都有道理,模型反而更准、也更好解释。这就是稀疏解(大部分权重为零的解)在实际业务里的价值。

这里头有个细节值得提一句,岭回归有上面那种漂亮的解析解,Lasso却没有一个简单的闭式解(就是能一步写出来的公式解)。原因出在 L1 范数那个绝对值上——wj|w_j|wj=0w_j=0 处不可导,所以损失函数 J(w)=yXw22+λw1J(w)=\|y-Xw\|_2^2+\lambda\|w\|_1 整体不是处处可导的,没法像岭回归那样直接令梯度为零一步解出。要绕过这个麻烦,工程上通常用坐标下降法

坐标下降法的思路很朴素:一次只优化一个权重 wjw_j,把其余权重全部摁住当常数。固定其余权重后,损失里和 wjw_j 有关的部分可以写成:

J(wj)=i=1n(yikjxikwkxijwj)2+λwjJ(w_j)=\sum_{i=1}^{n}\Bigl(y_i-\sum_{k\neq j}x_{ik}w_k-x_{ij}w_j\Bigr)^2+\lambda|w_j|

记残差(扣掉第 jj 个特征贡献后的部分)ri(j)=yikjxikwkr_i^{(-j)}=y_i-\sum_{k\neq j}x_{ik}w_k,那么对 wjw_j 来说问题变成最小化 i(ri(j)xijwj)2+λwj\sum_i(r_i^{(-j)}-x_{ij}w_j)^2+\lambda|w_j|。这是个一维的、带绝对值的最优化问题,它有闭式解(软阈值,soft-thresholding):

wj=sign(zj)xjxjmax(zjλ/2,  0),zj=ixijri(j)w_j=\frac{\operatorname{sign}(z_j)}{x_j^\top x_j}\max\bigl(|z_j|-\lambda/2,\;0\bigr),\quad z_j=\sum_{i}x_{ij}r_i^{(-j)}

这里 sign\operatorname{sign} 是符号函数,max(,0)\max(\cdot,0) 那一项就是关键:当 zjλ/2|z_j|\leq\lambda/2 时,wjw_j 直接被压成精确的 00——这就是 Lasso 产生稀疏解的直接来源。坐标下降法就是轮流对每个 wjw_j 用这个公式更新一轮,反复几轮直到收敛。好在这些算法成熟稳定,各大机器学习库都现成有,调一个参数就能用。

4.圆和菱形:一图看懂L1和L2的差别

那么为什么L1能产生零权重,L2却做不到呢,这件事用几何画面来理解最清楚。

我们设想权重只有两个,w1w_1w2w_2,这样方便在平面上画图。先看正则项这边的约束。L2正则的约束区域(也就是 w2\|w\|_2 不超过某个值的那些点)是一个圆,圆心在原点。L1正则的约束区域(w1\|w\|_1 不超过某个值的那些点)则是一个菱形,四个角分别落在两条坐标轴上。

再看损失这一边。把损失 yXw22\|y - Xw\|_2^2 取相同值的点连起来,会得到一圈一圈的椭圆,也就是等高线(地理课上地图里那种等高线是同一个意思)。

我们想象这两张图叠在一起,然后去寻找最优的 ww。可以这么想,损失这一头的椭圆从远离原点的地方慢慢往原点方向收缩,它第一次碰到正则约束区域的那个点,就是我们要的最优解。

差别就出在这个第一次相碰的位置上。L2那边是圆,圆周处处光滑,椭圆碰到圆周,碰触的位置几乎不会正好落在坐标轴上,所以两个权重都取非零的小数值。L1那边是菱形,菱形有大段是直线边、四个尖角却凸出来,椭圆最先碰到的,往往就是某个尖角,而尖角恰好落在坐标轴上,这意味着另一个权重是零。再扩到多维权重的情形也是一样道理,L1的约束区域是个高维的菱形,它的尖角大量落在坐标轴上,损失等高线很容易就切在这些角上,于是相当一部分权重直接归零。

某部讲数学的纪录片里把这两种约束比作两种不同形状的笼子,圆笼子怎么都关不出零来,菱形笼子的尖角却专门干这个。我觉得这个比方格外贴切。

用 KKT 条件把"相切在角上"说严丝合缝。 上面的几何画面可以用 1.5 节讲过的 KKT 条件严格化。把 Lasso 写成带约束的优化:minyXw22\min\|y-Xw\|_2^2 受限于 w1t\|w\|_1\leq t。最优解处,损失的负梯度 f-\nabla f 必须落在约束区域(L1 菱形)在当前点的法锥里。关键差别就在法锥上:

  • L2 圆周上每一点都光滑,法线方向唯一,最优解要求 f-\nabla f 沿径向,几乎不会精确指向某个坐标轴方向,所以权重都非零。
  • L1 菱形在尖角(坐标轴上的点)处不光滑,法锥是一个扇形区域,覆盖了一整片方向,损失等高线的法向很容易落进这个扇形里——于是最优解大量落在尖角上,对应的权重精确为零。

这正好呼应前面坐标下降的软阈值公式里那个 max(zjλ/2,0)\max(|z_j|-\lambda/2,0):它就是 KKT 条件在一维情形下的直接体现。直觉(角上相切)和数学(KKT 法锥)在这里合龙。

5. λ\lambda 怎么挑:交叉验证来掌眼

正则化强度 λ\lambda 该选多大,这件事不能拍脑袋。λ\lambda 太小,正则项约等于没有,模型照旧过拟合,训练误差很低、验证误差却很高。λ\lambda 太大,权重被压得太狠,连真正有用的信号也学不进去,模型变成欠拟合,训练误差和验证误差一起高。两头都不行,得挑中间那个合适的值。

业界通行的做法是交叉验证(cross validation)。具体怎么做呢,我们先挑一组候选的 λ\lambda 值,比方按几何级数取 0.0010.0010.010.010.10.1111010100100 这一组。然后把训练数据均分成若干份(比方五份),每次留出一份当验证集、其余几份用来训练,对每一个候选的 λ\lambda 都跑一遍、记下验证误差。五个验证集轮一遍,平均起来得到这个 λ\lambda 的平均验证误差。最后挑平均验证误差最小的那个 λ\lambda 作为最终用的值。这么一套流程下来,λ\lambda 的取值就有了依据,不至于凭感觉。

这里头还有个折中的路子叫Elastic Net(弹性网络),它把L1和L2两种正则化混在一起,损失里同时加上 αw1+(1α)w22\alpha\|w\|_1 + (1-\alpha)\|w\|_2^2,这里 α\alpha 是一个 0011 之间的混合比例参数。α\alpha11 就是纯Lasso,取 00 就是纯岭回归。要是你既想要稀疏解做特征选择、又担心纯Lasso在特征高度相关时表现不稳(相关特征里Lasso往往只随机留一个、其余归零),Elastic Net是个很稳的折中选择。

顺便提一句更深一层的视角。从贝叶斯的角度看(1.4 节我们讲过概率那套思路),L2正则化相当于假设权重服从一个高斯先验,L1正则化相当于假设权重服从一个拉普拉斯先验,求正则化的最优解,本质就是在做最大后验估计(MAP)。这个视角虽然不改变算法本身,却能帮我们把正则化理解得更透:正则化表达的是我们事先对权重大小的一种偏爱,偏爱小的权重,模型自然就不那么容易撒野。

6.回到小张:一份房价数据实战

讲完理论,我们还是回到小张身上。小张前阵子在某家房产中介实习,主管甩给他一份房价数据,让他建一个预测模型。数据里特征多得吓人,什么建筑面积、使用面积、公摊面积、楼层、总层数、建成年份、地铁距离、学区等级、商业配套指数、绿化率、容积率、物业费、近一年成交均价、片区挂牌均价,零零碎碎加起来快四十个。

小张第一反应是直接上普通最小二乘。模型一跑,训练集上拟合得漂亮极了,误差小得惊人,可一拿到测试集上,误差直接翻了好几倍,典型的过拟合。他盯着相关系数矩阵看了半天,发现建筑面积、使用面积、公摊面积这三个特征之间的相关系数都在 0.950.95 以上,几乎就是一回事,共线性严重得很。

我建议他试试Lasso。他把 λ\lambda 用五折交叉验证扫了一遍,最终挑中的 λ\lambda 大约是 0.50.5。跑完一看,将近一半的特征权重直接归零,留下来的有建筑面积(Lasso从那几个高度相关的面积特征里只留了这一个,其余压成零,相当于替他做了取舍)、地铁距离、学区等级、建成年份这几个真正影响价格的因素。测试集误差比原来低了不少,模型也变得特别好解释,给主管一讲就通。

小明后来听说了这件事,在自己的医学项目里也照方抓药。他手头的基因表达数据特征数比样本数还多(几百个病人、上万个基因),用Lasso筛出几十个关键基因去做后续分析,省了大把力气。这么看来,线性模型加上正则化,虽然是个有年头的老办法,却处处能用上,值得好好揣摩。

岭回归管住权重不撒野,Lasso顺手把没用的特征扫地出门,下一章我们聊聊逻辑回归,把这套思路搬到分类问题上头,到时见。

练习

Q1. 岭回归和 Lasso 分别用什么范数做正则?两者最关键的区别(谁能做特征选择)是什么?

岭回归用 L2 范数 λw22\lambda\lVert w\rVert_2^2,它把所有权重按比例一起压小,缓解过拟合,但压不到精确的零,所以不擅长特征选择。Lasso 用 L1 范数 λw1\lambda\lVert w\rVert_1,会把很多权重直接压成零,没用的特征权重清零,相当于在拟合的同时顺手做了一轮特征选择,所以做特征选择靠 Lasso。

Q2. 小张那份房价数据,建筑面积、使用面积、公摊面积三个特征相关系数都在 0.950.95 以上。直接上普通最小二乘会出什么问题?换 Lasso 之后会怎样?

三者高度共线,会让 XXX^\top X 接近奇异(不可逆),求逆时小特征值被翻成巨大的数,权重数值乱跳、过拟合——训练集误差小得惊人,测试集误差翻好几倍。换成 Lasso 后,从那几个高度相关的面积特征里只留一个、其余压成零,留下真正影响价格的因素(建筑面积、地铁距离、学区等级等),测试集误差降下来,模型也变得好解释。

Q3. 课文说 Lasso"没有简单的闭式解",根子出在哪?工程上一般用什么算法绕过去?

根子出在 L1 范数那个绝对值上——wj|w_j|wj=0w_j=0 处不可导,所以损失 J(w)=yXw22+λw1J(w)=\lVert y-Xw\rVert_2^2+\lambda\lVert w\rVert_1 整体不是处处可导的,没法像岭回归那样直接令梯度为零一步解出。工程上一般用坐标下降法,一次只优化一个权重 wjw_j、把其余摁住当常数,用软阈值公式 wj=sign(zj)xjxjmax(zjλ/2,0)w_j=\frac{\operatorname{sign}(z_j)}{x_j^\top x_j}\max(|z_j|-\lambda/2,0) 更新,当 zjλ/2|z_j|\leq\lambda/2wjw_j 直接被压成零。

Q4.(面试题) 用"圆和菱形"的几何画面,再结合 KKT 法锥,解释清楚 L1 正则为什么能把一部分权重精确压成零,而 L2 做不到。

把正则项的约束区域画出来:L2 是个圆(处处光滑),L1 是个菱形(四个尖角落在坐标轴上)。损失的等高线是一圈圈椭圆,从远处往原点收缩,第一次碰到约束区域的位置就是最优解。圆周光滑,椭圆碰到它几乎不会正好落在坐标轴上,所以两个权重都取非零小数;菱形的尖角凸出来,椭圆最先碰到的往往是某个尖角,而尖角恰好落在坐标轴上,意味着另一个权重是零。用 KKT 严格化:L2 圆周每点法线唯一,几乎不会精确指向某个坐标轴;L1 菱形在尖角处不光滑,法锥是个扇形、覆盖一整片方向,损失等高线的法向很容易落进去,于是最优解大量落在尖角上,对应权重精确为零。这正是软阈值公式里那个 max(zjλ/2,0)\max(|z_j|-\lambda/2,0) 的几何来源。

相关标签
机器学习线性回归正则化