1. 问题背景与定位
在初识隐马尔可夫模型中,我们已经知道一个完整的隐马尔可夫模型 (HMM) 由三要素 λ=(A,B,π) 定义。现在,我们面临 HMM 的第一个核心问题:评估 (Evaluation)。
评估问题描述:给定一个 HMM 模型 λ=(A,B,π) 和一个观测序列 O=(o1,o2,…,oT),我们如何计算这个模型产生出该特定观测序列的概率 P(O∣λ)?
例如,在语音识别中,我们有两个 HMM 模型:λ你好 和 λ再见。当系统接收到一段语音(观测序列 O)时,我们可以分别计算 P(O∣λ你好) 和 P(O∣λ再见)。哪个概率更高,就说明这段语音更可能对应哪个词语。因此,高效计算 P(O∣λ) 是许多 HMM 应用的基础。
接下来,我们将探索解决这个问题的三种方法:从最直观但最笨拙的“直接计算法”,到作为标准解决方案的“前向算法”与“后向算法”。
2. 直接计算法
2.1 直观理解
最符合直觉的方法是什么?就是把所有可能发生的情况都列出来,计算每一种情况的概率,然后把它们全部加起来。
具体来说,一个观测序列 O=(o1,…,oT) 是由一个我们看不见的隐藏状态序列 Q=(q1,…,qT) 生成的。我们不知道真实的隐藏状态序列是什么,但我们可以枚举所有可能的隐藏状态序列。
对于任何一条特定的隐藏状态序列,例如 Q=(si1,si2,…,siT),计算它和观测序列 O 同时发生的联合概率 P(O,Q∣λ) 是很直接的:
P(O,Q∣λ)=P(Q∣λ)×P(O∣Q,λ)
让我们把这两项拆开:
-
P(Q∣λ): 隐藏状态序列自身的概率。根据马尔可夫链的性质,它等于:
P(Q∣λ)=P(q1=si1)×P(q2=si2∣q1=si1)×⋯×P(qT=siT∣qT−1=siT−1)
用我们的模型参数表示就是:
P(Q∣λ)=πi1⋅ai1i2⋅ai2i3⋯aiT−1iT
-
P(O∣Q,λ): 在这个特定的隐藏状态序列下,生成观测序列 O 的概率。根据观测独立性假设,它等于:
P(O∣Q,λ)=P(o1∣q1=si1)×P(o2∣q2=si2)×⋯×P(oT∣qT=siT)
用我们的模型参数表示就是:
P(O∣Q,λ)=bi1(o1)⋅bi2(o2)⋯biT(oT)
将两者相乘,就得到了一条特定路径的概率。
2.2 最终计算与问题
为了得到最终的 P(O∣λ),我们需要将所有可能的隐藏状态序列 Q 的概率加起来:
P(O∣λ)=所有可能的Q∑P(O,Q∣λ)=i1,i2,…,iT∑πi1bi1(o1)ai1i2bi2(o2)⋯aiT−1iTbiT(oT)
问题出在哪里?
这个方法的计算量是灾难性的。
- 隐藏状态共有 N 种。
- 序列长度为 T。
- 那么,所有可能的隐藏状态序列 Q 的总数是 NT。
- 计算每一条序列的概率,需要进行 O(T) 次乘法。
- 总的计算复杂度大约是 O(T⋅NT)。
这是一个指数级别的复杂度。假设一个简单的词性标注任务,有 N=50 个词性,一句话长度为 T=20。那么 5020 是一个天文数字,即使用最快的计算机也无法完成计算。因此,直接计算法在实践中是不可行的,它只是一种理论思想。
3. 前向算法
为了解决直接计算法的指数爆炸问题,我们需要一种更聪明的方法。前向算法利用动态规划 (Dynamic Programming) 的思想,通过存储和复用中间计算结果,将复杂度从指数级降到了多项式级。
3.1 直观理解与核心定义
直接计算法的问题在于,它进行了大量的重复计算。例如,在计算很多不同的长路径时,它们的前缀部分(比如从时刻1到时刻3的路径)被反复计算了无数次。
前向算法的核心思想是:在时刻 t 到达某个状态 si 的概率,可以由在时刻 t−1 到达所有可能状态的概率之和来递推得到。我们不需要关心 t−1 之前具体的路径是什么,只需要一个“总的概率”即可。
为此,我们定义一个关键变量——前向概率 (Forward Probability) αt(i)。
定义: 前向概率 αt(i) 是指,在 HMM 模型 λ下,观测序列为 o1,o2,…,ot 且在时刻 t 处于隐藏状态 si 的联合概率。
αt(i)=P(o1,o2,…,ot,qt=si∣λ)
请仔细理解这个定义:它包含了到时刻 t 为止的两个条件:
- 已经看到了观测子序列 o1,…,ot。
- 在时刻 t,系统正好处于状态 si。
这个 αt(i) 已经将所有能够“在时刻 t 到达状态 si 并产生观测子序列 o1,…,ot”的路径概率全部加在一起了。
3.2 算法推导与步骤
前向算法的推导过程分为三步:
1. 初始化 t=1
我们来计算初始时刻的前向概率 α1(i)。
根据定义:
α1(i)=P(o1,q1=si∣λ)
根据概率的链式法则,上式可以分解为:
α1(i)=P(q1=si∣λ)×P(o1∣q1=si,λ)=πi⋅bi(o1)(应用链式法则)(根据 π 和 B 的定义)
含义:在时刻1,处于状态 si 并观测到 o1 的概率,就是“初始时选择状态 si 的概率”乘以“状态 si 生成观测 o1 的概率”。
2. 递推 for t=1,…,T−1
这是算法的核心。假设我们已经计算出了时刻 t 的所有前向概率 αt(j)(对于所有 j=1,…,N),我们如何计算时刻 t+1 的前向概率 αt+1(i)?
根据定义: αt+1(i)=P(o1,…,ot,ot+1,qt+1=si∣λ)
我们可以通过对时刻 t 的所有可能状态 sj 进行边缘化 (Marginalization) 来展开它:
αt+1(i)=j=1∑NP(o1,…,ot,qt=sj,ot+1,qt+1=si∣λ)=j=1∑NP(o1,…,ot,qt=sj∣λ)×P(ot+1,qt+1=si∣o1,…,ot,qt=sj,λ)(对 qt 的所有可能状态求和)(应用链式法则)
现在,我们利用 HMM 的两个核心假设来简化第二项:
- 齐次马尔可夫性: qt+1 只依赖于 qt。所以 P(qt+1=si∣…,qt=sj)=P(qt+1=si∣qt=sj)=aji。
- 观测独立性: ot+1 只依赖于 qt+1。所以 P(ot+1∣…,qt+1=si)=P(ot+1∣qt+1=si)=bi(ot+1)。
将这些简化代入,第二项变为 aji⋅bi(ot+1)。
而第一项 P(o1,…,ot,qt=sj∣λ) 正是我们定义的 αt(j)!
所以,我们得到了递推公式:
αt+1(i)=[j=1∑Nαt(j)aji]×bi(ot+1)
含义: 要计算在时刻 t+1 到达状态 si 的总概率,我们首先要汇总所有从时刻 t 的任意状态 sj 转移到 si 的概率(方括号内的部分),然后再乘以 si 生成观测 ot+1 的概率。
**3. 终止
当我们递推到最后一步,计算完所有 αT(i) 后,我们如何得到最终的 P(O∣λ)?
根据定义,αT(i)=P(o1,…,oT,qT=si∣λ)。
我们要求的 P(O∣λ)=P(o1,…,oT∣λ),只需要对最后一个时刻的所有可能状态 si 进行边缘化即可:
P(O∣λ)=i=1∑NP(o1,…,oT,qT=si∣λ)=i=1∑NαT(i)
含义: 观测序列 O 出现的总概率,等于在最后时刻,系统处于任何一个可能状态 si 并完成观测 O 的概率之和。
算法复杂度:
- 初始化需要 O(N)。
- 每一步递推,计算一个 αt+1(i) 需要 O(N) 次计算。要计算所有 N 个状态,需要 O(N2)。
- 总共有 T−1 步递推。
- 总复杂度为 O(N2T),这是一个多项式级别的复杂度,相比 O(T⋅NT) 是巨大的飞跃。
3.3 盒子和球模型
模型参数 λ=(A,B,π):
- 状态 Q={1,2,3}, N=3
- 观测 V={红, 白}, M=2
- 初始概率 π=(0.2,0.4,0.4)
- 状态转移矩阵 A=0.50.30.20.20.50.30.30.20.5
- 观测概率矩阵 B=0.50.40.70.50.60.3 (第1列是红,第2列是白)
观测序列 O=(红, 白, 红), T=3。
1. 初始化 (t=1), 观测 o1=红
- α1(1)=π1⋅b1(o1)=0.2×0.5=0.10
- α1(2)=π2⋅b2(o1)=0.4×0.4=0.16
- α1(3)=π3⋅b3(o1)=0.4×0.7=0.28
2. 递推 (t=2), 观测 o2=白
-
计算 α2(1):
α2(1)=[α1(1)a11+α1(2)a21+α1(3)a31]×b1(o2)=[0.10×0.5+0.16×0.3+0.28×0.2]×0.5=[0.05+0.048+0.056]×0.5=0.154×0.5=0.077
-
计算 α2(2):
α2(2)=[α1(1)a12+α1(2)a22+α1(3)a32]×b2(o2)=[0.10×0.2+0.16×0.5+0.28×0.3]×0.6=[0.02+0.08+0.084]×0.6=0.184×0.6=0.1104
-
计算 α2(3):
α2(3)=[α1(1)a13+α1(2)a23+α1(3)a33]×b3(o2)=[0.10×0.3+0.16×0.2+0.28×0.5]×0.3=[0.03+0.032+0.14]×0.3=0.202×0.3=0.0606
3. 递推 (t=3), 观测 o3=红
-
计算 α3(1):
α3(1)=[α2(1)a11+α2(2)a21+α2(3)a31]×b1(o3)=[0.077×0.5+0.1104×0.3+0.0606×0.2]×0.5=[0.0385+0.03312+0.01212]×0.5=0.08374×0.5=0.04187
-
计算 α3(2):
α3(2)=[α2(1)a12+α2(2)a22+α2(3)a32]×b2(o3)=[0.077×0.2+0.1104×0.5+0.0606×0.3]×0.4=[0.0154+0.0552+0.01818]×0.4=0.08878×0.4=0.035512
-
计算 α3(3):
α3(3)=[α2(1)a13+α2(2)a23+α2(3)a33]×b3(o3)=[0.077×0.3+0.1104×0.2+0.0606×0.5]×0.7=[0.0231+0.02208+0.0303]×0.7=0.07548×0.7=0.052836
4. 终止
P(O∣λ)=i=1∑3α3(i)=α3(1)+α3(2)+α3(3)=0.04187+0.035512+0.052836=0.130218
4. 后向算法
后向算法是解决评估问题的另一种动态规划方法。它与前向算法对称,从序列的末尾开始,向前递推。
4.1 直观理解与核心定义
我们定义一个后向概率 (Backward Probability) βt(i)。
定义: 后向概率 βt(i) 是指,在 HMM 模型 λ下,并且在时刻 t 处于隐藏状态 si 的条件下,观测到未来观测序列 ot+1,ot+2,…,oT 的条件概率。
βt(i)=P(ot+1,ot+2,…,oT∣qt=si,λ)
请注意它与前向概率的区别:
- αt(i) 是一个联合概率,包含了 o1..ot 和 qt=si。
- βt(i) 是一个条件概率,条件是 qt=si,计算的是未来观测序列的概率。
4.2 算法推导与步骤
1. 初始化 t=T
按照惯例,我们定义序列末尾的后向概率为一个基准值。
βT(i)=1,for all i=1,…,N
含义: 在时刻 T 已经处于状态 si 的条件下,未来的观测序列(空序列)发生的概率自然是1。这是一个递归的起点。
2. 递推 for t=T−1,…,1
假设我们已经计算出了时刻 t+1 的所有后向概率 βt+1(j),我们来计算时刻 t 的后向概率 βt(i)。
根据定义,βt(i)=P(ot+1,…,oT∣qt=si,λ)。
我们通过对时刻 t+1 的所有状态 sj 进行边缘化来展开:
βt(i)=j=1∑NP(ot+1,…,oT,qt+1=sj∣qt=si,λ)=j=1∑NP(qt+1=sj∣qt=si,λ)×P(ot+1∣qt+1=sj,qt=si,λ)×P(ot+2,…,oT∣ot+1,qt+1=sj,qt=si,λ)
再次利用HMM假设简化:
- P(qt+1=sj∣qt=si,λ)=aij
- P(ot+1∣…,qt+1=sj,…)=P(ot+1∣qt+1=sj)=bj(ot+1)
- P(ot+2,…,oT∣…,qt+1=sj,…)=P(ot+2,…,oT∣qt+1=sj)=βt+1(j)
将它们代入,得到递推公式:
βt(i)=j=1∑Naij⋅bj(ot+1)⋅βt+1(j)
3. 终止
后向算法也可以用来计算总概率 P(O∣λ)。我们可以在任意时刻 t 将前向和后向概率结合起来。最简单的是在 t=1 时:
P(O∣λ)=i=1∑NP(o1,…,oT,q1=si∣λ)
我们将 P(o1,…,oT,q1=si∣λ) 分解为 P(q1=si)⋅P(o1∣q1=si)⋅P(o2,…,oT∣q1=si)。
这三项正好是 πi, bi(o1), 和 β1(i)。
所以:
P(O∣λ)=i=1∑Nπi⋅bi(o1)⋅β1(i)
这个结果必须与前向算法得到的结果完全相同。
5. 补充概率概念
5.1 单个状态的概率:γt(i)
定义: 给定模型 λ 和 整个 观测序列 O,在时刻 t 处于状态 si 的概率。
γt(i)=P(qt=si∣O,λ)
这个概率回答了“在看到了所有证据之后,我们回头看,在时刻 t 系统处于状态 si 的可能性有多大?”
推导:
根据条件概率的定义 P(A∣B)=P(A,B)/P(B):
γt(i)=P(O∣λ)P(qt=si,O∣λ)
我们来分析分子 P(qt=si,O∣λ)。它可以被看作是“过去”、“现在”和“未来”的结合:
- “过去”:观测到 o1,…,ot 并且在时刻 t 处于状态 si。这正是前向概率 αt(i)。
- “未来”:在时刻 t 处于状态 si 的条件下,观测到 ot+1,…,oT。这正是后向概率 βt(i)。
因此, P(qt=si,O∣λ)=αt(i)βt(i)。
代入可得:
γt(i)=P(O∣λ)αt(i)βt(i)=∑j=1Nαt(j)βt(j)αt(i)βt(i)
意义: γt(i) 在模型训练中,可以被看作是在时刻 t 访问状态 i 的期望次数。对所有时刻求和 ∑t=1Tγt(i) 就是在整个序列中访问状态 i 的总期望次数。
5.2 两个状态的转移概率:ξt(i,j)
定义: 给定模型 λ 和 整个 观测序列 O,在时刻 t 处于状态 si 且在时刻 t+1 处于状态 sj 的概率。
ξt(i,j)=P(qt=si,qt+1=sj∣O,λ)
这个概率回答了“在看到了所有证据之后,在时刻 t 到 t+1 之间,发生一次从 si到sj转移的可能性有多大?”
推导:
同样地,ξt(i,j)=P(O∣λ)P(qt=si,qt+1=sj,O∣λ)。
分子可以被分解为:
P(…)=αt(i)P(o1,…,ot,qt=si)×aijP(qt+1=sj∣qt=si)×bj(ot+1)P(ot+1∣qt+1=sj)×βt+1(j)P(ot+2,…,oT∣qt+1=sj)
将所有部分组合起来,得到:
ξt(i,j)=P(O∣λ)αt(i)aijbj(ot+1)βt+1(j)=∑k=1N∑l=1Nαt(k)aklbl(ot+1)βt+1(l)αt(i)aijbj(ot+1)βt+1(j)
意义: ξt(i,j) 可以被看作是在时刻 t 从状态 i 转移到状态 j 的期望次数。对时间求和 ∑t=1T−1ξt(i,j) 是在整个序列中从 i 转移到 j 的总期望次数。
这两个量,γt(i) 和 ξt(i,j),是鲍姆-韦尔奇 (Baum-Welch) 学习算法的核心,它们被用来在给定观测数据的情况下,迭代地更新模型参数 A,B,π。
6. 总结一下
本次我们深入探讨了 HMM 的概率评估问题。
- 直接计算法 思路简单,但因 O(T⋅NT) 的指数复杂度而不可行。
- 前向算法 利用动态规划,定义了前向概率 αt(i),自前向后递推,将复杂度降至 O(N2T),是解决评估问题的标准方法。
- 后向算法 是前向算法的镜像,定义了后向概率 βt(i),自后向前递推,同样可以计算总概率,并且是计算其他重要概率的必要工具。
- 组合概率 γt(i) 和 ξt(i,j) 利用前向和后向概率,让我们能深入洞察序列内部的动态,是连接评估问题和学习问题的桥梁。
至此,我们已经掌握了HMM三大问题中的第一个。下一个自然是解决隐马尔科夫模型的学习问题了。