维特比算法的通俗案例解释

维特比算法本质上就是一个动态规划DP算法,在知乎上看到了关于一个解释维特比算法的解释https://www.zhihu.com/question/20136144, 因此在此特意在转载下,并加入一些个人对于结合实际案例场景下的算法理解说明:

1.题目背景:

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

因此,从HMM隐马尔科夫模型的角度来说,健康或者发烧 是身体隐含的状态state, 而正常,头晕或者冷是观察序列,

因此这三天的观察序列为: 正常, 冷, 头晕, 而每天的身体隐含状况则未知, 这在HMM问题中属于解码问题,可以通过维特比算法,利用动态规划算法,来求解出整个HMM链中每天的隐含状态。

2.已知情况:

隐含的身体状态 = { 健康 , 发烧 }

可观察的感觉状态 = { 正常 , 冷 , 头晕 }

假定阿驴身体状态的概率分布为 = { 健康:0.6 , 发烧: 0.4 }   这就是初始状态序列。

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

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


月儿认为的在相应身体状况条件下,身体感觉这一观测序列的条件概率分布 = {
             正常            冷            头晕

健康:    0.5             0.4             0.1


发烧:    0.1             0.3             0.6 

}

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

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

3.题目:

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

  • 第一天的时候,观测值为正常, 因此对每一个状态(健康或者发烧)的情况下,根据状态分布矩阵与条件概率矩阵,求得观测值与每个状态的联合概率分布
  •      P(正常,第一天健康) = P(正常|健康) * P(健康|初始情况) = 0.5 * 0.6 = 0.3  
  •      P(正常, 第一天发烧) = P(正常|发烧) * P(发烧|初始情况) = 0.1 * 0.4 = 0.04
  • 注意点:P(第一天健康) == P(正常,第一天健康), 因为观察值正常 是实际确定了的序列值,因此联合概率与隐含状态的概率 等价
  • 第二天的时候,观测值为冷,继续来求观测值与所有可能的隐含状态的联合概率, 而此时每个隐含状态(健康或者发烧),都要考虑上一个状态的概率以及到当前状态的条件转移概率分布,
  •        例如: 当前观测值为冷,假定当前隐含状态为健康,求当前的联合概率分布P(冷,第二天健康) 。首先从 昨天的状态到当前的健康状态 有两种路径(昨天的状态还没确定,而只是先计算出每个状态的概率分布): 昨天健康 ----> 今天健康,   昨天发烧 -----> 今天健康。 这两个路径分别的概率为 0.3 * 0.7 以及 0.04 * 0.4, 可以看到 当前如果为健康时,昨天为健康的概率更大,因此我们选定昨天健康 ----> 今天健康 这条路径,即记录下当前为健康时,昨天也为健康状态, 然后求得当前的联合概率分布 P(冷,第二天健康) = (0.3 * 0.7 ) * 0.4 = P(第二天健康), 即如下:
  •  P(冷,第二天健康) = max{0.3*0.7, 0.04*0.4} * 0.4=0.3* 0.7 * 0.4=0.084 此时我们需要记录概率最大的路径的前一个状态,即0.084路径的前一个状态,我们在小本本上记下,第二天健康时,第一天的状态也为健康。 
  •  同理, 假定当前隐含状态为发烧时, 求当前的联合概率分布P(冷,第二天发烧) 。一样的道理,从昨天的状态到当前的发烧状态也有两种路径:  昨天健康 ----> 今天发烧,   昨天发烧 -----> 今天发烧,这两个路径分别的概率为 0.3 * 0.3以及 0.04 * 0.6, 可以看到 当前如果为发烧时,昨天为健康的概率更大,因此我们选定昨天健康 ----> 今天发烧 这条路径,即记录下当前为发烧时,昨天也为健康状态, 当前的联合概率分布 P(冷,第二天发烧) = (0.3 * 0.3 ) * 0.3 = P(第二天发烧), 即如下:
  •  P(冷,第二天发烧) = max{0.3*0.3,  0.04*0.6} * 0.3=0.027, 同样的在0.027这个路径上,第二天为发烧时,第一天也是健康的。
  • 第三天的时候,观察序列为头晕,仍旧来求第三天观察序列与所有状态的联合概率分布,此时通过第二天的计算,可以求得第二天的健康状态与发烧状态的概率分别0.084 和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,这样我们可以得到最优路径的终点,是发烧状态
  • 由最优状态开始回溯。根据前面所记录的, 在求得第三天发烧的时候,我们记录的第二天最大概率的状态为健康,因此确定第二天为健康状态,继续回溯,当第二天为健康状态时,我们记录的第一天是健康的。这样,我们的状态序列逆推出来了。即为:健康,健康,发烧
  • 简略的画个图吧:
  • 注意点:图中求得max概率的时候 其实省略了 状态到观测值的概率,例如max = 0.084 = 03 * 0.7 * 0.3, 由于画图缘故省略了这一块,P(第一天健康) = P(正常,第一天健康), 因为观察值正常 是实际确定了的序列值,因此联合概率与隐含状态的概率 等价
别人也给出了一个HMM概率图 可以参考下:
这儿的箭头指向就是一个回溯查询小本本的过程,我们在编写算法的时候,其实也得注意,每一个概率最大的 单条路径 上都要把前一个状态记录下来。
知乎上也有人给出了相应的代码实现:
https://github.com/qqiang00/Machine-Learning-Samples/blob/master/mynltk/cn_viterbi.py
后续CRF条件随机场其实也是强化版的马尔科夫随机场,核心还是维特比算法等等

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值