L1/L2 正则化的几何意义?为什么 L1 产生稀疏?
- —用 sklearn 对同一数据跑 Lasso/Ridge,对比系数稀疏度
核心概念
L1 和 L2 正则化是在机器学习模型的损失函数中加入惩罚项,以防止模型过拟合、提高泛化能力的常用技术。其核心思想是在最小化经验风险(如均方误差)的同时,限制模型参数(权重)的大小。L1 正则化(Lasso)添加的惩罚是模型权重的绝对值之和,倾向于产生稀疏解(即许多权重为零)。L2 正则化(Ridge)添加的惩罚是模型权重的平方和,倾向于使权重值变得平滑且接近于零,但通常不为零。
原理与推导
正则化的目标函数由两部分组成:原始损失项 和正则化惩罚项 。
其中 是模型权重向量, 是正则化系数,用于控制惩罚的强度。对于线性回归,损失函数 通常是均方误差(MSE):。
- L1 正则化 (Lasso):
- L2 正则化 (Ridge):
几何解释:为什么 L1 产生稀疏?
理解 L1 稀疏性的关键在于将优化问题转化为带约束的优化问题。原始的优化问题 等价于以下约束优化问题(对于某个常数 ):
我们可以从几何上直观地理解这个过程。假设我们只有两个权重 。
-
损失函数的等高线: 损失函数 在权重空间中可以表示为一系列的等高线(对于 MSE 来说是椭圆形),等高线的中心是未加正则化时的最优解 。我们的目标是找到一个 ,使得 尽可能小。
-
正则化约束的几何形状:
- L1 约束: 。这个不等式在 平面上定义了一个菱形(旋转了45度的正方形)。这个菱形有尖锐的角点,这些角点正好落在坐标轴上。
- L2 约束: 。这个不等式定义了一个圆形区域。这个圆形是平滑的,没有角点。
-
求解过程的可视化: 优化的过程就是寻找 的等高线与正则化约束区域首次相交的点。这个交点就是正则化约束下的最优解。
-
L1 (菱形): 如下图所示,当椭圆形的等高线从中心点 开始向外扩张时,它有很大概率首先接触到菱形的角点。而菱形的角点恰好位于坐标轴上,例如 或 。在这些点上,其中一个权重( 或 )为零。当扩展到更高维度时,L1 约束是一个超多面体,它有大量的角点和棱边落在某些维度为零的子空间上,因此解更容易出现在这些位置,导致许多权重为零,从而产生稀疏性。
-
L2 (圆形): 同样地,当等高线扩张时,它与圆形约束区域的交点几乎总是发生在圆上的某个切点,这个切点极不可能正好落在坐标轴上。因此,L2 正则化会使权重向量的每个分量都变小,但通常不会变为严格的零。
-
算法复杂度
- L2 (Ridge): 对于线性回归,Ridge 有解析解(闭式解):。其主要计算开销在于矩阵求逆,时间复杂度为 ,其中 是特征维度。
- L1 (Lasso): 由于绝对值函数在零点不可导,Lasso 没有通用的解析解。它需要使用迭代优化算法求解,如坐标下降法(Coordinate Descent)或最小角回归(LARS)。坐标下降法在每次迭代中更新一个权重,其复杂度约为 ,其中 是样本数, 是特征数, 是迭代次数。
代码实现
下面的 Python 代码使用 scikit-learn 来训练 Lasso (L1) 和 Ridge (L2) 回归模型,并可视化它们的系数,直观地展示 L1 的稀疏性。
1import numpy as np2import matplotlib.pyplot as plt3from sklearn.linear_model import Lasso, Ridge4from sklearn.datasets import make_regression5from sklearn.preprocessing import StandardScaler67# 1. 生成合成数据8# 创建一个有100个特征的数据集,但其中只有10个特征是真正有信息的。9# 这是为了模拟真实世界中特征冗余或无关的情况,Lasso应该能识别出这些无用特征。10X, y = make_regression(n_samples=100, n_features=100, n_informative=10, noise=20, random_state=42)1112# 2. 数据预处理13# 正则化对特征的尺度非常敏感,因此在应用Lasso或Ridge之前,必须进行特征缩放。14# 否则,惩罚项会不成比例地惩罚那些尺度较大的特征。15scaler = StandardScaler()16X_scaled = scaler.fit_transform(X)1718# 3. 定义和训练模型19# alpha参数对应于我们公式中的lambda,控制正则化的强度。20alpha = 1.02122# 训练Lasso (L1)模型23lasso = Lasso(alpha=alpha)24lasso.fit(X_scaled, y)2526# 训练Ridge (L2)模型27ridge = Ridge(alpha=alpha)28ridge.fit(X_scaled, y)2930# 4. 提取并对比系数31lasso_coefs = lasso.coef_32ridge_coefs = ridge.coef_3334# 打印稀疏性统计35print(f"Lasso模型 (L1) 找到 {np.sum(lasso_coefs != 0)} 个非零系数。")36print(f"Ridge模型 (L2) 找到 {np.sum(np.abs(ridge_coefs) > 1e-6)} 个非零系数。") # 用一个小的阈值来计数,因为Ridge系数很小但不完全为03738# 5. 可视化系数39plt.figure(figsize=(14, 6))40plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签41plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号4243# 绘制Lasso系数44plt.subplot(1, 2, 1)45plt.plot(lasso_coefs, marker='o', linestyle='None')46plt.title(f'Lasso (L1) 系数 (alpha={alpha})')47plt.xlabel('特征索引')48plt.ylabel('系数大小')49plt.grid(True)5051# 绘制Ridge系数52plt.subplot(1, 2, 2)53plt.plot(ridge_coefs, marker='o', linestyle='None', color='orange')54plt.title(f'Ridge (L2) 系数 (alpha={alpha})')55plt.xlabel('特征索引')56plt.ylabel('系数大小')57plt.grid(True)5859plt.tight_layout()60plt.show()6162# 观察结果:63# 左图(Lasso)中,绝大多数系数都被压缩到了精确的0,只有少数几个系数有非零值。64# 右图(Ridge)中,所有系数都被缩小了,但几乎没有一个系数是精确的0。65# 这清晰地证明了L1正则化产生稀疏解,而L2正则化产生平滑解。
工程实践
-
使用场景:
- L1 (Lasso): 主要用于特征选择。当你有成千上万个特征,并怀疑其中大部分是无关或冗余的时(例如基因组学数据、高维文本特征),Lasso 是一个极好的工具。它能自动将不重要特征的权重设为零,从而简化模型,提高解释性,并可能加快预测速度。
- L2 (Ridge): 主要用于防止过拟合和处理多重共线性问题。当你相信大部分特征都有用,但又想避免模型对训练数据过拟合时,Ridge 是首选。当特征之间存在高度相关性时,普通最小二乘法(OLS)的估计会非常不稳定,而 Ridge 通过向
X^T*X矩阵添加一个对角矩阵λI,保证了其可逆性,从而使求解更加稳定。 - Elastic Net: L1 和 L2 的结合,既能进行特征选择,又能处理相关特征。当特征组之间有关联时,Lasso 倾向于随机选择一个,而 Elastic Net 会倾向于同时选择或排除整个特征组。
-
超参数选择 (
λ或alpha):λ是最重要的超参数,控制着模型的复杂度和拟合程度的平衡。λ = 0: 无正则化,模型可能过拟合。λ → ∞: 所有权重趋近于零,模型可能欠拟合。- 最佳实践是使用交叉验证(Cross-Validation)来寻找最优的
λ。通常在一个对数尺度上进行搜索,例如[1e-4, 1e-3, 1e-2, 0.1, 1, 10, 100]。
-
性能权衡:
- 模型稀疏性: L1 产生稀疏模型,这在推理(prediction)时可能更快,因为只需计算非零权重的点积。
- 预测精度: 如果大部分特征确实都对结果有贡献,L2 通常会提供略好的预测精度,因为它保留了所有特征的信息。
- 训练速度: 对于线性模型,Ridge 有解析解,在特征数不多时可能更快。而 Lasso 依赖迭代算法,在特征数远大于样本数()的场景下,坐标下降法可能反而更高效。
-
调试技巧:
- 必须进行特征缩放! 正则化惩罚的是权重的大小,如果特征尺度不一(如年龄和收入),模型会不公平地惩罚与大尺度特征相关的权重。使用
StandardScaler或MinMaxScaler是标准步骤。 - 如果所有权重都变为零(对于 Lasso)或非常接近零,说明
λ可能设置得太大了。 - 如果模型仍然过拟合,说明
λ可能太小了。
- 必须进行特征缩放! 正则化惩罚的是权重的大小,如果特征尺度不一(如年龄和收入),模型会不公平地惩罚与大尺度特征相关的权重。使用
常见误区与边界情况
-
误区一:正则化只适用于线性模型。
- 纠正: 这是错误的。L1/L2 正则化是通用技术,可以应用于任何参数化模型,包括逻辑回归、支持向量机和深度神经网络。在神经网络中,对权重矩阵应用 L2 正则化(称为“权重衰减”,Weight Decay)是抑制过拟合的标准做法。
-
误区二:L1 因为能做特征选择,所以总是优于 L2。
- 纠正: 不一定。L1 的特征选择能力是一把双刃剑。如果特征之间高度相关,Lasso 倾向于任意选择其中一个特征,而放弃其他相关的特征,这使得模型不稳定。而 Ridge 会倾向于给这些相关特征分配相似的、较小的权重。如果所有特征都包含有用信息,L2 的“平滑”收缩效果可能带来更好的泛化性能。
-
边界情况:处理高度相关的特征
- Lasso: 如上所述,当一组特征高度相关时,Lasso 的选择行为可能不稳定。对数据进行微小的扰动(如重抽样)可能导致它选择完全不同的特征子集。
- Ridge: 表现更稳定。它会把相关的特征的系数一起缩小,相当于在它们之间“分享”权重。
-
面试追问:
- 问:为什么我们通常不对偏置项(bias/intercept)进行正则化?
- 答: 偏置项 捕捉的是目标变量的基线值,即所有特征都为零时的预测值。它与特征的贡献无关。对它进行正则化会不必要地将模型的平均预测值“拉向”零,这通常没有物理或统计意义,可能导致模型欠拟合。偏置项的大小不反映模型的复杂性。
- 问:L1/L2 正则化和贝叶斯推断有什么联系?
- 答: 这是一个非常深刻的联系。从贝叶斯角度看,正则化等价于为模型参数引入一个先验分布。
- L2 正则化 等价于为权重 设置一个均值为0的高斯先验(Gaussian Prior)。
- L1 正则化 等价于为权重 设置一个均值为0的拉普拉斯先验(Laplace Prior)。
- 拉普拉斯分布在零点处有一个尖峰,这意味着它认为权重更有可能取值为零,这从概率角度解释了 L1 的稀疏性。高斯分布则在零点处平滑,认为权重在零附近取值的可能性更大,但不强制为零。
- 答: 这是一个非常深刻的联系。从贝叶斯角度看,正则化等价于为模型参数引入一个先验分布。
- 问:为什么我们通常不对偏置项(bias/intercept)进行正则化?