You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.x中带L2正则化的批量逻辑回归梯度下降实现求助

带L2正则化的批量梯度下降逻辑回归实现(Python 3.x)

嘿,我来帮你搞定这个实现!先把你提到的核心公式明确下来(毕竟你说的公式1和2没贴出来,我按标准的「标签y∈{-1,1}、带L2正则化」的逻辑回归来梳理),然后一步步写代码,把每个细节讲清楚。

核心公式回顾

(1)逻辑回归假设函数

因为你的标签是-1和+1,我们用sigmoid函数结合标签定义预测逻辑:

$h_\theta(x) = \sigma(\theta^T x)$,其中$\sigma(z) = \frac{1}{1+e^{-z}}$
分类时等价于:$\theta^T x > 0$则预测+1,否则预测-1,这样计算更高效。

(2)带L2正则化的损失函数

损失包含经验损失(拟合数据)+ L2正则项(防止过拟合),注意偏置项$\theta_0$不参与正则化:

$J(\theta) = \frac{1}{N} \sum_{i=1}^N \log\left(1 + e^{-y_i \theta^T x_i}\right) + \frac{\lambda}{2N} \sum_{j=1}^d \theta_j^2$
这里d是特征维度(你的情况d=2,加偏置后θ是3维),λ是正则化强度。

(3)批量梯度下降的梯度公式

批量GD每次用全量数据计算梯度,参数更新的核心依据:

$\nabla J(\theta) = -\frac{1}{N} \sum_{i=1}^N \frac{y_i x_i}{1 + e^{y_i \theta^T x_i}} + \frac{\lambda}{N} \tilde{\theta}$
其中$\tilde{\theta}$是和θ同维度的向量:$\tilde{\theta}_0=0$,$\tilde{\theta}_j=\theta_j$(j≥1),也就是偏置项的梯度不加正则化。

Python代码实现

用numpy做矩阵运算,效率更高,避免冗余循环:

import numpy as np

class LogisticRegressionGD:
    def __init__(self, learning_rate=0.01, lambda_reg=0.01, max_iter=1000, tol=1e-6):
        self.learning_rate = learning_rate  # 学习率
        self.lambda_reg = lambda_reg        # L2正则化强度
        self.max_iter = max_iter            # 最大迭代次数
        self.tol = tol                      # 收敛阈值(损失变化小于该值则停止)
        self.theta = None                   # 模型参数
    
    def _sigmoid(self, z):
        # 解决数值溢出问题的sigmoid实现
        return np.where(z >= 0, 
                        1 / (1 + np.exp(-z)), 
                        np.exp(z) / (1 + np.exp(z)))
    
    def _add_bias(self, X):
        # 给特征矩阵添加偏置项(第一列全1,对应θ₀)
        return np.hstack([np.ones((X.shape[0], 1)), X])
    
    def fit(self, X, y):
        # X: (N, 2)的样本矩阵,y: (N, 1)的标签向量(取值-1或+1)
        X_bias = self._add_bias(X)
        N, d = X_bias.shape
        self.theta = np.zeros((d, 1))  # 初始化参数为全零
        
        prev_loss = float('inf')
        for i in range(self.max_iter):
            # 计算线性组合 z = θ^T · X
            z = np.dot(X_bias, self.theta)
            # 计算经验损失的梯度部分
            gradient = -np.dot(X_bias.T, y * self._sigmoid(-y * z)) / N
            # 给非偏置项添加L2正则化梯度
            gradient[1:] += (self.lambda_reg / N) * self.theta[1:]
            
            # 更新参数
            self.theta -= self.learning_rate * gradient
            
            # 监控收敛:损失变化小于阈值则提前停止
            current_loss = self._compute_loss(X_bias, y)
            if np.abs(current_loss - prev_loss) < self.tol:
                print(f"提前收敛,迭代次数: {i+1}")
                break
            prev_loss = current_loss
        
        print("训练完成!")
    
    def _compute_loss(self, X_bias, y):
        # 计算带L2正则化的总损失
        z = np.dot(X_bias, self.theta)
        loss = np.mean(np.log(1 + np.exp(-y * z)))
        # 正则项只计算非偏置参数
        reg_loss = (self.lambda_reg / (2 * len(y))) * np.sum(self.theta[1:] ** 2)
        return loss + reg_loss
    
    def predict(self, X):
        # 预测类别(-1或+1)
        X_bias = self._add_bias(X)
        z = np.dot(X_bias, self.theta)
        return np.where(z > 0, 1, -1)
    
    def predict_proba(self, X):
        # 可选:预测正类的概率
        X_bias = self._add_bias(X)
        z = np.dot(X_bias, self.theta)
        return self._sigmoid(z)

关键细节说明

  • 数值稳定性:_sigmoid做了分支处理,避免z过大时exp(-z)下溢、z过小时exp(z)溢出的问题。
  • 偏置项处理:特意给特征矩阵加全1列对应偏置参数,正则化时排除它——因为偏置项不会导致过拟合。
  • 收敛监控:迭代中计算损失值,当两次迭代的损失差小于阈值时提前停止,避免无效计算。
  • 批量GD的特点:每次用全量数据算梯度,比随机GD更稳定,适合样本量不大的场景(你的情况刚好适用)。

使用示例

# 生成模拟测试数据
np.random.seed(42)
X = np.random.randn(100, 2)
y = np.where(np.dot(X, [1, -2]) + 0.5 > 0, 1, -1).reshape(-1, 1)

# 初始化并训练模型
model = LogisticRegressionGD(learning_rate=0.1, lambda_reg=0.001, max_iter=5000)
model.fit(X, y)

# 预测并计算准确率
y_pred = model.predict(X)
accuracy = np.mean(y_pred == y.flatten())
print(f"训练集准确率: {accuracy:.4f}")

常见问题排查

  • 模型不收敛:试试调大学习率(比如从0.01调到0.1),或者对X做标准化(X = (X - X.mean(axis=0)) / X.std(axis=0))——特征尺度差异大会拖慢梯度下降速度。
  • 过拟合:增大lambda_reg的值,增强正则化强度。
  • 维度报错:确保y的形状是(N,1),如果是一维数组,用y.reshape(-1,1)转换。

内容的提问来源于stack exchange,提问作者Mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:23:05