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

news2024/11/26 6:00:38

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%

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/651581.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用华为云开发者插件一键部署应用到ECS

前言 笔者是一名码龄5年左右的程序员,大学是能源行业,处于对技术(碎银几两)的热爱,选择投身搬砖之路。从用C语言在控制台打印第一句“Hello World!”开始,笔者陆续接触过C/C、Java、Golang、Py…

STM32 Proteus仿真4x4矩阵15位抢答器数码管TM1637显示-0039

STM32 Proteus仿真4x4矩阵15位抢答器数码管TM1637显示-0039 Proteus仿真小实验: STM32 Proteus仿真4x4矩阵15位抢答器数码管TM1637显示-0039 功能: 硬件组成:STM32F103R6单片机 TM1637驱动4位数码管4x4矩阵键盘蜂鸣器 1.有一个开启键&am…

【Unity Shader】从入门到着魔(1)基本概念:什么是网格?材质?Shader?

文章目录 一、什么是网格(Mesh)?二、什么是MeshFilter(网格过滤器)?三、什么是MeshRenderer(网格渲染器)?四、什么是材质(Material)?五、什么是Shader(着色器)?一、什么是网格(Mesh)? 如上图,模型的三角形面就叫做网格(Mesh),它的本质是一堆顶点数据的规则…

前端基础知识学习——获取dom对象、获取html属性、获取内容、更改样式、创建dom元素、删除元素、代替元素(十)

<!DOCTYPE html> <html lang"en"><head ><meta charset"utf-8" /><title>这是一首离别信</title><script src"https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script></head&g…

Git 基础知识

看版本 git --version 初始化 git init &#xff08;需要在准备建的仓库的目标文件夹根目录下运行&#xff09; 初始化一个仓库供所有其他人一起使用&#xff0c;平时一般都是建好的&#xff0c;个人克隆拉取这个仓库到本地进行编辑。 初始化会产生一个分支叫 master 初…

vue3创建新项目报错:Cannot find module ‘xxx‘

创建vue3项目&#xff0c;命令&#xff1a; 1. 使用vite创建&#xff1a; npm create vitelatest my-vue-app -- --template vue-ts 2.使用vue官方命令&#xff1a; npm init vuelatest 创建vue3模板学习vue3.3的新语法&#xff0c;创建完成后发现文件很多爆红&#xff1a…

华为虚拟化openEuler release 22.03 (LTS-SP1)安装VMTools

华为虚拟化openEuler release 22.03 (LTS-SP1)安装VMTools 环境 虚拟化平台&#xff1a;华为Fusioncompute 6.5.1.SPH6 X86 虚拟机操作系统&#xff1a;openEuler release 22.03 (LTS-SP1) VMTools版本&#xff1a;vmtools-2.5.0.155.tar.bz2 默认vmtools不支持openEuler rele…

【C/C++练习】合并k个已排序的链表

目录 &#x1f43b;题目描述&#xff1a; &#x1f43b;‍❄️思路一&#xff1a;暴力求解法 &#x1f43c;第一步&#xff1a;确定合并后链表的头节点rhead&#x1f43c;第二步&#xff1a;选择次小的进行尾插&#x1f43c;代码实现&#xff1a; &#x1f43b;‍❄️思路二&a…

《C++继承》

本文主要介绍继承的相关知识 文章目录 思维导图一、继承的概念及定义1.继承的概念2.继承的定义2.1 定义格式2.2 继承关系和访问限定符2.3 继承基类成员访问方式的变化 二、基类和派生类对象的赋值转换三、继承中的作用域四、派生类的默认成员函数五、继承与友元六、继承与静态成…

Vue中的Ajax 配置代理 slot插槽

4.1.Vue脚手架配置代理 本案例需要下载axios库npm install axios 配置参考文档Vue-Cli devServer.proxy vue.config.js 是一个可选的配置文件&#xff0c;如果项目的 (和 package.json 同级的) 根目录中存在这个文件&#xff0c;那么它会被 vue/cli-service 自动加载。你也可…

【OJ比赛日历】快周末了,不来一场比赛吗? #06.17-06.23 #13场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 2023-06-17&#xff08;周六&#xff09; #2场比赛2023-06-18…

使用matplotlib制作动态图

使用matplotlib制作动态图 一、简介二、模块简介1. **FuncAnimation**类介绍2. 定义动画更新函数 三、使用matplotlib制作动画1.一步法制作动态图片2. 两步法制作动态图片 一、简介 matplotlib(https://matplotlib.org/)是一个著名的python绘图库&#xff0c;由于其灵活强大的…

【Qt】使用libmodbus

这里写目录标题 下载编译使用Demo参照&#xff1a; Qt自带QModbusTcpClient&#xff0c;换个电脑就不好使了&#xff0c;换libmodbus 下载 可以去github下载 链接: https://pan.baidu.com/s/13lgEZ59Dt5M7zmTJNpfKvg?pwdyzfm 提取码: yzfm 下载libmodbus 并解压 编译 进入…

20分钟做一套采购审批系统

1、设计输入模板 excel画表格界面 # 公式代表新建时以默认值代替 2、设置单元格为签名控件 双击单元格后&#xff0c;会默认显示当前用户的信息,用于签名 3、设置要合计的数据 生成的合计公式会默认放到下一行 4、设置单元格的ID与标题&#xff0c;在添加或者删除行或者列时&am…

影像组学技术的基础和应用

一、概述 1. 影像组学足迹史 2003年&#xff0c;Mark A. Kriegsman和Randy L. Buckner发表的关于视觉系统空间组织的研究文章The genetic and functional basis of the spatial organization of the visual system&#xff0c;为影像组学领域提供了先驱性思路&#xff0c;奠定…

PID算法:过程控制中的重要质量指标

PID算法&#xff1a;过程控制中几个重要的概念 PID算法广泛的被应用在很多的控制系统中&#xff0c;最终的目的都是希望通过pid控制器实现被控量能稳定在预期的目标值。 使用pid控制器作用于系统的时候&#xff0c;正常情况下它应该是不断的发生作用的&#xff0c;从而让系统能…

OJ Goldbach‘s Conjecture

1.题目 题目描述 In 1742, Christian Goldbach, a German amateur mathematician, sent a letter to Leonhard Euler in which he made the following conjecture: Every even number greater than 4 can be written as the sum of two odd prime numbers. For exampl…

可调电源LM317 的内部原理 - 特殊的电压跟随器

之前一直没想过这类LDO 内部是怎么整的&#xff0c;它似乎是用一个分压电路采集它输出的电压作为参考&#xff0c;然后却能把输出电压稳定下来&#xff0c;颇有种左脚踩右脚上天的意思。典型的LM317 电路如下&#xff1a; 如果是个普通的电压跟随器&#xff0c;无论是基于三极管…

K8S之istio流量控制管理(十七)

一&#xff0c;istio介绍 1、istio架构 结合上图我们来理解Istio的各组件的功能及相互之间的协作方式。 1. 自动注入&#xff1a;在创建应用程序时自动注入 Sidecar代理Envoy程序。在 Kubernetes中创建 Pod时&#xff0c;Kube-apiserver调用控制面组件的 Sidecar-Injector服…

4年外包上岸,想劝大家:这类公司能不去就不去...

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…