隐马尔可夫简介(转)

同前面一样,因为编辑器不支持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模型还涉及另外两个问题:

        1. 评估问题。就是知道了模型的各个参数(对应到我们这里所说的转移概率矩阵,三种天气情况下的午休概率),我们来计算一下某个观察值序列发生的概率;

        2. 学习问题。对于一个给定的观察值序列,我们想通过修改模型参数,使得这个观察值序列发生的概率最大。

我们现在来更完整地描述一下隐马可夫模型。这个模型有两个关键过程:一个是状态转移。对应到我们前面的例子,就是天气情况。某一天的天气情况是一个状态,次日的天气情况由前日天气状态转移而来,晴阴雨的可能性由状态转移概率决定。但是,这个状态及状态转移对于观察者而言都是未知的。对应到我们的例子,就是老先生的儿子是不知道家里一周天气情况的。第二个关键过程就是一个随机过程。对应到我们的例子就是天气与老先生午休的关系。这其实是一个不确定的关系,也就是说,是一个概率事件。这个随机过程的观察值对于观察者而言是已知的。对应到我们的例子就是老先生的儿子知道他父亲一周来的午休情况。

        这个模型有三个经典问题:

        1. 评估问题。已知这个模型的各个参数(转移概率矩阵,初始时刻各个状态出现的概率,随机过程概率),求解某个观察值序列出现的概率;

        2. 解码问题。已知这个模型的参数、观察值序列。推导最有可能的状态序列;

        3. 学习问题。已知一个观察值序列。推导一个参数组合,使得这个观察值序列出现的可能性最大。

        下面我们来一一考察这三个问题。先来第一个问题。我们首先考虑最简单的一个情况,整个序列长度就是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算法。

        对整个算法有不解的,可以参考网上的一个总结:http://math.sjtu.edu.cn/faculty/ykwu/HMM-DL.pdf


你可能感兴趣的:(游戏,算法,语言,联想)