查看全课大纲(第 56 / 82 节)
  1. 1.函数与数据泛化
  2. 2.向量:从几何直觉到高维空间
  3. 3.矩阵与张量
  4. 4.特征值与特征向量:矩阵变换的不动方向
  5. 5.凸函数:从向量求导的矩阵记号到好优化的函数形状
  6. 6.概率与统计:机器学习的数学基础
  7. 7.独立性与随机变量:贝叶斯公式与二项分布
  8. 8.期望、方差与协方差:随机变量的数字画像
  9. 9.联合概率:当一条轴不够用的时候
  10. 10.概率分布(一):从伯努利到伽马函数
  11. 11.概率分布(二):贝塔、泊松、正态与两个贝叶斯故事
  12. 12.机器学习的模型:找输入与输出的关系
  13. 13.机器学习的应用
  14. 14.过拟合
  15. 15.机器学习的分类
  16. 16.有监督学习:从房价预测说起
  17. 17.损失函数
  18. 18.梯度下降(上):更新规则与学习速率
  19. 19.梯度下降(2)
  20. 20.牛顿方法
  21. 21.KNN简介
  22. 22.距离测算
  23. 23.朴素贝叶斯
  24. 24.朴素贝叶斯的实际应用
  25. 25.信息熵:决策树构建的度量基础
  26. 26.信息增益与决策树的构建
  27. 27.ID3算法
  28. 28.决策树节点的划分
  29. 29.CART树
  30. 30.Bagging
  31. 31.Boosting:自适应提升算法
  32. 32.Gradient Boosting
  33. 33.线性模型:回归与分类的同一副骨架
  34. 34.最小二乘:把最优参数直接解出来
  35. 35.最小二乘法的几何与概率视角
  36. 36.极大似然:给最小二乘一个概率出身
  37. 37.逻辑回归(1):把线性模型接到分类上
  38. 38.逻辑回归(2):损失函数与多分类
  39. 39.---- 手造数据: 5 个样本, 2 个特征; x2 几乎 = 2*x1 (偏差手工指定, 无随机) ----
  40. 40.讲师例: 向量 "23014" -- 三把范数尺子量同一个向量
  41. 41.优化方法(1):坐标下降与前向选择
  42. 42.优化方法(2):前向策略与最小角回归
  43. 43.拉格朗日乘子法(1):从无约束到等式约束
  44. 44.拉格朗日乘子法(2):等式约束下的平行条件与拉格朗日函数
  45. 45.拉格朗日乘子法(3):不等式约束与 KKT 条件
  46. 46.最大间隔:把分类问题变成优化问题
  47. 47.拉格朗日对偶问题:把 w 和 b 全部换成 α
  48. 48.支持向量:边界上的少数派
  49. 49.SVM 计算过程:一笔到底算完,再走进核方法
  50. 50.贝叶斯公式:概率即信念
  51. 51.隐含变量和概率模型:给看不见的原因建模
  52. 52.EM 算法:期望与最大化的迭代
  53. 53.琴生不等式:EM 的数学钥匙
  54. 54.三个硬币问题:EM 的复盘与衔接
  55. 55.高斯混合模型:用隐变量解释双峰数据
  56. 56.隐马尔可夫模型
  57. 57.隐马尔可夫模型(2):前向算法与动态混合模型
  58. 58.隐马尔可夫模型在 NLP 中的运用
  59. 59.EM 算法:把「为什么收敛」推到底
  60. 60.HMM 在 NLP 中的运用:从分词到机器翻译
  61. 61.HMM 参数估计:Baum-Welch 的三块拉格朗日
  62. 62.高维下的高斯模型
  63. 63.主题模型:从词袋到隐含主题
  64. 64.Dirichlet 分布(1)
  65. 65.Dirichlet 分布(2)
  66. 66.统计学习内容回顾
  67. 67.K-means 算法
  68. 68.PCA 降维
  69. 69.SVD 降维
  70. 70.从聚类到流形
  71. 71.局部线性嵌入
  72. 72.随机邻域嵌入:SNE 与 t-SNE
  73. 73.无参模型:让数据自己说话
  74. 74.高斯过程:函数空间里的正态分布
  75. 75.高斯过程(2):噪声、正则化与核的线性组合
  76. 76.神经网络简介:从感知器到自编码器
  77. 77.反向传播:把误差一层层传回去
  78. 78.卷积神经网络(CNN):让特征自己学出来
  79. 79.循环神经网络(RNN):给网络装上记忆
  80. 80.深度学习回顾:静态一类,动态一类
  81. 81.增强学习(1):蒙特卡洛、树搜索与 Q-learning
  82. 82.强化学习(2):从乌鸦吃核桃到井字棋的 value 回传

隐马尔可夫模型

约 31 分钟

📺 正在播放小象官方高清录播(支持倍速与清晰度调节)

小象实战讲义 · 机器学习算法精讲

第 12~13 章的三硬币、EM、GMM 处理的都是「静态」的隐含变量:每一次掷硬币用 B 还是 C、每个数据点来自哪个高斯分量,彼此独立、互不相关。这一节讲师还是从掷硬币开场:「我给大家呢再说一件事情,还是掷硬币。但这个硬币呢就跟以前不一样了,变得更复杂了。」复杂在哪?隐含状态自己会随时间演化——上一次掷出 B 会影响下一次掷谁。把静态混合模型加上状态之间的「接力」,就得到隐马尔可夫模型(Hidden Markov Model,HMM)。

💡 核心导读

  • 记号交接:隐含变量从 zz 换成 qq、观测记作 yy;HMM 部分全用下角标表示时间——Notation 是为内容服务的。
  • 从静态到动态:假设「下一次的状态与前一次相关」,隐含状态就连成一条马尔可夫链;这就是 HMM 名字的由来。
  • 模型三要素:π\pi(初始状态分布)、AA(状态转移矩阵)、BB(释放概率矩阵)——与前两章的隐含变量模型相比,唯一的增量就是 AA。
  • 联合概率:把图模型上每条箭头翻译成一个条件概率再连乘:P(Q,Y)=π(q0)⋅∏A⋅∏BP(Q,Y) = \pi(q_0) \cdot \prod A \cdot \prod B。
  • 两个例子:天气-活动(阴晴决定三件事)、盒子-小球(三箱取红白球)——后者的参数会一直沿用到下一节。

从掷硬币到动态隐含模型

回顾三硬币:掷硬币 A,正面用硬币 B、反面用硬币 C 去生成观测。本节起做一次记号交接——隐含变量不再叫 zz,改叫 qq:qq 代表状态,取值 BB 或 CC;观测 yy 取值 HH 或 TT。讲师特意交代了记号约定:

HMM 这部分我都是用下角标描述的(q0,q1,…q_0, q_1, \dots)。如果大家觉得这件事很别扭,那我们就一样了——数学的 Notation 和里边所用的东西,都是为了你这件事服务的。公式本身也不见得一定有这一种写法;想表述什么东西,Notation 都是可以自己去定的,描述清楚就可以了。

先确认一件「我们已经会的事」:yy 和 qq 之间的关系是可算的。给定 q=Bq = B,观测服从伯努利分布:

P(y∣q=B)=py(1−p)1−yP(y \mid q=B) = p^{y}(1-p)^{1-y}

y=1y=1 时是 pp、y=0y=0 时是 1−p1-p;换成硬币 C 同理用 qq 参数。把「B 或 C」与「H 或 T」排成一张小表,每个格子都算得出来——这部分生成概率,静态模型里早就有。

现在加一个新假设(讲师原话):「如果我掷的这次是硬币 B,我下一次掷硬币 B 或者 C 的概率,是跟前一次相关的。」 也就是每次掷的结果之间在时间上有关联——这就构造出了一个动态的隐含模型。「动态」指的就是跟时间 tt 相关。这种情况叫一条马尔可夫链(Markov Chain):一串变量里,xtx_t 与 xt−1x_{t-1} 之间相关,当前的状态跟前面的状态直接相关。

用字词预测理解马尔可夫性

讲师举的例子是自然语言。我写了一个字「我」——下一个字是什么?再来:「我爱」后面接一个字,你猜什么?最后:「我喝」后面接什么?

  • 只有「我」时,可能接「爱」「喝」等,各有概率;
  • 前面是「我爱」时,接「你」的概率会远远大于其他字;
  • 前面是「我喝」时,一般接「水」,不会是「我喝吃」「我喝电」这种奇怪的话。

某个字出现的概率跟它前面的字相关——这就是马尔可夫性。还有一个极端情形值得停一下:如果只有一个字、前面没有任何信息呢? 那这个字的分布就是我们所有词的先验概率 P(w)P(w)。把所有中文词从字典的第一个字排到最后一个字,用一个特别大的语料库——比如说大概 50 年的《人民日报》——看每一个词出现的频率,你会发现空着的位置上概率最大的可能是「的」「了」这类语气助词,因为它们在整个语料里出现得最多。

诚实地说一句:掷硬币其实是这个例子里比较「牵强」的例子——大家都认为掷硬币是独立事件,这一次的结果与前一次没有关系。但正是「假设它们有关联」这一步,把独立的三硬币升级成了有结构的链。隐含状态(qq)之间构成马尔可夫链,所以这个模型叫隐马尔可夫模型(Hidden Markov Model)。

画法约定:空心圈与阴影圈

图模型上,每个节点是一个变量,画法有讲究:

  • 隐含变量(不能被观察到)画空白的圈;
  • 可观测变量(直接有值)画阴影的圈。

HMM 的图是两条平行的链:上面一排空心圈 q0→q1→q2→⋯→qTq_0 \to q_1 \to q_2 \to \dots \to q_T(状态之间的箭头就是转移),每个圈下面挂一个阴影圈 yty_t(状态「释放」出观测)。讲师还专门交代了一个细节:q0q_0 单独画出来是有好处的——它头上没有转移进来的箭头,控制它的是 π\pi,就是给最开始的状态一个初始的选择;之后 y0,y1,y2y_0, y_1, y_2 才一个接一个地生成出来。

一个更「正常」的例子:天气与活动

为了让大家对 HMM 更有感觉,讲师换了一个听起来更正常的例子。天气有两种状况:rainy(下雨) 和 sunny(晴天)。每天我们做三件事之一:shop(购物)、clean(在家打扫卫生)、walk(散步)。

天气影响做事的概率(释放概率):

  • 晴天:walk 的概率 0.70.7,shop 的概率 0.20.2,clean 的概率 0.10.1——「听起来很 make sense,还是可以的」;
  • 雨天:walk 的概率 0.20.2,shop 的概率 0.30.3,clean 的概率 0.50.5——下雨天在家什么都不做、打扫卫生的概率最高。

第一天还必须指定一个先验概率(start)。讲师边写边自我修正:先说「大概 0.4 是阴天」,随即改口「这个听起来阴天没有那么多,0.2 吧是下雨,0.8 是晴天」。

最后加上动态部分——今天的天气影响明天:

  • 今天下雨,明天继续下雨的概率 0.60.6;今天下雨、明天转晴的概率 0.40.4(「因为它必须相加为一」);
  • 今天晴天,明天仍然晴天的概率 0.80.8(讲师先说 0.7,又改成「就 0.8 吧,晴天都是接在一起的」);今天晴天、明天下雨的概率 0.20.2。

这套系统怎么用?讲师给了一个场景:假设你有一个好朋友住在另一个国家,他每天告诉你「我今天打扫卫生了」「我去 shopping 了」「我去散步了」……而你从不知道那个国家的天气。你看到的是一串观测,比如 clean、shopping、shopping、shopping、clean、walk、walk……这时你自然会问:他下一次出现做什么事的概率最大? 这就需要学出上面这些参数,使它们在最大程度上拟合这串数据、得到最大似然值——「如何训练一个隐马尔可夫链的问题就出来了」。

HMM 的参数:π\pi、AA、BB

现在把天气例子形式化。一个完整的 HMM 由三组参数 λ=(A,B,π)\lambda = (A, B, \pi) 定义。

状态转移矩阵 AA(transition matrix / transitional probability,转移概率):

A=[0.80.20.40.6]A = \begin{bmatrix} 0.8 & 0.2 \\ 0.4 & 0.6 \end{bmatrix}

行是今天的 sunny/rainy,列是明天的 sunny/rainy:A11=0.8A_{11} = 0.8 是晴天接晴天,A12=0.2A_{12} = 0.2 是晴天转下雨。注意下标的含义:AA 的两个下标写的是 qtq_t 和 qt+1q_{t+1}——tt 与 t+1t+1 代表的是不同的时刻,qq 本身取 sunny 或 rainy。如果你觉得用 i,ji, j 别扭,直接读成「tt 时刻的状态到 t+1t+1 时刻的状态」就好。

释放概率矩阵 BB(也有人叫生成概率):给定状态,生成观测的概率。

B=[0.10.20.70.50.30.2]B = \begin{bmatrix} 0.1 & 0.2 & 0.7 \\ 0.5 & 0.3 & 0.2 \end{bmatrix}

行是晴天/雨天,列是 clean、shopping、walk。下标同样是双重的:Bqt, ytB_{q_t,\, y_t},其中 qtq_t 属于 sunny 或 rainy,yty_t 属于 clean、shopping、walk。记号上有个小细节:shopping 缩写成 sh,免得跟 sunny 的 s 搞混。tt 从 0 开始,1,2,…1, 2, \dots 一直到 TT,代表不同的时间段。

初始状态分布 π\pi:0.20.2 下雨、0.80.8 晴天。只有两个状态时就是 π\pi 与 1−π1-\pi;状态多的时候则是 π1,π2,π3,…\pi_1, \pi_2, \pi_3, \dots 每个状态一个先验。

与前两章的模型差在哪

讲师把这笔账算得很清楚:隐马尔可夫链和普通的隐含变量模型,差就差在了 AA 的部分上。

  • π\pi 一直都有的——你最开始的先验部分;
  • BB 刚才的模型里也是有的——给定了状态就生成观测。状态可以是第一个高斯、第二个高斯(GMM),可以是第一个硬币、第二个硬币(三硬币),也可以是下雨天、晴天(HMM);有了状态做的事,分别是从高斯里采出一个连续数据、掷出正面或反面、去做 clean/shop/walk。
  • AA 是新东西:状态之间不再独立,而是随时间转移。

所以给定观测序列 yy,我们想求 P(Y∣A,B,π)P(Y \mid A, B, \pi)——这是一个比较复杂的动态模型,需要对它建模和理解。

联合概率:把箭头翻译成乘积

生成模型的老问题:求 QQ 和 YY 的联合概率(大 QQ 代表所有 qq 的集合,大 YY 代表所有 yy 的集合)。先复习一个小工具:两个变量的联合概率怎么拆?

P(x,y)=P(y∣x)⋅P(x)P(x, y) = P(y \mid x) \cdot P(x)

xx 是 yy 的条件,联合概率就等于条件乘先验。图模型上,每一个箭头所指的方向,就是一个条件概率——把链上所有箭头逐一翻译、连乘即可:

  1. 初始:P(q0)=π(q0)P(q_0) = \pi(q_0);
  2. 状态转移(沿上面的链):∏t=0T−1P(qt+1∣qt)\prod_{t=0}^{T-1} P(q_{t+1} \mid q_t),即一连串 AA;
  3. 释放(沿每个状态垂下的箭头):∏t=0TP(yt∣qt)\prod_{t=0}^{T} P(y_t \mid q_t),即一连串 BB。

P(Q,Y∣λ)=π(q0)⋅∏t=0T−1Aqt, qt+1⋅∏t=0TBqt, ytP(Q, Y \mid \lambda) = \pi(q_0) \cdot \prod_{t=0}^{T-1} A_{q_t,\, q_{t+1}} \cdot \prod_{t=0}^{T} B_{q_t,\, y_t}

讲师板书时用三种颜色区分这三部分(初始一项、转移一串、释放一串)——公式的结构完全对应图的结构。第 13 章课件(Note_21)上写的也是同一形式:π(q0)\pi(q_0) 是 prior probability,转移乘积是 transitional probability,释放乘积是 emission probability。

示例:盒子与小球

讲师用一个可以动手算的例子收尾。有三个盒子(三个状态),每个盒子里装着红色和白色两种小球,比例各不相同。实验流程:

  1. 最开始根据先验概率 π\pi 选一个盒子;
  2. 从当前盒子里取出一个小球,记录颜色;
  3. 根据转移概率 AA,从当前盒子转移到下一个盒子;
  4. 回到第 2 步,继续取球。

一句话记住分工(讲师原话):「箱子之间是转移概率,球和箱子之间是释放概率。」

参数(讲师逐个口播,全部有据):

  • π=(0.2,0.4,0.4)\pi = (0.2, 0.4, 0.4):最开始选盒 1、盒 2、盒 3 的概率;
  • 转移矩阵(行是当前盒子,列是下一个盒子):

A=[0.50.30.20.20.50.30.30.20.5]A = \begin{bmatrix} 0.5 & 0.3 & 0.2 \\ 0.2 & 0.5 & 0.3 \\ 0.3 & 0.2 & 0.5 \end{bmatrix}

检算一下读法:第一次拿盒 2、下一次拿盒 3 的概率是 A23=0.3A_{23} = 0.3——「第二个箱子,它下一次是第三个箱子,就是 0.3」。

  • 释放矩阵(行是盒子,列是红、白):

B=[0.50.50.40.60.70.3]B = \begin{bmatrix} 0.5 & 0.5 \\ 0.4 & 0.6 \\ 0.7 & 0.3 \end{bmatrix}

第三个盒子里大部分是红球,第二个盒子里 60% 是白球,第一个盒子里红白各一半。

现在假设我们看到了「红、白、红」这个观测序列——想知道生成这样一个序列的概率到底有多大、似然函数怎么算。视频到这里戛然而止,把计算方法留给了下一节。讲义先演示前半步:如果状态序列也已知(假设路径 盒2 → 盒3 → 盒1),联合概率 P(Q,Y∣λ)P(Q, Y \mid \lambda) 怎么算——这正是上面公式的直接实例:

import math

# HMM 参数 λ = (A, B, pi):三个盒子(隐状态),红/白两种小球(观测)
pi = [0.2, 0.4, 0.4]          # π:第一次选盒 1/2/3 的先验概率

# A[i][j]:这一次在盒子 i,下一次转到盒子 j 的转移概率
A = [
    [0.5, 0.3, 0.2],          # 盒子1 → (盒1, 盒2, 盒3)
    [0.2, 0.5, 0.3],          # 盒子2 → (盒1, 盒2, 盒3)
    [0.3, 0.2, 0.5],          # 盒子3 → (盒1, 盒2, 盒3)
]

# B[i][k]:在盒子 i 取出(红, 白)的概率
B = [
    [0.5, 0.5],               # 盒子1:红白各一半
    [0.4, 0.6],               # 盒子2:40% 红,60% 白
    [0.7, 0.3],               # 盒子3:大部分是红球
]

# 状态序列与观测序列(状态路径为讲义设定的演示;观测 = 红、白、红)
Q = [1, 2, 0]                 # 盒2 → 盒3 → 盒1
Y = [0, 1, 0]                 # 0=红,1=白

# P(Q,Y|λ) = π(q0) · ∏转移 · ∏释放,六个因子逐个收集
factors = [pi[Q[0]]]                          # 初始:π
for t in range(len(Q)):
    factors.append(B[Q[t]][Y[t]])             # 释放:当前盒子掷出当前颜色
    if t < len(Q) - 1:
        factors.append(A[Q[t]][Q[t + 1]])    # 转移:换到下一个盒子

print("逐因子:", " x ".join(f"{f:.1f}" for f in factors))
prob = 1.0
for f in factors:
    prob *= f
print(f"联合概率 P(Q,Y|lambda) = {prob:.6f}")
print(f"对数值 log(P) = {math.log(prob):.6f}")
逐因子: 0.4 x 0.4 x 0.3 x 0.3 x 0.3 x 0.5
联合概率 P(Q,Y|lambda) = 0.002160
对数值 log(P) = -6.137647

手算对账(六个因子一一对应):初始在盒 2 的概率 π2=0.4\pi_2 = 0.4;盒 2 出红球 B2,红=0.4B_{2,\text{红}} = 0.4;盒 2 转盒 3 的概率 A23=0.3A_{23} = 0.3;盒 3 出白球 B3,白=0.3B_{3,\text{白}} = 0.3;盒 3 转盒 1 的概率 A31=0.3A_{31} = 0.3;盒 1 出红球 B1,红=0.5B_{1,\text{红}} = 0.5。连乘 0.4×0.4×0.3×0.3×0.3×0.5=0.002160.4 \times 0.4 \times 0.3 \times 0.3 \times 0.3 \times 0.5 = 0.00216,与程序输出一致。

但要注意:现实中状态序列 QQ 是隐藏的、未知的。我们真正要算的是对所有可能的盒子路径求和后的 P(Y∣λ)P(Y \mid \lambda)——三个时刻、三个盒子,有 33=273^3 = 27 种路径组合,一条条硬算当然算得出来,但是「不是(不可)算」的量级。怎么把它算得聪明?这正是下一节前向-后向算法要解决的问题。

📝 动手练一练

  1. 概念辨析:隐马尔可夫模型(HMM)与高斯混合模型(GMM)在「隐含变量」这个概念上有何共同点?最主要的区别是什么?
👉 点击查看参考答案

共同点:两者都引入隐含变量来解释观测的生成过程(HMM 中是状态 qtq_t,GMM 中是分量归属),并且给定隐含变量后,观测的条件分布是已知的(伯努利、高斯等),先验部分也都是一开始就有的 π\pi(GMM 的混合权重、HMM 的初始分布)。

主要区别:GMM 的每个数据点的隐含变量是独立同分布的,彼此之间没有任何依赖;HMM 为隐含状态引入了时间上的马尔可夫依赖——当前状态 qtq_t 依赖于前一个状态 qt−1q_{t-1},由转移矩阵 AA 刻画。用本节的话说:两者差就差在 AA 上。所以 GMM 适合独立数据点的聚类,HMM 适合序列数据。

  1. 概率计算:盒子-小球模型中,观测序列改为 Y=(红,红,红)Y = (\text{红}, \text{红}, \text{红})(三次都是红球),状态路径不变(盒2 → 盒3 → 盒1)。请手算新的联合概率,并修改上面代码中的 Y 验证。
👉 点击查看参考答案

手算:初始 π2=0.4\pi_2 = 0.4;盒 2 出红 0.40.4;转盒 3 的 A23=0.3A_{23} = 0.3;盒 3 出红 0.70.7(只有这一步变了——盒 3 红多白少);转盒 1 的 A31=0.3A_{31} = 0.3;盒 1 出红 0.50.5:

0.4×0.4×0.3×0.7×0.3×0.5=0.005040.4 \times 0.4 \times 0.3 \times 0.7 \times 0.3 \times 0.5 = 0.00504

把代码中 Y 改为 [0, 0, 0] 后运行:

逐因子: 0.4 x 0.4 x 0.3 x 0.7 x 0.3 x 0.5
联合概率 P(Q,Y|lambda) = 0.005040
对数值 log(P) = -5.290349

与手算一致。由于盒子 3 出红的概率(0.7)高于出白(0.3),第三个观测从白变红后,整条路径的联合概率从 0.00216 升到 0.00504。

本章小结

本节从掷硬币出发,把静态的隐含变量模型升级为隐马尔可夫模型:假设隐含状态之间有时间上的关联(当前状态依赖前一个状态),状态就连成一条马尔可夫链——空心圈画隐含状态、阴影圈画可观测变量,箭头逐一翻译成条件概率。HMM 由三组参数定义:初始分布 π\pi、状态转移矩阵 AA、释放概率矩阵 BB;与三硬币、GMM 相比,唯一的增量是 AA。联合概率按「初始一项、转移一串、释放一串」三部分连乘:P(Q,Y)=π(q0)⋅∏A⋅∏BP(Q,Y) = \pi(q_0) \cdot \prod A \cdot \prod B,并用盒子-小球例子把它算了一遍。视频在本节末尾留下的问题——状态序列未知时如何求 P(Y)P(Y)——正是下一节前向-后向算法的入口。

📋 行动清单

  • 默写 HMM 三参数(π,A,B\pi, A, B)的定义与物理含义,并指出与前两章静态混合模型相比唯一的增量。
  • 盒子-小球例子:换一条状态路径(比如 盒1 → 盒1 → 盒3)手算联合概率,再用本节代码验证。
  • 回到「好朋友在国外」的天气例子:列出你需要学习的全部参数;想一想观测序列到手之后,你希望模型回答什么问题。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第13章笔记:期望最大化(EM)算法
    下载