一:隐马尔科夫模型 本人对这篇转载做了修改!
英文链接:http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/html_dev/main.html
文章链接:http://blog.csdn.net/likelet/article/details/7056068 此文的公式和说明更清晰一些,没有分段总结。
文章原始链接:http://www.52nlp.cn/hmm-learn-best-practices-one-introduction
算法杂货铺——分类之贝叶斯网络及应用:http://www.cnblogs.com/leoo2sk/archive/2010/09/18/bayes-network.html
(一):定义及简介:
介绍(introduction)
通常我们总是对寻找某一段时间上的模式感兴趣,这些模式可能出现在很多领域:一个人在使用电脑的时候使用的命令的序列模式;一句话中的单词的序列;口语中的音素序列。总之能产生一系列事件的地方都能产生有用的模式。
考虑一个最简单的情况:有人(柯南?)试图从一块海藻来推断天气的情况。一些民间的传说认为“soggy”的海藻意味着潮湿(wet)的天气,“dry”的海藻预示着晴朗(sun)。如果海藻处于中间状态“damp”,那就无法确定了。但是,天气的情况不可能严格的按照海藻的状态来变化,所以我们可以说在一定程度上可能是雨天或是晴天。另一个有价值的信息是之前某些天的天气情况,结合昨天的天气和可以观察到的海藻的状态,我们就可以为今天的天气做一个较好的预报。
这是在我们这个系列的介绍中一个非常典型的系统。
- 首先我们介绍一个可以随时间产生概率性模型的系统,例如天气在晴天或者雨天之间变动。
- 接下来我们试图去预言我们所不能观察到的"隐形"的系统状态,在上面的例子中,能被观察到的序列就是海藻的状态吗,隐形的系统就是天气情况
- 然后我们看一下关于我们这个模型的一些问题,在上面那个例子中,也许我们想知道
- 如果我们观察一个星期每一天的海藻的状态,我们是否能知相应的其天气情况
- 如果给出一个海藻状态的序列,我们是否能判断是冬天还是夏天?我们假设,如果海藻干(dry)了一段时间,那就意味着是夏天如果海藻潮湿(soggy)了一段时间,那可能就是冬天。
(二):生成模式(Generating Patterns)
- 确定的模式(Deterministic Patterns)
考虑交通灯的例子,一个序列可能是红-红/橙-绿-橙-红。这个序列可以画成一个状态机,不同的状态按照这个状态机互相交替
我们可以注意到,每一个状态都只依赖于此前的状态,如果当前的是绿灯,那么接下来就是橙灯,这就是一个确定型的系统。确定型的系统更容易理解和分析,只要这些状态转移都是已知的。
- 不确定的模式(Non-Deterministic Patterns)
为了让之前那个天气的例子更贴近现实,我们可以添加一个状态-多云。和交通灯的例子不同,我们不能得到一个确定的状态转移系统,但是我们还是希望能得到一个天气的模式。
一种办法就是假设这个模型的每个状态都只依赖于之前的状态,这个假设被称为马尔科夫假设,这个假设可以大大的简化这个问题。显然,这个假设可能是一个非常糟糕的假设,导致很多重要的信息都丢失了。
当涉及到天气的时候,马尔科夫假设假设如果我们知道之间一些天的天气的信息,不考虑风力、气压等因素,那么我们就能预言今天的天气。当然,和其他许多例子一样,这个列子也是不合实际的。但是,这样一个简化的系统可以有利于我们的分析,所以我们通常接受这样的假设,因为我们知道这样的系统能让我们获得一些有用的信息,尽管不是十分准确的。
一个马尔科夫过程就是指过程中的每个状态的转移只依赖于之前的n个状态,这个过程被称为1个n阶的模型,其中n是影响转移的状态的数目。最简单的马尔科夫过程就是一阶过程,每一个状态的转移只依赖于其之间的那一个状态。注意这和确定型的系统不一样,因为这种装因是有概率的,而不是确定的。下面这个图展示了天气这个例子中所有可能的一阶转移:
注意一个含有M个状态的一阶过程有M的平方个状态转移。每一个转移的概率叫做状态转移概率(state transition probability),就是从一个状态转移到另一个状态的概率。这所有的M的平方个概率可以用一个状态转移矩阵来表示。注意这里有一个假设,概率不随时间的变化而变化,这又是一个不现实但很重要的假设。下面就是一个状态转移矩阵的列子:
这个矩阵的意思是,如果昨天是晴天,那么今天又50%的可能是晴天,37.5%的概率是阴天,12.5%的概率会下雨,很明显,每一行的和都是1。
为了初始化这样一个系统,我们需要一个初始的概率向量:
这个向量表示第一天是晴天。
到这里,我们就为一阶马尔科夫过程定义了以下三个部分:
- 状态:晴天、阴天和下雨
- 初始向量:定义系统在时间为0的时候的状态的概率
- 状态转移矩阵:每种天气转换的概率
所有的能被这样描述的系统都是一个马尔科夫过程。
- 总结(Summary)
我们为了找到随时间变化的模式,就试图去建立一个可以产生模式的过程模型。我们使用了具体的时间步骤、状态、并且做了马尔科夫假设。有了这些假设,这个能产生模式系统就是一个马尔科夫过程。一个马尔科夫过程包括一个初始向量和一个状态转移矩阵。关于这个假设需要注意的一点是状态转移概率不随时间变化。
(三):隐含模式(Hidden Patterns)
当马尔科夫过程不够强大的时候,我们又该怎么办呢?
在某些情况下马尔科夫过程不足以描述我们希望发现的模式。回到之前那个天气的例子,一个隐居的人可能不能直观的观察到天气的情况,但是有一些海藻。民间的传说告诉我们海藻的状态在某种概率上是和天气的情况相关的。在这种情况下我们有两个状态集合,一个可以观察到的状态集合(海藻的状态)和一个隐藏的状态(天气的状况)。我们希望能找到一个算法可以根据海藻的状况和马尔科夫假设来预测天气的状况。
一个更现实的例子是语音识别,我们听到的声音是声带、喉咙和一起其他的发音器官共同作用的结果。这些因素相互作用,共同决定了每一个单词的声音,而一个语音识别系统检测的声音(可以观察的状态)是人体内部各种物理变化(隐藏的状态、引申一个人真正想表达的意思)产生的。
某些语音识别设备把内部的发音机制作为一个隐藏的状态序列,把最后的声音看成是一个和隐藏的状态序列十分相似的可以观察到的状态的序列。在这两个例子中,一个非常重要的地方是隐藏状态的数目和可以观察到的状态的数目可能是不一样的。在一个有三种状态的天气系统(sunny、cloudy、rainy)中,也许可以观察到四种潮湿程度的海藻(dry、dryish、damp、soggy)。在语音识别中,一个简单的发言也许只需要80个语素来描述,但是一个内部的发音机制可以产生不到80或者超过80种不同的声音。
在上面的这些情况下,可以观察到的状态序列和隐藏的状态序列是概率相关的。于是我们可以将这种类型的过程建模为又一个隐藏的马尔科夫过程和一个和这个马尔科夫过程概率相关的并且可以观察到的状态集合。
下图显示了天气的例子中隐藏的状态和可以观察到的状态之间的关系。我们假设隐藏的状态是一个简单的一阶马尔科夫过程,并且他们两两之间都可以相互转换。
下图则明确的表示出模型的演化,其中绿色的圆圈表示隐藏状态,紫色圆圈表示可观察到状态,箭头表示状态之间的依存概率,一个 HMM 可用一个5元组 { N, M, π,A,B } 表示,其中 N 表示隐藏状态的数量,我们要么知道确切的值,要么猜测该值,M 表示可观测状态的数量,可以通过训练集获得, π={πi} 为初始状态概率,A={aij} 为隐藏状态的转移矩阵 Pr(xt(i) | xt-1(j)),B={bik} 表示某个时刻因隐藏状态而可观察的状态的概率,即混淆矩阵,Pr(ot(i) | xt(j))。在状态转移矩阵和混淆矩阵中的每个概率都是时间无关的,即当系统演化时,这些矩阵并不随时间改变。对于一个 N 和 M 固的 HMM 来说,用 λ={ π, A, B } 表示 HMM 参数。
隐藏的状态和可以观察到的状态之间有一种概率上的关系,也就是说某种隐藏状态H被认为是某个可以观察的状态O1是有概率的,假设为P(O1|H)。如果可以可以观察的状态有三种,那么很显然P(O1|H)+ P(O2|H)+ P(O3|H) = 1。这里我和原文的意思不太相同,原文说的意思是P(O1|H1)+ P(O1|H2)+P(O1|H3)= 1,但是这和下面的例子又不同。
这样,我们也可以得到一个另一个矩阵,称为混淆矩阵。这个矩阵的内容是某个隐藏的状态被分别观察成集中不同的可以观察的状态的概率,在天气的例子中,这个矩阵如下图:
注意到图中每一行的和为1,但是每一列的和不为1,这里我觉得可能是原文出错了,或者隐藏状态还有其他。
总结
我们已经看到有一些过程是和一个隐藏的马尔科夫过程概率相关的。在这种情况下,可以观察到的状态和隐藏的状态的数目可能是不一样的。我们可以把这种过程建模为隐马尔科夫模型(HMM)。这个模型包含两个状态集合和三个概率集合。
- 隐藏的状态:一个隐藏的马尔科夫过程
- 可以观察到的状态:如名
- 初始向量:初始状态的隐藏状态的概率
- 状态转移矩阵:隐藏状态的状态转移概率
- 混淆矩阵:隐藏状态被观察成各个可以观察到的状态的概率
我们可以认为隐马尔科夫模型是在一个不可观察的马尔科夫过程上添加了一个可以观察到的状态集合,加上这个过程到这个集合的一些概率关系得到的。
(四): 隐马尔科夫模型(Hidden Markov Models)
定义:隐马尔科夫模型可以用一个三元组(π,A,B)来定义:
- π 表示初始状态概率的向量
- A =(aij)(隐藏状态的)转移矩阵 P(Xit|Xj(t-1)) t-1时刻是j而t时刻是i的概率
- B =(bij)混淆矩阵 P(Yi|Xj)在某个时刻因隐藏状态为Xj而观察状态为Yi的概率
值得注意的是,在状态转移矩阵中的每个概率都是时间无关的,也就是说我们假设这个概率是固定的,不随时间变化。当然,这是马尔科夫模型最不切合实际的一个假设。
隐马尔科夫模型的使用
如果一个模型可以被描述成一个隐马尔科夫模型,有三个问题可以得到解决。
前两个是模式识别的问题:1)根据隐马尔科夫模型得到一个可观察状态序列的概率(评价);2)找到一个隐藏状态的序列使得这个序列产生一个可观察状态序列的概率最大(解码)。
第三个问题就是根据一个可以观察到的状态序列集产生一个隐马尔科夫模型(学习)。
1.评价
假设我们有很多隐马尔科夫模型(也就是说一个三元组的集合)描述不同的系统和一个可观察状态序列集。我们也许想知道哪一个隐马尔科夫模型最可能产生某个可观察状态序列。比如说,我们也许有一个海藻的“Summer”模型和一个“Winter”模型,因为海藻在夏天和冬天的状态应该是不同的,我们希望根据一个可观察状态(海藻的潮湿与否)序列来判断现在是夏天还是冬天。
我们可以使用前向算法来计算在某个特定的HMM下一个可观察序列的概率,然后据此找到最可能的模型。
这种类型的应用通常出现在语音设别中,通常我们会使用很多HMM,每一个针对一个特别的单词。一个可观察状态的序列是从一个可以听到的单词向前得到的,然后这个单词就可以通过找到满足这个可观察状态序列的最大概率的HMM来识别。
2.解码
根绝可观察状态的序列找到一个最可能的隐藏状态序列。
和上面一个问题相似的并且更有趣的是根据可观察序列找到隐藏序列。在很多情况下,我们队隐藏状态更有兴趣,因为其包含了一些不能被直接观察到的有价值的信息。比如说在海藻和天气的例子中,一个隐居的人只能看到海藻的状态,但是他想知道天气的状态。这时候我们就可以使用Viterbi算法来根据可观察序列得到最优可能的隐藏状态的序列,当然前提是已经有一个HMM。
另一个广泛使用Viterbi算法的领域是自然语言处中标引词性。句子中的单词是可以观察到的,词性是隐藏的状态。通过根据语句的上下文找到一句话中的单词序列的最有可能的隐藏状态序列,我们就可以得到一个单词的词性(可能性最大)。这样我们就可以用这种信息来完成其他一些工作。
3.学习
从一个观察集中得到一个隐马尔科夫模型。
第三个问题也是最困难的问题,根绝观察到的序列集来找到一个最有可能的HMM,也就是说确定一个最有可能的三元组(π,A,B)。当A,B矩阵都不是直观可测量(通过经验得到)的的时候,可以使用前向后向算法来解决这个问题。
总结
尽管做出了一些不太符合实际的假设,但是用三元组描述的HMMs在描述真实系统并进行分析的时候具有很大的价值,并且可以解决下面这些问题:
- 用前向算法找到最有可能的隐马尔科夫模型
- 用Viterbi算法根据观察序列找到最有可能的隐藏序列
- 用前向后向算法决定最有可能产生某个观察集的隐马尔科夫模型的参数
(五):前向算法(Forward Algorithm)
1、如果计算一个可观察序列的概率?
1.穷举搜索
加入给定一个HMM,也就是说(,A,B)这个三元组已知,我们想计算出某个可观察序列的概率。考虑天气的例子,我们知道一个描述天气和海藻状态的HMM,而且我们还有一个海藻状态的序列。假设这个状态中的某三天是(dry,damp,soggy),在这三天中的每一天,天气都可能是晴朗,多云或者下雨,我们可以用下图来描述观察序列和隐藏序列:
在这个图中的每一列表示天气的状态可能,并且每个状态都指向相邻的列的每个状态,每个状态装换在状态转移矩阵中都有一个概率。每一列的下面是当天的可观察的海藻的状态,在每种状态下出现这种可观察状态的概率是由混淆矩阵给出的。
一个可能的计算可观察概率的方法是找到每一个可能的隐藏状态的序列,这里有3^3 = 27种,这个时候的可观察序列的概率就是 Pr(dry,damp,soggy | HMM) = Pr(dry,damp,soggy | sunny,sunny,sunny) + Pr(dry,damp,soggy | sunny,sunny ,cloudy) + Pr(dry,damp,soggy | sunny,sunny ,rainy) + . . . . Pr(dry,damp,soggy | rainy,rainy ,rainy)。
很显然,这种计算的效率非常低,尤其是当模型中的状态非常多或者序列很长的时候。事实上,我们可以利用概率不随时间变化这个假设来降低时间的开销。
2.使用递归来降低复杂度
我们可以考虑给定HMM的情况下,递归的计算一个可观察序列的概率。我们可以首先定义一个部分概率,表示达到某个中间状态的概率。接下来我们将看到这些部分概率是如何在time=1和time = n(n > 1)的时候计算的。
假设一个T时间段的可观察序列是:
2a.部分概率
下面这张图表示了一个观察序列(dry,damp,soggy)的一阶转移
我们可以通过计算到达某个状态的所有路径的概率和来计算到达某个中间状态的概率。比如说,t = 2时刻clody的概率用三条路径的概率之和来表示:
我们用t(j)来表示在t时刻是状态j的概率,t ( j )= Pr( observation | hidden state is j ) x Pr(all paths to state j at time t)。
最后一个观察状态的部分概率就表示了整个序列最后达到某个状态的所有可能的路径的概率和,比如说在这个例子中,最后一列的部分状态
是通过下列路径计算得到的:
因为最后一列的部分概率是所有可能的路径的概率和,所以就是这个观察序列在给定HMM下的概率了。
2b.计算 t = 1时候的部分概率
计算部分概率的公式是: t ( j )= Pr( observation | hidden state is j ) x Pr(all paths to state j at time t)
当t = 1的时候,没有路径到某个状态,所以这里是初始概率, Pr( state | t = 1) = (state),这样我们就可以计算t=1时候的部分概率为:
因为在初始的时候,是状态j的概率不仅和这个状态本身相关,还和观察状态有关,所以这里用到了混淆矩阵的值,k1表示第一个观察状态,bjk1表示隐藏状态是j,但是观察成k1的概率。
2c.计算t > 1时候的部分概率
还是看计算部分概率的公式: t ( j )= Pr( observation | hidden state is j ) x Pr(all paths to state j at time t)
这个公式的左边是从混淆矩阵中已知的,我只需要计算右边部分,很显然右边是所有路径的和:
需要计算的路径数是和观察序列的长度的平方相关的,但是t时刻的部分概率已经计算过了之前的所有路径,所以在t+1时刻只需要根据t时刻的概率来计算就可以了:
这里简单解释下,bjkt+1 就是在t+1时刻的第j个隐藏状态被认为是当前的观察状态的概率,后面一部分是所有t时刻的隐藏状态到t+1时候的隐藏状态j的转移的概率的和。这样我们每一步的计算都可以利用上一步的结果,节省了很多时间。
2d.降低计算复杂度
我们可以比较穷举和递归算法的复杂度。假设有一个HMM l =(,A,B),其中有n个隐藏状态,我们有一个长度为T的观察序列。
穷举算法的需要计算所有可能的隐藏序列:
需要计算:
很显然穷举算法的时间开销是和T指数相关的,而如果采用递归算法,由于我们每一步都可以利用上一步的结果,所以是和T线性相关的。(这里认为n是一个常数)
3.总结
这里我们的目的是在某个给定的HMM下,计算出某个可观察序列的概率。我们通过先计算部分概率的方式递归的计算整个序列的所有路径的概率,大大节省了时间。在t=1的时候,使用了初始概率和混淆矩阵的概率,而在t时刻的概率则可以利用t - 1时刻的结果。
2、前向算法的定义
我们使用前向算法去计算T长度序列的概率:
每一个y就是观察状态。在t=1时刻的中间节点的部分状态可以用下面的公式计算:
对于t>1的情况,部分概率的计算可以用下面的公式:
这里,我觉得是原作者的笔误,后面的应该是bjkt+1
这样我们就可以用递归的方式来计算所有可能的路径的概率和,最后,所有的部分概率的计算公式为
使用天气的例子,计算t = 2时刻的cloud状态的概率方法如图:
3、总结
我们使用前向算法在给定的一个HMM下计算某个可观察序列的概率。前向算法主要采用的是递归的思想,利用之前的计算结果。有了这个算法,我们就可以在一堆HMM中,找到一个最满足当前的可观察序列的模型(前向算法计算出来的概率最大)。
(六): 维特比算法(Viterbi Algorithm)
找到可能性最大的隐藏序列
通常我们都有一个特定的HMM,然后根据一个可观察序列去找到最可能生成这个可观察序列的隐藏序列。
1.穷举搜索
我们可以在下图中看到每个状态和观察的关系。
通过计算所有可能的隐藏序列的概率,我们可以找到一个可能性最大的隐藏序列,这个可能性最大的隐藏序列最大化了Pr(observed sequence | hidden state combination)。比如说,对于上图中的可观察序列(dry damp soggy),最可能的隐藏序列就是下面这些概率中最大的:
Pr(dry,damp,soggy | sunny,sunny,sunny),
Pr(dry,damp,soggy | sunny,sunny,cloudy),
Pr(dry,damp,soggy | sunny,sunny,rainy),
. . . .
Pr(dry,damp,soggy | rainy,rainy,rainy)
这个方法是可行的,但是这种计算的代价是昂贵。和前向算法一样,我们可以利用转移概率在时间上的不变性来降低计算的复杂度。
2.使用递归降低复杂度
在给定了一个可观察序列和HMM的情况下,我们可以考虑递归的来寻找最可能的隐藏序列。我们可以先定义一个部分概率,既是到达某个中间状态的概率。接下来我们将讨论如果计算t = 1和t = n( n > 1)的部分概率。
注意这里的部分概率和前向算法中的部分概率是不一样的,这里的部分概率表示的是在t时刻最可能到达某个状态的一条路径的概率,而不是所有概率之和。
2a.部分概率和部分最优路径
考虑下面这个图以及可观察序列(dry,damp,soggy)的一阶转移
对于每一个中间状态和终止状态(t = 3)都有一个最可能的路径。比如说,在t=3时刻的三个状态都有一个如下的最可能的路径:
我们可以称这些路径为部分最优路径。这些部分最优路径都有一个概率,也就是部分概率。和前向算法中的部分概率不一样,这里的概率只是一个最可能路径的概率,而不是所有路径的概率和。
我们可以用 (i,t)来表示在t时刻,到状态i的所有可能的序列(路径)中概率最大的序列的概率,部分最优路径就是达到这个最大概率的路径,对于每一个时刻的没一个状态都有这样一个概率和部分最优路径。
最后,我们通过计算t = T时刻的每一个状态的最大概率和部分最优路径,选择其中概率最大的状态和它的部分最优路径来得到全局的最优路径。
2b.计算t = 1时刻的部分概率
当t=1时刻的时候,到达某个状态最大可能的路径还不存在,但是我们可以直接使用在t=1时刻某个状态的概率和这个状态到可观察序列k1的转移概率:
2c.计算t >1 时刻的部分概率
接下来我们可以根据t - 1时刻的部分概率来求t 时刻的部分概率
我们可以计算所有到状态X的路径的概率,找到其中最可能的路径,也就是局部最优路径。注意到这里,到达X的路径必然会经过t - 1时刻的A、B和C,所以我们可以利用之前的结果。达到X的最可能的路径就是下面三个之一:
(sequence of states), . . ., A, X(sequence of states), . . ., B, Xor (sequence of states), . . ., C, X
我们需要做的就是找到以AX、BX和CX结尾的路径中概率最大的那个。
根据一阶马尔科夫的假设,一个状态的发生之和之前的一个状态有关系,所以X在某个序列的最后发生的概率只依赖于其之前的一个状态:
Pr (most probable path to A) . Pr (X | A) . Pr (observation | X)
有个了这个公式,我们就可以利用t - 1时刻的结果和状态转移矩阵和混淆矩阵的数据:
将上面这个表达式推广一下,就可以得到t时刻可观察状态为kt的第i个状态的最大部分概率的计算公式:
其中aji表示从状态j转移到状态i的概率,bikt表示状态i被观察成kt的概率。
2d.后向指针
考虑下图
在每一个中间状态和结束状态都有一个部分最优概率 (i,t)。但是我们的目的是找到最可能的隐藏状态序列,所以我们需要一个方法去记住部分最优路径的每一个节点。
考虑到要计算t时刻的部分概率,我们只需要知道t-1时刻的部分概率,所以我们只需要记录那个导致了t时刻最大部分概率的的状态,也就是说,在任意的时刻,系统都必须处在一个能在下一时刻产生最大部分概率的状态。我们可以利用一个后向指针来记录导致某个状态最大部分概率的上一个状态,形式化的描述为:
这里argmax表示能最大化后面公式的j值,同样可以发现这个公式之和t-1时刻的部分概率和转移概率有关,因为后向指针只是为了找到“我从哪里来”,这个问题和可观察没有关系,所以这里不需要再乘上混淆因子。
2e.优点
使用viterbi算法对一个可观察状态进行解码有两个重要的优点:
- 通过使用递归来减少复杂度,这点和之前的前想算法是一样的
- 可以根据可观察序列找到最优的隐藏序列,这个的计算公式是:
where
这里就是一个从左往右翻译的过程,通过前面的翻译结果得到后面的结果,起始点是初始向量。
2.补充
但在序列某个地方有噪声干扰的时候,某些方法可能会和正确答案相差的较远。
但是Viterbi算法会查看整个序列来决定最可能的终止状态,然后通过后向指针来找到之前的状态,这对忽略孤立的噪声非常有用。
3.总结
Viterbi算法提供了一个根据可观察序列计算隐藏序列的很高效的方法,它利用递归来降低计算复杂度,并且使用之前全部的序列来做判断,可以很好的容忍噪声。
在计算的过程中,这个算法计算每一个时刻每一个状态的部分概率,并且使用一个后向指针来记录达到当前状态的最大可能的上一个状态。最后,最可能的终止状态就是隐藏序列的最后一个状态,然后通过后向指针来查找整个序列的全部状态。
(七): 前向后向算法(Forward-Backward Algorithm)
和隐马尔科夫模型相关的有趣的问题就是判断一个模型的实用性(前向算法)和找到一个隐藏在可观察序列背后的隐藏序列(Viterbi算法)。当然,这两个过程都需要知道HMM的一些信息,比如转移矩阵,混淆矩阵以及初始的π向量。
但是在很多实际的情况下,HMM不能被直接的判断,这就变成了一个学习问题,前向后向算法可以根据一系列可观察序列来对HMM进行评测。一个可能的例子就是一个很大的语音处理数据库,语音序列可能被建模为一个马尔科夫链,可观察的序列可以被建模为可识别的状态,但是不能直接获得一些其他的相关信息。
前向后向算法理解起来并不困难,但是却要比前向算法和Viterbi算法要复杂,所以这里我们不再详细的介绍。总的来说,这个算法先对一些参数进行猜测,然后再通过评估这些参数的价值来修改这些参数,使得和给定的训练数据的误差变小,这其实是机器学习中的梯度下降的思想。
前向后向算法的名称来源于对于每一个状态,这个算法既要计算到达这一状态的前一个状态的概率,也要计算产生终止状态的后向状态的概率,这两个概率都可以通过递归的方法来实现。对HMM参数的调整可以提高中间概率的准确性,并且这些调整是算法迭代的基础。
详细介绍:
根据观察到的序列集来找到一个最有可能的 HMM。
在很多实际的情况下,HMM 不能被直接的判断,这就变成了一个学习问题,因为对于给定的可观察状态序列 O 来说,没有任何一种方法可以精确地找到一组最优的HMM 参数 λ 使 P(O | λ) 最大,于是人们寻求使其局部最优的解决办法,而前向后向算法(也称为Baum-Welch算法)就成了HMM 学习问题的一个近似的解决方法。
前向后向算法首先对于HMM 的参数进行一个初始的估计,但这个很可能是一个错误的猜测,然后通过对于给定的数据评估这些参数的的有效性并减少它们所引起的错误来更新HMM 参数,使得和给定的训练数据的误差变小,这其实是机器学习中的梯度下降的思想。
对于网格中的每一个状态,前向后向算法既计算到达此状态的“前向”概率,又计算生成此模型最终状态的“后向”概率,这些概率都可以通过前面的介绍利用递归进行高效计算。可以通过利用近似的 HMM 模型参数来提高这些中间概率从而进行调整,而这些调整又形成了前向后向算法迭代的基础。
另外,前向后向算法是 EM 算法的一个特例,它避免了 EM 算法的暴力计算,而采用动态规划思想来解决问题,Jelinek 在其书《Statistical Methods for Speech Recognition》中对前向后向算法与 EM 算法的关系进行了详细描述,有兴趣的读者可以参考这本书。
类似于上面讲到的前向算法,我们也可以定义后向变量 βt(i) 来计算给定当前隐藏状态 i 时,部分观察序列 ot+1,ot+2,…,oT的概率,即:
与前向算法类似,我们也可以通过迭代算法有效计算 βt(i),计算公式如下:
其中
进一步我们可以发现
因此
下面开始介绍前向后向算法。
首先我们需要定义两个辅助变量,这两个变量可以用前文介绍过的前向变量和后向变量进行定义。
第一个变量定义为 t 时状态 i 和 t+1 时状态 j 的概率,即
该变量在网格中所代表的关系如下图所示:
该等式等价于
利用前向变量和后向变量,上式可以表示为
第二个变量定义为后验概率,也就是在给定观察状态序列和HMM 的情况下,t 时状态 i 的概率,即
利用前向变量和后向变量,上式可以表示为
因此,下式为在任意时刻状态 i 的期望,也就是从状态 i 转移到观察状态 o 的期望
同样,下式也就是从状态 i 转移到状态 j 的期望
我们可以发现定义的这两个变量之间的关系为
下面介绍前向后向算法的参数学习过程,在学习的过程中,不断更新 HMM 的参数,从而使得 P(O | λ) 最大。我们假设初始的HMM 参数为 λ={ π, A, B },首先计算前向变量 α 和后向变量 β,再根据刚刚介绍的公式计算期望 ξ 和 ζ,最后,根据下面的3个重估计公式更新 HMM 参数。
如果我们定义当前的HMM 模型为 λ={ π,A,B },那么可以利用该模型计算上面三个式子的右端;我们再定义重新估计的 HMM 模型为,那么上面三个式子的左端就是重估的HMM 模型参数。Baum 及他的同事在70年代证明了,因此如果我们迭代地计算上面三个式子,由此不断地重新估计HMM 的参数,那么在多次迭代后可以得到 HMM 模型的一个最大似然估计。不过需要注意的是,前向后向算法所得的这个最大似然估计是一个局部最优解。
通常一个特别的模式不是单独的出现,而是作为某一个时间段下的序列出现。对于以时间为单位的过程有一个假设,一个状态的出现之和其前N个时间单位的状态有关系,这样就是一个N阶马尔科夫链,最简单的情况就是一阶马尔科夫链。
很多情况下,真实的状态序列是不能被直接观察到的,但是可以在一定概率下被间接观察到,这个观察的结果就是另一个可观察的序列,这样我们就可以定义一个隐马尔科夫模型,这个模型在现在的某些领域体现了很大的价值,尤其是语音识别。
这种关于真实序列的模型有三个相关的问题:
- 评价:一个给定的模型在多大的概率下能产生某个可观察的序列,这个问题可以用前向算法来解决。
- 解码:给定一个模型和某个可观察序列,最可能的隐藏序列是什么,这个问题可以用Viterbi算法来解决。
- 学习:给定某个可观察序列,怎么知道这个模型的一些参数,这个问题可以用前向后向算法来解决。
隐马尔科夫模型在分析真实系统的时候表现出了巨大的价值,但是它也有一些缺点,一个最大的缺点就是由于之前的假设导致的过于简化——一个状态只依赖其之间的状态,而且这种依赖是时间无关的。
一个更详细的关于HMMs的介绍可以参见
L R Rabiner and B H Juang, `An introduction to HMMs', iEEE ASSP Magazine, 3, 4-16.
参考资料:
1.http://blog.csdn.net/eaglex/article/details/6376826
2. http://en.wikipedia.org/wiki/Markov_chain
3. http://en.wikipedia.org/wiki/Hidden_Markov_model
4. Lawrence R. Rabiner, A Tutorial on Hidden Markov Models and Selected Applications in Speech Recognition.Proceedings of the IEEE, 77 (2), p. 257–286, February 1989.
5. L. R. Rabiner and B. H. Juang, “An introduction to HMMs,”IEEE ASSP Mag., vol. 3, no. 1, pp. 4-16, 1986.
6. http://jedlik.phy.bme.hu/~gerjanos/HMM/node2.html
7. http://www.cs.brown.edu/research/ai/dynamics/tutorial/Documents/HiddenMarkovModels.html
8. 隐马尔可夫模型简介,刘群
9.这个