SL Scikit-Learn Learn机器学习教程

Lesson 07

朴素贝叶斯:用概率做分类

朴素贝叶斯是最快的概率分类器。本章从贝叶斯定理出发,解释条件独立假设为什么"朴素"但有效,再用 GaussianNB 和 MultinomialNB 完成实战。

  • 预计时长35 分钟
  • 难度中等
  • 前置章节第 04、06 章

本章细分学习地图

模块拆细学习单元完成后应产出掌握标准
贝叶斯定理先验 P(C)、似然 P(X|C)、后验 P(C|X)。手算一个简单例子。能说清贝叶斯定理各项的含义。
朴素假设条件独立、为什么"朴素"、优缺点。条件独立的直觉解释。能说清假设何时成立何时不成立。
变体选择Gaussian / Multinomial / Bernoulli 适用场景。变体对比表。能根据特征类型选择正确变体。
实战文本分类 Pipeline、鸢尾花分类。完整可运行代码。能独立构建朴素贝叶斯分类器。

学习目标

朴素贝叶斯分类流程

1计算先验 P(C)
2计算似然 P(X|C)
3贝叶斯定理求后验
4选后验最大的类

本章完成度

已完成 0/4

贝叶斯定理

贝叶斯定理描述了在已知证据 X 的情况下,如何更新对类别 C 的信念:

P(C|X) = P(X|C) · P(C) / P(X) 后验 = 似然 × 先验 / 证据

先验 P(C)

在看到特征之前,每个类别的概率。通常用训练集中各类别的比例估计。

似然 P(X|C)

假设类别为 C 时,观测到特征 X 的概率。不同 NB 变体对似然的建模方式不同。

后验 P(C|X)

看到特征后,每个类别的更新概率。分类时选后验最大的类。

证据 P(X)

所有类别下 P(X|C)·P(C) 的总和。分类时是常数,可以忽略。

朴素假设:条件独立

"朴素"指的是假设在给定类别 C 的条件下,所有特征相互独立

P(x₁, x₂, …, xp | C) = P(x₁|C) · P(x₂|C) · … · P(xp|C) 条件独立假设:把联合概率分解为各特征概率的乘积
为什么"朴素"但有效

现实中特征几乎不可能完全独立。但朴素贝叶斯只需要后验概率的大小排序正确即可做对分类,不需要概率值本身精确。这就是它在文本分类、垃圾邮件过滤等场景表现出色的原因。

优势局限
训练和预测都极快(O(n·p))。条件独立假设在强相关特征下失效。
小数据集也能工作,不容易过拟合。输出的概率值不够校准(虽然排序正确)。
天然支持增量学习(partial_fit)。无法捕捉特征间的交互效应。

变体选择

不同的朴素贝叶斯变体对似然 P(X|C) 的建模方式不同,适用于不同类型的特征:

变体似然分布适用特征
GaussianNB每个特征服从高斯分布。连续数值特征(鸢尾花、波士顿房价)。
MultinomialNB多项式分布(词频/计数)。BoW / TF-IDF 文本特征。
BernoulliNB伯努利分布(0/1 出现与否)。二值特征(词是否出现)。

sklearn 实战

1. GaussianNB:鸢尾花分类

from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
from sklearn.naive_bayes import GaussianNB

X, y = load_iris(return_X_y=True)
gnb = GaussianNB()
scores = cross_val_score(gnb, X, y, cv=5)
print(f"GaussianNB 准确率: {scores.mean():.3f} ± {scores.std():.3f}")

2. MultinomialNB:文本分类 Pipeline

from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
from sklearn.model_selection import cross_val_score

cats = ["sci.space", "rec.sport.baseball"]
data = fetch_20newsgroups(subset="train", categories=cats, random_state=42)

pipe = Pipeline([
    ("tfidf", TfidfVectorizer(max_features=5000, stop_words="english")),
    ("nb", MultinomialNB(alpha=1.0)),
])
scores = cross_val_score(pipe, data.data, data.target, cv=5, scoring="f1")
print(f"MultinomialNB F1: {scores.mean():.3f} ± {scores.std():.3f}")
alpha 参数(拉普拉斯平滑)

alpha=1.0 是拉普拉斯平滑,防止某个词在某类中从未出现导致概率为零。alpha 越大,平滑越强。

练习题

第 1 题:贝叶斯定理中的"先验"和"后验"分别在什么时候计算?

参考思路:先验在看到特征之前,由训练数据的类别比例估计;后验在看到特征之后,通过贝叶斯定理计算。

第 2 题:特征是 TF-IDF 向量,应该用哪个 NB 变体?

参考思路:MultinomialNB,因为 TF-IDF 值是非负的词频权重,符合多项式分布的假设。

第 3 题:用 20newsgroups 数据集,对比 MultinomialNB 和 GaussianNB 的 F1 分数。

参考思路:MultinomialNB 通常在文本 TF-IDF 特征上表现更好。GaussianNB 需要 .toarray() 转换稀疏矩阵,且高斯假设不适合词频分布。

检查点

离开本章前,请确认:

  • 能写出贝叶斯定理并解释先验、似然、后验、证据。
  • 能解释条件独立假设为什么"朴素"但分类时仍有效。
  • 能根据特征类型(连续/计数/二值)选择正确的 NB 变体。
  • 能用 TfidfVectorizer + MultinomialNB 构建文本分类 Pipeline。