ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从线性回归到正则化:岭回归与Lasso的原理、实战与竞赛应用

从线性回归到正则化:岭回归与Lasso的原理、实战与竞赛应用 1. 从线性回归的“完美”困境说起如果你参加过数学建模竞赛或者处理过任何涉及预测、拟合的课程项目线性回归大概率是你工具箱里的第一把锤子。它简单、直观公式漂亮y β₀ β₁x₁ ... βₚxₚ ε每个系数βᵢ都对应一个特征xᵢ的贡献解释性极强。在理想世界里当我们的数据满足高斯-马尔可夫定理的所有假设线性关系、无多重共线性、误差同方差且独立等时普通最小二乘法给出的解就是最优线性无偏估计。但现实数据往往骨感得多尤其是当你面对高维数据或者特征之间存在千丝万缕的联系时线性回归的“完美”表象就会瞬间崩塌。最典型的两个“骨感现实”就是多重共线性和过拟合。想象一下你要用一个人的“年龄”和“工龄”来预测其收入这两个特征高度相关几乎是一个信息的两种表达。在线性回归中模型会变得非常“敏感”试图精确分配这两个高度相关特征的贡献导致系数估计值变得极不稳定方差巨大。今天用这批数据算出来年龄的系数是正100工龄是负50明天数据稍微波动一下可能就变成年龄负200工龄正150。这样的模型你敢用吗它的预测结果会像过山车一样毫无可靠性可言。这就是多重共线性带来的系数估计不稳定的噩梦。另一个问题是维度灾难下的过拟合。当特征数量p很多甚至接近或超过样本数量n时普通最小二乘解会变得极其“贪婪”它试图用一条极其复杂的超平面去穿过每一个数据点包括那些由噪声产生的点。结果就是模型在训练集上表现近乎完美R²趋近于1但一旦遇到新数据预测误差就会爆炸。模型记住了所有噪声却丧失了泛化能力。正是在这样的背景下岭回归和Lasso回归作为正则化线性模型的代表登上了舞台。它们不是要推翻线性回归而是给它套上“缰绳”通过给损失函数增加一个惩罚项约束系数的大小从而换取模型的稳定性和泛化能力。在数学建模竞赛中从国赛到美赛从数据预测题到综合评价题只要涉及回归分析这两个方法几乎成了标配。但很多同学只是照搬代码调个alpha参数了事并不清楚背后的“为什么”以及“怎么选”。这篇内容我就结合自己带赛和评审的经验把岭回归和Lasso回归从原理到实操再到竞赛中的实战技巧掰开揉碎了讲清楚。2. 岭回归稳定性优先的“温和”约束我们先从岭回归说起。它的核心思想非常直观既然普通最小二乘法OLS的系数估计不稳定方差大那我们能不能牺牲一点无偏性来换取方差的显著降低从而获得一个更稳定、泛化能力更强的模型岭回归的回答是可以。2.1 原理拆解给损失函数加个“紧箍咒”普通最小二乘法的目标是最小化残差平方和RSSRSS Σ(yᵢ - ŷᵢ)² Σ(yᵢ - β₀ - Σβⱼxᵢⱼ)²岭回归在这个目标上加了一个惩罚项变成了最小化以下函数RSS λ * Σβⱼ² (j1 to p)注意这里的求和不包括截距项β₀。我们通常不希望惩罚截距因为它只是整体的平移。这个惩罚项λ * Σβⱼ²就是L2范数惩罚。λ (lambda)是一个大于等于0的超参数它控制着惩罚的力度。这个惩罚项到底做了什么收缩系数它迫使所有系数βⱼ向0收缩。λ越大收缩力度越强系数越趋近于0但永远不会等于0。降低方差通过收缩系数模型对数据中微小波动的敏感性大大降低从而显著减少了系数的方差提高了估计的稳定性。引入偏差强制收缩意味着我们得到的系数估计不再是真实系数的无偏估计。这就是经典的偏差-方差权衡。我们用引入一点偏差的代价换来了方差的大幅下降总体预测误差通常用均方误差MSE衡量往往能得到优化。从几何角度理解也很有趣。OLS的解是在所有可能的系数向量中找到使RSS最小的那个点。而岭回归的解则是在一个中心在原点的“球”L2球的约束下寻找使RSS最小的点。λ越大这个球的半径越小解就被限制在离原点更近的区域内。2.2 关键超参数λ的选择定性与定量方法λ是岭回归的灵魂它没有“正确”值只有“合适”的值。选择λ是建模的核心步骤。1. 可视化方法岭迹图这是最经典、最直观的方法。其做法是取一系列λ值通常在对数尺度上如10^(-2), 10^(-1), ..., 10^10。对每个λ拟合一个岭回归模型记录所有系数的估计值。以log(λ)为横轴系数值为纵轴画出每个系数随λ变化的曲线这就是岭迹图。如何解读岭迹图稳定性观察随着λ增大所有系数应逐渐平稳地趋向于0。如果某些系数在λ变化初期剧烈震荡说明原数据存在多重共线性岭回归正在发挥稳定作用。选择λ选择一个λ值使得所有系数都趋于稳定曲线变得相对平缓且不至于收缩得太厉害导致模型失去解释能力。这通常是一个需要经验判断的“拐点”。2. 定量方法交叉验证这是更客观、自动化且更推荐在实战中使用的方法尤其是在追求预测精度时。最常用的是K折交叉验证将数据集随机分成K份通常K5或10。依次将其中一份作为验证集其余K-1份作为训练集。对于每一个候选的λ值在训练集上拟合模型在验证集上计算预测误差如均方误差MSE。对每个λ计算K次验证误差的平均值。选择使平均验证误差最小的那个λ值。在Python的sklearn中RidgeCV类可以自动完成这个过程非常方便。from sklearn.linear_model import RidgeCV import numpy as np # 生成一系列lambda值sklearn中参数名为alpha alphas np.logspace(-3, 3, 50) # 从10^-3到10^3生成50个对数间隔的值 # 使用交叉验证寻找最优alpha ridge_cv RidgeCV(alphasalphas, store_cv_valuesTrue) ridge_cv.fit(X_train, y_train) print(f“最优 alpha 值: {ridge_cv.alpha_}”) print(f“交叉验证下的最佳得分R²: {ridge_cv.best_score_}”)注意交叉验证找到的λ是基于预测误差最小化的不一定能保证系数有最好的解释性。如果你的目标是模型解释可能需要结合岭迹图进行微调。2.3 实战中的标准化一个必须的步骤这是一个极易被忽略但至关重要的细节。岭回归的惩罚项是系数的平方和。如果特征X的尺度不同惩罚的效果就会失真。例如特征A的取值范围是[0, 1]特征B的取值范围是[0, 10000]。那么特征B的系数即使很小其平方项也可能很大导致惩罚项过度针对特征B这是不合理的。因此在拟合岭回归模型之前必须对特征进行标准化处理通常是将每个特征减去其均值除以其标准差使其均值为0方差为1。这样所有特征都被放在了同一尺度上惩罚才是公平的。幸运的是sklearn的Ridge和RidgeCV等模型在拟合时如果设置normalizeTrue旧版本或使用StandardScaler预处理会自动处理这一问题。但最佳实践是显式地使用StandardScalerfrom sklearn.preprocessing import StandardScaler scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 注意使用训练集的均值和标准差来转换测试集 ridge Ridge(alpha1.0) ridge.fit(X_train_scaled, y_train) # 此时得到的系数是基于标准化后数据的系数一个重要提醒模型预测时输入的新数据也必须用相同的scaler进行转换。最终解释系数时要清楚它对应的是标准化后的特征。3. Lasso回归特征选择的“锐利”武器如果说岭回归是一位温和的调解员通过收缩所有系数来稳定模型那么Lasso回归就像一位果断的指挥官它倾向于将一些不重要的特征的系数直接压缩到零从而实现自动化的特征选择。3.1 原理对比从L2到L1惩罚Lasso回归的目标函数是RSS λ * Σ|βⱼ| (j1 to p)关键变化在于惩罚项从系数的平方和L2范数变成了系数的绝对值之和L1范数。这个看似微小的改变带来了质的不同。L1惩罚的几何特性 L2惩罚的约束区域是一个“圆滑”的球体最优解往往在边界与目标函数等高线的切点上这个点通常所有坐标都不为零。而L1惩罚的约束区域是一个“菱形”它有角。当目标函数RSS的等高线与这个菱形在角上相切时就会导致该角对应的坐标即某个系数为0。这就是Lasso能够产生稀疏解许多系数为0的几何解释。它不仅仅收缩系数更是在进行一种连续的子集选择。3.2 特征选择的意义与局限性优势可解释性最终模型只保留了一部分特征模型更简单更容易向非专业人士解释。在数学建模论文中这是一个巨大的优点。应对高维数据当特征数量p远大于样本数量n时普通线性回归已不可解岭回归虽然可解但模型依然复杂所有特征都在。Lasso可以在p n的情况下选择出最多n个非零系数的特征得到一个可用的模型。消除共线性对于一组高度相关的特征Lasso倾向于从中只选择一个而将其他相关的系数设为0。这在一定程度上缓解了多重共线性的问题虽然方法比较“粗暴”。局限性选择不稳定如果有一组高度相关的特征Lasso可能会随机地从中选一个而不是像岭回归那样给它们分配相似的权重。数据的微小变化可能导致选出的特征子集发生较大变化。饱和性当n p时Lasso最多只能选择n个特征。如果真实情况中有多于n个重要特征Lasso无法发现它们。分组效应缺失对于代表同一类别或信息的多个特征例如一组哑变量表示“职业”我们希望它们要么同时被选入要么同时被剔除。但Lasso没有这种“分组”意识它可能只选择组内的部分特征。3.3 超参数λ的选择与系数路径图与岭回归类似λ控制着惩罚的强度。λ越大被压缩为零的系数越多模型越稀疏。系数路径图是分析Lasso的利器。它绘制了每个系数随λ或正则化路径的步长变化的轨迹。from sklearn.linear_model import Lasso import numpy as np import matplotlib.pyplot as plt alphas, coefs, _ Lasso().path(X_train_scaled, y_train, alphasnp.logspace(-2, 2, 100)) plt.figure(figsize(10, 6)) for i in range(coefs.shape[0]): plt.plot(alphas, coefs[i, :], labelf‘Coeff {i}’) plt.xscale(‘log’) plt.xlabel(‘log(alpha)’) plt.ylabel(‘Coefficient Value’) plt.title(‘Lasso Coefficient Paths’) plt.legend() plt.show()从图中你可以清晰地看到随着λ增大从左到右各条系数路径逐渐“死亡”趋于0。哪条线最晚消失通常意味着对应的特征越重要。选择λ的实践方法 同样交叉验证是最可靠的方法。使用LassoCV可以自动完成from sklearn.linear_model import LassoCV lasso_cv LassoCV(alphasnp.logspace(-3, 0, 50), cv5, max_iter10000) lasso_cv.fit(X_train_scaled, y_train) print(f“最优 alpha 值: {lasso_cv.alpha_}”) print(f“选择的特征数量: {np.sum(lasso_cv.coef_ ! 0)}”)注意Lasso的优化算法坐标下降法对迭代次数敏感。如果特征很多或数据特殊可能需要增加max_iter参数以避免“未收敛”的警告。同样数据标准化对Lasso也是必须的。4. 竞赛实战如何根据题目需求做选择与调优在数学建模竞赛的短短几天里面对一个具体的回归问题你该如何在岭回归和Lasso回归之间抉择并快速得到一个可靠的模型下面是我的实战流程和建议。4.1 第一步问题分析与模型目标判断拿到题目后不要急着跑代码。先花时间理解问题首要目标是预测精度还是特征解释如果题目明确要求“找出关键影响因素”、“分析哪些变量最重要”例如2019年国赛C题“机场的出租车问题”中分析影响司机决策的因素那么Lasso回归的特征选择能力就是你的首选。它给出的稀疏模型直接指明了“关键变量”。如果题目核心是“预测”、“估计”例如许多预测类题目且特征间可能存在相关性那么岭回归的稳定性可能提供更好的预测性能。你也可以两者都试用交叉验证比较预测误差。数据维度如何特征数量p远大于样本数量nLasso是更自然的选择因为它可以处理p n的情况并自动降维。特征数量p适中但高度相关岭回归可能更优因为它能平滑地处理共线性而不是武断地丢弃特征。一个常用策略先使用Lasso进行特征筛选剔除掉系数为零的特征然后在剩下的特征子集上使用岭回归或普通线性回归进行精调。这结合了两种方法的优点。4.2 第二步数据预处理与基准建立处理缺失值根据情况用均值、中位数、众数填充或使用插值法、模型预测法。在竞赛中简单稳健的方法往往比复杂方法更可靠。异常值处理对于回归问题异常值影响巨大。使用箱线图、3σ原则等进行识别并根据业务逻辑决定是修正、剔除还是保留。特征工程这是提升模型性能的关键。根据题目背景创造新特征如比值、差值、多项式项、交互项。特别注意如果创建了多项式项或交互项共线性会急剧增加此时正则化方法尤其是岭回归的价值更大。划分数据集务必划分训练集和测试集如80%-20%或直接使用交叉验证。绝对禁止在测试集上进行任何基于数据分布的操作如标准化。建立基准模型跑一个普通线性回归作为基准。记录它在训练集和测试集上的性能如R², MSE。这个基准有两个作用一是验证预处理流程是否正确模型应能运行二是作为对比的锚点看正则化模型是否带来了提升。4.3 第三步模型训练、评估与对比# 示例完整的对比流程 from sklearn.model_selection import train_test_split, cross_val_score from sklearn.linear_model import LinearRegression, Ridge, Lasso, RidgeCV, LassoCV from sklearn.preprocessing import StandardScaler from sklearn.metrics import mean_squared_error, r2_score import pandas as pd import numpy as np # 假设 df 是特征DataFramey 是目标变量 X df.values y target.values # 1. 划分数据 X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) # 2. 标准化非常重要 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 3. 基准模型普通线性回归 lr LinearRegression() lr.fit(X_train_scaled, y_train) y_pred_lr lr.predict(X_test_scaled) mse_lr mean_squared_error(y_test, y_pred_lr) print(f“OLS - Test MSE: {mse_lr:.4f}, R²: {r2_score(y_test, y_pred_lr):.4f}”) # 4. 岭回归交叉验证选参 ridge_cv RidgeCV(alphasnp.logspace(-3, 3, 100), cv5) ridge_cv.fit(X_train_scaled, y_train) y_pred_ridge ridge_cv.predict(X_test_scaled) mse_ridge mean_squared_error(y_test, y_pred_ridge) print(f“Ridge (alpha{ridge_cv.alpha_:.4f}) - Test MSE: {mse_ridge:.4f}, R²: {r2_score(y_test, y_pred_ridge):.4f}”) # 5. Lasso回归交叉验证选参 lasso_cv LassoCV(alphasnp.logspace(-3, 0, 100), cv5, max_iter10000) lasso_cv.fit(X_train_scaled, y_train) y_pred_lasso lasso_cv.predict(X_test_scaled) mse_lasso mean_squared_error(y_test, y_pred_lasso) selected_features np.sum(lasso_cv.coef_ ! 0) print(f“Lasso (alpha{lasso_cv.alpha_:.4f}) - Test MSE: {mse_lasso:.4f}, R²: {r2_score(y_test, y_pred_lasso):.4f}”) print(f“Lasso 选择了 {selected_features} 个特征。”) # 6. 模型对比与选择 results pd.DataFrame({ ‘Model’: [‘OLS’, ‘Ridge’, ‘Lasso’], ‘Test MSE’: [mse_lr, mse_ridge, mse_lasso], ‘Num_Features’: [X.shape[1], X.shape[1], selected_features] }) print(results)评估要点首要看测试集性能比较MSE或R²。哪个模型在测试集上表现更好结合模型复杂度如果两个模型预测误差相近选择更简单的模型Lasso选择的特征更少或岭回归的系数更小。检查系数打印出Lasso筛选后的特征及其系数结合题目背景判断其合理性。如果结果与常识严重相悖需要回头检查数据或特征工程。4.4 第四步结果解释与论文撰写要点在论文中呈现这部分内容时不能只贴代码和结果要讲好“故事”方法论阐述简要说明线性回归在面临多重共线性和过拟合时的局限性引出岭回归和Lasso回归的思想加入惩罚项以实现偏差-方差权衡或特征选择。数据处理说明明确写出“对所有连续型特征进行了标准化处理以消除量纲对正则化惩罚的影响”。超参数选择过程说明你是如何选择λ的。“我们采用5折交叉验证在对数尺度上搜索了从10⁻³到10³的100个α值选取使交叉验证均方误差最小的α作为最终模型的超参数。” 附上交叉验证误差随α变化的曲线图会非常专业。结果对比表格用清晰的表格展示OLS、Ridge、Lasso在训练集和测试集上的关键指标R², MSE, MAE等以及Lasso筛选后的特征数量。模型选择与解释根据对比结果说明你最终选择了哪个模型以及理由。“由于Lasso回归在测试集上取得了最低的MSE且其模型仅保留了5个特征在保证预测精度的同时极大地提升了模型的可解释性因此我们选择Lasso回归作为最终模型。” 然后对最终模型的系数进行解释说明每个特征对目标变量的影响方向和程度。敏感性分析加分项可以讨论一下如果改变训练集/测试集划分比例或者使用不同的随机种子模型结果是否稳定。这体现了你对模型稳健性的思考。5. 高级话题与常见陷阱当你掌握了基本用法后下面这些进阶知识和常见“坑”能让你在竞赛中更游刃有余。5.1 Elastic Net岭回归与Lasso的折衷有没有方法能结合岭回归和Lasso的优点这就是Elastic Net。它的目标函数是RSS λ₁ * Σ|βⱼ| λ₂ * Σβⱼ²它同时包含L1和L2惩罚。通过调整混合比例参数l1_ratio即λ₁占总惩罚λ₁λ₂的比例你可以在纯Lasso (l1_ratio1)、纯岭回归 (l1_ratio0) 以及中间状态之间平滑过渡。Elastic Net的优势当特征数量远大于样本数p n时Lasso最多选n个特征的问题可能被缓解。当特征存在高度相关分组时Elastic Net倾向于将整个组的特征一起选入或剔除模仿了“分组效应”。在特征高度相关且数量很多时它通常比单纯的Lasso有更好的预测表现。在sklearn中使用ElasticNetCV可以方便地进行交叉验证选择alpha和l1_ratio。from sklearn.linear_model import ElasticNetCV # l1_ratio在0到1之间0是岭回归1是Lasso elastic_cv ElasticNetCV(l1_ratio[.1, .5, .7, .9, .95, .99, 1], alphasnp.logspace(-3, 1, 30), cv5, max_iter10000) elastic_cv.fit(X_train_scaled, y_train) print(f“最优 l1_ratio: {elastic_cv.l1_ratio_}, 最优 alpha: {elastic_cv.alpha_}”)5.2 正则化路径与变量重要性排序无论是岭回归、Lasso还是Elastic Net系数的大小并不直接等同于特征的重要性尤其是在特征未标准化或存在共线性的情况下。一个更稳健的评估变量重要性的方法是观察其在整个正则化路径上的行为。在Lasso路径中一个特征越晚被压缩到0即需要更大的λ才能使其系数归零通常意味着它越重要。你可以计算每个特征系数首次变为零时所对应的λ值或正则化强度并以此排序。5.3 必须避开的“坑”忘记标准化这是新手最常犯的错误会导致正则化惩罚完全失真。务必记住只要使用带惩罚项的回归特征标准化是强制步骤。在测试集上拟合或转换永远用训练集拟合StandardScaler然后用其参数去转换测试集。用测试集的信息来“帮助”训练模型是严重的数据泄露会导致模型评估结果过于乐观。盲目相信交叉验证的最优值交叉验证找到的λ是基于你提供的数据和搜索范围的。如果搜索范围设置不合理比如alphas范围太小可能找不到真正的最优点。务必绘制交叉验证误差曲线确保你找到的点位于曲线的最低谷附近而不是边界上。忽略系数解释的尺度你最终解释的系数是基于标准化后数据的。如果要解释原始特征的影响需要进行反向转换但这通常比较复杂。在论文中更常见的做法是直接说“在标准化后特征A每增加一个标准差预测值Y平均增加β个单位”或者通过比较系数绝对值大小来定性说明相对重要性。将Lasso用于绝对的特征选择Lasso能产生稀疏解但它本质上是一个连续收缩方法特征是否为零对λ值非常敏感。不要把它当成一个非黑即白的特征选择器。更稳妥的做法是结合领域知识对Lasso筛选出的特征子集进行稳定性检查如通过Bootstrap抽样观察特征被选中的频率。5.4 在数学建模中的特殊应用场景除了常规的预测和影响因素分析正则化回归在建模中还有一些巧用处理多重共线性的主成分回归替代方案当遇到严重多重共线性时除了主成分回归岭回归是一个更直接的解决方案它不需要对特征进行旋转变换保留了原始特征的解释性。集成学习中的基学习器在Stacking等集成学习中由于第一层预测结果作为第二层特征时往往高度相关使用岭回归作为第二层的元学习器是非常合适的选择可以有效防止过拟合。变量筛选预处理在大规模特征筛选的第一步可以使用一个较大的λ值运行Lasso快速剔除掉大量明显不相关的变量缩小后续精细建模的特征空间提高效率。从我带队的经验来看很多队伍在应用这些方法时最大的问题不是代码不会写而是缺乏对结果的分析和批判性思考。模型跑出来了MSE降低了就万事大吉。实际上你应该多问几个为什么为什么是这个特征被选中系数符号是否符合业务逻辑如果不符合是数据问题还是模型局限模型的假设是否被严重违背如误差项严重非正态或异方差把这些思考过程体现在论文里才是拉开差距的关键。正则化回归是强大的工具但让它发挥威力的始终是使用工具的人的思维。
返回列表