朴素贝叶斯:最简单的分类器,最深刻的贝叶斯思维

· 约 4 分钟 ·
本文目录(7 节)

朴素贝叶斯把分类问题写成概率比较:看到这些特征后,哪一个类别更可能?它通过条件独立假设简化计算,因此训练成本较低,适合作为文本分类基线。特征在现实中并不需要真的互不相关;关键是这种近似会怎样影响分类结果和概率可信度。

前置阅读:机器学习数学基础(贝叶斯定理)、机器学习基础。

原理:贝叶斯定理 + 一个天真的假设

分类问题写成概率:已知特征 xx,求最可能的类别:

P(y∣x)=P(x∣y) P(y)P(x)∝P(x∣y) P(y)P(y|x) = \frac{P(x|y) \, P(y)}{P(x)} \propto P(x|y)\, P(y)

困难在 P(x∣y)P(x|y)——特征有几千维时,这个联合分布没法估。朴素贝叶斯的”天真”假设:特征之间条件独立(给定类别,各特征互不影响)。于是联合概率拆成逐个特征的乘积:

P(y∣x)∝P(y)∏jP(xj∣y)P(y|x) \propto P(y) \prod_{j} P(x_j | y)

每个 P(xj∣y)P(x_j|y) 只要在训练集上数数就能估出来。假设显然是假的(“免费”和”发票”在垃圾邮件里明明相关),但实践反复证明:假设错误不妨碍分类效果好——因为分类只要求正确类别的概率最大,不要求概率值本身精确。

实战:垃圾邮件过滤 20 行代码

from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.pipeline import Pipeline

# 多项分布变体:处理词频计数,文本分类的标准选择
pipe = Pipeline([
    ("vec", CountVectorizer(ngram_range=(1, 2), min_df=3)),
    ("nb", MultinomialNB(alpha=1.0)),       # alpha 是平滑参数
])
pipe.fit(train_texts, train_labels)
print(pipe.score(test_texts, test_labels))

# 看看模型认为哪些词最"垃圾"
import numpy as np
vec, nb = pipe["vec"], pipe["nb"]
words = np.array(vec.get_feature_names_out())
spam_log = nb.feature_log_prob_[1] - nb.feature_log_prob_[0]
print(words[np.argsort(spam_log)[-10:]])     # 最指向垃圾邮件的词

alpha 是拉普拉斯平滑:训练集里没出现过的词,计数为 0 会导致整个乘积变 0(一个词没见过,邮件就被判死刑)。平滑给所有计数加一个底数,没见过不等于不可能。alpha 通常 0.1-1.0,是重要的调参点。

三种变体:按特征形态选

变体特征假设适用
MultinomialNB词频计数(多项分布)文本分类首选
BernoulliNB词出现/不出现(0/1)短文本、特征本身是二值的
GaussianNB连续特征服从正态分布数值特征、快速基线

文本场景记住:词频用多项版,词袋布尔值用伯努利版。把词频喂给伯努利版(它会把所有非零都当 1)是常见错误,会丢掉词频信息。

它的真实定位:快基线 + 可解释

朴素贝叶斯的优势清单:训练毫秒级(一遍数数)、小数据表现好(参数少不怕过拟合)、天然输出概率、特征对类别的贡献直接可查(feature_log_prob_ 差值就是证据权重)。它至今是任何文本分类任务的第一基线——领域分类的逻辑回归基线之前,先用它十分钟立个下限。

短板也明确:特征独立假设让它无法理解词之间的组合(“不 推荐”和”推荐”在它眼里差不多,ngram 特征能部分缓解);概率输出虽然快但校准不准(排序可用,当精确概率用要校准)。

踩坑排查

症状原因处理
预测全是某一类先验悬殊没处理class_prior 调整;评估看宏 F1
遇到新词就崩没设平滑alpha > 0(默认 1.0 即可)
用错变体效果差词频喂了伯努利文本词频用 MultinomialNB
概率值极端(0.99/0.01)NB 概率本性排序可用;要准概率做校准
长文档效果差词频随长度膨胀归一化或换 TF-IDF + 线性模型

练习

  1. 在 20newsgroups 子集上对比三种变体的分数,解释差异来源。
  2. 扫 alpha ∈ {0.01, 0.1, 1, 10},观察对验证分的影响并解释平滑的作用。
  3. 提取最指向各类别的 Top 10 词,人工检查可解释性。
  4. 对比朴素贝叶斯与逻辑回归在小样本(500 条)和大样本(5 万条)下的表现。

面试常问

Q:朴素贝叶斯为什么”朴素”? 假设特征条件独立。现实中几乎从不成立,但分类只比较各类别后验的相对大小,独立性假设的误差在所有类别上同向存在,排序常常仍然正确——这是它”假设错但效果好”的原因。

Q:拉普拉斯平滑解决什么? 训练集中未出现的特征-类别组合概率为 0,乘法链中一个 0 就判死刑。平滑给计数加底数 α,未见事件获得小而非零的概率。

Q:朴素贝叶斯和逻辑回归的关系? 都是线性分类器(NB 的对数几率是特征的线性函数),但训练目标不同:NB 是生成式(学 P(x|y) 和 P(y)),逻辑回归是判别式(直接学 P(y|x))。数据少时生成式的 NB 常有优势,数据多时判别式上限更高(Ng & Jordan 的经典结论)。

Q:为什么 NB 适合小数据? 参数少(每类每特征一个计数),估计方差小,不易过拟合;复杂模型在小数据上估不准参数。这是”简单模型的偏差换方差”的典型案例。


相关阅读:机器学习数学基础、逻辑回归与 SVM(判别式的对照)。

💬 评论

这套方案在哪一步卡住了?也欢迎补充你的实现方式或踩坑经验。

正在连接评论服务,首次访问可能需要几秒…