第3周:逻辑回归与正则化
课程简介
逻辑回归与分类、决策边界、过拟合问题与 L1/L2 正则化。
🎬 本课程视频:吴恩达机器学习 (2014) — 交互式学习笔记
一、分类问题与逻辑回归
1.1 为什么线性回归不适合分类
分类问题需要输出离散的类别——例如邮件是垃圾邮件(1)或不是(0),肿瘤是恶性(1)或良性(0)。直接用线性回归做分类有两个严重问题:
第一,线性回归的输出范围是 (-∞, +∞),远超 [0,1] 的分类区间。虽然可以设定阈值——输出大于 0.5 判为 1,小于等于 0.5 判为 0——但如果有极端值,阈值法会失效。
第二,当加入新的训练样本时,线性回归的决策边界会发生不应有的偏移,分类性能急剧下降。
解决方案是逻辑回归(Logistic Regression)——虽然名字带有回归,但它是一个分类算法。
1.2 逻辑回归的假设函数
逻辑回归的核心是在线性组合的基础上应用一个非线性函数——Sigmoid 函数(也叫 Logistic 函数):
$$h_\theta(x) = g(\theta^T x) = \frac{1}{1 + e^{-\theta^T x}}$$
Sigmoid 函数具有优美的 S 形曲线:
$$g(z) = \frac{1}{1 + e^{-z}}$$
它的重要性质:
- 当 z → +∞ 时,g(z) → 1
- 当 z → -∞ 时,g(z) → 0
- 当 z = 0 时,g(0) = 0.5
- 输出范围严格在 (0, 1) 之间,可以解释为概率
- 导数形式简洁:g'(z) = g(z)(1-g(z))
hθ(x) 的输出可以解释为在给定特征 x 和参数 θ 的条件下,y=1 的概率。
1.3 决策边界
决策边界(Decision Boundary)是分类器区分不同类别的分界线。对于逻辑回归:
- 当 hθ(x) ≥ 0.5 即 θᵀx ≥ 0 时,预测 y=1
- 当 hθ(x) < 0.5 即 θᵀx < 0 时,预测 y=0
决策边界由 θᵀx = 0 决定。它是参数 θ 的属性,而不是训练集的属性——训练数据只是用来拟合 θ 的。
通过引入高阶多项式特征,逻辑回归可以拟合非常复杂的决策边界:
$$\theta_0 + \theta_1 x_1 + \theta_2 x_2 + \theta_3 x_1^2 + \theta_4 x_2^2 = 0$$
可以在二维空间中拟合圆形或椭圆形的决策边界。
二、逻辑回归的代价函数与梯度下降
2.1 代价函数
如果在线性回归的 MSE 代价函数中代入 Sigmoid 函数,得到的 J(θ) 是非凸的——存在多个局部极小值,梯度下降无法保证找到全局最优。
逻辑回归使用交叉熵损失(Cross-Entropy Loss):
$$J(\theta) = -\frac{1}{m} \sum_{i=1}^{m} [y^{(i)} \log h_\theta(x^{(i)}) + (1-y^{(i)}) \log (1 - h_\theta(x^{(i)}))]$$
这个代价函数的直观理解:
- 当 y=1 时,如果 hθ(x)→1,代价→0;如果 hθ(x)→0,代价→∞
- 当 y=0 时,如果 hθ(x)→0,代价→0;如果 hθ(x)→1,代价→∞
也就是说,当预测严重错误时,代价函数会施加非常大的惩罚。
2.2 梯度下降
令人惊喜的是,逻辑回归的梯度下降更新公式与线性回归形式完全一致:
$$\theta_j := \theta_j - \alpha \frac{1}{m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)}) \cdot x_j^{(i)}$$
区别在于 hθ(x) 的定义不同——线性回归使用 θᵀx,逻辑回归使用 Sigmoid(θᵀx)。但梯度的数学表达式巧合地一致,这使得实现非常方便。
三、多分类问题:一对多
逻辑回归天然是二分类器,但可以推广到多分类。一对多方法(One-vs-All)的核心思想:
对于 K 个类别,训练 K 个二分类器。第 k 个分类器将第 k 类作为正类,其余所有类别作为负类。
预测时,将新样本输入所有 K 个分类器,选择输出概率最大的那个类别。
四、过拟合与正则化
4.1 什么是过拟合
过拟合发生在模型过于复杂、对训练数据学得太好,甚至学到了噪声中的随机模式,导致模型在训练集上表现极好但在新数据上表现很差。
三种拟合状态:
- 欠拟合:模型太简单,无法捕捉数据的模式——高偏差
- 恰到好处:模型复杂度适中,既能拟合训练数据又能泛化到新数据
- 过拟合:模型太复杂,拟合了数据的噪声——高方差
4.2 解决过拟合的方法
- 减少特征数量:手动选择特征或使用模型选择算法
- 正则化(Regularization):保持所有特征但减小参数的值
- 增加训练数据:更多的数据可以减少过拟合
- 数据增强:通过对现有数据进行变换生成新样本
4.3 L2 正则化
正则化通过在代价函数中加入惩罚项来抑制参数的大小。L2 正则化(也称权重衰减)是最常用的正则化形式:
$$J(\theta) = \frac{1}{2m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)})^2 + \lambda \sum_{j=1}^{n} \theta_j^2$$
其中 λ(lambda)是正则化参数,控制正则化的强度:
- λ 太小 → 正则化效果不足,仍然过拟合
- λ 太大 → 参数被惩罚到接近零,模型变为欠拟合
注意:我们通常不惩罚 θ₀(截距项)。
4.4 正则化后的梯度下降
正则化后,梯度下降的更新规则变为:
$$\theta_0 := \theta_0 - \alpha \frac{1}{m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)}) \cdot x_0^{(i)}$$
$$\theta_j := \theta_j - \alpha \left[ \frac{1}{m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)}) \cdot x_j^{(i)} + \frac{\lambda}{m} \theta_j \right]$$
可以看到,(1 - αλ/m) 是一个略小于 1 的数——每次更新前将 θ_j 收缩一点——这就是权重衰减名称的由来。
4.5 正则化与正规方程
在线性回归中,带 L2 正则化的正规方程为:
$$\theta = (X^T X + \lambda \cdot I)^{-1} X^T y$$
添加 λI 后,括号内的矩阵一定是可逆的——正则化顺便解决了矩阵奇异的问题。
4.6 正则化与逻辑回归
正则化同样可以应用于逻辑回归的代价函数。
五、实践中的逻辑回归
import numpy as np
from scipy.optimize import minimize
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def cost_function(theta, X, y, lambda_val):
m = len(y)
h = sigmoid(X.dot(theta))
J = -1/m * (y.T.dot(np.log(h)) + (1-y).T.dot(np.log(1-h)))
J += lambda_val/(2*m) * np.sum(theta[1:]**2)
return J
def gradient(theta, X, y, lambda_val):
m = len(y)
h = sigmoid(X.dot(theta))
grad = 1/m * X.T.dot(h - y)
grad[1:] += lambda_val/m * theta[1:]
return grad
result = minimize(cost_function, initial_theta,
args=(X, y, lambda_val),
method='BFGS', jac=gradient)
optimal_theta = result.x
第 3 周的内容是机器学习中分类问题的基石。逻辑回归虽然名字带有回归,但它是最重要的分类算法之一。理解 Sigmoid 函数、交叉熵损失和决策边界,你就掌握了分类问题的核心。正则化是防止过拟合的最重要工具——λ 的选择是模型调优的关键。下周我们将进入神经网络——一个更强大的非线性模型家族。
决策边界的深入理解
决策边界是分类问题中最重要的概念之一。它是特征空间中不同类别的分界区域。对于逻辑回归,决策边界由 θᵀx = 0 定义。但这不是由训练数据直接决定的——而是由模型参数 θ 决定的。训练数据通过梯度下降影响 θ,从而间接影响决策边界的位置和形状。
线性决策边界是直线或超平面。但通过特征变换,逻辑回归可以产生非常复杂的决策边界:
- 二次特征:椭圆、抛物线、双曲线
- 高次特征:任意形状的封闭曲线
- 特征组合:交叉项产生复杂的非线性边界
逻辑回归的数值稳定性
在实现逻辑回归时,需要注意数值稳定性问题:
1. Sigmoid 函数的参数过大时,e^{-z} 可能溢出——需要做数值截断
2. log(hθ(x)) 在 hθ(x)=0 时无定义——需要添加极小值 epsilon
3. 高级优化器(fminunc、BFGS)比手写梯度下降更稳定
def sigmoid(z):
# 防止 exp 溢出
z = np.clip(z, -500, 500)
return 1 / (1 + np.exp(-z))
def cost_function(theta, X, y, lambda_val):
m = len(y)
h = sigmoid(X @ theta)
# 添加极小值防止 log(0)
epsilon = 1e-15
J = -1/m * (y @ np.log(h + epsilon) + (1-y) @ np.log(1-h + epsilon))
J += lambda_val/(2*m) * np.sum(theta[1:]**2)
return J
一对多分类的详细实现
一对多(One-vs-All)分类的完整实现:
from scipy.optimize import minimize
def one_vs_all(X, y, num_labels, lambda_val):
m, n = X.shape
all_theta = np.zeros((num_labels, n + 1))
X = np.hstack([np.ones((m, 1)), X])
for c in range(num_labels):
# 将第 c 类标记为 1,其余为 0
y_c = (y == c).astype(int)
initial_theta = np.zeros(n + 1)
result = minimize(
cost_function, initial_theta,
args=(X, y_c, lambda_val),
method='BFGS', jac=gradient,
options={'maxiter': 50}
)
all_theta[c, :] = result.x
return all_theta
def predict_one_vs_all(X, all_theta):
X = np.hstack([np.ones((X.shape[0], 1)), X])
probs = sigmoid(X @ all_theta.T)
return np.argmax(probs, axis=1)
正则化的完整理论
正则化可以解释为贝叶斯统计中的先验分布。L2 正则化等价于对参数施加高斯先验——参数趋向于集中在 0 附近。λ 控制先验的强度:λ 越大,先验越强,参数被压缩得越厉害。
从优化角度看,正则化通过在损失函数中加入参数惩罚项来限制模型的假设空间。这防止了模型使用极端参数值来拟合数据中的噪声——从而提高了泛化能力。
正则化参数 λ 的选择应该系统化:
1. 尝试 λ = 0(无正则化)作为基线
2. 尝试 λ = 0.001, 0.01, 0.1, 1, 10, 100
3. 对每个 λ,在训练集上训练,在验证集上评估
4. 选择验证误差最小的 λ
5. 在测试集上报告该 λ 的最终性能
精确率与召回率
在分类问题中,仅用准确率评估模型远远不够。特别是在类别不平衡的情况下——比如癌症筛查中只有1%的患者是阳性——一个永远预测阴性的模型也有99%的准确率,但它毫无价值。
混淆矩阵包含四个关键指标:
- 真正例(TP):正确预测为正类的样本数
- 假正例(FP):错误预测为正类的样本数(假报警)
- 真负例(TN):正确预测为负类的样本数
- 假负例(FN):错误预测为负类的样本数(漏检)
精确率 = TP / (TP + FP):模型预测为正类的结果中有多少是真正的正类
召回率 = TP / (TP + FN):所有真正的正类中有多少被模型正确识别
F1 分数 = 2 × 精确率 × 召回率 / (精确率 + 召回率):精确率和召回率的调和平均
在癌症筛查中,召回率比精确率重要得多——宁可误诊也不可漏诊。
延伸阅读
- 📺 B 站播放列表:吴恩达机器学习 (2014) — 交互式学习笔记
- 📚 更多学习资源,请访问 deeplearning.ai 官网