这篇文章写得实在是通俗易懂,做者幽默的解释了Markov和隐Markov模型,入门必看。算法
同前面同样,由于编辑器不支持latex方式的数学公式输入,因此我就试图用文字的方式来简要描述一下隐Markov模型(Hidden Markov Model,HMM)。全部这类模型都有一个前提假设,就是下一个时刻的状态只与当前时刻相关。知足这种特性的过程就是Markov过程。可能有人会马上 联想到物理学中的绝对论,Laplace当年豪迈地宣称,只要给定某个时刻宇宙的所有状态,那么理论上咱们能够计算出宇宙的下一时刻的所有状态,以至能够 计算出宇宙的无限将来。可是,Markov过程与Laplace决定论仍是有本质区别的。区别在于,决定论下一时刻的状态彻底由当前时刻决定;而 Markov过程下一时刻的状态可能有多种,知道了当前时刻的状态,咱们只能知道下一时刻可能会出现哪些状态,这些状态出现的几率如何。所 以,Markov过程更接近量子物理,固然,这种接近仅仅在几率这一点上。编辑器
回到咱们的主题。谈到隐Markov模型,那么咱们天然就先想知道不隐的Markov模型是啥。咱们来看一个例子。按照咱们的感受,若是今天下雨,那么我 们认为明天也下雨的可能性是至关高的;而若是今天艳阳高照,那么明天也很是多是晴天。这能够说就是知足了前述的Markov假设。咱们把天气的状态分红三种:晴天、阴天、雨天。那么咱们就能够根据咱们的经验获得状态之间的转移几率, 从而造成一个矩阵。而且咱们注意到,前面所说的这个事情是与时间无关的。也就是,今年的状况是这样,明年的状况也应该是这样,这个转移几率矩阵是不随时间 而变化的。那么咱们知道了初始状态後就能够计算将来某个时刻系统可能处于的状态的几率,这是很是简单的一个计算。这样一个模型就是所谓的Markov模 型。学习
可是,做为男人,咱们就甘心玩这种简单得不能再简单的游戏吗?显然不能!再简单的东西咱们也要玩出花样来,至少让别人看了能吓一跳,然後翘起大拇指说:你 牛!因此,隐Markov模型就应运而生了。记住咱们的宗旨,咱们的宗旨是要吓住别人,而吓住别人的最好办法就是一环套一环。你看,地球火星都绕着太阳 转,这是简单得不能再简单的圆。可若是我说地球是中心,然後让你计算火星的运动轨迹,这马上吓倒一大片。当年地心说盛行之时,这种一轮套一轮的天体计算着 实是把至关多的热情少年拒之门外。而隐Markov过程也是引入了两个随机过程,而且隐去中间一个环节,让一切看起来复杂而不简单。递归
咱们继续前面的例子。在计算已知当前天气状况,推导将来天气状况的问题时,咱们感受很轻松。那么如今咱们进一步将问题复杂化。咱们这有一个老先生,他中午 有时候午休,有时候不午休。奇怪的是,他的这个做息规律跟天气有必定的关系。若是是晴天,他午休的几率更大一点;而若是是雨天,他不午休的几率更大一点。 这个老先生一日突发奇想,他把前面咱们说的转移几率以及三种天气条件下他午休的几率整理好发给他远在异地的儿子,他还告诉他儿子最近一周的每一天他是午休 了仍是没午休。他要考考他儿子,从他这一周的做息状况可否得出家乡这一周最可能的天气状况。这就是一个典型的隐Markov问题。游戏
要解决这个问题咱们必须注意到一点:这是一个最优问题,而且这个最优问题存在最优子结构。若是咱们标记这个时间序列是1到7,那么对于这个问题一个最优解 若是是q[1]到q[7]标记的一个天气状态序列,那么对于一个子问题1到6,q[1]到q[6]标记的状态序列必然是这个子问题的最优解。咱们能够很轻 松地证实这一点,由于若是存在其余的解是最优解,那么咱们能够将这个最优解移植过来,那么q[1]到q[7]造成的状态序列就不是当前问题的最优解了。另 外,这个问题也具有重叠子结构的特征,因此他适合用动态规划算法。固然,在这里,他换了一个名字,叫Viterbi算法。数学
事实上,上面这个问题仅仅是隐Markov模型的三个经典问题中的一种,即所谓的“解码问题”。这类问题是隐去了状态序列(对应到最近一周天天的天气情 况),而根据观察值序列(对应到老先生最近一周的天天做息状态)来估计最可能的状态序列(解码)。隐Markov模型还涉及另外两个问题:it
1. 评估问题。就是知道了模型的各个参数(对应到咱们这里所说的转移几率矩阵,三种天气状况下的午休几率),咱们来计算一下某个观察值序列发生的几率;入门
2. 学习问题。对于一个给定的观察值序列,咱们想经过修改模型参数,使得这个观察值序列发生的几率最大。方法
下面咱们来一一考察这三个问题。先来第一个问题。咱们首先考虑最简单的一个状况,整个序列长度就是1,也就是咱们只考察一个观察值出现的几率。这显然就将各个状态初始出现的几率乘以各个状态中出现观察值的几率获得的结果加起来求和。如今咱们再来看两个观察值的情形。咱们仍然但愿这个时候可以获得各个状态出现的几率,然後乘以各自的观察值出现几率,最後求和。而各个状态出现的几率并不可贵出:由于咱们已经有了初始时刻各个状态出现几率,也有了状态转换几率。因而两个观察值情形咱们也能很轻松解决。推而广之,咱们就能够用一个递归的方式完成这个问题。经验
再来考察第二个问题。咱们前面已经说过,第二个问题事实上就是一个动态规划问题。有不解者,请参考教科书相关章节。
学习问题的一个通行解法是迭代算法。也就是,先凭经验估计一组参数值,然後每计算一步就改进一步参数值,直到相邻两次计算出来的几率小于一个阈值。这里关键的问题就是如何根据这一步的计算结果来改进参数值。更具体的就是咱们要从新计算状态转换几率和随机过程的观察值出现几率。先看状态转移几率。咱们计算系统从状态 i 跳转到状态 j 无非就是要计算从 i 跳转到 j 的预期次数和从 i 跳出的预期总次数,然後将二者相除。那么从i 跳转到j 的次数如何计算呢?提及来,步骤倒简单。咱们先计算时刻t系统处于状态i而时刻t+1系统处于j状态的几率,然後将这个几率对t求和。这是显而易见的。而且若是继续对j求和,咱们还能够获得从i跳出的总次数。关键就是这个t时刻处于i而t+1时刻处于j的几率如何求?这是关键。
故事仍是要从头讲起。咱们以前在计算评估问题时已经计算过某个时刻出现某个状态i的几率。事实上,这种作法叫前向法。咱们彻底能够後向地计算评估问题,就是计算某个时候之後出现某个状态序列的几率。有了这两个几率,咱们能够简单地用前向几率乘以转换几率乘以後向几率这样的方法来计算t时刻处于i而t+1时刻处于j的几率。固然,这只是语言的描述,读者应当去看相关文献以获得更精确的数学表达式。
咱们还须要计算状态j下出现观察值k的几率。同前面同样,咱们就是要计算出现状态j以及观察值是k的次数除以出现状态j的次数。後者咱们已经计算过了,而前者其实也简单。由于咱们已经知道了观察值序列,因此咱们只要挑出t时刻出现观察值k的那些来求和便可。这样整个算法就完成了。这个算法也有一个名字,叫Baum-Welch算法。