逻辑回归

目标读者: 机器学习初学者 核心内容: Sigmoid 函数、交叉熵损失、梯度推导、决策边界、Softmax 前置知识: 线性回归、概率统计


1. 从线性回归到逻辑回归

线性回归输出连续值

但分类问题需要输出概率(0~1 之间)。

解决方案:加一个 Sigmoid 函数把输出压缩到 (0, 1)


2. Sigmoid 函数

2.1 函数特性

输入 输出

2.2 导数(很优雅)

推导过程

2.3 逻辑回归预测公式


3. 损失函数:交叉熵

3.1 为什么不能用 MSE?

Sigmoid + MSE 会导致:

  1. 非凸优化:多个局部最小值,梯度下降可能卡住
  2. 梯度消失:当预测很自信但错误时(如 , ),MSE 的梯度很小

3.2 二分类交叉熵 (Binary Cross-Entropy)

直观理解

真实值 预测值 损失 说明
10.90.105预测正确,损失小
10.12.303预测错误,损失大
00.10.105预测正确,损失小
00.92.303预测错误,损失大

核心思想:预测错得越离谱,惩罚越大!

3.3 交叉熵的概率解释

最大似然估计角度,假设数据独立同分布:

取负对数(最小化负对数似然 = 最大化似然):

这正是交叉熵损失的形式!


4. 梯度推导

4.1 链式法则

4.2 各项计算

第一项

第二项(Sigmoid 导数):

第三项

4.3 合并结果

化简:

4.4 最终梯度(与线性回归形式相同!)

向量形式

这个优雅的结果意味着:梯度下降的代码几乎和线性回归一样,只是预测函数不同。


5. 决策边界

5.1 阈值分类

通过阈值 0.5 进行分类:

  • 预测为类别 1
  • 预测为类别 0

5.2 决策边界方程

由于 ,决策边界就是:

这是一个线性超平面,所以逻辑回归是线性分类器

5.3 几何直观

       x2
        │     类别 1
        │   ● ● ●
        │  ● ● ●
   ─────┼─────────── ← 决策边界 w₁x₁ + w₂x₂ + b = 0
        │  ○ ○ ○
        │   ○ ○ ○
        │     类别 0
        └──────────→ x1

6. 多分类:Softmax

6.1 Softmax 函数

将 K 个类别的得分转换为概率分布:

其中

6.2 性质

  • 所有类别概率之和为 1:
  • 每个概率在 (0, 1) 之间
  • 保持相对大小关系

6.3 多分类交叉熵

如果使用 one-hot 编码(只有真实类别 ):


7. 与线性回归对比

方面线性回归逻辑回归
任务类型回归分类
输出范围
激活函数Sigmoid
损失函数MSE交叉熵
梯度形式
决策边界-线性超平面
输出含义数值预测概率预测

8. Scikit-learn 实践

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report
 
# 准备数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
 
# 训练模型
model = LogisticRegression()
model.fit(X_train, y_train)
 
# 预测
y_pred = model.predict(X_test)        # 类别预测
y_prob = model.predict_proba(X_test)  # 概率预测
 
# 评估
print(f"准确率: {accuracy_score(y_test, y_pred):.4f}")
print(classification_report(y_test, y_pred))
 
# 查看模型参数
print(f"权重: {model.coef_}")
print(f"偏置: {model.intercept_}")

8.1 正则化选项

# L2 正则化(默认)
model_l2 = LogisticRegression(penalty='l2', C=1.0)
 
# L1 正则化
model_l1 = LogisticRegression(penalty='l1', solver='saga', C=1.0)
 
# 无正则化
model_none = LogisticRegression(penalty='none')

注:C 是正则化强度的倒数,C 越小,正则化越强。


9. 从零实现

import numpy as np
 
class LogisticRegressionScratch:
    def __init__(self, lr=0.01, epochs=1000):
        self.lr = lr
        self.epochs = epochs
 
    def sigmoid(self, z):
        return 1 / (1 + np.exp(-z))
 
    def fit(self, X, y):
        m, n = X.shape
        self.w = np.zeros(n)
        self.b = 0
 
        for _ in range(self.epochs):
            z = X @ self.w + self.b
            y_hat = self.sigmoid(z)
 
            # 梯度
            dw = (1/m) * X.T @ (y_hat - y)
            db = (1/m) * np.sum(y_hat - y)
 
            # 更新
            self.w -= self.lr * dw
            self.b -= self.lr * db
 
    def predict_proba(self, X):
        return self.sigmoid(X @ self.w + self.b)
 
    def predict(self, X, threshold=0.5):
        return (self.predict_proba(X) >= threshold).astype(int)

小结

概念要点
Sigmoid,将输出压缩到 (0,1)
交叉熵,预测错误惩罚大
梯度与线性回归形式相同:
决策边界,线性分类器
Softmax多分类扩展,
为什么用交叉熵避免 MSE 的非凸和梯度消失问题

参考资料


相关笔记