专栏名称: 机器学习研究会
机器学习研究会是北京大学大数据与机器学习创新中心旗下的学生组织,旨在构建一个机器学习从事者交流的平台。除了及时分享领域资讯外,协会还会举办各种业界巨头/学术神牛讲座、学术大牛沙龙分享会、real data 创新竞赛等活动。
目录
相关文章推荐
机器之心  ·  独享MRDIMM有多强?至强6性能核处理器的 ... ·  2 天前  
宝玉xp  ·  转发微博-20241226062500 ·  3 天前  
爱可可-爱生活  ·  几篇论文实现代码:《Salient ... ·  3 天前  
爱可可-爱生活  ·  “AI能成为探索科学未知的新工具吗?一项创新 ... ·  3 天前  
51好读  ›  专栏  ›  机器学习研究会

【学习】 隐马尔科夫模型-前向算法

机器学习研究会  · 公众号  · AI  · 2017-05-26 21:37

正文

隐马尔科夫模型-前向算法


在该篇文章中讲了隐马尔科夫模型(HMM)一基本模型与三个基本问题 隐马尔科夫模型-基本模型与三个基本问题,这篇文章总结一下隐马尔科夫链(HMM)中的前向与后向算法,首先给出这俩个算法是为了解决HMM的第一个基本问题。


先回忆一下第一个问题:

第一个问题是求,给定模型的情况下,求某种观测序列出现的概率。


比如,给定的HMM模型参数已知,求出三天观察是(Dizzy,Cold,Normal)的概率是多少?(对应的HMM模型参数已知的意思,就是说的A(trainsition_probability),B(emission_probability),pi矩阵是已经知道的。)


相关条件如下图所示:

由上图所示,也就是说,可以写成如下代码:

trainsition_probability = [[0.7,0.3],[0.4,0.6]]     emission_probability = [[0.5,0.4,0.1],[0.1,0.3,0.6]]   

pi = [0.6,0.4]


在第一个问题中,我们需要求解出三天观察是(Dizzy,Cold,Normal)的概率是多少?


这里为了演示简单,我只求解出俩天观察为(Dizzy,Cold)的概率是多少!


这个问题太好求解了,最暴力的方法就是将路径全部遍历一遍。下面尽可能通俗易懂的说明一下:
首先画出时间序列状态图如下:



下面,我详细走一遍一条路径的暴力算法,这样既可以避开公式的晦涩,也不失正确性。其它路径完全类似


第一天为Healthy的概率为:0.6


在第一天为Healthy的基础上,观察为Dizzy的概率为:P(Dizzy|Healthy)=0.6*P(Healthy->Dizzy)=0.6*0.1=0.06


然后求出在第一天为Healthy的基础上,并且第一天表现为Dizzy的前提下,第二天也为Healthy的概率为:
P(Healthy|Healthy,Dizzy) = P(Dizzy|healthy)*07 = 0.06*0.7


上面求完的时候,代表下图中的红线已经转移完了。


好,那么当在前面基础上,第二天观察为Cold的概率为:
P(Cold|(Healthy,Dizzy),(Healthy)) = P(Healthy|Healthy,Dizzy)*
0.4 = 0.06*0.7*0.4
现在我们已经完成一条路径的完整结果了。


就是在第一天隐含状态为Healthy和第二天隐含状态为Healthy的基础上,观察序列为Dizzy,Cold的概率为
P(Dizzy,Cold|Healthy,Healthy) = 0.06*0.7*0.4=0.0168


那么同理,我们就可以求出其它三条路径。
(1)在第一天隐含状态为Healthy和第二天隐含状态为Fever的基础上,观察序列为Dizzy,Cold的概率
(2)在第一天隐含状态为Fever和第二天隐含状态为Healthy的基础上,观察序列为Dizzy,Cold的概率
(3)在第一天隐含状态为Fever和第二天隐含状态为Fever的基础上,观察序列为Dizzy,Cold的概率


然后最后的第一个问题的结果就是将这四个结果相加起来就可以了。是不是很简单,那么为了还需要前向后向算法来解决这个事呢?


其实这个算法在现实中是不可行的。我给的例子由于是为了讲解容易,状态值和观察值都很小,但是实际中的问题,隐状态的个数是非常大的。


那么我们的计算量是不可以忍受的。


我们可以稍微估计一下,加入状态值是N个,观察值是K个。总共观察长度为T。


那么我们的路径总个数就是N的T次方,我的天,这个复杂度已经接受不了了,到达了每个隐含状态的时候,还需要算一遍观察值出现的概率(每个隐状态计算一遍到观察值的概率)。又要乘以NT(当然这已经对前面很大复杂度构成不了多少作用了)


所以我们得出结论,暴力法在这里并不实用,于是就引出了前向后向算法。它们都是基于动态规划思想求解。下面介绍一下:


1

  前向算法



我们首先定义一下前向概率


定义:给定隐马科夫模型lamda,定义到时刻t为止的观测序列为01,02,03....0t且状态为qi的概率为前向概率,记作

可以递推地求得前向概率及观测序列概率


下面,我们可以整理一下前向算法的流程:

输入:隐马尔可夫模型,观测序列

输出:观测序列概率


(1)初值

前向概率的定义中一共限定了两个条件。


一是到当前为止的观测序列,另一个是当前的状态。所以初值的计算也有两项(观测和状态),一项是初始状态概率,另一项是发射到当前观测的概率。


(2)递推对t=1,2,3,.....,T-1



每次递推同样由两部分构成,大括号中是当前状态为i且观测序列的前t个符合要求的概率,括号外的是状态i发射观测t+1的概率。


下面稍微解释一下公式:


(3)终止

由于到了时间T,一共有N种状态发射了最后那个观测,所以最终的结果要将这些概率加起来(因为每个隐状态都可能产生我们需要的观测值,所以都要加起来)。


公式可以用下面的转移图表示,假设我要求第二层某个结点的前向概率,等于前一层所有结点到该结点的转移,如下图:

由于每次递推都是在前一次的基础上进行的,所以降低了复杂度(计算只存在于相邻的俩个时间点)。计算如下图所示:

下方标号表示时间节点,每个时间点都有N种状态,所以相邻两个时间之间的递推消耗N^2次计算。


而每次递推都是在前一次的基础上做的,所以只需累加O(T)次,所以总体复杂度是O(T)个N^2,即0(TN^2),这比起我们前面说的暴力法的复杂度已经好了太多了。


到这里为止,前向算法也就讲完了。本文通过一个具体简单例子,走了一遍过程,期间有一些自己的总结和理解,希望对大家有帮助~


2

  python实现代码



代码如下: