摘要:线性回归解决了"预测多少"的问题,但现实中更多问题是要回答"是或否"------这封邮件是垃圾邮件吗?这个病人患病吗?这个用户会点击广告吗?逻辑回归就是解决这类问题的经典算法。虽然名字里有"回归",但它实际上是一个分类算法。这篇文章讲清楚它是如何从线性回归演变而来的、Sigmoid 函数的作用、以及如何评估分类模型。
一、从回归到分类:问题变了
线性回归做不到的事
假设你有肿瘤数据,想预测"肿瘤是恶性还是良性":
肿瘤大小 (cm) → 是否恶性(是=1, 否=0)
1.0 0
1.5 0
2.0 0
2.8 1
3.5 1
... ...
如果用线性回归来拟合这些点:
恶性 ↑
1 -│ ● ●
│ ●
0 -│ ● ● ●
└──────────────────→ 肿瘤大小
线性回归会画一条直线穿过这些点,但当肿瘤很大时,预测值可能 >1;当肿瘤很小时,预测值可能 <0。
但概率必须在 [0,1] 范围内!这就是线性回归不能直接做分类的原因。
核心挑战
线性回归输出: (-∞, +∞) ← 任意实数
分类需要输出: [0, 1] ← 概率值
需要一个函数把 (-∞, +∞) 映射到 [0, 1]。
这个函数就是 Sigmoid。
二、Sigmoid 函数:把实数变成概率
数学形式
Sigmoid 函数:
σ(z) = 1 / (1 + e^(-z))
其中 z = w·x + b(就是线性回归的表达式)
函数图像
σ(z) ↑
1 ────────────────╮
│ ╲
│ ╲
0.5 ──╮──────────────╲───
│ ╲ ╲
│ ╲ ╲
0 ────╴───────────────╴──→ z
-2 0 2 4
Sigmoid 的三个重要性质:
1. 输出范围 (0, 1) ------ 天然是概率
2. σ(0) = 0.5 ------ 当 z=0 时,两类概率相等
3. z → +∞ 时,σ(z) → 1;z → -∞ 时,σ(z) → 0
逻辑回归的完整表达式
P(y=1 | x) = σ(w·x + b) = 1 / (1 + e^{-(w·x + b)})
当 P(y=1|x) > 0.5 时,预测为类别 1(恶性)
当 P(y=1|x) < 0.5 时,预测为类别 0(良性)
决策边界
决策边界是 P(y=1|x) = 0.5 的位置,即 w·x + b = 0。
线性决策边界(二维特征):
特征 ₂ ↑
│ ○ ○ ○
│ ○
│ ○ ╱ ○
│ ○ ╱ ○
│ ╱ ×
│ × ╱ × ×
│ × × ×
└─────────────────→ 特征₁
╱ 是决策边界:w₁x₁ + w₂x₂ + b = 0
╱ 的一侧预测为类别 ○,另一侧预测为类别 ×
和线性回归一样,逻辑回归的决策边界也是线性的------它只能学习线性分类边界。
三、损失函数:为什么不直接用 MSE?
MSE 在分类中的问题
如果用 MSE 做分类损失,损失函数不是凸函数------有很多局部最优解,梯度下降很难收敛。
MSE 作为分类损失的形状:
损失 ↑
│ ╱╲ ╱╲
│ ╱ ╲ ╱ ╲
│╱ ╲╱ ╲
└────────────────→ 参数 w
多个局部最优,梯度下降可能停在半路
交叉熵损失(Cross-Entropy Loss)
逻辑回归使用**交叉熵(Cross-Entropy)**作为损失函数,它是凸函数------只有一个全局最优解。
对于单个样本 (x, y):
当 y=1 时:Loss = -log(P(y=1|x))
当 y=0 时:Loss = -log(1 - P(y=1|x))
合并成一个公式:
Loss = -[y × log(ŷ) + (1-y) × log(1-ŷ)]
其中 ŷ = P(y=1|x) = σ(w·x + b)
理解交叉熵:
当真实标签 y=1 时:
预测 ŷ=0.99 → Loss = -log(0.99) ≈ 0.01 ✅ 几乎没错
预测 ŷ=0.50 → Loss = -log(0.50) ≈ 0.69 ⚠️ 不确定
预测 ŷ=0.01 → Loss = -log(0.01) ≈ 4.61 ❌ 错得离谱
当真实标签 y=0 时:
预测 ŷ=0.01 → Loss = -log(0.99) ≈ 0.01 ✅
预测 ŷ=0.99 → Loss = -log(0.01) ≈ 4.61 ❌
交叉熵的特性:对"过度自信的错误"惩罚非常重------模型如果以高置信度做出错误预测,会得到极大的损失。这让模型倾向于保持谨慎。
MSE vs 交叉熵
| 对比 | MSE | 交叉熵 |
|---|---|---|
| 损失函数形状 | ❌ 非凸(多个局部最优) | ✅ 凸函数(一个全局最优) |
| 梯度大小 | 预测错误时梯度小 | 预测错误时梯度大,学习快 |
| 分类任务效果 | ❌ 差 | ✅ 好,标准选择 |
| 回归任务效果 | ✅ 好 | ❌ 不适用 |
四、梯度下降求解逻辑回归
逻辑回归的损失函数(交叉熵)是凸函数,可以用梯度下降法求解:
# 伪代码:梯度下降求解逻辑回归
w = [0, 0, ..., 0]
learning_rate = 0.1
for step in range(1000):
# 1. 计算线性部分
z = X @ w # 线性得分
# 2. 通过 Sigmoid 转成概率
y_pred = 1 / (1 + np.exp(-z)) # 预测概率
# 3. 计算梯度(交叉熵对 w 的导数)
gradient = X.T @ (y_pred - y_true) / N # 和线性回归的梯度形式一样!
# 4. 更新参数
w = w - learning_rate × gradient
有趣的事实 :逻辑回归的梯度公式和线性回归完全一样------都是 X^T × (y_pred - y_true) / N。区别只在 y_pred 的计算方式不同。
五、多分类:一对多(OvR)和 Softmax
一对多(One-vs-Rest)
当类别超过 2 个时,一个简单的策略是:对每个类别训练一个"是否是这个类"的二分类器。
三类分类:猫、狗、兔子
分类器 1:猫 vs [狗+兔子] → 输出"是猫的概率"
分类器 2:狗 vs [猫+兔子] → 输出"是狗的概率"
分类器 3:兔子 vs [猫+狗] → 输出"是兔子的概率"
最终预测:取概率最大的类别
sklearn 中 LogisticRegression(multi_class='ovr') 默认使用此策略。
Softmax 回归
更优雅的方式是使用 Softmax 函数------Sigmoid 的多分类推广。
Softmax 把 K 个得分转换成 K 个概率,所有概率之和为 1:
P(y=k|x) = e^(z_k) / Σ(e^(z_j)) for j=1..K
其中 z_k = w_k · x + b_k(第 k 个类别的线性得分)
sklearn 中 LogisticRegression(multi_class='multinomial') 使用此策略。
| 策略 | 原理 | 适用场景 |
|---|---|---|
| OvR(一对多) | 每个类别一个二分类器 | 类别数少,或类别不互斥 |
| Softmax | 统一的多分类概率输出 | 类别互斥(一个样本只能属于一个类) |
六、评估分类模型
准确率不是唯一的指标------尤其是在类别不平衡的情况下。
混淆矩阵
预测 正类 预测 负类
真实 正类 TP(真正例) FN(假负例)
真实 负类 FP(假正例) TN(真负例)
从混淆矩阵导出的指标
accuracy = (TP + TN) / (TP + TN + FP + FN) # 整体准确率
precision = TP / (TP + FP) # 查准率:预测为正类中有多少是对的
recall = TP / (TP + FN) # 查全率:真实正类中有多少被找出来了
F1 = 2 × precision × recall / (precision + recall) # 两者的调和平均
# 在 sklearn 中
from sklearn.metrics import classification_report, confusion_matrix
y_true = [1, 0, 1, 1, 0, 1, 0, 0, 1, 0]
y_pred = [1, 0, 1, 0, 0, 1, 0, 1, 1, 0]
print(confusion_matrix(y_true, y_pred))
print(classification_report(y_true, y_pred))
# precision recall f1-score
# 0 0.67 0.67 0.67
# 1 0.75 0.75 0.75
什么时候关注哪个指标?
| 场景 | 关注指标 | 原因 |
|---|---|---|
| 疾病筛查 | 召回率(Recall) | 宁可误报,不能漏诊 |
| 垃圾邮件过滤 | 精确率(Precision) | 宁可漏过,不能误删正常邮件 |
| 通用场景 | F1 Score | 综合平衡 |
| 类别平衡 | 准确率(Accuracy) | 简单直观 |
ROC 曲线与 AUC
逻辑回归输出的是概率,改变分类阈值(默认 0.5)会影响性能。
ROC 曲线绘制了不同阈值下 TPR(召回率)和 FPR 的关系:
TPR = TP / (TP + FN) ← 越高越好
FPR = FP / (FP + TN) ← 越低越好
AUC = ROC 曲线下的面积
AUC = 1.0 → 完美分类器
AUC = 0.5 → 随机猜测(和抛硬币一样)
AUC = 0.8 → 较好的分类器
from sklearn.metrics import roc_auc_score, roc_curve
# 用概率而不是类别做评估
y_prob = model.predict_proba(X_test)[:, 1] # 预测为正类的概率
auc = roc_auc_score(y_test, y_prob)
print(f"AUC = {auc:.3f}")
# AUC = 0.921 → 模型有 92% 的概率把正类排在负类前面
七、sklearn 完整代码示例
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, classification_report, ConfusionMatrixDisplay
import matplotlib.pyplot as plt
# ===== 1. 生成示例数据(乳腺癌分类) =====
from sklearn.datasets import load_breast_cancer
data = load_breast_cancer()
X = data.data
y = data.target
feature_names = data.feature_names
target_names = data.target_names # ['malignant', 'benign']
print(f"样本数: {X.shape[0]}, 特征数: {X.shape[1]}")
print(f"类别分布: 恶性={sum(y==0)}, 良性={sum(y==1)}")
# ===== 2. 划分 + 标准化 =====
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
# ===== 3. 训练逻辑回归 =====
model = LogisticRegression(
C=1.0, # 正则化强度的倒数(越小正则化越强)
penalty='l2', # L2 正则化
solver='lbfgs', # 求解器
max_iter=1000,
random_state=42
)
model.fit(X_train, y_train)
# ===== 4. 预测与评估 =====
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1] # 预测为正类的概率
accuracy = accuracy_score(y_test, y_pred)
print(f"\n准确率: {accuracy:.3f}")
print(f"\n分类报告:")
print(classification_report(y_test, y_pred, target_names=target_names))
# ===== 5. 查看特征重要性 =====
coeff_df = pd.DataFrame({
'feature': feature_names,
'coefficient': model.coef_[0]
}).sort_values('coefficient', key=abs, ascending=False)
print("\n最重要的 5 个特征(绝对值最大的权重):")
print(coeff_df.head(5))
# ===== 6. 混淆矩阵 =====
ConfusionMatrixDisplay.from_estimator(
model, X_test, y_test,
display_labels=target_names,
cmap='Blues'
)
plt.title('混淆矩阵')
plt.show()
输出示例:
样本数: 569, 特征数: 30
类别分布: 恶性=212, 良性=357
准确率: 0.974
分类报告:
precision recall f1-score
malignant 0.98 0.95 0.96
benign 0.97 0.99 0.98
最重要的 5 个特征:
feature coefficient
worst concave points -1.80
worst perimeter -1.52
worst radius -1.38
mean radius 1.37
worst compactness -1.28
八、逻辑回归 vs 线性回归
| 对比维度 | 线性回归 | 逻辑回归 |
|---|---|---|
| 任务 | 回归(预测连续值) | 分类(预测离散类别) |
| 输出范围 | (-∞, +∞) | (0, 1) 概率 |
| 激活函数 | 无(或恒等映射) | Sigmoid / Softmax |
| 损失函数 | MSE | 交叉熵 |
| 决策边界 | 回归线/面 | 线性分界线/面 |
| 评估指标 | MSE, MAE, R² | Accuracy, Precision, Recall, F1, AUC |
两者本质上是一个框架
线性模型家族:
┌── 无激活函数 + MSE ──→ 线性回归
y = w·x + b ────┤
└── Sigmoid + 交叉熵 ──→ 逻辑回归
它们共享同一套"线性 + 参数优化"的框架,只是最后一步不同。
九、逻辑回归的局限与适用场景
局限
1. 决策边界必须是线性的
→ 无法处理 XOR 类问题
→ 无法拟合复杂的非线性边界
2. 需要特征工程
→ 需要用多项式特征、特征交叉来引入非线性
3. 对异常值敏感
→ 极端的特征值会影响决策边界
2026 年逻辑回归还有用吗?
| 场景 | 为什么还用它 |
|---|---|
| 风控模型 | 逻辑回归的可解释性无与伦比------监管部门要求解释"为什么拒绝贷款" |
| 医疗诊断 | 医生需要知道"哪些指标导致了高风险" |
| 电商 CTR 预估 | 作为超大模型的 baseline,有时候就是最好的模型 |
| A/B 测试分析 | 逻辑回归的系数可以直接解读为"风险比/优势比" |
十、总结
| 概念 | 一句话理解 |
|---|---|
| Sigmoid | 把任意实数映射到 (0,1) 区间的函数------让线性回归输出变成概率 |
| 决策边界 | w·x + b = 0 的分界线------一侧预测为正类,另一侧为负类 |
| 交叉熵 | 分类任务的"标准"损失函数------对错误概率大的预测惩罚重 |
| 精确率 vs 召回率 | 精确率="猜对的里面有多少真对",召回率="真的里面找回了多少" |
| AUC | 模型把正类排在负类前面的概率 |
核心三句话:
- 逻辑回归 = 线性回归 + Sigmoid + 交叉熵------它把回归问题变成了分类问题
- 决策边界是线性的------这是它的最大限制,也是它的最大优势(简单、可解释)
- 不要因为它"简单"就忽视它------在大量工业场景中,逻辑回归仍然是首选
逻辑回归是整个分类任务的起点。从这里出发,后续可以走向 SVM(追求最大间隔)、决策树(追求可解释规则)、神经网络(追求非线性拟合)。