06 - 朴素贝叶斯与概率图模型

3 阅读17分钟

从"猜测"到"推理" —— 让机器像医生一样根据症状做判断


目录

  1. 从生活中理解概率
  2. 贝叶斯定理:逆向推理的艺术
  3. 先验、后验与似然
  4. 朴素贝叶斯:一个"天真"的假设
  5. 三种朴素贝叶斯变体
  6. 拉普拉斯平滑
  7. 实战案例
  8. 概率图模型简介
  9. 总结与进阶

1. 从生活中理解概率

1.1 医生看病的故事

想象你去看医生,你对医生说:"我头疼、流鼻涕、打喷嚏。"

医生脑子里会怎么想?

  症状(你告诉医生的)          医生的推理过程            结论
 +------------------+      +------------------+    +----------+
 | * 头疼           |      | 感冒的人 80% 头疼 |    |          |
 | * 流鼻涕         | ---> | 感冒的人 90% 流涕 | -> | 你可能是  |
 | * 打喷嚏         |      | 感冒的人 70% 喷嚏 |    | 感冒了!  |
 +------------------+      +------------------+    +----------+

医生并不是随意猜测的,而是根据**过去的经验(数据)**来推理的:

  • 他见过很多病人(训练数据)
  • 他知道不同疾病会有什么症状(条件概率)
  • 他结合当前季节等信息(先验概率)来做判断

这就是贝叶斯推理的核心思想!

1.2 什么是概率?

概率就是某件事发生的可能性大小,用 0 到 1 之间的数字表示:

  不可能                                              一定会
    |                                                    |
    0 -------- 0.25 -------- 0.5 -------- 0.75 -------- 1
    |           |              |             |           |
  太阳从      抛硬币         抛硬币        明天        太阳从
  西边升起    两次都正面      一次正面      不下暴雪     东边升起

条件概率 P(A|B):在 B 已经发生的情况下,A 发生的概率。

生活例子:

  • P(带伞 | 下雨) = 0.9 → 下雨了,你带伞的概率很高
  • P(迟到 | 堵车) = 0.7 → 堵车了,你迟到的概率较高
  • P(考高分 | 认真复习) = 0.8 → 认真复习了,考高分的概率较高
  条件概率图解:P(A|B) 表示"已知 B 发生,A 也发生"的概率

  +---------------------------------------+
  |            所有可能的情况(全集)         |
  |                                       |
  |    +----------+                       |
  |    |    B     |                       |
  |    |   +------+---+                   |
  |    |   | AB|   |                  |
  |    |   | (AB) |   |                  |
  |    |   +------+---+                   |
  |    |          | A  |                  |
  |    +----------+----+                  |
  |                                       |
  +---------------------------------------+

  P(A|B) = P(AB) / P(B)

  即:在 B 这个范围内,AB 占了多大比例?

2. 贝叶斯定理:逆向推理的艺术

2.1 正向 vs 逆向

我们常常知道"原因→结果"的概率,但需要从"结果→原因"来推理。

  【正向推理 — 容易】              【逆向推理 — 贝叶斯帮你】
  已知疾病 -> 预测症状              已知症状 -> 推断疾病

  P(打喷嚏|感冒) = 0.7             P(感冒|打喷嚏) = ?
  "感冒的人有70%会打喷嚏"            "打喷嚏的人有多大概率是感冒?"

2.2 贝叶斯公式

                    P(B|A) × P(A)
  P(A|B)  =  -------------------------
                      P(B)

  其中:
  P(A|B)  = 后验概率(我们想知道的)
  P(B|A)  = 似然(已知 AB 的概率)
  P(A)    = 先验概率(A 本身的概率)
  P(B)    = 证据(B 发生的总概率)

2.3 一个具体例子

问题:一种疾病的发病率为 1%(先验)。检测试剂的准确率如下:

  • 真的有病,检测阳性的概率 = 99%(似然 / 灵敏度)
  • 没有病,检测阳性的概率 = 5%(假阳性率)

你检测结果为阳性,真的有病的概率是多少?

  直觉回答:99%?—— 错!

  贝叶斯计算:

  P(有病|阳性) = P(阳性|有病) × P(有病)
                 --------------------------
                        P(阳性)

  P(阳性) = P(阳性|有病)×P(有病) + P(阳性|没病)×P(没病)
           = 0.99 × 0.01 + 0.05 × 0.99
           = 0.0099 + 0.0495
           = 0.0594

  P(有病|阳性) = 0.0099 / 0.05940.16716.7%

  结论:即使检测阳性,真正有病的概率只有 16.7%

为什么这么低?因为这种病本身就很罕见(先验概率低),大量健康人中也会产生假阳性。

  直观理解(假设 10000 人接受检测):

  10000 人
    |
    +-- 100 人真的有病(1%)
    |     |-- 99 人检测阳性  (真阳性)
    |     +--  1 人检测阴性
    |
    +-- 9900 人没有病(99%)
          |-- 495 人检测阳性 (假阳性) ← 这些人数量很多!
          +-- 9405 人检测阴性

  阳性总人数 = 99 + 495 = 594
  其中真正有病 = 99
  概率 = 99 / 59416.7%

3. 先验、后验与似然

这三个概念是贝叶斯体系的核心,我们用天气预报来类比:

  +------------------------------------------------------------------+
  |  概念      |  含义                |  天气类比                      |
  +------------------------------------------------------------------+
  |  先验概率   |  在看到证据之前的    |  "根据历史,3月份下雨的         |
  |  P(A)      |  初始信念            |   概率大约是 30%"              |
  +------------------------------------------------------------------+
  |  似然      |  在假设成立时,      |  "如果要下雨,天空出现乌云       |
  |  P(B|A)   |  看到证据的概率       |   的概率是 85%"                |
  +------------------------------------------------------------------+
  |  后验概率   |  看到证据之后,      |  "现在天空有乌云,那么今天       |
  |  P(A|B)   |  更新后的信念         |   下雨的概率更新为 65%"         |
  +------------------------------------------------------------------+

  核心思想:先验 + 新证据 --> 后验

  P(下雨|乌云) ∝ P(乌云|下雨) × P(下雨)
  "看到乌云后下雨的概率" 正比于 "下雨时有乌云的概率" 乘以 "下雨的先验概率"

贝叶斯思维本质上是一种"不断更新信念"的过程。


4. 朴素贝叶斯:一个"天真"的假设

4.1 为什么叫"朴素"(Naive)?

朴素贝叶斯的核心假设:所有特征之间相互独立

这就像假设一个人的"身高"和"体重"毫无关系——我们知道现实中它们是有关联的, 但这个"天真的"假设让计算变得极其简单,而且效果出奇地好!

  朴素假设图解:

  【现实世界 — 特征之间有关联】        【朴素假设 — 特征各自独立】

      特征1 <---> 特征2                    特征1     特征2
        |    \   /   |                       |         |
        |     \ /    |                       |         |
        v      X     v                       v         v
      特征3 <---> 特征4                    特征3     特征4
            \   /                              |         |
             \ /                               |         |
              v                                v         v
            类别                              类别      类别
                                         (每个特征独立地影响类别)

  有了朴素假设:
  P(特征1,特征2,...,特征n | 类别)
    = P(特征1|类别) × P(特征2|类别) × ... × P(特征n|类别)

  计算从指数级复杂度变成了线性复杂度!

4.2 朴素贝叶斯分类器

给定一个样本 X = (x1, x2, ..., xn),我们要判断它属于哪个类别 C:

  P(C|X) ∝ P(C) × P(x1|C) × P(x2|C) × ... × P(xn|C)

  分类规则:选择使 P(C|X) 最大的那个类别

  y = argmax P(Ck) × ∏ P(xi|Ck)
        Ck            i=1..n

4.3 文本分类流水线

以垃圾邮件过滤为例:

  文本分类流水线(Pipeline)

  输入邮件           分词             特征提取           分类器          输出
  +--------+     +--------+      +-----------+     +---------+    +--------+
  |"恭喜你 |     |恭喜/你 |      | 恭喜: 1   |     |         |    |        |
  | 中奖了 | --> |中奖/了 | ---> | 中奖: 1   | --> | 朴素    | -> | 垃圾   |
  | 点击.. |     |点击/链接|      | 点击: 1   |     | 贝叶斯  |    | 邮件! |
  | 链接.. |     |免费/..  |      | 免费: 1   |     |         |    |        |
  +--------+     +--------+      +-----------+     +---------+    +--------+
                                  词频向量化          训练好的模型

  训练过程:
  +-----------+     +---------+     +----------+     +-----------+
  | 大量已标注 |     | 统计每个 |     | 计算先验  |     | 得到模型   |
  | 的邮件    | --> | 词在垃圾/ | --> | 和似然   | --> | (各概率   |
  | (训练集)  |     | 正常邮件  |     | 概率     |     |  参数)    |
  |           |     | 中的频率  |     |          |     |           |
  +-----------+     +---------+     +----------+     +-----------+

5. 三种朴素贝叶斯变体

5.1 高斯朴素贝叶斯 (Gaussian Naive Bayes)

适用场景:特征是连续数值(身高、体重、温度等)

假设每个特征在给定类别下服从正态分布(高斯分布):

                    1              (x - μ)²
  P(x|C) = -------------- × exp(- ---------)
            sqrt(2π × σ²)          2 × σ²

  其中 μ 是均值,σ² 是方差

  高斯分布长这样:

         *
        * *
       *   *
      *     *
     *       *
    *         *         μ = 均值(钟形曲线的中心)
   *           *        σ = 标准差(曲线的胖瘦)
  *             *
 *               *
*                 *
---+-----+-----+---
  μ-2σ   μ   μ+2σ

例子:根据身高体重判断性别

from sklearn.naive_bayes import GaussianNB
import numpy as np

# 训练数据:[身高(cm), 体重(kg)]
X_train = np.array([
    [170, 65], [180, 80], [175, 70], [168, 60],  # 男性
    [158, 48], [162, 52], [155, 45], [160, 50],  # 女性
])
y_train = np.array(['男', '男', '男', '男', '女', '女', '女', '女'])

# 创建并训练模型
model = GaussianNB()
model.fit(X_train, y_train)

# 预测新数据
X_test = np.array([[165, 55], [178, 75]])
predictions = model.predict(X_test)
print(f"预测结果: {predictions}")
# 输出: 预测结果: ['女' '男']

# 查看概率
probabilities = model.predict_proba(X_test)
print(f"概率分布: {probabilities}")

5.2 多项式朴素贝叶斯 (Multinomial Naive Bayes)

适用场景:特征是离散计数值(词频、评分次数等)

这是文本分类中最常用的变体。

  P(xi|C) = (该词在类别 C 中出现的次数 + α) / (类别 C 中所有词的总数 + α × 词表大小)

  其中 α 是拉普拉斯平滑参数(后面会讲)

例子:情感分析

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

# 训练数据
texts = [
    "这部电影太棒了 非常好看 强烈推荐",
    "演技精湛 剧情感人 五星好评",
    "画面精美 音乐动听 值得一看",
    "太难看了 浪费时间 不推荐",
    "剧情无聊 演技尴尬 差评",
    "烂片一部 毫无亮点 退票",
]
labels = ['正面', '正面', '正面', '负面', '负面', '负面']

# 文本向量化(把文字变成数字)
vectorizer = CountVectorizer()
X_train = vectorizer.fit_transform(texts)

# 训练模型
model = MultinomialNB(alpha=1.0)  # alpha 就是拉普拉斯平滑参数
model.fit(X_train, labels)

# 预测新评论
new_reviews = ["这部电影不好看 差评", "非常好看 强烈推荐 五星"]
X_test = vectorizer.transform(new_reviews)
predictions = model.predict(X_test)

for review, pred in zip(new_reviews, predictions):
    print(f"评论: {review} --> 情感: {pred}")
# 输出:
# 评论: 这部电影不好看 差评 --> 情感: 负面
# 评论: 非常好看 强烈推荐 五星 --> 情感: 正面

5.3 伯努利朴素贝叶斯 (Bernoulli Naive Bayes)

适用场景:特征是二元值(是/否、有/无、0/1)

不关心词出现了几次,只关心词是否出现。

  特征表示对比:

  句子:"我 喜欢 这部 电影 电影 真的 好看"

  多项式 (Multinomial):  我:1  喜欢:1  这部:1  电影:2  真的:1  好看:1
                          (记录出现次数)

  伯努利 (Bernoulli):    我:1  喜欢:1  这部:1  电影:1  真的:1  好看:1
                          (只记录是否出现,出现就是1)
from sklearn.naive_bayes import BernoulliNB
from sklearn.feature_extraction.text import CountVectorizer

# 使用二值化的特征
vectorizer = CountVectorizer(binary=True)  # binary=True 只记录有无

texts = ["免费 中奖 点击 链接", "会议 明天 下午 三点",
         "恭喜 获奖 领取 优惠", "项目 报告 请查收 附件"]
labels = ['垃圾', '正常', '垃圾', '正常']

X = vectorizer.fit_transform(texts)
model = BernoulliNB()
model.fit(X, labels)

# 预测
test = vectorizer.transform(["免费 领取 优惠券"])
print(f"预测: {model.predict(test)[0]}")  # 垃圾

5.4 三种变体对比

  +----------+------------------+------------------+------------------+
  |          | 高斯 Gaussian    | 多项式 Multinomial| 伯努利 Bernoulli |
  +----------+------------------+------------------+------------------+
  | 特征类型  | 连续数值         | 离散计数          | 二元(0/1)        |
  +----------+------------------+------------------+------------------+
  | 分布假设  | 正态分布         | 多项分布          | 伯努利分布        |
  +----------+------------------+------------------+------------------+
  | 典型场景  | 鸢尾花分类       | 文本分类(词频)     | 文本分类(词有无)   |
  |          | 医学数据         | 垃圾邮件过滤       | 短文本分类         |
  +----------+------------------+------------------+------------------+
  | sklearn  | GaussianNB       | MultinomialNB     | BernoulliNB      |
  +----------+------------------+------------------+------------------+

6. 拉普拉斯平滑

6.1 零概率问题

假设在训练数据中,"退款"这个词从未在正常邮件中出现过:

  P("退款"|正常邮件) = 0 / 5000 = 0

  那么一封包含"退款"的正常邮件的概率:
  P(正常|...) ∝ P(正常) × ... × P("退款"|正常) × ...
              = P(正常) × ... × 0 × ...
              = 0       ← 直接变成零了!不管其他词是什么!

这就是零概率灾难:仅仅因为一个词没见过,整个概率就归零了。

6.2 拉普拉斯平滑的解决方案

  原始公式:
                     count(xi, C)
  P(xi|C) = -------------------------
              count(所有词, C)

  平滑后:
                     count(xi, C) + α
  P(xi|C) = --------------------------------
              count(所有词, C) + α × |V|

  α = 平滑参数(通常取 1)
  |V| = 词表大小(不同词的总数)

直觉理解:相当于给每个词都"预先"加了 α 次出现,确保没有任何词的概率为零。

  没有平滑:                      有平滑 (α=1):

  词     | 计数 | 概率             词     | 计数   | 概率
  -------|------|------            -------|--------|-------
  免费   |  50  | 50/200=0.25     免费   | 50+1   | 51/2100.243
  中奖   |  30  | 30/200=0.15     中奖   | 30+1   | 31/2100.148
  点击   |  20  | 20/200=0.10     点击   | 20+1   | 21/2100.100
  ...    | ...  | ...              ...    | ...    | ...
  退款   |   0  | 0/200=0 !!      退款   |  0+1   | 1/2100.005 (不再为零!)
  总计   | 200  |                  总计   | 200+10 | (假设词表大小=10)

7. 实战案例

7.1 案例一:垃圾邮件过滤(完整版)

from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
import numpy as np

# 模拟数据集
emails = [
    "恭喜您中奖了 点击领取百万大奖",
    "免费赠送 优惠券 限时抢购 点击链接",
    "您的账户异常 请立即点击验证",
    "贷款 低利率 快速放款 无需审核",
    "明天下午三点开会 请准时参加",
    "项目进度报告已发送 请查收邮件",
    "周末团建活动 请大家报名参加",
    "下周一提交季度总结 注意截止时间",
    "免费试用 VIP会员 特价促销",
    "会议室已预定 请准时到达",
    "投资理财 高额回报 稳赚不赔",
    "代码审查完毕 请合并分支",
]
labels = ['垃圾','垃圾','垃圾','垃圾','正常','正常',
          '正常','正常','垃圾','正常','垃圾','正常']

# 特征工程:TF-IDF 向量化
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(emails)
y = np.array(labels)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# 训练朴素贝叶斯
clf = MultinomialNB(alpha=1.0)
clf.fit(X_train, y_train)

# 预测与评估
y_pred = clf.predict(X_test)
print("分类报告:")
print(classification_report(y_test, y_pred))

# 对新邮件进行预测
new_emails = [
    "恭喜获得免费旅游机会 点击领取",
    "请审阅附件中的设计方案"
]
new_X = vectorizer.transform(new_emails)
for email, pred in zip(new_emails, clf.predict(new_X)):
    print(f"'{email}' --> {pred}")

7.2 案例二:医学诊断

from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import cross_val_score
import numpy as np

# 模拟患者数据
# 特征: [体温, 心率, 白细胞计数(万), 血沉]
np.random.seed(42)

# 健康人群
healthy = np.random.randn(100, 4) * [0.3, 5, 0.5, 3] + [36.5, 72, 0.7, 10]
# 感冒患者
cold = np.random.randn(60, 4) * [0.5, 8, 0.8, 5] + [38.0, 85, 1.0, 20]
# 肺炎患者
pneumonia = np.random.randn(40, 4) * [0.4, 10, 1.0, 8] + [39.2, 95, 1.5, 35]

X = np.vstack([healthy, cold, pneumonia])
y = np.array(['健康']*100 + ['感冒']*60 + ['肺炎']*40)

# 交叉验证评估
model = GaussianNB()
scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')
print(f"5折交叉验证准确率: {scores.mean():.3f} (+/- {scores.std():.3f})")

# 训练最终模型
model.fit(X, y)

# 新患者
new_patient = np.array([[38.5, 88, 1.2, 25]])
prediction = model.predict(new_patient)
proba = model.predict_proba(new_patient)
classes = model.classes_

print(f"\n新患者诊断结果: {prediction[0]}")
print("各类别概率:")
for cls, prob in zip(classes, proba[0]):
    print(f"  {cls}: {prob:.4f}")
  诊断决策过程可视化:

  新患者数据: 体温=38.5, 心率=88, 白细胞=1.2, 血沉=25

  计算 P(类别|特征) ∝ P(类别) × P(体温|类别) × P(心率|类别) × ...

  +--------+--------+--------+--------+--------+----------+
  | 类别    | P(类别)| P(体温 | P(心率 | P(白细 | P(血沉   |
  |        | 先验   | |类别)  | |类别)  | 胞|类别)| |类别)   |
  +--------+--------+--------+--------+--------+----------+
  | 健康   | 0.50   | 低     | 中     | 中     | 低       |  --> 综合较低
  | 感冒   | 0.30   | 高     | 高     | 中     | 高       |  --> 综合最高 ★
  | 肺炎   | 0.20   | 中     | 中     | 中     | 中       |  --> 综合中等
  +--------+--------+--------+--------+--------+----------+

  结论: 最可能是感冒

7.3 案例三:新闻分类

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

# 新闻文本数据
news = [
    "国足世界杯预选赛 主场击败对手", "NBA季后赛 湖人险胜勇士",
    "奥运会百米决赛 创造新纪录",
    "央行宣布降息 股市应声上涨", "GDP增长超预期 经济形势向好",
    "房价走势分析 楼市调控政策",
    "新型芯片发布 性能提升显著", "人工智能突破 机器人学会推理",
    "5G网络全面覆盖 速度提升十倍",
]
categories = ['体育','体育','体育','财经','财经','财经','科技','科技','科技']

# 使用 Pipeline 简化流程
pipeline = Pipeline([
    ('tfidf', TfidfVectorizer()),
    ('clf', MultinomialNB(alpha=0.5)),
])

pipeline.fit(news, categories)

# 预测
test_news = ["足球比赛精彩进球", "股票大涨创历史新高", "手机芯片技术创新"]
for text, pred in zip(test_news, pipeline.predict(test_news)):
    print(f"'{text}' --> {pred}")

8. 概率图模型简介

朴素贝叶斯只是概率模型家族中最简单的成员。下面简要介绍更强大的概率图模型。

8.1 什么是概率图模型?

概率图模型用**图(Graph)**来表示变量之间的概率依赖关系。

  概率图模型分类:

  概率图模型
      |
      +-- 有向图模型(贝叶斯网络)
      |     节点之间有方向,表示因果关系
      |     例: 下雨 --> 路滑 --> 摔倒
      |
      +-- 无向图模型(马尔可夫随机场)
            节点之间无方向,表示相关关系
            例: 图像中相邻像素倾向于有相似颜色

8.2 贝叶斯网络 (Bayesian Network)

贝叶斯网络用有向无环图(DAG)表示变量之间的条件依赖关系。

  例:一个简单的医学诊断贝叶斯网络

        [吸烟]         [遗传因素]
          |    \          |
          v     \         v
       [肺癌]    +---> [心脏病]
          |               |
          v               v
       [X光异常]       [心电图异常]
          |               |
          v               v
       [呼吸困难] <------+

  含义:
  - 吸烟 影响 肺癌和心脏病
  - 遗传因素 影响 心脏病
  - 肺癌 导致 X光异常
  - 心脏病 导致 心电图异常
  - X光异常和心电图异常 共同影响 呼吸困难

朴素贝叶斯其实是贝叶斯网络的一个特例

  朴素贝叶斯的网络结构:

              [类别 C]
            /  |  |  \
           v   v  v   v
         [x1] [x2][x3][x4]

  类别是所有特征的唯一父节点
  特征之间没有任何连线(独立假设)

8.3 隐马尔可夫模型 (HMM)

隐马尔可夫模型处理序列数据,包含可观测的状态和隐藏的状态。

  HMM 结构图:

  隐藏状态:   S1 -------> S2 -------> S3 -------> S4
  (看不到)     |           |           |           |
               v           v           v           v
  观测状态:   O1          O2          O3          O4
  (看得到)

  --> 表示转移概率
  |   表示发射概率

生活例子:通过朋友的活动猜测天气

  你有一个外地的朋友,每天告诉你他做了什么(散步/购物/宅家),
  但不告诉你那里的天气。你要根据他的活动推测天气。

  隐藏状态(天气):  晴天 ----> 阴天 ----> 雨天 ----> 晴天
                      |          |          |          |
                      v          v          v          v
  观测状态(活动):  散步       购物       宅家       散步

  转移概率: P(明天天气|今天天气)
  +--------+------+------+------+
  | 今天\明天| 晴天 | 阴天 | 雨天 |
  +--------+------+------+------+
  | 晴天    | 0.6  | 0.3  | 0.1  |
  | 阴天    | 0.3  | 0.4  | 0.3  |
  | 雨天    | 0.2  | 0.3  | 0.5  |
  +--------+------+------+------+

  发射概率: P(活动|天气)
  +--------+------+------+------+
  | 天气\活动| 散步 | 购物 | 宅家 |
  +--------+------+------+------+
  | 晴天    | 0.6  | 0.3  | 0.1  |
  | 阴天    | 0.3  | 0.4  | 0.3  |
  | 雨天    | 0.1  | 0.2  | 0.7  |
  +--------+------+------+------+

HMM 的典型应用:

  • 语音识别:观测=声音信号,隐藏=文字
  • 词性标注:观测=词语,隐藏=词性(名词/动词/形容词...)
  • 基因序列分析:观测=碱基序列,隐藏=基因区域类型

8.4 概率图模型总结

  +------------------+------------------+-------------------------------+
  |      模型         |     核心思想      |         典型应用               |
  +------------------+------------------+-------------------------------+
  | 朴素贝叶斯        | 特征独立假设      | 文本分类、垃圾邮件             |
  +------------------+------------------+-------------------------------+
  | 贝叶斯网络        | 有向图表示因果    | 医学诊断、故障检测             |
  +------------------+------------------+-------------------------------+
  | 隐马尔可夫模型    | 序列中的隐藏状态   | 语音识别、词性标注             |
  +------------------+------------------+-------------------------------+
  | 条件随机场(CRF)   | 无向图+序列标注   | 命名实体识别、图像分割          |
  +------------------+------------------+-------------------------------+
  | 马尔可夫随机场    | 无向图表示相关性   | 图像去噪、纹理分析             |
  +------------------+------------------+-------------------------------+

9. 总结与进阶

9.1 朴素贝叶斯的优缺点

  优点                                缺点
  +-------------------------------+  +-------------------------------+
  | * 训练速度极快 (扫一遍数据)    |  | * 独立假设太强,现实中很少成立  |
  | * 预测速度极快                 |  | * 对特征之间的关联无能为力      |
  | * 小数据集上表现很好           |  | * 概率估计可能不够准确          |
  | * 不容易过拟合                 |  | * 对输入数据的分布有假设        |
  | * 可解释性强                   |  |                               |
  | * 多分类问题天然支持            |  |                               |
  +-------------------------------+  +-------------------------------+

9.2 什么时候用朴素贝叶斯?

  选择决策树:

  你的数据是什么类型?
      |
      +-- 文本数据 -----------> MultinomialNB / BernoulliNB (首选!)
      |
      +-- 连续数值数据 -------> GaussianNB
      |
      +-- 混合类型 -----------> 考虑其他模型(如随机森林)

  你的数据量大小?
      |
      +-- 很小 (几百条) ------> 朴素贝叶斯很合适 (不容易过拟合)
      |
      +-- 中等 (几千条) ------> 朴素贝叶斯仍然是好的基准线
      |
      +-- 很大 (几十万+) -----> 可以尝试更复杂的模型

9.3 完整学习路线

  朴素贝叶斯(你在这里!)
       |
       v
  贝叶斯网络 -------> 因果推断
       |
       v
  隐马尔可夫模型 ----> 序列标注
       |
       v
  条件随机场(CRF) ---> 结构化预测
       |
       v
  变分推断 / MCMC ---> 贝叶斯深度学习

9.4 关键公式速查

  +----------------------------------------------------+
  |  贝叶斯定理                                         |
  |                                                    |
  |              P(B|A) × P(A)                         |
  |  P(A|B) = ------------------                       |
  |                 P(B)                                |
  +----------------------------------------------------+
  |  朴素贝叶斯分类                                     |
  |                         n                           |
  |  y = argmax  P(Ck) ×  ∏  P(xi|Ck)                 |
  |       Ck              i=1                           |
  +----------------------------------------------------+
  |  拉普拉斯平滑                                       |
  |                                                    |
  |              count(xi, C) + α                      |
  |  P(xi|C) = -----------------------                 |
  |             count(all, C) + α|V|                   |
  +----------------------------------------------------+
  |  高斯似然                                           |
  |                   1              (x-μ)²            |
  |  P(x|C) = ------------ exp(- ---------)           |
  |           sqrt(2πσ²)           2σ²                 |
  +----------------------------------------------------+

学习建议:先用 sklearn 跑通上面的代码示例,建立直觉。然后尝试用真实数据集 (如 20 Newsgroups、IMDB 影评数据集)进行练习。理解概率的关键是多做实验, 观察不同参数(如 alpha 值)对结果的影响。


下一章预告:07 - 支持向量机(SVM):在数据中找到最优分割线