逻辑回归(Logistic Regression)名字里有“回归”,但它最常用于分类任务,尤其是二分类问题。

它要回答的问题不是“这个样本的数值是多少”,而是“这个样本属于某一类的概率有多大”。例如:

  • 一封邮件是垃圾邮件的概率是多少?
  • 一个用户会不会点击广告?
  • 一个肿瘤样本是恶性的概率是多少?
  • 一个学生是否能通过考试?

逻辑回归的核心思想可以概括为一句话:先用一条直线算出一个分数,再用 Sigmoid 函数把这个分数压缩成 $0$ 到 $1$ 之间的概率。

线性分数经过 Sigmoid 函数变成概率

1. 从线性回归说起

在线性回归中,我们用一个线性函数预测连续值:

$$
z = wx + b
$$

如果是多个特征,可以写成:

$$
z = \mathbf{w}^{T}\mathbf{x} + b
$$

这里的 $z$ 可以理解为模型给样本打出的“原始分数”。

但是分类问题不能直接使用这个分数。比如判断一封邮件是不是垃圾邮件时,我们希望模型输出的是:

$$
P(y=1|\mathbf{x})
$$

也就是“在输入特征为 $\mathbf{x}$ 的条件下,样本属于正类的概率”。

概率必须满足两个条件:

  • 不能小于 $0$
  • 不能大于 $1$

而线性函数 $z=\mathbf{w}^{T}\mathbf{x}+b$ 的取值范围是 $(-\infty,+\infty)$。所以逻辑回归需要一个函数,把任意实数压缩到 $0$ 和 $1$ 之间。

这个函数就是 Sigmoid 函数。

2. Sigmoid 函数:把分数变成概率

Sigmoid 函数定义为:

$$
\sigma(z)=\frac{1}{1+e^{-z}}
$$

它有几个重要特点:

  • 当 $z$ 很大时,$\sigma(z)$ 接近 $1$
  • 当 $z$ 很小时,$\sigma(z)$ 接近 $0$
  • 当 $z=0$ 时,$\sigma(z)=0.5$

所以逻辑回归的完整模型可以写成:

$$
\hat{y}=P(y=1|\mathbf{x})=\sigma(\mathbf{w}^{T}\mathbf{x}+b)
$$

其中 $\hat{y}$ 表示模型预测为正类的概率。

直观地看:

  • $z$ 越大,模型越相信样本属于正类。
  • $z$ 越小,模型越相信样本属于负类。
  • $z=0$ 时,模型刚好一半一半,不偏向任何一类。

3. 分类规则:概率超过阈值就判为正类

逻辑回归输出的是概率,不是直接输出类别。因此还需要设定一个阈值。

最常见的阈值是 $0.5$:

$$
\hat{y}_{class} =
\begin{cases}
1, & \hat{y} \ge 0.5 \
0, & \hat{y} < 0.5
\end{cases}
$$

由于 $\sigma(0)=0.5$,所以:

$$
\hat{y} \ge 0.5 \Longleftrightarrow \mathbf{w}^{T}\mathbf{x}+b \ge 0
$$

这说明逻辑回归的决策边界其实是一条线,或者在高维空间里是一个超平面:

$$
\mathbf{w}^{T}\mathbf{x}+b=0
$$

逻辑回归的线性决策边界

图中蓝色点和红色点代表两类样本,中间的黑色直线就是决策边界。边界的一侧被预测为正类,另一侧被预测为负类。

4. 一个具体例子:学习时长与是否通过考试

假设我们只用“学习时长”这一个特征,预测学生是否通过考试。

学习时长/小时 是否通过
1 0
2 0
3 0
4 1
5 1
6 1

我们希望模型学到一个函数:

$$
P(\text{通过}|x)=\sigma(wx+b)
$$

假设模型学到:

$$
w=1.4,\quad b=-5.6
$$

那么当 $x=4$ 时:

$$
z=1.4 \times 4 - 5.6 = 0
$$

于是:

$$
P(\text{通过}|x=4)=\sigma(0)=0.5
$$

这意味着学习 $4$ 小时是模型眼中的临界点。

当 $x=5$ 时:

$$
z=1.4 \times 5 - 5.6 = 1.4
$$

$$
P(\text{通过}|x=5)=\sigma(1.4)\approx0.80
$$

模型会认为通过概率较高。

当 $x=2$ 时:

$$
z=1.4 \times 2 - 5.6 = -2.8
$$

$$
P(\text{通过}|x=2)=\sigma(-2.8)\approx0.06
$$

模型会认为通过概率很低。

这就是逻辑回归最直观的含义:输入特征先转成分数,再转成概率,最后根据阈值做分类。

5. 为什么不用均方误差

在线性回归中,我们常用均方误差:

$$
J=\frac{1}{m}\sum_{i=1}^{m}(\hat{y}^{(i)}-y^{(i)})^2
$$

但逻辑回归通常不用它,而是使用交叉熵损失(Cross Entropy Loss)。

原因是:逻辑回归输出的是概率。对于概率预测,我们更关心“模型对真实类别有多自信”。

如果真实标签 $y=1$,模型预测 $\hat{y}=0.99$,说明模型非常正确;如果预测 $\hat{y}=0.01$,说明模型非常自信地错了,应该受到很重的惩罚。

交叉熵正好有这个特点。

6. 交叉熵损失

对单个样本,逻辑回归的损失函数为:

$$
L(\hat{y},y)=-\left[y\log(\hat{y})+(1-y)\log(1-\hat{y})\right]
$$

分两种情况看就很清楚。

当 $y=1$ 时:

$$
L=-\log(\hat{y})
$$

如果模型把正类预测成 $0.99$,损失很小;如果预测成 $0.01$,损失会非常大。

当 $y=0$ 时:

$$
L=-\log(1-\hat{y})
$$

如果模型把负类预测成 $0.01$,损失很小;如果预测成 $0.99$,损失会非常大。

交叉熵损失对错误自信预测的惩罚更大

对全部训练样本,代价函数为:

$$
J(\mathbf{w},b)=
-\frac{1}{m}\sum_{i=1}^{m}
\left[
y^{(i)}\log(\hat{y}^{(i)})
+(1-y^{(i)})\log(1-\hat{y}^{(i)})
\right]
$$

训练逻辑回归,就是找到合适的 $\mathbf{w}$ 和 $b$,让这个代价函数尽可能小。

7. 梯度下降如何学习参数

逻辑回归也可以用梯度下降来训练。

每轮迭代大致做三件事:

  1. 用当前的 $\mathbf{w}$ 和 $b$ 计算每个样本的预测概率。
  2. 根据交叉熵损失计算模型错得有多严重。
  3. 沿着损失下降最快的方向更新参数。

参数更新公式可以写成:

$$
w_j := w_j - \alpha \frac{\partial J}{\partial w_j}
$$

$$
b := b - \alpha \frac{\partial J}{\partial b}
$$

其中 $\alpha$ 是学习率,控制每次更新走多远。

逻辑回归的直觉就是:如果正类样本被预测得太低,就把决策边界往能提高它概率的方向推;如果负类样本被预测得太高,就把边界往能降低它概率的方向推。

8. Python 实战

下面用 scikit-learn 训练一个二维逻辑回归模型,并画出决策边界。

安装依赖:

pip install scikit-learn numpy matplotlib

示例代码:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler

X, y = make_classification(
    n_samples=120,
    n_features=2,
    n_redundant=0,
    n_informative=2,
    n_clusters_per_class=1,
    class_sep=1.4,
    random_state=42,
)

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

model = LogisticRegression()
model.fit(X_scaled, y)

x_min, x_max = X_scaled[:, 0].min() - 0.5, X_scaled[:, 0].max() + 0.5
y_min, y_max = X_scaled[:, 1].min() - 0.5, X_scaled[:, 1].max() + 0.5
xx, yy = np.meshgrid(
    np.linspace(x_min, x_max, 200),
    np.linspace(y_min, y_max, 200),
)

grid = np.c_[xx.ravel(), yy.ravel()]
proba = model.predict_proba(grid)[:, 1].reshape(xx.shape)

plt.figure(figsize=(7, 5))
plt.contourf(xx, yy, proba, levels=20, cmap="RdBu", alpha=0.35)
plt.contour(xx, yy, proba, levels=[0.5], colors="black", linewidths=2)
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=y, cmap="RdBu", edgecolors="k")
plt.title("Logistic Regression Decision Boundary")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.show()

这段代码中的黑色线就是 $P(y=1|\mathbf{x})=0.5$ 的位置,也就是逻辑回归的分类边界。

9. 逻辑回归的优缺点

优点

  • 简单、稳定、可解释性强。
  • 输出的是概率,而不仅仅是类别。
  • 训练速度快,适合做二分类基线模型。
  • 对线性可分或近似线性可分的数据效果很好。

缺点

  • 决策边界是线性的,难以直接处理复杂非线性数据。
  • 对特征缩放比较敏感,实践中通常需要标准化。
  • 如果特征之间关系很复杂,单纯逻辑回归可能欠拟合。
  • 对异常值和强相关特征也需要适当处理。

10. 实践建议

使用逻辑回归时,可以优先注意下面几点:

  1. 对连续特征做标准化。
  2. 用验证集或交叉验证选择正则化强度。
  3. 如果类别不平衡,不要只看准确率,可以关注精确率、召回率、F1、AUC。
  4. 如果数据明显非线性,可以加入多项式特征,或者换用树模型、SVM、神经网络等方法。
  5. 业务上需要概率解释时,逻辑回归往往比只输出类别的模型更方便。

11. 总结

逻辑回归虽然名字叫“回归”,但它解决的是分类问题。

它的核心链路是:

$$
\mathbf{x}
\rightarrow
z=\mathbf{w}^{T}\mathbf{x}+b
\rightarrow
\hat{y}=\sigma(z)
\rightarrow
\text{类别}
$$

从图像上看,逻辑回归用一条直线或一个超平面切分空间;从概率上看,它用 Sigmoid 函数把线性分数转成属于正类的概率;从优化上看,它用交叉熵损失惩罚错误预测,并通过梯度下降学习参数。

因此,逻辑回归非常适合作为理解分类算法的第一站:它足够简单,但又包含了概率、损失函数、决策边界、梯度下降这些机器学习中非常核心的概念。