首页 / 资讯中心 / 文章详情

从线性回归到岭回归与LASSO:正则化如何解决过拟合与特征选择

从线性回归到岭回归与LASSO:正则化如何解决过拟合与特征选择 ★ FEATURED ARTICLE
1. 从最小二乘说起线性回归为什么需要正则化1.1 线性回归的损失函数与参数求解线性回归、岭回归和LASSO回归这三个模型放到一起几乎就是入门机器学习第一道分水岭。很多人线性回归学得很顺一到岭回归和LASSO就开始犯迷糊好好的最小二乘为什么不用非要加惩罚项加了惩罚项之后参数解出来的意义是不是就变了这篇文章我就结合自己实际做项目的经历把三个模型从头到尾捋一遍——从损失函数构造逻辑、正则化项的数学原理到实际调参和选型的操作细节一次性讲清楚。线性回归的任务本质上是找一组权重 w 和一个偏置 b让预测值 ŷ Xw b 与真实值 y 之间的误差尽可能小。最经典的做法是最小二乘法损失函数写成L(w) Σ(y_i - ŷ_i)² ||y - Xw||²这个形式看起来简单但它背后有一个重要假设误差服从正态分布且各样本独立同分布。对损失函数求导并令导数为零可以直接得到闭式解w (XᵀX)⁻¹Xᵀy这个解在教科书里写得漂漂亮亮但实际项目里你会遇到几个很现实的问题。第一特征之间高度相关时XᵀX 可能接近奇异矩阵求逆结果极不稳定参数估计值方差大到离谱。第二特征维度很多时模型会把训练数据里的噪声也当成规律学进去造成严重过拟合。我刚做项目时踩过一个典型的坑当时建模用了几十个原始特征训练集上 R² 高到 0.98换一批数据直接掉到 0.6这种“训练漂亮、上线惨”的症状几乎都是过拟合。注意线性回归的闭式解不是任何时候都能直接用的。特征数量超过样本数量时XᵀX 不可逆闭式解直接失效这也是后面引入正则化的现实原因之一。1.2 过拟合的实质最小二乘的方差为什么失控要理解正则化先得理解过拟合是怎么来的。模型复杂度高等价于模型参数的自由度大而自由度大的模型对训练样本中的每一点抖动都很敏感。最小二乘的目标就是纯粹拟合训练误差它不会管参数值大小结果就是权重可以变得非常大正负穿插试图精确“描”出每一个训练样本点。这里可以用一个直观类比你请了一个记忆力超强的学生他考试前把练习题答案逐字背下来题目稍微换个数字他就不会了。最小二乘就是这个“死记硬背”的学生。岭回归和 LASSO 要做的就是给这个学生定规矩你可以记但不能毫无节制地记对每个知识点参数都要付出一定“代价”。于是“正则化惩罚项”就登场了。它的本质是在原始损失函数后面加一项用参数大小来约束模型复杂度。参数太大即使训练误差很小整体损失也会变大这样优化过程就会自动在“拟合得更好”和“参数更小”之间找平衡点。至于这个惩罚项是用 L1 范数还是 L2 范数就衍生出了岭回归和 LASSO 两条完全不同的技术路线。2. 岭回归L2 正则化如何稳住参数估计2.1 岭回归的损失函数与闭式解岭回归的损失函数写成L_ridge(w) ||y - Xw||² λ||w||²后面加的是 L2 范数的平方λ 是正则化强度也可以叫岭参数。对 w 求导并令其为零解变成w_ridge (XᵀX λI)⁻¹XᵀyXᵀX 加上 λI 之后原来可能接近奇异甚至不可逆的矩阵变成了严格正定矩阵求逆问题被稳稳地解决了。这就是“岭”这个名字的来源——在矩阵对角线上加了一条“山脊”让它变得数值稳定。从参数估计的角度看L2 惩罚把权重整体往零的方向压缩但它不会直接让某个权重变成绝对的零。什么意思呢如果原始最小二乘解是 w3加上岭惩罚之后解可能是 2.7但它还是一个非零的数。每个特征对预测仍然有微小贡献只是整体幅度被压住了。这就决定了岭回归擅长处理“特征都多少有用、且相关性较强”的场景。实操心得我刚开始用岭回归时最大的误解是以为它能做特征选择。它其实做的是特征“压缩”不是“删除”。你想让模型自动挑出几个最重要的特征岭回归做不到得交给 LASSO。2.2 岭参数 λ 的调参逻辑与交叉验证λ 的大小直接决定惩罚力度。λ0 时岭回归退化成普通最小二乘λ 趋向无穷大时所有权重都被压向 0模型退化成一条水平线只保留偏置。实际操作中λ 的选择几乎都是用交叉验证完成的常见做法是将训练集分成 K 折我一般用 5 折或 10 折在一组对数均匀分布的候选 λ 上依次训练记录每一折的验证误差取平均值选择平均验证误差最小的 λ这里有个细节容易被忽略λ 的取值范围最好用对数刻度比如 10⁻⁴ 到 10⁴而不是线性从 0.001 到 1 均匀取数。因为正则化对 λ 的响应在数量级层面变化线性取值会浪费大量计算在几乎没区别的区间。选择最小验证误差对应的 λ 时我习惯再加一个“邻近选择”原则。最小误差对应的 λ 往往偏小模型复杂度偏高泛化风险仍在。我会在误差-λ 曲线比较平坦的区域里选一个稍微大一点的 λ让模型参数压缩得更多一些换取更好的稳定性。代价是验证误差可能上升一点点但换来的是实打实的泛化能力提升。3. LASSO 回归L1 惩罚带来的稀疏解与特征选择3.1 LASSO 的损失函数与几何直觉LASSOLeast Absolute Shrinkage and Selection Operator的损失函数是L_lasso(w) ||y - Xw||² λ||w||₁这里的 ||w||₁ 是绝对值和。与 L2 惩罚不同L1 惩罚有一个非常独特的性质在最优解处部分参数会被精确压缩到 0。这意味着 LASSO 天然能做特征选择保留下来的特征就是模型认为真正有用的变量。为什么 L1 能让参数归零而 L2 不能画个二维参数空间图就明白了。L2 约束是一个圆目标函数等高线与圆周相切的位置基本不会落在坐标轴上L1 约束是一个菱形菱形的角尖就长在坐标轴上等高线一碰到角尖对应的参数就是 0。维度越高这种稀疏效应越明显。从另一种角度看稀疏解等价于模型在诸多特征里做了一次“硬决策”——有些特征直接不要了。这在特征维度几千上万的项目里特别有价值特征少了模型解释性变强部署时的存储和计算成本也降下来了。我当时做一个信息筛选类的模型几百个候选特征里最后 LASSO 只保留了二十几个解释业务时省了太多力气。3.2 坐标下降法与正则化路径LASSO 的损失函数虽然在 0 点不可导没法直接用梯度下降处理所有位置但有一个非常高效的标准算法叫坐标下降法。它的思路是固定其他所有参数只优化当前这个参数然后逐个循环直到收敛。因为每一步的优化都有解析解实际运行速度非常快。坐标下降的推导中有个软阈值操作w_j S(z_j, λα_j)其中 S 是软阈值函数它做的事情很简单当 z_j 的绝对值小于阈值 λα 时直接把 w_j 置为 0否则把 z_j 往零的方向缩一段距离。这个“要么归零、要么收缩”的行为正是 LASSO 稀疏解的直接来源。实操中我一般不手写坐标下降直接用现成库里的实现但理解它仍然有价值。你可以通过调节 λ 得到一条正则化路径观察每个特征系数在 λ 从小到大过程中的变化轨迹。特征系数从非零变成零的那个 λ 值可以作为判断特征重要性的参考依据。这个可视化在业务汇报中特别加分比直接甩一个最终特征列表好理解得多。4. 三种模型怎么选从数据特征到业务场景4.1 模型对比与适用场景先放一张我在项目里经常用来给团队讲清楚的三模型对照表模型惩罚项能否特征选择适合场景参数解释性线性回归无否特征少、样本充足、无明显共线性最直观岭回归L2否只压缩特征相关性强、维度中等、所有特征都可能有用尚可权重被压缩需说明LASSOL1是特征维度高、存在大量冗余特征、需要模型可解释稀疏后解释性强选择逻辑上我的经验是先用一个快速基线判断。特征数量远小于样本量、共线性不严重、模型不加正则化也能稳定用普通线性回归甚至更好参数直接就是业务分析里需要的“边际效应”。但大多数真实数据没这么干净特征一多正则化基本就是默认项。如果特征是业务逻辑确认过都有效的比如价格、促销、库存这些核心变量你不能把任何一个剔除掉那岭回归是稳妥的。如果特征里有大量噪音、候选特征成千上万你需要一个自动筛选机制那就用 LASSO。当特征数量特别大或者共线性非常明显时很多人会选择 ElasticNet——它是 L1 和 L2 惩罚的线性组合兼顾稀疏性和稳定性。这个正文里不展开但它在实际工业项目中非常常见。4.2 评估指标与模型对比的完整流程三种模型不能只看训练集误差来对比评估流程必须统一。我在项目中一般这样做先把数据拆成训练集、验证集和测试集三者比例大致 7:2:1训练集上做交叉验证确定每个模型各自的 λ在所有模型都确定 λ 后在测试集上统一计算 RMSE、MAE、R²如果需要解释模型还要额外看稀疏度、特征保留情况、系数符号是否符合业务常识这里尤其要提醒一个经验不同模型的 RMSE 差异如果小于 5%我会倾向于选择解释性更好的那个而不是数值上略优的那个。因为回归模型在工业项目里往往不只做预测还要给业务同事讲清楚“哪些因素在起作用、方向是什么、影响有多大”。LASSO 能给出一个简洁的特征集合很多时候比那 5% 的精度提升更有价值。注意不要用同一个固化的数据预处理流程去套所有模型。比如对是否标准化三种模型的态度是不同的。线性回归对特征尺度敏感但不是由于数学上不能算而是由于系数的可解释性岭回归和 LASSO 由于惩罚项直接作用在系数上特征不标准化会造成不公平的压缩。这个细节直接影响选型结果。5. 实操流程从数据预处理到调参落地的完整记录5.1 数据清洗与标准化我常用一个任务来演示三种模型的完整实操。任务背景是预测某地区房屋价格原始数据有 20 个特征包含面积、房龄、周边配套评分、交通便利指数等还掺杂着一些噪声特征比如房源编号、录入员代号这种理论上有唯一性的变量。这种数据是典型的需要正则化处理的场景维度不算特别多但噪声特征和相关性都有一点。预处理顺序上我习惯按“清洗 → 编码 → 标准化 → 切分”来走。清洗阶段要处理缺失值和异常值尤其是房龄这种明显违背常识的数值比如出现负值或者 300 年以上这种记录直接删除或按边界值替换。编码阶段处理类别变量比如朝向、装修档次转为 one-hot。标准化阶段特别关键因为岭回归和 LASSO 的惩罚项对每个特征系数都敏感如果面积以“平方米”为单位、交通指数以“分”为单位数值范围差几个数量级λ 对它们的作用就会失衡。具体标准化我会用 sklearn 的 StandardScaler先 fit 训练集再 transform 测试集。注意这里一定要用同一个 scaler 去处理测试集绝不能在测试集上重新 fit否则相当于把测试集的信息泄露给了训练过程。这是我看到很多新手反复犯的错。5.2 三种模型的构建与调参以 Python 生态为例核心代码大致是这个框架from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.linear_model import LinearRegression, Ridge, Lasso import numpy as np X_train, X_val, y_train, y_val train_test_split(X, y, test_size0.2, random_state42) scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_val_scaled scaler.transform(X_val) # 线性回归 lr LinearRegression() lr.fit(X_train_scaled, y_train) # 岭回归用交叉验证选择 lambda ridge_params {alpha: np.logspace(-4, 4, 50)} ridge GridSearchCV(Ridge(), ridge_params, cv5, scoringneg_mean_squared_error) ridge.fit(X_train_scaled, y_train) # LASSO lasso_params {alpha: np.logspace(-4, 2, 30)} lasso GridSearchCV(Lasso(max_iter10000), lasso_params, cv5, scoringneg_mean_squared_error) lasso.fit(X_train_scaled, y_train) # 统一在验证集上评估 from sklearn.metrics import mean_squared_error, r2_score for name, model in [(LinearRegression, lr), (Ridge, ridge), (Lasso, lasso)]: pred model.predict(X_val_scaled) print(name, RMSE:, np.sqrt(mean_squared_error(y_val, pred)), R2:, r2_score(y_val, pred))代码非常简单真正有讲究的是几个点。第一LASSO 的 max_iter 需要设得大一点默认 1000 在某些数据上可能还没收敛直接导致结果不稳定。第二岭回归的候选 alpha 范围不需要取到 10⁴ 那么高因为 L2 惩罚对极端大值的响应太强很容易把所有系数都压成接近 0。第三GridSearchCV 的 scoring 参数要明确指定千万别用默认的 R²否则你选出来的参数跟用 RMSE 选的完全不是一回事。调参跑完之后我还会做一个稳定性确认把随机种子换几个不同的值重新切分数据看选出来的最优 α 是否在同一个数量级内。如果换一次切分最优 α 就跳跃两三个数量级说明模型对数据划分极度敏感这时我会回头检查数据本身的质量而不是继续调参。这是个很多人没意识到的问题。5.3 结果解读与特征重要性的视角模型跑完别急着写报告。拿到三个模型的系数之后我会按这样一组步骤来解读看 LASSO 保留下来哪些非零系数这些特征就是模型认为的“硬核”变量对比岭回归中同一批特征的系数排序验证方向和相对大小是否一致把线性回归的系数也列出来观察正负号是否与业务认知相符如果岭回归和 LASSO 对某个特征的系数方向不一致我会立刻标记为“需要人工核查”。这种不一致往往意味着特征本身有异常或者与其他特征存在强相关导致系数符号翻转、稳定性变差而不是模型错了。这种对比工作价值远高于单纯比较 RMSE 数字。对于特征重要性LASSO 的系数绝对值可以当成初步排序依据但不要把它当成严格重要性度量。原因在于 L1 惩罚会系统性地缩小系数而且特征共线时谁被保留、谁被剔除存在随机性。想得到更可靠的重要性排序我会再做一次基于置换的特征重要性评估或者用交叉验证中不同折里 LASSO 保留特征的频次来判断。6. 常见问题与排查技巧实录6.1 特征尺度不一致导致正则化失衡症状加了 L1/L2 惩罚之后模型表现还不如不加或者某些大数值特征被强制压成 0 但业务上它们明明很重要。原因几乎都是没做标准化。想象一下房龄单位是“年”数值通常 0 到 100交通指数是 0 到 1 的浮点数同时还有个“房源面积”是几十到几百平方米。L1 惩罚对参数绝对值加总一个面积对应的系数只要稍微被压缩一点点损失就变化巨大而交通指数对应的系数缩到 0 的成本小得多模型就会优先把标度小的特征砍掉这不是特征本身不重要而是量纲在捣乱。解决方式很简单对每个特征做标准化让它们处在同一量级。标准化之后再做模型系数的大小才真正反映特征对目标的贡献强度。这一条是所有正则化模型使用的前提没有例外。6.2 λ 选得过大导致欠拟合症状训练集误差明显高于普通线性回归验证集误差也没有变好模型输出近似于一条水平线。原因很直接λ 太大所有系数都被压向 0 了。我见过有人直接用默认的 α1 去跑 LASSO结果特征全被删光模型只剩一个 intercept。用交叉验证的目的就是避免这种情况但交叉验证也不是无脑套用候选 λ 的范围要覆盖到相对小的区域比如从 0.001 起步而不是一律从 1 起步。排查时我会把正则化路径画出来横轴是 log(λ)纵轴是系数值一眼就能看到系数从非零到归零的临界点。如果最优 λ 恰好在临界点右侧很远说明正则化过度如果在临界点左侧太远说明正则化几乎没有作用模型接近最小二乘。合理值应该落在临界点附近偏右一点点的区域。6.3 LASSO 在特征高度相关时的表现不稳定症状多次运行中LASSO 保留的特征集合变化很大这次留下 A 特征删掉 B下次反过来。或者 A 和 B 明明高度相关模型却只选其中一个导致业务解释困难。这是 LASSO 的固有缺陷。L1 惩罚在特征存在高度共线性时会随机选择从一组强相关特征里挑一个因为它对“选谁”的过程并不敏感——只要损失差不多路径就会摇摆。对于这种情况我通常有两种处理一是先用相关性分析把强相关特征聚类每组只保留一个代表特征再进 LASSO二是直接换 ElasticNet用 L2 项稳定相关特征组的系数估计再用 L1 项做稀疏化。经验上在典型业务数据里特征之间几乎不可能完全独立所以我现在做 LASSO 时从不只看一次结果而是结合多次交叉验证的保留频次来下结论。一个特征如果在大多数折里都被保留了我才认定它稳定重要。6.4 对线性回归的一个常见误判共线性不等于必须用正则化很多人一看到特征相关性强就无条件认为必须上岭回归。其实共线性的危害主要在参数估计方差的增大但如果你的目标是做预测而不是解释参数共线性对预测精度的影响没那么致命。样本量足够大时普通线性回归的预测结果也可能完全可用参数方差虽然大但整体拟合效果照样稳定。所以我的建议里有一条先问业务目标。只做预测且特征不多普通线性回归甚至更好因为不用调 λ模型简单直接。要做变量解释、梳理影响因子再看共线性的严重程度决定要不要岭回归。这一点在面试交流中也常被问到能分清楚“预测视角”和“解释视角”的差异说明你对模型的理解已经不只是停留在公式层面。最后分享一个个人项目里的体会。我最初上手这三个模型时把大量时间花在调整代价函数的细节和比较验证误差数字上后来才发现真正决定项目成败的两个前置问题数据到底干不干净、业务上究竟需要预测还是解释。想清楚这两件事再选模型、调参数事半功倍。还有一个我后来固定下来的小习惯把每一次跑出来的正则化路径图、系数对比表、验证误差曲线全都存档哪怕当时觉得没用。项目周期一长新需求来了要复用旧结论这些存档就是最值钱的参考资料比任何记忆都可靠。如果你正要拿这三个模型做练习或上线我的建议是别急着追求最优精度先把每一个模型在一个简单数据集上完整跑通线性回归打印系数、岭回归看不同 lambda 下系数收缩曲线、LASSO 观察特征从有到无的删除过程。把这三张图看明白了你才算真正理解正则化到底在做什么。
阅读完成 · 觉得有帮助?
咨询建站