学完线性回归后,很多人第一次看到"逻辑回归"都会困惑:它既然叫回归,为什么常被用来判断"是或否""会或不会"这类分类问题?
关键在于它并不直接输出类别,而是先输出一个概率。例如"这条短信是垃圾短信的概率为 0.86",然后我们再根据阈值把概率变成最终类别。
从线性分数开始
逻辑回归和线性回归一样,先把输入特征做加权求和:
text
z = wx + b
这个 z 是一个线性分数,可以是任意实数,例如 -4.2、0.7 或 12。但分类概率必须落在 0 到 1 之间,所以它还会经过一个 Sigmoid 函数:
σ ( z ) = 1 1 + e − z \sigma(z) = \frac{1}{1 + e^{-z}} σ(z)=1+e−z1
Sigmoid 会把很小的分数压到接近 0,把很大的分数压到接近 1。于是输出 p p p 就可以理解为"样本属于正类的概率"。
| 输入 z | 输出 σ(z) | 含义 |
|---|---|---|
| 很大(+5) | ≈ 0.993 | 正类概率极高 |
| 0 | = 0.5 | 各 50%,踩在决策边界上 |
| 很小(-5) | ≈ 0.007 | 正类概率极低 |
线性回归的输出范围是 ( − ∞ , + ∞ ) (-\infty, +\infty) (−∞,+∞),而分类任务只需要 0 或 1。Sigmoid 就是中间那个"翻译官",把任意实数压缩到 (0, 1) 区间。
模型做的事可以拆成三步:
- 先线性加权: z = w 1 x 1 + w 2 x 2 + ⋯ + b z = w_1x_1 + w_2x_2 + \dots + b z=w1x1+w2x2+⋯+b;
- 再套 Sigmoid: y ^ = σ ( z ) \hat{y} = \sigma(z) y^=σ(z),输出一个 0, 1 之间的概率;
- 最后做决策:超过阈值判正类,否则判负类。
概率如何变成类别
最常见的阈值是 0.5:
text
p >= 0.5 -> 正类(1)
p < 0.5 -> 负类(0)
例如垃圾短信概率 0.86,在 0.5 阈值下判为垃圾短信;用户流失概率 0.22,判为不流失。
但阈值不是自然规律。信用风控中漏掉高风险用户的代价很大,可以把阈值调低,让模型更积极地提示风险;医学初筛中不希望漏检,也常优先提高召回率。反过来,误报很昂贵时可以提高阈值。
交叉熵:专为概率设计的损失函数
既然输出变成了概率,就不能再用 MSE(平方误差)来度量。线性回归最小化的是均方误差,逻辑回归最小化的是交叉熵:
L = − 1 n ∑ i = 1 n y i log y \^ i + ( 1 − y i ) log ( 1 − y \^ i ) \mathcal{L} = -\frac{1}{n}\sum_{i=1}^{n} \left y_i \\log \\hat{y}_i + (1-y_i) \\log(1-\\hat{y}_i) \\right L=−n1i=1∑nyilogy\^i+(1−yi)log(1−y\^i)
它的特点是越想当然地判错,惩罚越猛。预测概率 0.8、真实标签是 1,扣 0.22 分;预测概率 0.2、真实标签是 1,扣 1.61 分;预测概率 0.0001、真实标签是 1,扣 9.21 分。MSE 在概率上梯度太小,模型学不动,所以分类任务用交叉熵。
它和线性回归到底有什么不同
| 对比项 | 线性回归 | 逻辑回归 |
|---|---|---|
| 任务 | 预测连续数值 | 预测类别概率 |
| 输出范围 | 任意实数 | 0 到 1 |
| 损失函数 | MSE | 交叉熵 |
| 常见场景 | 房价、销量、温度 | 流失、欺诈、垃圾短信 |
| 常见评估 | MAE、RMSE、R² | 精确率、召回率、F1、AUC |
两者都包含"线性组合"这一部分,但最后的目标、损失函数和评估方式不同。逻辑回归的"回归"说的是它学习一个连续的分数和概率,最终用途是分类。
用 scikit-learn 训练一个二分类模型
下面以"是否通过考试"为例,输入是复习小时数,标签是是否通过:
python
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix
# 每个样本只有一个特征:复习小时数
X = np.array([[1], [2], [3], [4], [5], [6], [7], [8]])
y = np.array([0, 0, 0, 0, 1, 1, 1, 1])
model = LogisticRegression()
model.fit(X, y)
hours = np.array([[4.5]])
probability = model.predict_proba(hours)[0, 1]
label = model.predict(hours)[0]
print(f"通过概率:{probability:.2%}")
print(f"预测类别:{label}")
predict_proba() 很重要。它返回每个类别的概率,二分类时 [0, 1] 中索引为 1 的位置就是"正类"的概率。predict() 则使用模型默认阈值,直接返回类别标签。想知道模型有多确信,应该用 predict_proba(),不要把 predict() 当成概率。
不要只盯着默认阈值
如果需要自定义阈值,可以先拿到概率再自行判断:
python
threshold = 0.35
custom_label = int(probability >= threshold)
调阈值之前要先想清楚:误判正类和漏掉正类,哪一种代价更高?然后结合验证集上的混淆矩阵、精确率和召回率做选择。只凭感觉改成 0.3 或 0.8,通常会让模型更难解释。
两个常用选项也值得记一下:
python
model = LogisticRegression(
penalty="l2", # 正则化:l1(稀疏解)/ l2(默认)/ None
C=1.0, # 正则化强度的倒数,值越小正则化越强
solver="lbfgs", # 优化器
max_iter=1000 # 迭代次数,特征多时需增加
)
逻辑回归的优点和局限
逻辑回归训练快、可解释性强,对中小规模表格数据是很好的基线。它还可以通过权重的正负大致判断特征和正类概率的关系方向。
但它的分类边界本质上是线性的。数据存在复杂的非线性关系时,可能需要构造交互特征,或者尝试 KNN、决策树、随机森林等模型。下一个模型 KNN 就完全不学习一条显式公式,而是让"最近的样本"参与投票。
常见错误
把 predict() 当成概率
predict() 返回的是最终类别,不是概率。想知道模型有多确信,应该使用 predict_proba()。
忽略类别不平衡
如果 99% 的样本都是"正常",一个永远预测"正常"的模型准确率也可能是 99%。这时要结合精确率、召回率、F1、类别权重和采样策略,而不能只看准确率。
用测试集反复调阈值
测试集是最后一次客观检查的机会。阈值选择应在训练集内部的验证集或交叉验证中完成,否则测试分数会被人为"调高"。
课后练习
把示例中的 hours 改成 [[3.5]]、[[5.5]] 和 [[7.5]],记录每个样本的通过概率。然后分别用 0.5 和 0.7 作为阈值,观察最终类别如何变化。
小结
- 逻辑回归是经典的分类模型,名字里的"回归"指的是它学一个连续分数和概率;
- 它先计算线性分数,再用 Sigmoid 压缩到 0, 1,作为正类概率;
- 损失函数用交叉熵而不是 MSE,因为 MSE 在概率上梯度太小;
predict_proba()返回概率,predict()返回类别,阈值选择应由业务代价与分类指标共同决定。
下一课学习 KNN 分类:模型不再先学一条公式,而是让距离最近的邻居来投票。
在线阅读
原文地址:https://bestsdz.xyz/posts/logistic-regression-for-classification/