HMM 完整推导:前向算法、维特比解码与 Baum-Welch EM

分类: 概率模型 · 难度: 进阶 · 关联讲座: L01

隐马尔可夫模型(Hidden Markov Model, HMM)是统计 NLP 时代最核心的序列建模工具之一,在词性标注、命名实体识别、语音识别等任务中有着广泛应用。HMM 通过引入”隐状态”来建模序列中不可直接观测的结构(如词性标签),并在马尔可夫假设下实现高效推断。本文完整推导 HMM 的三大核心算法:前向算法(评估)、维特比算法(解码)和 Baum-Welch 算法(学习),并附带手算示例帮助建立直觉。

📐 隐马尔可夫模型(HMM)——序列标注的数学基础

HMM 是这个时代词性标注(POS tagging)的主力模型。一个 HMM 由五元组 λ=(S,V,π,A,B)\lambda = (S, V, \pi, A, B) 定义:

  • S={s1,,sK}S = \{s_1, \ldots, s_K\}:隐状态集合(如词性标签:N, V, Det, Adj, …)
  • V={v1,,vM}V = \{v_1, \ldots, v_M\}:观测符号集合(词汇表)
  • πi=P(t1=si)\pi_i = P(t_1 = s_i)初始状态概率
  • Aij=P(tn+1=sjtn=si)A_{ij} = P(t_{n+1} = s_j | t_n = s_i)转移概率矩阵K×KK \times K
  • Bj(w)=P(wt=sj)B_j(w) = P(w | t = s_j)发射概率(每个状态对词汇表的分布)

联合概率(一阶马尔可夫假设 + 输出独立假设): P(w,t)=πt1i=1TBti(wi)i=2TAti1,tiP(\mathbf{w}, \mathbf{t}) = \pi_{t_1} \cdot \prod_{i=1}^{T} B_{t_i}(w_i) \cdot \prod_{i=2}^{T} A_{t_{i-1}, t_i}

HMM 的三个核心问题

问题算法复杂度用途
评估:P(wλ)P(\mathbf{w} \| \lambda)前向算法O(TK2)O(TK^2)语言模型评分
解码:argmaxtP(tw)\arg\max_\mathbf{t} P(\mathbf{t} \| \mathbf{w})维特比算法O(TK2)O(TK^2)词性标注
学习:argmaxλP(wλ)\arg\max_\lambda P(\mathbf{w} \| \lambda)Baum-Welch (EM)O(ITK2)O(ITK^2)参数估计

📐 前向算法——高效计算观测序列概率

问题:直接枚举所有 KTK^T 条路径求 P(w)P(\mathbf{w}) 是不可行的。前向算法用动态规划将复杂度降到 O(TK2)O(TK^2)

定义前向变量αt(j)=P(w1,w2,,wt,tt=sjλ)\alpha_t(j) = P(w_1, w_2, \ldots, w_t, t_t = s_j | \lambda)

第 1 步:初始化(t=1t=1α1(j)=πjBj(w1),j=1,,K\alpha_1(j) = \pi_j \cdot B_j(w_1), \quad j = 1, \ldots, K

直觉:时刻 1 处于状态 jj 并发射 w1w_1 的联合概率

第 2 步:递推(t=2,,Tt = 2, \ldots, Tαt(j)=[i=1Kαt1(i)Aij]Bj(wt)\alpha_t(j) = \left[\sum_{i=1}^{K} \alpha_{t-1}(i) \cdot A_{ij}\right] \cdot B_j(w_t)

所有可能的前驱状态 ii 的概率累加后,乘以当前发射概率

第 3 步:终止 P(wλ)=j=1KαT(j)P(\mathbf{w} | \lambda) = \sum_{j=1}^{K} \alpha_T(j)

后向算法类似,定义 βt(i)=P(wt+1,,wTtt=si,λ)\beta_t(i) = P(w_{t+1}, \ldots, w_T | t_t = s_i, \lambda),从 TT11 递推。前向和后向变量共同用于 Baum-Welch 参数学习。

📐 维特比算法——最优路径解码

目标:找到使 P(tw)P(\mathbf{t} | \mathbf{w}) 最大的标注序列。

定义维特比变量δt(j)=maxt1,,tt1P(t1,,tt1,tt=sj,w1,,wt)\delta_t(j) = \max_{t_1, \ldots, t_{t-1}} P(t_1, \ldots, t_{t-1}, t_t = s_j, w_1, \ldots, w_t)

第 1 步:初始化 δ1(j)=πjBj(w1),ψ1(j)=0\delta_1(j) = \pi_j \cdot B_j(w_1), \quad \psi_1(j) = 0

第 2 步:递推(与前向唯一区别:max\sum \to \maxδt(j)=max1iK[δt1(i)Aij]Bj(wt)\delta_t(j) = \max_{1 \le i \le K} \left[\delta_{t-1}(i) \cdot A_{ij}\right] \cdot B_j(w_t) ψt(j)=argmax1iK[δt1(i)Aij]\psi_t(j) = \arg\max_{1 \le i \le K} \left[\delta_{t-1}(i) \cdot A_{ij}\right]

ψt(j)\psi_t(j) 记录回溯指针:状态 jj 在时刻 tt 的最优前驱

第 3 步:终止 + 回溯 tT=argmaxjδT(j),tt=ψt+1(tt+1)(t=T1,,1)t_T^* = \arg\max_j \delta_T(j), \quad t_t^* = \psi_{t+1}(t_{t+1}^*) \quad (t = T{-}1, \ldots, 1)

实践注意:实际实现中使用 log 概率避免浮点下溢:logδt(j)=maxi[logδt1(i)+logAij]+logBj(wt)\log\delta_t(j) = \max_i[\log\delta_{t-1}(i) + \log A_{ij}] + \log B_j(w_t)

📐 Baum-Welch 算法(EM)——无监督参数学习

当没有标注数据时(只有句子,没有词性标签),用 EM 算法迭代估计 HMM 参数。

定义辅助变量

ξt(i,j)=P(tt=si,tt+1=sjw,λ)=αt(i)AijBj(wt+1)βt+1(j)P(wλ)\xi_t(i,j) = P(t_t = s_i, t_{t+1} = s_j | \mathbf{w}, \lambda) = \frac{\alpha_t(i) \cdot A_{ij} \cdot B_j(w_{t+1}) \cdot \beta_{t+1}(j)}{P(\mathbf{w}|\lambda)}

γt(i)=P(tt=siw,λ)=j=1Kξt(i,j)=αt(i)βt(i)P(wλ)\gamma_t(i) = P(t_t = s_i | \mathbf{w}, \lambda) = \sum_{j=1}^{K} \xi_t(i,j) = \frac{\alpha_t(i) \cdot \beta_t(i)}{P(\mathbf{w}|\lambda)}

E 步:用当前参数计算 ξt(i,j)\xi_t(i,j)γt(i)\gamma_t(i)

M 步:重估参数(最大化期望似然)

π^i=γ1(i)(初始状态概率)\hat{\pi}_i = \gamma_1(i) \qquad \text{(初始状态概率)}

A^ij=t=1T1ξt(i,j)t=1T1γt(i)(转移概率:从 i 转到 j 的期望次数 / 从 i 出发的总次数)\hat{A}_{ij} = \frac{\sum_{t=1}^{T-1} \xi_t(i,j)}{\sum_{t=1}^{T-1} \gamma_t(i)} \qquad \text{(转移概率:从 $i$ 转到 $j$ 的期望次数 / 从 $i$ 出发的总次数)}

B^j(vk)=t=1,wt=vkTγt(j)t=1Tγt(j)(发射概率:在状态 j 发射 vk 的期望次数 / 处于 j 的总次数)\hat{B}_j(v_k) = \frac{\sum_{t=1, w_t=v_k}^{T} \gamma_t(j)}{\sum_{t=1}^{T} \gamma_t(j)} \qquad \text{(发射概率:在状态 $j$ 发射 $v_k$ 的期望次数 / 处于 $j$ 的总次数)}

收敛保证:EM 保证每次迭代 P(wλ)P(\mathbf{w}|\lambda) 单调不减,但只收敛到局部最优——初始化很重要。

🔢 数值计算示例:维特比解码手算

设定:一个极简 HMM 做词性标注

  • 隐状态 S={N(名词),V(动词)}S = \{\text{N(名词)}, \text{V(动词)}\}
  • 句子:w=[fish,sleep]\mathbf{w} = [\text{fish}, \text{sleep}]

参数:

π\piA(N)A(\cdot \to \text{N})A(V)A(\cdot \to \text{V})B(,fish)B(\cdot, \text{fish})B(,sleep)B(\cdot, \text{sleep})
N0.60.30.70.80.2
V0.40.60.40.30.7

计算

t=1t=1,观测 “fish”:

  • δ1(N)=πNBN(fish)=0.6×0.8=0.48\delta_1(\text{N}) = \pi_\text{N} \cdot B_\text{N}(\text{fish}) = 0.6 \times 0.8 = 0.48
  • δ1(V)=πVBV(fish)=0.4×0.3=0.12\delta_1(\text{V}) = \pi_\text{V} \cdot B_\text{V}(\text{fish}) = 0.4 \times 0.3 = 0.12

t=2t=2,观测 “sleep”:

  • δ2(N)=max(0.48×0.3, 0.12×0.6)×BN(sleep)\delta_2(\text{N}) = \max(0.48 \times 0.3,\ 0.12 \times 0.6) \times B_\text{N}(\text{sleep}) =max(0.144,0.072)×0.2=0.144×0.2=0.0288= \max(0.144, 0.072) \times 0.2 = 0.144 \times 0.2 = 0.0288,回溯 → N
  • δ2(V)=max(0.48×0.7, 0.12×0.4)×BV(sleep)\delta_2(\text{V}) = \max(0.48 \times 0.7,\ 0.12 \times 0.4) \times B_\text{V}(\text{sleep}) =max(0.336,0.048)×0.7=0.336×0.7=0.2352= \max(0.336, 0.048) \times 0.7 = 0.336 \times 0.7 = 0.2352,回溯 → N

回溯t2=Vt_2^* = \text{V}(0.2352 > 0.0288),ψ2(V)=N\psi_2(\text{V}) = \text{N},所以 t1=Nt_1^* = \text{N}

最优标注:fish/N sleep/V ✓(名词”鱼” + 动词”睡觉”,语义正确!)

观察:即使 “fish” 可以是名词也可以是动词(“to fish”),HMM 通过转移概率 A(NV)=0.7A(\text{N} \to \text{V}) = 0.7(名词后跟动词是常见模式)正确消歧。

💡 为什么 HMM 有效?

HMM 之所以在词性标注等任务上表现出色,根本原因在于词性标注本质上有强烈的局部依赖:“形容词后面大概率跟名词”这种模式,bigram 转移矩阵就能捕捉。HMM 用 O(TK2)O(TK^2) 时间处理了”序列中每个位置选择最优标签”这个组合爆炸问题(暴力法 O(KT)O(K^T))。

⚠️ 常见误区

  1. 误区:这个时代没有”学习”,全是手工规则 → 正确:HMM 的概率参数是从语料库统计的(有学习),PCFG 的规则概率也是从 Penn Treebank 估计的。区别在于特征工程是手工的,而非端到端学习。
  2. 误区:HMM 的维特比算法和前向算法是一回事 → 正确:前向算法求所有路径的概率之和\sum),维特比求最优路径max\max),递推结构相同但语义完全不同。

🔗 知识关联

  • HMM → CRF(L03 神经网络):CRF 是 HMM 的判别式推广——HMM 建模 P(w,t)P(\mathbf{w}, \mathbf{t})(生成式),CRF 直接建模 P(tw)P(\mathbf{t} | \mathbf{w})(判别式),可以使用任意特征函数,不受独立性假设限制。
  • 前向-后向算法 → Transformer 注意力:前向-后向本质是”每个位置综合过去和未来的信息”——BERT 的双向注意力可以看作这个思想的神经网络版本。