[学习笔记] [机器学习] 12. [下] HMM 隐马尔可夫算法(马尔科夫链、HMM 三类问题、前后后向算法、维特比算法、鲍姆-韦尔奇算法、API 及实例)

5. 维特比算法解码隐藏状态序列 Q Q Q

学习目标:

  • 知道维特比算法解码隐藏状态序列 Q Q Q

在本篇我们会讨论维特比算法解码隐藏状态序列 Q Q Q,即给定模型 λ \lambda λ 和观测序列 O O O,求给定观测序列 O O O 条件下,最可能出现的对应的隐藏状态序列 Q ∗ Q^* Q

HMM 模型的解码问题最常用的算法是维特比算法,当然也有其他的算法可以求解这个问题。同时维特比算法是一个通用的求序列最短路径的动态规划算法,也可以用于很多其他问题

5.1 HMM 最可能隐藏状态序列求解概述

HMM 模型的解码问题即:

给定模型 λ = ( A , B , Π ) \lambda=(A,B,\Pi) λ=(A,B,Π) 和 观测序列 O = o 1 , o 2 , . . . , o T O = o_1,o_2, ..., o_T O=o1,o2,...,oT,求给定观测序列 O O O 条件下,最可能出现的对应的隐藏状态序列 Q ∗ = q 1 ∗ , q 2 ∗ , . . . , q T ∗ Q^*=q^*_1, q^*_2, ..., q^*_T Q=q1,q2,...qT,即 P ( Q ∗ ∣ O ) P(Q^*|O) P(QO) 的最大化。

一个可能的近似解法是求出观测序列 O O O 在每个时刻 t t t 最可能的隐藏状态 q t ∗ q^*_t qt,然后得到一个近似的隐藏状态序列 Q ∗ = q 1 ∗ , q 2 ∗ , . . . , q T ∗ Q^*=q^*_1, q^*_2, ..., q^*_T Q=q1,q2,...qT。要这样近似求解不难,利用前向后向算法评估观察序列概率的定义:

  • 在给定模型 λ \lambda λ 和观测序列 O O O 时,在时刻 t t t 处于状态 q i q_i qi 的概率是
    γ t ( i ) \gamma_t(i) γt(i),这个概率可以通过 HMM 的前向算法与后向算法计算。这样我们就有:

Q t ∗ = a r g m a x i ≤ i ≤ N ( ˚ i ) t = 1 , 2 , . . . , T Q^*_t = \underset{i \le i \le N}{\mathrm{arg max}} \r(i) \quad t = 1, 2, ..., T Qt=iiNargmax(˚i)t=1,2,...,T

其中:

  • A A A:状态转移矩阵,其中 a i j a_{ij} aij 表示从隐藏状态 i i i 转移到隐藏状态 j j j 的概率。
  • B B B:观测概率矩阵,其中 b j ( k ) b_j(k) bj(k) 表示在隐藏状态 j j j 下观测到符号 k k k 的概率。
  • Π \Pi Π:初始状态概率向量,其中 π i \pi_i πi 表示初始时刻隐藏状态为 i i i 的概率。
  • O O O:观测序列,其中 o t o_t ot 表示时刻 t t t 的观测值。
  • λ \lambda λ:HMM 模型参数,包括状态转移矩阵 A A A、观测概率矩阵 B B B 和初始状态概率向量 Π \Pi Π
  • Q ∗ Q^* Q:最可能的隐藏状态序列(即预测的隐藏状态序列),其中 q t ∗ q^*_t qt 表示时刻 t t t 最可能的隐藏状态。
  • γ t ( i ) \gamma_t(i) γt(i):在给定模型 λ \lambda λ 和观测序列 O O O 时,在时刻 t t t 处于状态 q i q_i qi 的概率。

近似算法很简单,但是却不能保证预测的状态序列 Q ∗ Q^* Q 整体是最可能的状态序列 Q best Q_{\text{best}} Qbest,因为预测的状态序列 Q ∗ Q^* Q 中某些相邻的隐藏状态 q q q 可能存在转移概率 a i j a_{ij} aij 为 0 的情况。

维特比算法可以将 HMM 的状态序列作为一个整体来考虑,避免近似算法的问题,下面我们来看看维特比算法进行 HMM 解码的方法。

5.2 维特比算法概述

维特比算法是一个通用的解码算法,是基于动态规划的求序列最短路径的方法。既然是动态规划算法,那么就需要找到合适的局部状态,以及局部状态的递推公式。

在 HMM 中,维特比算法定义了两个局部状态用于递推:

第一个局部状态 δ t ( q ) \delta_t(q) δt(q)第一个局部状态是在时刻 t t t 隐藏状态为 q q q 所有可能的状态转移路径 q 1 , q 2 , . . . , q t q_1,q_2, ..., q_t q1,q2,...,qt 中的概率最大值,记为 δ t ( q ) \delta_t(q) δt(q)

δ t ( q ) = max ⁡ q 1 , q 2 , . . . , q t − 1 P ( q t = q , q 1 , q 2 , . . . , q t − 1 , o t , o t − 1 , . . . , o 1 ∣ λ ) i = 1 , 2 , . . . , N \delta_t(q) = \underset{q_1, q_2, ..., q_{t-1}}{\max}P(q_t = q, q_1, q_2, ..., q_{t-1}, o_t, o_{t-1}, ..., o_1|\lambda) \quad i = 1, 2, ..., N δt(q)=q1,q2,...,qt1maxP(qt=q,q1,q2,...,qt1,ot,ot1,...,o1λ)i=1,2,...,N

δ t ( q ) \delta_t(q) δt(q) 的定义可以得到 δ \delta δ 的递推表达式:

δ t + 1 ( q ) = max ⁡ q 1 , q 2 , . . . , q t P ( q t + 1 = q , q 1 , q 2 , . . . , q t , o t + 1 , o t , . . . , o 1 ∣ λ ) = max ⁡ 1 ≤ j ≤ N [ δ t ( j ) a j i ] b i ( o t + 1 ) \begin{aligned} \delta_{t+1}(q) & = \underset{q_1, q_2, ...,q_t}{\max}P(q_{t+1} = q, q_1, q_2, ..., q_t, o_{t+1}, o_t, ..., o_1 | \lambda)\\ &= \underset{1\le j \le N}{\max}[\delta_t(j)a_{ji}]b_{i}(o_{t+1}) \end{aligned} δt+1(q)=q1,q2,...,qtmaxP(qt+1=q,q1,q2,...,qt,ot+1,ot,...,o1λ)=1jNmax[δt(j)aji]bi(ot+1)

第二个局部状态 ψ t ( q ) \psi_t(q) ψt(q)第二个局部状态由第一个局部状态递推得到

我们定义在时刻 t t t 隐藏状态为 q q q 的所有单个状态转移路径 ( q 1 , q 2 , . . . , q t − 1 ) (q_1,q_2, ..., q_{t-1}) (q1,q2,...,qt1) 中概率最大的转移路径中第 t − 1 t-1 t1 个节点的隐藏状态为 ψ t ( q ) \psi_t(q) ψt(q)。其递推表达式可以表示为:

ψ t ( q ) = argmax 1 ≤ j ≤ N [ δ t − 1 ( j ) a j i ] \psi_t(q) = \underset{1 \le j \le N}{\text{argmax}}[\delta_{t-1}(j)a_{ji}] ψt(q)=1jNargmax[δt1(j)aji]

有了这两个局部状态,我们就可以从时刻 0 一直递推到时刻 T T T,然后利用 ψ t ( i ) \psi_t(i) ψt(i) 记录的前一个最可能的状态节点回溯,直到找到最优的隐藏状态序列。

其中:

  • A A A:状态转移矩阵,其中 a i j a_{ij} aij 表示从隐藏状态 i i i 转移到隐藏状态 j j j 的概率。
  • B B B:观测概率矩阵,其中 b j ( k ) b_j(k) bj(k) 表示在隐藏状态 j j j 下观测到符号 k k k 的概率。
  • Π \Pi Π:初始状态概率向量,其中 π i \pi_i πi 表示初始时刻隐藏状态为 i i i 的概率。
  • O O O:观测序列,其中 o t o_t ot 表示时刻 t t t 的观测值。
  • λ \lambda λ:HMM 模型参数,包括状态转移矩阵 A A A、观测概率矩阵 B B B 和初始状态概率向量 Π \Pi Π
  • δ t ( q ) \delta_t(q) δt(q):在时刻 t t t 隐藏状态为 q q q 的所有可能的状态转移路径中的概率最大值。
  • ψ t ( q ) \psi_t(q) ψt(q):在时刻 t t t 隐藏状态为 q q q 的所有单个状态转移路径中概率最大的转移路径中第 t − 1 t-1 t1 个节点的隐藏状态。

维特比算法通过动态规划来求解最优状态序列,具有较高的效率和准确性。

5.3 维特比算法流程总结

  • 输入:HMM 模型 λ = ( A , B , ∏ ) \lambda = (A, B, \prod) λ=(A,B,),观测序列 O = ( o 1 , o 2 , . . . , o T ) O = (o_1, o_2, ..., o_T) O=(o1,o2,...,oT)
  • 输出:最有可能的隐藏状态序列 Q ∗ = q 1 ∗ , q 1 ∗ , . . . , q T ∗ Q^* = q^*_1, q^*_1,..., q^*_T Q=q1,q1,...,qT

流程如下

步骤一:初始化局部状态

δ 1 ( q ) = Π i b i ( o 1 ) i = 1 , 2 , . . . , N ψ 1 ( q ) = 0 i = 1 , 2 , . . . , N \begin{aligned} & \delta_1(q) = \Pi_i b_i (o_1) \quad i = 1, 2, ..., N\\ & \psi_1(q) = 0 \quad i = 1, 2, ..., N \end{aligned} δ1(q)=Πibi(o1)i=1,2,...,Nψ1(q)=0i=1,2,...,N

步骤二:进行动态规划递推时刻 t = 2 , 3 , . . . , T t = 2, 3,..., T t=2,3,...,T 的局部状态

δ t ( q ) = max ⁡ 1 ≤ j ≤ N [ δ t − 1 ( j ) a j i ] b i ( o t ) i = 1 , 2 , . . . , N ψ t ( i ) = argmax 1 ≤ j ≤ N [ δ t − 1 ( j ) a j i ] i = 1 , 2 , . . . , N \begin{aligned} & \delta_t(q) = \underset{1 \le j \le N}{\max}[\delta_{t-1}(j)a_{ji}]b_i(o_t) \quad & i = 1, 2, ..., N\\ & \psi_t(i) = \underset{1 \le j \le N}{\text{argmax}}[\delta_{t-1}(j)a_{ji}] \quad & i = 1, 2, ..., N \end{aligned} δt(q)=1jNmax[δt1(j)aji]bi(ot)ψt(i)=1jNargmax[δt1(j)aji]i=1,2,...,Ni=1,2,...,N

步骤三:计算时刻 T T T 最大的 δ T ( i ) \delta_T(i) δT(i),即为最可能隐藏状态序列出现的概率。计算时刻 T T T 最大的 ψ t ( q ) \psi_t(q) ψt(q),即为时刻 T T T 最可能的隐藏状态。

P ∗ = max ⁡ 1 ≤ j ≤ N δ T ( i ) q T ∗ = argmax 1 ≤ j ≤ N [ δ T ( q ) ] \begin{aligned} & P^* = \underset{1 \le j \le N}{\max} \delta_T(i)\\ & q^*_T = \underset{1 \le j \le N}{\text{argmax}}[\delta_T(q)] \end{aligned} P=1jNmaxδT(i)qT=1jNargmax[δT(q)]

步骤四:利用局部状态 ψ t ( i ) \psi_t(i) ψt(i) 开始回溯。对于 t = T − 1 , T − 2 , . . . , 1 t = T - 1, T- 2, ..., 1 t=T1,T2,...,1

q t ∗ = ψ t + 1 ( q t + 1 ∗ ) q^*_t = \psi_{t+1}(q^*_{t+1}) qt=ψt+1(qt+1)

最终得到最有可能的隐藏状态序列 Q ∗ = q 1 ∗ , q 2 ∗ , . . . , q T ∗ Q^* = q^*_1, q^*_2, ..., q^*_T Q=q1,q2,...,qT

其中:

  • A A A:状态转移矩阵,其中 a i j a_{ij} aij 表示从隐藏状态 i i i 转移到隐藏状态 j j j 的概率。
  • B B B:观测概率矩阵,其中 b j ( k ) b_j(k) bj(k) 表示在隐藏状态 j j j 下观测到符号 k k k 的概率。
  • Π \Pi Π:初始状态概率向量,其中 π i \pi_i πi 表示初始时刻隐藏状态为 i i i 的概率。
  • O O O:观测序列,其中 o t o_t ot 表示时刻 t t t 的观测值。
  • λ \lambda λ:HMM 模型参数,包括状态转移矩阵 A A A、观测概率矩阵 B B B 和初始状态概率向量 Π \Pi Π
  • δ t ( q ) \delta_t(q) δt(q):在时刻 t t t 隐藏状态为 q q q 的所有可能的状态转移路径中的概率最大值。
  • ψ t ( q ) \psi_t(q) ψt(q):在时刻 t t t 隐藏状态为 q q q 的所有单个状态转移路径中概率最大的转移路径中第 t − 1 t-1 t1 个节点的隐藏状态。

5.4 HMM 维特比算法求解实例

下面我们仍然用盒子与球的例子来看看 HMM 维特比算法求解。我们的观察集合是:

V = { 红 , 白 } M = 2 \begin{aligned} & V = \{ 红,白 \}\\ & M = 2 \end{aligned} V={ ,}M=2

我们的状态集合是:

Q = { 盒子 1 , 盒子 2 , 盒子 3 } N = 3 \begin{aligned} & Q = \{盒子1, 盒子2, 盒子3\}\\ & N = 3 \end{aligned} Q={ 盒子1,盒子2,盒子3}N=3

而观察序列 O O O 和状态序列 i i i 的长度为都为 3。

初始状态分布为:

Π = ( 0.2 , 0.4 , 0.4 ) T \Pi = (0.2, 0.4, 0.4)^T Π=(0.2,0.4,0.4)T

状态转移概率分布矩阵 A A A(不可见的,隐含的)为:

A = [ 0.5 0.2 0.3 0.3 0.5 0.2 0.2 0.3 0.5 ] N × N = 3 × 3 A = \begin{bmatrix} 0.5 & 0.2 & 0.3\\ 0.3 & 0.5 & 0.2\\ 0.2 & 0.3 & 0.5 \end{bmatrix}_{N \times N = 3 \times 3} A= 0.50.30.20.20.50.30.30.20.5 N×N=3×3

行表示第几次抽球(从2开始);列表示使用第几个盒子的概率

观测状态概率矩阵 B B B(可见的)为:

B = [ 0.5 0.5 0.4 0.6 0.7 0.3 ] N × M = 3 × 2 B = \begin{bmatrix} 0.5 & 0.5\\ 0.4 & 0.6\\ 0.7 & 0.3 \end{bmatrix}_{N \times M = 3 \times 2} B= 0.50.40.70.50.60.3 N×M=3×2

行代表第几个盒子;列1代表红球的概率,列2代表白球的概率

球的颜色的观测序列:

O = { 红 , 白 , 红 } O = \{红, 白, 红\} O={ ,,}


按照我们前面的维特比算法,首先需要得到三个隐藏状态在 时刻1 时对应的各自两个局部状态,此时观测状态为 1:

δ 1 ( 1 ) = Π 1 b 1 ( o 1 ) = 0.2 第一个盒子 × 0.5 红球 = 0.1 δ 1 ( 2 ) = Π 2 b 2 ( o 1 ) = 0.4 第二个盒子 × 0.4 红球 = 0.16 δ 1 ( 3 ) = Π 3 b 3 ( o 1 ) = 0.4 第三个盒子 × 0.7 红球 = 0.16 ψ 1 ( 1 ) = ψ 1 ( 2 ) = ψ 1 ( 3 ) = 0 \begin{aligned} & \delta_1(1) = \Pi_1b_1(o_1) = \underset{第一个盒子}{0.2} \times \underset{红球}{0.5} = 0.1\\ & \delta_1(2) = \Pi_2b_2(o_1) = \underset{第二个盒子}{0.4} \times \underset{红球}{0.4} = 0.16\\ & \delta_1(3) = \Pi_3b_3(o_1) = \underset{第三个盒子}{0.4} \times \underset{红球}{0.7} = 0.16\\ & \psi_1(1) = \psi_1(2) = \psi_1(3) = 0 \end{aligned} δ1(1)=Π1b1(o1)=第一个盒子0.2×红球0.5=0.1δ1(2)=Π2b2(o1)=第二个盒子0.4×红球0.4=0.16δ1(3)=Π3b3(o1)=第三个盒子0.4×红球0.7=0.16ψ1(1)=ψ1(2)=ψ1(3)=0

ψ 1 ( 1 ) = ψ 1 ( 2 ) = ψ 1 ( 3 ) = 0 \psi_1(1) = \psi_1(2) = \psi_1(3) = 0 ψ1(1)=ψ1(2)=ψ1(3)=0 是因为初始化设定它们为 0

现在开始递推三个隐藏状态在 时刻2 时对应的各自两个局部状态,此时观测状态为 2:

δ 2 ( 1 ) = max ⁡ 1 ≤ j ≤ 3 [ δ 1 ( j ) a j 1 ] b 1 ( o 2 ) = max ⁡ 1 ≤ j ≤ 3 [ 0.1 上一次是盒子 1 × 0.15 盒子 1 → 盒子 1 ‾ 第一种情况 , 0.16 上一次是盒子 2 × 0.3 盒子 2 → 盒子 1 ‾ 第二种情况 , 0.28 上一次是盒子 3 × 0.2 盒子 3 → 盒子 1 ‾ 第三种情况 ] × 0.5 白球 = 0.028 ψ 2 ( 1 ) = 3 最大值对应的索引 ( 从 1 开始 ) δ 2 ( 2 ) = max ⁡ 1 ≤ j ≤ 3 [ δ 1 ( j ) a j 2 ] b 2 ( o 2 ) = max ⁡ 1 ≤ j ≤ 3 [ 0.1 上一次是盒子 1 × 0.2 盒子 1 → 盒子 2 ‾ 第一种情况 , 0.16 上一次是盒子 2 × 0.5 盒子 2 → 盒子 2 ‾ 第二种情况 , 0.28 上一次是盒子 3 × 0.3 盒子 3 → 盒子 2 ‾ 第三种情况 ] × 0.6 白球 = 0.0504 ψ 2 ( 2 ) = 3 最大值对应的索引 ( 从 1 开始 ) δ 2 ( 3 ) = max ⁡ 1 ≤ j ≤ 3 [ δ 1 ( j ) a j 3 ] b 3 ( o 2 ) = max ⁡ 1 ≤ j ≤ 3 [ 0.1 上一次是盒子 1 × 0.3 盒子 1 → 盒子 3 ‾ 第一种情况 , 0.16 上一次是盒子 2 × 0.2 盒子 2 → 盒子 3 ‾ 第二种情况 , 0.28 上一次是盒子 3 × 0.5 盒子 3 → 盒子 3 ‾ 第三种情况 ] × 0.3 白球 = 0.042 ψ 2 ( 3 ) = 3 最大值对应的索引 ( 从 1 开始 ) \begin{aligned} & \delta_2(1) = \underset{1 \le j \le 3}{\max}[\delta_1(j)a_{j1}]b_1(o_2) = \underset{1 \le j \le 3}{\max}[\underset{第一种情况}{\underline{\underset{上一次是盒子1}{0.1} \times \underset{盒子1\rightarrow盒子1}{0.15}}}, \underset{第二种情况}{\underline{\underset{上一次是盒子2}{0.16} \times \underset{盒子2\rightarrow盒子1}{0.3}}}, \underset{第三种情况}{\underline{\underset{上一次是盒子3}{0.28} \times \underset{盒子3\rightarrow盒子1}{0.2}}}] \times \underset{白球}{0.5} = 0.028\\ & \qquad \psi_2(1) = \underset{最大值对应的索引(从1开始)}{3}\\ & \delta_2(2) = \underset{1 \le j \le 3}{\max}[\delta_1(j)a_{j2}]b_2(o_2) = \underset{1 \le j \le 3}{\max}[\underset{第一种情况}{\underline{\underset{上一次是盒子1}{0.1} \times \underset{盒子1\rightarrow盒子2}{0.2}}}, \underset{第二种情况}{\underline{\underset{上一次是盒子2}{0.16} \times \underset{盒子2\rightarrow盒子2}{0.5}}}, \underset{第三种情况}{\underline{\underset{上一次是盒子3}{0.28} \times \underset{盒子3\rightarrow盒子2}{0.3}}}] \times \underset{白球}{0.6} = 0.0504\\ & \qquad \psi_2(2) = \underset{最大值对应的索引(从1开始)}{3}\\ & \delta_2(3) = \underset{1 \le j \le 3}{\max}[\delta_1(j)a_{j3}]b_3(o_2) = \underset{1 \le j \le 3}{\max}[\underset{第一种情况}{\underline{\underset{上一次是盒子1}{0.1} \times \underset{盒子1\rightarrow盒子3}{0.3}}}, \underset{第二种情况}{\underline{\underset{上一次是盒子2}{0.16} \times \underset{盒子2\rightarrow盒子3}{0.2}}}, \underset{第三种情况}{\underline{\underset{上一次是盒子3}{0.28} \times \underset{盒子3\rightarrow盒子3}{0.5}}}] \times \underset{白球}{0.3} = 0.042\\ & \qquad \psi_2(3) = \underset{最大值对应的索引(从1开始)}{3}\\ \end{aligned} δ2(1)=1j3max[δ1(j)aj1]b1(o2)=1j3max[第一种情况上一次是盒子10.1×盒子1盒子10.15,第二种情况上一次是盒子20.16×盒子2盒子10.3,第三种情况上一次是盒子30.28×盒子3盒子10.2]×白球0.5=0.028ψ2(1)=最大值对应的索引(1开始)3δ2(2)=1j3max[δ1(j)aj2]b2(o2)=1j3max[第一种情况上一次是盒子10.1×盒子1盒子20.2,第二种情况上一次是盒子20.16×盒子2盒子20.5,第三种情况上一次是盒子30.28×盒子3盒子20.3]×白球0.6=0.0504ψ2(2)=最大值对应的索引(1开始)3δ2(3)=1j3max[δ1(j)aj3]b3(o2)=1j3max[第一种情况上一次是盒子10.1×盒子1盒子30.3,第二种情况上一次是盒子20.16×盒子2盒子30.2,第三种情况上一次是盒子30.28×盒子3盒子30.5]×白球0.3=0.042ψ2(3)=最大值对应的索引(1开始)3

继续递推三个隐藏状态在 时刻3 时对应的各自两个局部状态,此时观测状态为 1:

δ 3 ( 1 ) = max ⁡ 1 ≤ j ≤ 3 [ δ 1 ( j ) a j 1 ] b 1 ( o 3 ) = max ⁡ 1 ≤ j ≤ 3 [ 0.028 上一次是盒子 1 × 0.5 盒子 1 → 盒子 1 ‾ 第一种情况 , 0.0504 上一次是盒子 2 × 0.3 盒子 2 → 盒子 1 ‾ 第二种情况 , 0.042 上一次是盒子 3 × 0.2 盒子 3 → 盒子 1 ‾ 第三种情况 ] × 0.5 红球 = 0.00756 ψ 3 ( 1 ) = 2 最大值对应的索引 ( 从 1 开始 ) δ 3 ( 2 ) = max ⁡ 1 ≤ j ≤ 3 [ δ 1 ( j ) a j 2 ] b 2 ( o 3 ) = max ⁡ 1 ≤ j ≤ 3 [ 0.028 上一次是盒子 1 × 0.2 盒子 1 → 盒子 2 ‾ 第一种情况 , 0.0504 上一次是盒子 2 × 0.5 盒子 2 → 盒子 2 ‾ 第二种情况 , 0.042 上一次是盒子 3 × 0.3 盒子 3 → 盒子 2 ‾ 第三种情况 ] × 0.4 红球 = 0.0504 ψ 3 ( 2 ) = 2 最大值对应的索引 ( 从 1 开始 ) δ 3 ( 3 ) = max ⁡ 1 ≤ j ≤ 3 [ δ 1 ( j ) a j 3 ] b 3 ( o 3 ) = max ⁡ 1 ≤ j ≤ 3 [ 0.028 上一次是盒子 1 × 0.3 盒子 1 → 盒子 3 ‾ 第一种情况 , 0.0504 上一次是盒子 2 × 0.2 盒子 2 → 盒子 3 ‾ 第二种情况 , 0.042 上一次是盒子 3 × 0.5 盒子 3 → 盒子 3 ‾ 第三种情况 ] × 0.7 红球 = 0.042 ψ 3 ( 3 ) = 3 最大值对应的索引 ( 从 1 开始 ) \begin{aligned} & \delta_3(1) = \underset{1 \le j \le 3}{\max}[\delta_1(j)a_{j1}]b_1(o_3) = \underset{1 \le j \le 3}{\max}[\underset{第一种情况}{\underline{\underset{上一次是盒子1}{0.028} \times \underset{盒子1\rightarrow盒子1}{0.5}}}, \underset{第二种情况}{\underline{\underset{上一次是盒子2}{0.0504} \times \underset{盒子2\rightarrow盒子1}{0.3}}}, \underset{第三种情况}{\underline{\underset{上一次是盒子3}{0.042} \times \underset{盒子3\rightarrow盒子1}{0.2}}}] \times \underset{红球}{0.5} = 0.00756\\ & \qquad \psi_3(1) = \underset{最大值对应的索引(从1开始)}{2}\\ & \delta_3(2) = \underset{1 \le j \le 3}{\max}[\delta_1(j)a_{j2}]b_2(o_3) = \underset{1 \le j \le 3}{\max}[\underset{第一种情况}{\underline{\underset{上一次是盒子1}{0.028} \times \underset{盒子1\rightarrow盒子2}{0.2}}}, \underset{第二种情况}{\underline{\underset{上一次是盒子2}{0.0504} \times \underset{盒子2\rightarrow盒子2}{0.5}}}, \underset{第三种情况}{\underline{\underset{上一次是盒子3}{0.042} \times \underset{盒子3\rightarrow盒子2}{0.3}}}] \times \underset{红球}{0.4} = 0.0504\\ & \qquad \psi_3(2) = \underset{最大值对应的索引(从1开始)}{2}\\ & \delta_3(3) = \underset{1 \le j \le 3}{\max}[\delta_1(j)a_{j3}]b_3(o_3) = \underset{1 \le j \le 3}{\max}[\underset{第一种情况}{\underline{\underset{上一次是盒子1}{0.028} \times \underset{盒子1\rightarrow盒子3}{0.3}}}, \underset{第二种情况}{\underline{\underset{上一次是盒子2}{0.0504} \times \underset{盒子2\rightarrow盒子3}{0.2}}}, \underset{第三种情况}{\underline{\underset{上一次是盒子3}{0.042} \times \underset{盒子3\rightarrow盒子3}{0.5}}}] \times \underset{红球}{0.7} = 0.042\\ & \qquad \psi_3(3) = \underset{最大值对应的索引(从1开始)}{3}\\ \end{aligned} δ3(1)=1j3max[δ1(j)aj1]b1(o3)=1j3max[第一种情况上一次是盒子10.028×盒子1盒子10.5,第二种情况上一次是盒子20.0504×盒子2盒子10.3,第三种情况上一次是盒子30.042×盒子3盒子10.2]×红球0.5=0.00756ψ3(1)=最大值对应的索引(1开始)2δ3(2)=1j3max[δ1(j)aj2]b2(o3)=1j3max[第一种情况上一次是盒子10.028×盒子1盒子20.2,第二种情况上一次是盒子20.0504×盒子2盒子20.5,第三种情况上一次是盒子30.042×盒子3盒子20.3]×红球0.4=0.0504ψ3(2)=最大值对应的索引(1开始)2δ3(3)=1j3max[δ1(j)aj3]b3(o3)=1j3max[第一种情况上一次是盒子10.028×盒子1盒子30.3,第二种情况上一次是盒子20.0504×盒子2盒子30.2,第三种情况上一次是盒子30.042×盒子3盒子30.5]×红球0.7=0.042ψ3(3)=最大值对应的索引(1开始)3

维特比算法是一种常用的 HMM 解码算法,它基于动态规划来求解最优状态序列。维特比算法定义了两个局部状态 δ t ( q ) \delta_t(q) δt(q) ψ t ( q ) \psi_t(q) ψt(q) 来进行递推。其中, δ t ( q ) \delta_t(q) δt(q) 表示在时刻 t t t 隐藏状态为 q q q 的所有可能的状态转移路径中的概率最大值; ψ t ( q ) \psi_t(q) ψt(q) 表示在时刻 t t t 隐藏状态为 q q q 的所有单个状态转移路径中概率最大的转移路径中第 t − 1 t-1 t1 个节点的隐藏状态。

在上述的例子中,最后一个时刻的最大概率为 δ 3 ( 3 ) \delta_3(3) δ3(3),这意味着在时刻 3,隐藏状态为 3 的概率最大。因此,我们可以得到 q 3 ∗ = 3 q^*_3 = 3 q3=3,即在时刻 3 最可能的隐藏状态为 3。

接下来,我们可以利用局部状态 ψ t ( i ) \psi_t(i) ψt(i) 来回溯得到最优状态序列。由于 ψ 3 ( 3 ) = 3 \psi_3(3)=3 ψ3(3)=3,所以 q 2 ∗ = 3 q^*_2 = 3 q2=3;由于 ψ 2 ( 3 ) = 3 \psi_2(3)=3 ψ2(3)=3,所以 q 1 ∗ = 3 q^*_1 = 3 q1=3。因此,我们得到了最终的最优状态序列为 { 3 , 3 , 3 } \{3, 3, 3\} { 3,3,3}

维特比算法还是借鉴了动态规划的思想


小结

  • 输入:HMM 模型 λ = ( A , B , ∏ ) \lambda = (A, B, \prod) λ=(A,B,),观测序列 O = ( o 1 , o 2 , . . . , o T ) O = (o_1, o_2, ..., o_T) O=(o1,o2,...,oT)
  • 输出:最有可能的隐藏状态序列 Q ∗ = q 1 ∗ , q 1 ∗ , . . . , q T ∗ Q^* = q^*_1, q^*_1,..., q^*_T Q=q1,q1,...,qT

流程如下

步骤一:初始化局部状态

δ 1 ( q ) = Π i b i ( o 1 ) i = 1 , 2 , . . . , N ψ 1 ( q ) = 0 i = 1 , 2 , . . . , N \begin{aligned} & \delta_1(q) = \Pi_i b_i (o_1) \quad i = 1, 2, ..., N\\ & \psi_1(q) = 0 \quad i = 1, 2, ..., N \end{aligned} δ1(q)=Πibi(o1)i=1,2,...,Nψ1(q)=0i=1,2,...,N

步骤二:进行动态规划递推时刻 t = 2 , 3 , . . . , T t = 2, 3,..., T t=2,3,...,T 的局部状态

δ t ( q ) = max ⁡ 1 ≤ j ≤ N [ δ t − 1 ( j ) a j i ] b i ( o t ) i = 1 , 2 , . . . , N ψ t ( i ) = argmax 1 ≤ j ≤ N [ δ t − 1 ( j ) a j i ] i = 1 , 2 , . . . , N \begin{aligned} & \delta_t(q) = \underset{1 \le j \le N}{\max}[\delta_{t-1}(j)a_{ji}]b_i(o_t) \quad & i = 1, 2, ..., N\\ & \psi_t(i) = \underset{1 \le j \le N}{\text{argmax}}[\delta_{t-1}(j)a_{ji}] \quad & i = 1, 2, ..., N \end{aligned} δt(q)=1jNmax[δt1(j)aji]bi(ot)ψt(i)=1jNargmax[δt1(j)aji]i=1,2,...,Ni=1,2,...,N

步骤三:计算时刻 T T T 最大的 δ T ( i ) \delta_T(i) δT(i),即为最可能隐藏状态序列出现的概率。计算时刻 T T T 最大的 ψ t ( q ) \psi_t(q) ψt(q),即为时刻 T T T 最可能的隐藏状态。

P ∗ = max ⁡ 1 ≤ j ≤ N δ T ( i ) q T ∗ = argmax 1 ≤ j ≤ N [ δ T ( q ) ] \begin{aligned} & P^* = \underset{1 \le j \le N}{\max} \delta_T(i)\\ & q^*_T = \underset{1 \le j \le N}{\text{argmax}}[\delta_T(q)] \end{aligned} P=1jNmaxδT(i)qT=1jNargmax[δT(q)]

步骤四:利用局部状态 ψ t ( i ) \psi_t(i) ψt(i) 开始回溯。对于 t = T − 1 , T − 2 , . . . , 1 t = T - 1, T- 2, ..., 1 t=T1,T2,...,1

q t ∗ = ψ t + 1 ( q t + 1 ∗ ) q^*_t = \psi_{t+1}(q^*_{t+1}) qt=ψt+1(qt+1)

最终得到最有可能的隐藏状态序列 Q ∗ = q 1 ∗ , q 2 ∗ , . . . , q T ∗ Q^* = q^*_1, q^*_2, ..., q^*_T Q=q1,q2,...,qT

其中:

  • A A A:状态转移矩阵,其中 a i j a_{ij} aij 表示从隐藏状态 i i i 转移到隐藏状态 j j j 的概率。
  • B B B:观测概率矩阵,其中 b j ( k ) b_j(k) bj(k) 表示在隐藏状态 j j j 下观测到符号 k k k 的概率。
  • Π \Pi Π:初始状态概率向量,其中 π i \pi_i πi 表示初始时刻隐藏状态为 i i i 的概率。
  • O O O:观测序列,其中 o t o_t ot 表示时刻 t t t 的观测值。
  • λ \lambda λ:HMM 模型参数,包括状态转移矩阵 A A A、观测概率矩阵 B B B 和初始状态概率向量 Π \Pi Π
  • δ t ( q ) \delta_t(q) δt(q):在时刻 t t t 隐藏状态为 q q q 的所有可能的状态转移路径中的概率最大值。
  • ψ t ( q ) \psi_t(q) ψt(q):在时刻 t t t 隐藏状态为 q q q 的所有单个状态转移路径中概率最大的转移路径中第 t − 1 t-1 t1 个节点的隐藏状态。

6. 鲍姆-韦尔奇算法简介

学习目标:

  • 了解鲍姆-韦尔奇算法

6.1 问题引入

模型参数学习问题 ―― 鲍姆-韦尔奇(Baum-Welch)算法(状态未知),即给定观测序列 O = { o 1 , o 2 , . . . , o T } O = \{o_1,o_2,..., o_T\} O={ o1,o2,...,oT},估计模型 λ = ( A , B , Π ) \lambda = (A, B, \Pi) λ=(A,B,Π) 的参数,使该模型下观测序列的条件概率 P ( O ∣ A ) P(O|A) P(OA) 最大。

它的解法最常用的是鲍姆-韦尔奇算法,其实就是基于 EM 算法的求解,只不过鲍姆-韦尔奇算法出现的时代,EM 算法还没有被抽象出来,所以被叫为鲍姆-韦尔奇算法。

在这里插入图片描述

6.2 鲍姆-韦尔奇算法原理

鲍姆-韦尔奇算法原理既然使用的就是 EM 算法的原理,那么我们需要在 E 步求出联合分布 P ( O , I ∣ λ ) P(O, I | \lambda) P(O,Iλ) 基于条件概率 P ( I ∣ O , λ ‾ ) P(I|O,\overline{\lambda}) P(IO,λ) 的期望,其中 λ ‾ \overline{\lambda} λ 为当前的模型参数;然后在 M 步最大化这个期望,得到更新的模型参数 λ \lambda λ


首先来看看 E 步,当前模型参数为 λ ‾ \overline{\lambda} λ,联合分布 P ( O , I ∣ λ ) P(O,I|\lambda) P(O,Iλ) 基于条件概率P ( I ∣ O , λ ‾ ) (I|O, \overline{\lambda}) (IO,λ) 的期望表达式为:

L ( λ , λ ‾ ) = ∑ I P ( I ∣ O , λ ‾ ) log ⁡ P ( O , I ∣ λ ) L(\lambda, \overline{\lambda}) = \sum_I P(I|O, \overline{\lambda})\log P(O, I | \lambda) L(λ,λ)=IP(IO,λ)logP(O,Iλ)

在 M 步,我们极大化上式,然后得到更新后的模型参数如下:

λ ‾ = argmax λ ∑ I P ( I ∣ O , λ ‾ ) log ⁡ P ( O , I ∣ λ ) \overline{\lambda} = \underset{\lambda}{\text{argmax}}\sum_IP(I|O, \overline{\lambda})\log{P(O, I|\lambda)} λ=λargmaxIP(IO,λ)logP(O,Iλ)

通过 E 步和 M 步的迭代,直到 λ ‾ \overline{\lambda} λ 收敛。

7. HMM 模型 API 介绍

学习目标:

  • 指导 HMM 模型 API 使用方法

7.1 API 的安装

官网链接:https://hmmlearn.readthedocs.io/en/latest/

pip install hmmlearn==0.2.5

7.2 hmmlearn介绍

hmmlearn 实现了三种 HMM 模型类,按照观测状态是连续状态还是离散状态,可以分为两类。

  • GaussianHMM 和 GMMHMM 是连续观测状态的 HMM 模型
  • MultinomialHMM 是离散观测状态的模型,也是我们在 HMM 原理系列篇里面使用的模型
  • GaussianHMM:高斯隐马尔可夫模型(Gaussian Hidden Markov Model)
  • GMMHMM:混合高斯隐马尔可夫模型(Gaussian Mixture Hidden Markov Model)
  • MultinomialHMM:多项式隐马尔可夫模型(Multinomial Hidden Markov Model)

在这里主要介绍我们前面一直讲的关于离散状态的 MultinomialHMM 模型。对于 MultinomialHMM 的模型,使用比较简单。

from hmmlearn import hmm


model = hmm.MultinomialHMM (n_components=1, startprob_prior=1.0,
                            algorithm='viterbi', random_state=None,
                            n_iter=10, tol=0.01, verbose=False,
                            params='ste', init_params='ste')
  • 作用hmm.MultinomialHMM()hmmlearn 库中的一个类,它用于创建一个具有多项式(离散)发射的隐马尔可夫模型。
  • 参数
    • n_components:(int)隐含状态个数
    • n_iter:(int, optional )训练时循环(迭代)最大次数
    • tol:(float, optional )收敛阈值。如果对数似然的增益低于此值,则 EM 将停止。
    • verbose:(bool, optional )赋值为 True 时,会向标准输出输出每次迭代的概率(score)与本次
    • init_params:(string, optional )决定哪些参数会在训练时被初始化。
      • ‘s’表示 startprob:参数对应我们的隐藏状态初始分布 Π \Pi Π
      • ‘t’表示 transmat:对应我们的状态转移矩阵 A A A
      • ‘e’表示 emissionprob:对应我们的观测状态概率矩阵 B B B
      • 空字符串 “” 代表全部使用用户提供的参数进行训练
  • 方法
    • fit()
    • decode()
    • score()

7.3 MultinomialHMM 实例

下面我们用我们在前面讲的关于球的那个例子使用 MultinomialHMM 跑一遍。

import numpy as np
from hmmlearn import hmm
# 设定隐藏状态的集合 
states = ["box 1", "box 2", "box 3"]
n_states = len(states)

# 设定观察状态的集合
observations = ["red", "white"]
n_observations = len(observations)

# 设定初始状态分布
start_probability = np.array([0.2, 0.4, 0.4])

# 设定状态转移概率分布矩阵
transition_probability = np.array([[0.5, 0.2, 0.3],
                                   [0.3, 0.5, 0.2],
                                   [0.2, 0.3, 0.5]])

# 设定观测状态概率矩阵
emission_probability = np.array([[0.5, 0.5],
                                 [0.4, 0.6],
                                 [0.7, 0.3]])
# 定义模型
model = hmm.MultinomialHMM(n_components=n_states)

# 设定模型参数
model.startprob_ = start_probability  # 初始化状态分布
model.transmat_ = transition_probability  # 初始化状态转移概率分布矩阵
model.emissionprob_ = emission_probability  # 初始化观测状态概率矩阵

现在我们来跑一跑 HMM 问题三:维特比算法的解码过程,使用和之前一样的观测序列来解码,代码如下:

seen = np.array([[0, 1, 0]]).T  # 设定观测序列(红白红)

# 维特比模型训练
box = model.predict(seen)

print("球的观测顺序为:", ' → '.join(map(lambda x: observations[x], seen.flatten())))
# 注意:需要使用flatten方法,把seen从二维变成一维
print("最可能的隐藏状态序列为:", ' → '.join(map(lambda x: states[x], box)))

使用 map 函数将 seen 中数组的元素 对应 observations 中的元素
使用 map 函数将 box 中数组的元素 对应 states 中的元素

球的观测顺序为: red → white → red
最可能的隐藏状态序列为: box 3 → box 2 → box 2

我们再来看看求 HMM 问题一的观测序列的概率的问题,代码如下:

prob = model.score(seen)

print(f"观测序列出现的概率为:{
      
      prob}")
观测序列出现的概率为:-2.038545309915233

要注意的是 score 函数返回的是以自然对数为底的对数概率值,我们在 HMM 问题一中手动计算的结果是未取对数的原始概率是 0.13022。对比一下:

import math

prob_true = math.exp(prob)
print(f"观测序列出现的概率为:{
      
      prob_true * 100:.3f}%")
观测序列出现的概率为:13.022%

猜你喜欢

转载自blog.csdn.net/weixin_44878336/article/details/131237767