hmm和Veterbi算法(一)

只是略微的看了些,有点感觉,还未深入,做个记录。

参考: 隐马尔可夫 (HMM)、前 / 后向算法、Viterbi 算法 再次总结

   谁能通俗的讲解下 viterbi 算法?

   数学之美第二版的第 26 章

本文结构:

  1.hmm三要素

  2.维特比算法

  3.简明例子

hmm三要素:

1.初始概率分布 π

      z1 可能是状态 1,状态 2 ... 状态 n,于是 z1 就有个 N 点分布:

Z1

状态 1

状态 2

...

状态 n

概率

P1

P2

...

Pn

      即:Z1 对应个 n 维的向量。

      上面这个 n 维的向量就是初始概率分布,记做π。

2.状态转移矩阵 A

      但 Z2 就不能简单的 “同上” 完事了,因为 Z2 和 Z1 不独立,所以 Z2 是状态 1 的概率有:Z1 是状态 1 时 Z2 是状态 1,Z1 是状态 2 时 Z2 是状态 1,..., Z1 是状态 n 时 Z2 是状态 1,于是就是下面的表

Z2

Z1

状态 1

状态 2

...

状态 n

状态 1

P11

P12

...

P1n

状态 2

P21

P22

...

P2n

...

...

...

...

...

状态 n

Pn1

Pn2

...

Pnn

       即:Z1->Z2 对应个 n*n 的矩阵。

       同理:Zi -> Zi+1 对应个 n*n 的矩阵。

      上面这些 n*n 的矩阵被称为状态转移矩阵,用 An*n 表示。

      当然了,真要说的话,Zi -> Zi+1 的状态转移矩阵一定都不一样,但在实际应用中一般将这些状态转移矩阵定为同一个,即:只有一个状态转移矩阵

3.观测矩阵 B

      如果对于 zi 有:状态 1, 状态 2, ..., 状态 n,那 zi 的每一个状态都会从下面的 m 个观测中产生一个:观测 1, 观测 2, ..., 观测 m,所以有如下矩阵:

X

Z

观测 1

观测 2

...

观测 m

状态 1

P11

P12

...

P1m

状态 2

P21

P22

...

P2m

...

...

...

...

...

状态 n

Pn1

Pn2

...

Pnm

      这可以用一个 n*m 的矩阵表示,也就是观测矩阵,记做 Bn*m。

      由于 HMM 用上面的π,A,B 就可以描述了,于是我们就可以说:HMM 由初始概率分布π、状态转移概率分布 A 以及观测概率分布 B 确定,为了方便表达,把 A, B, π 用 λ 表示,即:

            λ = (A, B, π)

维特比算法

维特比算法是一个特殊但应用最广的动态规划算法,它是针对篱笆网络的有向图(Lattice)的最短路径问题而提出的。凡是使用隐含马尔可夫模型描述的问题都可以用维特比算法来解码,包括今天的数字通信、语音识别、机器翻译、拼音转汉字、分词等。

hmm和Veterbi算法(一)

1.基础概括


(1)如果概率最大的路径 P(或叫最短路径)经过某个点,比如下图中的 X22,那么这条路径上从起始点 S 到 X22 的这一段子路径 Q,一定是 S 到 X22 之间的最短路径。否则,用 S 到 X22 的最短路径 R 替代 Q,便构成了一条比 P 更短的路径,这显然是矛盾的。

(2)从 S 到 E 的路径必定经过第 i 时刻的某个状态,假定第 i 时刻有 k 个状态,那么如果记录了从 S 到第 i 个状态的所有 k 个节点的最短路径,最终的最短路径必经过其中的一条。这样,在任何时刻,只需要考虑非常有限条最短路径即可。

 (3)结合上述两点,假定当我们从状态 i 进入状态 i+1 时,从 S 到状态 i 上各个节点的最短路径已经找到,并且记录在这些节点上,那么在计算从起点 S 到前一个状态 i 所有的 k 个结点的最短路径,以及从这 k 个节点到 Xi+1,j 的距离即可。

2.总结

(1)从点 S 出发,对于第一个状态 X1 的各个节点,不妨假定有 n1 个,计算出 S 到它们的距离 d(S,X1i),其中 X1i 代表任意状态 1 的节点。因为只有一步,所以这些距离都是 S 到它们各自的最短距离。

(2)对于第二个状态 X2 的所有节点,要计算出从 S 到它们的最短距离。对于特点的节点 X2i,从 S 到它的路径可以经过状态 1 的 n1 中任何一个节点 X1i,对应的路径长度就是 d(S,X2i) = d(S,X1i) + d(X1i,X2i)。由于 j 有 n1 种可能性,我们要一一计算,找出最小值。即:

d(S,X2i) = minI=1,n1 d(S,X1i) + d(X1i,X2i)

这样对于第二个状态的每个节点,需要 n1 次乘法计算。假定这个状态有 n2 个节

点,把 S 这些节点的距离都算一遍,就有 O(n1·n2) 次计算。

(3)接下来,类似地按照上述方法从第二个状态走到第三个状态,一直走到最后一个状态,就得到了整个网格从头到尾的最短路径。每一步计算的复杂度都和相邻两个状态 Si 和 Si+1 各自的节点数目 ni,ni+1 的乘积成正比,即 O(ni·ni+1)

(4)假设这个隐含马尔可夫链中节点最多的状态有 D 个节点,也就是说整个网格的宽度为 D,那么任何一步的复杂度不超过 O(D2),由于网格长度是 N,所以整个维特比算法的复杂度是 O(N·D2)。

hmm和Veterbi算法(一)

 简明例子

1. 题目背景:

从前有个村儿,村里的人的身体情况只有两种可能:健康或者发烧。
假设这个村儿的人没有体温计或者百度这种神奇东西,他唯一判断他身体情况的途径就是到村头我的偶像金正月的小诊所询问。
月儿通过询问村民的感觉,判断她的病情,再假设村民只会回答正常、头晕或冷。
有一天村里奥巴驴就去月儿那去询问了。
第一天她告诉月儿她感觉正常。
第二天她告诉月儿感觉有点冷。
第三天她告诉月儿感觉有点头晕。
那么问题来了,月儿如何根据阿驴的描述的情况,推断出这三天中阿驴的一个身体状态呢?
为此月儿上百度搜 google ,一番狂搜,发现维特比算法正好能解决这个问题。月儿乐了。

2. 已知情况:

隐含的身体状态 = {健康 , 发烧}                    Q 所有可能的状态集合

可观察的感觉状态 = {正常 , 冷 , 头晕}                 V 所有可能的观测的集合

月儿预判的阿驴身体状态的概率分布 = {健康:0.6 , 发烧: 0.4}      pai 初始概率分布
这就是初始状态序列。


月儿认为的阿驴身体健康状态的转换概率分布 = {
健康 -> 健康: 0.7 ,
健康 -> 发烧: 0.3 ,
发烧 -> 健康:0.4 ,
发烧 -> 发烧: 0.6
}

这样就可以列出相应的状态转移矩阵。


月儿认为的在相应健康状况条件下,阿驴的感觉的概率分布 = {
健康,正常:0.5 ,冷 :0.4 ,头晕: 0.1 ;
发烧,正常:0.1 ,冷 :0.3 ,头晕: 0.6
}

这样就可以列出相应的观测矩阵。

由上面我们可以发现,HMM 的三要素都齐备了,下面就是解决问题了。
阿驴连续三天的身体感觉依次是: 正常、冷、头晕 。          O是对应的观测序列

3. 题目:

已知如上,求:阿驴这三天的身体健康状态变化的过程是怎么样的?即已知观测序列和 HMM 模型的情况下,求状态序列。     要求解的是   I,状态序列
4. 过程:

  • 初始化。第一天的时候,对每一个状态(健康或者发烧),分别求出第一天身体感觉正常的概率:

    P(第一天健康) = P(正常 | 健康)*P(健康 | 初始情况) = 0.5 * 0.6 = 0.3

    P(第一天发烧) = P(正常 | 发烧)*P(发烧 | 初始情况) = 0.1 * 0.4 = 0.04

  • 第二天的时候,对每个状态,分别求在第一天状态为健康或者发烧情况下观察到冷的最大概率。在维特比算法中,我们先要求得路径的单个路径的最大概率,然后再乘上观测概率。

    P(第二天健康) = max{0.3*0.7, 0.04*0.4}*0.4=0.3*0.7*0.4=0.084 此时我们需要记录概率最大的路径的前一个状态,即 0.084 路径的前一个状态,我们在小本本上记下,第一天健康。

    P(第二天发烧)=max{0.3*0.3, 0.04*0.6}*0.3=0.027, 同样的在 0.027 这个路径上,第一天也是健康的。

  • 第三天的时候,跟第二天一样。

    P(第三天健康)=max{0.084*0.7, 0.027*0.4}*0.1=0.00588,在这条路径上,第二天是健康的。

    P(第三天发烧)=max{0.084*0.3, 0.027*0.6}*0.6=0.01512, 在这条路径上,第二天是健康的。

  • 最后一天的状态概率分布即为最优路径的概率,即 P(最优)=0.01512,这样我们可以得到最优路径的终点,是健康
  • 由最优路径开始回溯。请看我们的小本本,在求得第三天发烧概率的时候,我们的小本本上面写的是第二天健康,好了,第二天就应该是健康的状态,然后在第二天健康的情况下,我们记录的第一天是健康的。这样,我们的状态序列逆推出来了。即为:健康,健康,发烧
  • 简略的画个图吧:
hmm和Veterbi算法(一)

这儿的箭头指向就是一个回溯查询小本本的过程,我们在编写算法的时候,其实也得注意,每一个概率最大的单条路径上都要把前一个状态记录下来。