#P4485. 逻辑回归(梯度下降)
-
1000ms
Tried: 10
Accepted: 4
Difficulty: 5
逻辑回归(梯度下降)
本题让我们从零实现二分类逻辑回归(Logistic Regression),并用**批量梯度下降(Batch Gradient Descent)**来训练参数。
模型形式为:
$$\hat{y} = \sigma(z), \quad z = w_1 x_1 + w_2 x_2 + b,\quad \sigma(z) = \frac{1}{1 + e^{-z}}$$损失函数是二分类交叉熵(Log Loss):
$$L = -\frac{1}{n}\sum_{i=1}^{n} \big[ y_i \log \hat{y}_i + (1 - y_i)\log(1 - \hat{y}_i) \big]$$对每个参数的梯度为:
$$\frac{\partial L}{\partial w_1} = \frac{1}{n}\sum_{i=1}^{n} ( \hat{y}_i - y_i ) x_{1i},\quad \frac{\partial L}{\partial w_2} = \frac{1}{n}\sum_{i=1}^{n} ( \hat{y}_i - y_i ) x_{2i}$$$$\frac{\partial L}{\partial b} = \frac{1}{n}\sum_{i=1}^{n} ( \hat{y}_i - y_i )$$每一轮迭代中,用学习率 lr 做参数更新:
初始时令 w1 = w2 = b = 0.0,循环 epochs 轮。
最终返回 [w1, w2, b]。
关键点:
- 正确实现 Sigmoid,并注意数值稳定性(避免
exp溢出)。 - 批量梯度下降:每轮用全部样本累加梯度,再统一更新参数。
- 样本输入格式为
samples = [[x1, x2, y], ...],注意拆包时同时取出(x1, x2, y)。
算法步骤
-
初始化参数
w1 = 0.0w2 = 0.0b = 0.0n = len(samples)为样本数
-
定义 Sigmoid 函数(数值稳定版本)
def sigmoid(z: float) -> float: if z >= 0: return 1.0 / (1.0 + math.exp(-z)) else: ez = math.exp(z) return ez / (1.0 + ez)这样写的好处是:
- 当
z很大为正时,exp(-z)非常小,不会下溢; - 当
z很大为负时,直接算exp(-z)会溢出,我们改为算exp(z)来规避。
- 当
-
外层循环
epochs轮-
每一轮都重新把梯度累加量置零:
dw1 = dw2 = db = 0.0
-
-
遍历所有样本,计算梯度累加 对每个样本
(x1, x2, y):-
线性部分:
z = w1 * x1 + w2 * x2 + b -
预测概率:
y_pred = sigmoid(z) -
误差项:
diff = y_pred - y # 这是 ∂L/∂z -
梯度累加:
dw1 += diff * x1 dw2 += diff * x2 db += diff
-
-
对梯度取平均
dw1 /= n dw2 /= n db /= n -
根据学习率更新参数
w1 -= lr * dw1 w2 -= lr * dw2 b -= lr * db -
重复上述步骤
epochs次后,返回结果return [w1, w2, b]
Python 代码
def sigmoid(z: float) -> float:
if z >= 0:
return 1.0 / (1.0 + math.exp(-z))
else:
ez = math.exp(z)
return ez / (1.0 + ez)
class Solution:
def logisticRegression(self, samples: List[List[float]], lr: float, epochs: int) -> List[float]:
w1 = 0.0
w2 = 0.0
b = 0.0
n = len(samples)
for _ in range(epochs):
dw1 = 0.0
dw2 = 0.0
db = 0.0
for x1, x2, y in samples:
z = w1 * x1 + w2 * x2 + b
y_pred = sigmoid(z)
diff = y_pred - y
dw1 += diff * x1
dw2 += diff * x2
db += diff
dw1 /= n
dw2 /= n
db /= n
w1 -= lr * dw1
w2 -= lr * dw2
b -= lr * db
return [w1, w2, b]
题目描述
你需要实现一个二分类逻辑回归模型(Logistic Regression)。 给定 n 个样本,每个样本有二维特征 (x1,x2) 和标签 y∈{0,1},使用梯度下降训练模型,并返回最终学习到的参数:
- 权重:w1,w2
- 偏置:b
模型形式为:
$$\hat{y} = \sigma(z) = \frac{1}{1 + e^{-z}}, \quad z = w_1 x_1 + w_2 x_2 + b$$其中 σ(⋅) 为 Sigmoid 函数。
训练目标是最小化二分类交叉熵损失(Log Loss):
$$L = -\frac{1}{n}\sum_{i=1}^{n} \big[ y_i \log \hat{y}_i + (1 - y_i)\log(1 - \hat{y}_i) \big]$$你需要使用给定的学习率 lr 和迭代轮数 epochs,通过批量梯度下降更新参数:
-
对于每一轮迭代:
-
对所有样本计算 y^i
-
计算梯度:
$$\frac{\partial L}{\partial w_1} = \frac{1}{n}\sum_{i=1}^{n} ( \hat{y}_i - y_i ) x_{1i}$$
-