L1正则化和L2正则化在机器学习中的详细介绍及Python代码实现

本文详细介绍了L1正则化和L2正则化,包括它们的定义、作用、适用场景和数学原理,并提供了Python实现代码。L1正则化产生稀疏模型,适合特征选择,而L2正则化产生平滑模型,能有效处理多重共线性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 什么是L1正则化和L2正则化?
1.1. L1正则化
1.2. L2正则化
2. 正则化在训练过程中的作用
2.1 适用的问题和数据类型
2.1.1. L1正则化
2.1.2. L2正则化
3. L1正则化和L2正则化的数学原理
3.1. 带L1正则化的损失函数
3.2. 带L2正则化的损失函数
4. L1正则化和L2正则化的Python实现
4.1. L1正则化的Python实现
4.2. L2正则化的Python实现
5. 比较L1正则化和L2正则化

在机器学习中,过拟合是一个常见的问题。过拟合指的是模型在训练数据上表现良好,但在新数据上的表现较差。为了防止过拟合,我们通常会使用正则化技术。正则化通过向损失函数中添加一个惩罚项,迫使模型参数保持较小的值,从而减少过拟合。最常见的两种正则化技术是L1正则化和L2正则化。

什么是L1正则化和L2正则化?

L1正则化

L1正则化,又称为Lasso正则化,其惩罚项是模型参数的绝对值之和。数学上,可以表示为:

L1 Regularization term = λ ∑ i ∣ w i ∣ \text{L1 Regularization term} = \lambda \sum_{i} |w_i| L1 Regularization term=λiwi

其中, λ \lambda λ 是正则化强度的超参数, w i w_i wi 是模型的参数。L1正则化的一个重要特性是它会产生稀疏模型,即一些权重参数会被驱动为零,这对于特征选择非常有用。

L2正则化

L2正则化,又称为Ridge正则化,其惩罚项是模型参数的平方和。数学上,可以表示为:

L2 Regularization term = λ ∑ i w i 2 \text{L2 Regularization term} = \lambda \sum_{i} w_i^2 L2 Regularization term=λiwi2

同样地, λ \lambda λ是正则化强度的超参数, w i w_i wi 是模型的参数。L2正则化的一个重要特性是它会产生平滑的模型,使得所有权重参数都尽可能小,但不会完全为零。

正则化在训练过程中的作用

正则化发生在模型的训练阶段。具体来说,当我们最小化损失函数时,会同时最小化正则化项。这样可以控制模型的复杂度,防止过拟合。我们通过调整正则化强度参数 λ \lambda λ 来平衡数据拟合程度和正则化惩罚项。

适用的问题和数据类型

L1正则化

L1正则化适用于以下情况:

  • 特征选择:由于L1正则化会产生稀疏模型,它能自动选择特征,将不重要的特征权重变为零。
  • 高维数据:在特征数量远多于样本数量的情况下,L1正则化可以帮助筛选出重要特征。

L2正则化

L2正则化适用于以下情况:

  • 多重共线性:当特征之间存在高度相关性时,L2正则化可以通过平滑权重来减小这种影响。
  • 一般回归问题:在特征数量与样本数量差不多时,L2正则化可以有效地控制模型复杂度。

L1正则化和L2正则化的数学原理

假设我们有一个线性回归模型,损失函数是均方误差(MSE)。
不加入正则化项前的损失函数比可以表示为:

y ^ ( i ) = w i ∗ x i + b \hat{y}^{(i)} = w_i*x_i+b y^(i)=wixi+b

J ( w ) = 1 2 m ∑ i = 1 m ( y ( i ) − y ^ ( i ) ) 2 J(w) = \frac{1}{2m} \sum_{i=1}^{m} (y^{(i)} - \hat{y}^{(i)})^2 J(w)=2m1i=1m(y(i)y^(i))2

加入正则化项后的损失函数可以表示为:

带L1正则化的损失函数

J ( w ) = 1 2 m ∑ i = 1 m ( y ( i ) − y ^ ( i ) ) 2 + λ ∑ j = 1 n ∣ w j ∣ J(w) = \frac{1}{2m} \sum_{i=1}^{m} (y^{(i)} - \hat{y}^{(i)})^2 + \lambda \sum_{j=1}^{n} |w_j| J(w)=2m1i=1m(y(i)y^(i))2+λj=1nwj

带L2正则化的损失函数

J ( w ) = 1 2 m ∑ i = 1 m ( y ( i ) − y ^ ( i ) ) 2 + λ ∑ j = 1 n w j 2 J(w) = \frac{1}{2m} \sum_{i=1}^{m} (y^{(i)} - \hat{y}^{(i)})^2 + \lambda \sum_{j=1}^{n} w_j^2 J(w)=2m1i=1m(y(i)y^(i))2+λj=1nwj2

其中, m m m 是样本数量, y ( i ) y^{(i)} y(i) 是第 i i i个样本的真实值, y ^ ( i ) \hat{y}^{(i)} y^(i)是第 i i i个样本的预测值, w j w_j wj是第 j j j个特征的权重参数, λ \lambda λ 是正则化强度。

L1正则化和L2正则化的Python实现

接下来,我们将通过Python代码展示如何在实际中应用L1正则化和L2正则化。我们将使用常见的机器学习库 scikit-learn

4.1 L1正则化的Python实现

我们以线性回归为例,展示如何使用L1正则化。

import numpy as np
from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 生成示例数据
np.random.seed(42)
X = np.random.randn(100, 10)
y = X @ np.random.randn(10) + np.random.randn(100) 
# @表示矩阵乘法,这段的意思是X乘以初始化权重np.random.randn(10)然后再加上噪音

# 拆分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建Lasso回归模型
lasso = Lasso(alpha=0.1)

# 训练模型
lasso.fit(X_train, y_train)

# 预测
y_pred_train = lasso.predict(X_train)
y_pred_test = lasso.predict(X_test)

# 计算训练误差和测试误差
train_mse = mean_squared_error(y_train, y_pred_train)
test_mse = mean_squared_error(y_test, y_pred_test)

print(f'Train MSE: {train_mse}')
print(f'Test MSE: {test_mse}')
print(f'Lasso coefficients: {lasso.coef_}')

手写L1正则化

class LassoRegression:
    def __init__(self, learning_rate=0.01, n_iterations=1000, lambda_=0.1):
        self.learning_rate = learning_rate
        self.n_iterations = n_iterations
        self.lambda_ = lambda_
        
    def fit(self, X, y):
        self.m, self.n = X.shape
        self.weights = np.zeros(self.n)
        self.bias = 0
        for _ in range(self.n_iterations):
            y_pred = self.predict(X)
            dw = (-2 * X.T @ (y - y_pred) + self.lambda_ * np.sign(self.weights)) / self.m
            db = -2 * np.sum(y - y_pred) / self.m
            self.weights -= self.learning_rate * dw
            self.bias -= self.learning_rate * db
    
    def predict(self, X):
        return X @ self.weights + self.bias

4.2. L2正则化的Python实现

我们同样以线性回归为例,展示如何使用L2正则化(岭回归)。

import numpy as np
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 生成示例数据
np.random.seed(42)
X = np.random.randn(100, 10)
y = X @ np.random.randn(10) + np.random.randn(100)

# 拆分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建Ridge回归模型
ridge = Ridge(alpha=0.1)

# 训练模型
ridge.fit(X_train, y_train)

# 预测
y_pred_train = ridge.predict(X_train)
y_pred_test = ridge.predict(X_test)

# 计算训练误差和测试误差
train_mse = mean_squared_error(y_train, y_pred_train)
test_mse = mean_squared_error(y_test, y_pred_test)

print(f'Train MSE: {train_mse}')
print(f'Test MSE: {test_mse}')
print(f'Ridge coefficients: {ridge.coef_}')

手写L2正则化

class RidgeRegression:
    def __init__(self, learning_rate=0.01, n_iterations=1000, lambda_=0.1):
        self.learning_rate = learning_rate
        self.n_iterations = n_iterations
        self.lambda_ = lambda_
        
    def fit(self, X, y):
        self.m, self.n = X.shape
        self.weights = np.zeros(self.n)
        self.bias = 0
        for _ in range(self.n_iterations):
            y_pred = self.predict(X)
            dw = (-2 * X.T @ (y - y_pred) + 2 * self.lambda_ * self.weights) / self.m
            db = -2 * np.sum(y - y_pred) / self.m
            self.weights -= self.learning_rate * dw
            self.bias -= self.learning_rate * db
    
    def predict(self, X):
        return X @ self.weights + self.bias

5. 比较L1正则化和L2正则化

L1正则化和L2正则化各有优缺点:

  • L1正则化

    • 优点:产生稀疏模型,有助于特征选择。
    • 缺点:当相关特征较多时,Lasso选择其中一个而忽略其他的。
  • L2正则化

    • 优点:权重分布更平滑,适合处理特征之间有相似性
    • 缺点:不能产生稀疏模型。

在实际应用中,可以通过交叉验证选择最合适的正则化方法和超参数。

### Python中L1正则化L2正则化实现及区别 #### L2 正则化(Ridge) 在机器学习模型训练过程中加入L2正则化可以防止过拟合。对于线性回归而言,在损失函数基础上增加权重参数平方之作为惩罚项,即: \[ J(\theta) = MSE(\theta) + \alpha\sum_{i=1}^{n}\theta_i^2 \] 其中 \(MSE\) 表示均方误差,\( n \) 是特征数量,而超参数 \( \alpha \geq 0 \) 控制着正则化的强度[^1]。 下面是一个简单的例子来展示如何在Python中应用L2正则化: ```python from sklearn.linear_model import Ridge import numpy as np X = np.array([[0, 0], [1, 1]]) y = np.array([0, 1]) ridge_reg = Ridge(alpha=0.5) ridge_reg.fit(X, y) print(ridge_reg.coef_) ``` #### L1 正则化(Lasso) 不同于L2正则化,L1正则化通过绝对值形式引入稀疏性的特点使得某些系数变为零从而达到变量选择的效果。其对应的代价函数表达式如下所示: \[ J(\theta)=M S E(\theta)+\alpha\|\theta\|_1=\frac{1}{m} \sum_{i=1}^{m}(h_\theta(x^{(i)})-y^{(i)})^2+\alpha\sum_{j=1}^{n}\left|\theta_j\right| \] 这里同样有超参α用于调整正则力度大小. 下面是利用scikit-learn库中的`Lasso`类来进行L1正则化的实例代码片段: ```python from sklearn.linear_model import Lasso lasso_reg = Lasso(alpha=0.5) lasso_reg.fit(X, y) print(lasso_reg.coef_) ``` #### 实现差异对比 主要体现在两个方面:一是数学公式的不同;二是实际效果上的差别——L1倾向于产生更少但是更大的权值估计,并可能使一些不重要的输入特性对应于完全消失的权重;相反地,L2会均匀缩小所有的权重但不会让它们变成确切意义上的零。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值