SL Scikit-Learn Learn机器学习教程

Lesson 06

逻辑回归:用概率做分类

逻辑回归虽然名字带"回归",但它是最经典的分类算法之一。本章从 Sigmoid 函数建立概率直觉,到二分类实战、Grid Search 调参、多分类与多标签扩展。

  • 预计时长50 分钟
  • 难度进阶
  • 前置章节第 05 章

本章细分学习地图

逻辑回归是分类模型的基线标配。掌握它不仅能直接用于生产,还能为后续理解 SVM、神经网络的分类机制打基础。

模块拆细学习单元完成后应产出掌握标准
Sigmoid 与概率线性输出 → Sigmoid → 概率 → 阈值 → 类别。手画 Sigmoid 曲线。能解释输出概率与决策阈值的关系。
二分类实战LogisticRegression 训练、预测、概率输出、系数解读。完整分类代码。能解读 coef_ 的正负对分类的影响。
Grid SearchC、penalty 的含义与搜索方式。调参代码与最佳参数输出。能选择合适的评分指标做交叉验证搜索。
多分类与多标签OvR vs Multinomial;MultiOutputClassifier。多分类示例。能区分多分类和多标签场景。

学习目标

逻辑回归流程

1线性组合 z=wX+b
2Sigmoid σ(z)
3概率 P(y=1)
4阈值 → 类别

本章完成度

已完成 0/4

本章核心判断

逻辑回归的核心不是"画一条线",而是用概率表达模型对分类结果的信心。理解 predict_proba 比只看 predict 更重要。

Sigmoid 函数与概率

逻辑回归在线性回归的输出 z = wX + b 外面套一层 Sigmoid 函数,把任意实数压缩到 (0, 1) 区间,解释为"属于正类的概率"。

σ(z) = 1 / (1 + e−z) Sigmoid 函数:z → (0, 1) 区间的概率值

z 很大 → σ ≈ 1

模型很有信心预测为正类。

z ≈ 0 → σ = 0.5

模型不确定,处于决策边界上。

z 很小 → σ ≈ 0

模型很有信心预测为负类。

阈值默认 0.5

σ(z) ≥ 0.5 预测正类,否则负类。阈值可调。

import numpy as np

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

z = np.array([-5, -1, 0, 1, 5])
print("z:", z)
print("σ(z):", np.round(sigmoid(z), 4))
# σ(z): [0.0067, 0.2689, 0.5, 0.7311, 0.9933]

互动实验:调整阈值如何影响精确率与召回率

下面 40 个样本按预测概率从左到右排列,上排是真实正类,下排是真实负类。拖动滑块调整判定阈值,绿色表示预测正确,红色表示预测错误,右侧面板实时显示混淆矩阵和指标。

TP
0
FP
0
TN
0
FN
0
Precision
0
Recall
0
F1
0
观察重点

阈值越高,模型越"谨慎":假阳性(FP)变少、精确率上升,但漏掉的真阳性(FN)变多、召回率下降;阈值越低则相反。选阈值本质上是在精确率和召回率之间权衡,取决于业务对两类误判的容忍度(比如垃圾邮件识别更怕误杀正常邮件,就该调高阈值)。

二分类实战

用乳腺癌数据集完成一个完整的逻辑回归二分类流程。

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.metrics import classification_report

X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

pipe = Pipeline([
    ("scaler", StandardScaler()),
    ("lr", LogisticRegression(max_iter=1000, random_state=42)),
])
pipe.fit(X_train, y_train)

# 预测与概率
y_pred = pipe.predict(X_test)
y_proba = pipe.predict_proba(X_test)[:, 1]  # 正类概率

print(classification_report(y_test, y_pred, target_names=["恶性", "良性"]))
print("前 5 个样本的正类概率:", y_proba[:5].round(3))
coef_ 的解读

coef_[0] 中第 i 个值为正,说明该特征增大时模型更倾向预测正类;为负则倾向负类。绝对值越大影响越强(前提是特征已缩放)。

Grid Search 调参

逻辑回归的核心超参数是正则化强度 C(C 越小正则越强)和正则化类型 penalty(l1 或 l2)。用 GridSearchCV 交叉验证搜索最优组合。

from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)

pipe = Pipeline([
    ("scaler", StandardScaler()),
    ("lr", LogisticRegression(max_iter=1000, random_state=42, solver="saga")),
])

param_grid = {
    "lr__C": [0.01, 0.1, 1, 10],
    "lr__penalty": ["l1", "l2"],
}

grid = GridSearchCV(pipe, param_grid, cv=5, scoring="f1", n_jobs=-1)
grid.fit(X, y)

print(f"最佳参数: {grid.best_params_}")
print(f"最佳 F1:  {grid.best_score_:.4f}")
超参数含义调参建议
C正则化强度的倒数。C 越小,正则越强,模型越简单。从 [0.01, 0.1, 1, 10, 100] 搜索。
penaltyl1 可产生稀疏系数(特征选择),l2 整体压缩。需要特征选择用 l1,否则用 l2。
scoring交叉验证评分指标。二分类用 f1;多分类用 f1_macro 或 f1_weighted。

多分类与多标签

逻辑回归天生是二分类模型,但可以扩展到多分类和多标签场景。

OvR (One vs Rest)

为每个类别训练一个二分类器。简单直观,类别多时训练量线性增长。

Multinomial

一个模型同时学所有类别的概率分布(softmax)。通常更准确但需要合适的 solver。

from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score

X, y = load_iris(return_X_y=True)

# OvR
lr_ovr = LogisticRegression(multi_class="ovr", max_iter=1000, random_state=42)
print(f"OvR 准确率: {cross_val_score(lr_ovr, X, y, cv=5).mean():.3f}")

# Multinomial
lr_multi = LogisticRegression(multi_class="multinomial", max_iter=1000, random_state=42)
print(f"Multinomial 准确率: {cross_val_score(lr_multi, X, y, cv=5).mean():.3f}")
多分类 vs 多标签

多分类:每个样本只属于一个类别(如鸢尾花三分类)。多标签:每个样本可以同时属于多个类别(如一篇文章同时属于"科技"和"教育"),需要用 MultiOutputClassifier 包裹。

练习题

第 1 题:Sigmoid 函数的输出范围是什么?当 z=0 时输出多少?

参考思路:输出范围 (0, 1),z=0 时输出 0.5,即模型对正负类没有偏好。

第 2 题:C=0.01 和 C=100 哪个正则化更强?对模型复杂度有什么影响?

参考思路:C=0.01 正则更强,模型更简单(系数被压缩更多),可能欠拟合。C=100 正则很弱,模型更复杂,可能过拟合。

第 3 题:用乳腺癌数据集,GridSearchCV 搜索 C 和 penalty,用 f1 评分,打印最佳参数和分数。

参考思路:参见本章 Grid Search 部分的完整代码。关键是 Pipeline 内先 StandardScaler 再 LogisticRegression,scoring="f1"。

检查点

离开本章前,请确认:

  • 能解释 Sigmoid 如何把线性输出变成概率,以及阈值的作用。
  • 能用 Pipeline(Scaler + LogisticRegression)完成二分类并解读系数。
  • 能用 GridSearchCV 搜索 C 和 penalty,选择合适的评分指标。
  • 能区分 OvR / Multinomial 多分类策略和多标签场景。