【原】隐马尔可夫模型及其典型应用
----by stackupdown
目录
前言
本文要介绍的是隐马尔可夫模型及其应用。
我们从一个史学家开始,假设他在看某国的史料时,辛辛苦苦地统计了上下数年,发现了粮食的增长和下降的一段,他会结合历史去分析一些问题。但是如果史书的其他记载得太少,他就找不到问题的所在,所以无从下手。
又比如,一个人出去旅行,相信民间的传说,海藻的湿度跟未来的天气有关,未来不同天气,海藻的湿度不一样,但是海藻有一定概率是错的。尽管如此,他还是想要根据这个来估计明天天气的可能性[1]。
这两个问题是跟时间相关的问题,有些这样的问题是解决不了的,有些则不然,我们在接下来的文章里会讲到相关问题的数学抽象和解决方法。
正文
一、随机过程
我们在自然世界中会遇到各种不确定的过程,它们的发生是不确定的,这种过程称为随机过程。像花粉的布朗运动、股票市值、天气变化都是随机过程[2]。
马尔科夫随机过程是一类随机过程。它的原始模型马尔可夫链,由俄国数学家A.A.马尔可夫于1907年提出。该过程有以下的性质:指定一个时间点,则未来时间的状态只与现在有关,跟它的过去没有关系。在现实生活中的马尔科夫过程是我们人为抽象进行简化的,如果我们认为一个事物的未来跟过去的变化没有太大关系,那么我们就可以把它抽象成马尔科夫过程[2]。
比如我们的天气,很不严谨地说,可以抽象成马尔科夫过程,从今天晴天转移到明天多云、下雨的转移只取决于今天的天气,而跟前天的天气无关。
如下图,这样我们按照概率的知识就可以得到今天下雨,明天放晴的概率:
P(明天晴|今天雨)=0.4
这就当做是我们最简单的一个模型了[3]。
马尔科夫过程的假设很简单,就是概率不依赖于之前的序列,写成公式:
就好像一条鱼不知道自己之前的运动轨迹,只知道自己在哪里,接着它就会按照现在的位置随机选择一个方向去游动了。鱼的前前后后的运动形成了一条链。
在一个马尔科夫模型中,我们可以利用它来计算概率,而且由于它是单个状态的转移,我们看起来它就像是一条链一样,状态从头到尾移动。跟时间有关的序列往往可以抽象成马尔科夫过程,像浏览网页这种简单的行为乃至写诗、谱曲这种复杂过程都可以用马尔科夫过程分析。
二、隐马尔科夫模型的假设
马尔科夫模型可以用来抽象一些问题,但是更多的情况下我们不能直接看到一些想要的序列,只能间接地通过其他序列来反推结果,这就是一类隐随机过程。
类似地,我们有隐马尔科夫模型(Hidden Markov Model, HMM) 。它是由学者Baum和其他人在60年代提出来的。
我们不能这么随意地把将隐随机过程等同为隐马尔科夫。为了实用性而提出的隐马尔科夫模型,必须满足如下的假设:
隐变量的状态转移概率必须是固定的,这样才有一个确定的概率转移矩阵。即使我们知道某个过程没有固定的状态转移概率,我们也可以把它看作一个近似。
从隐变量H到观测变量W的概率必须是确定的,也就是说P(W=b|H=a)是一个固定值,这样我们才能用到后面的各个算法。
缺少以上两点假设,会让实际中因为无法确定转移概率而无法计算序列的概率,或者根据观察序列无法得到可能的状态转移概率(因为一直在变化)。
注意到概率的已知和未知,我们要解决以下的问题。
三、隐马尔科夫模型的三个基本问题:
1.解码问题
在一个HMM模型里,假设我们已经观察到了一个序列O,而且我们有模型的参数:转移概率矩阵M,表现概率矩阵P,从观察到的序列O里可以看到各个状态,我们想知道最有可能的隐藏状态序列。解决这个问题要用到Viterbi算法, 它由安德鲁·维特比在1967年提出。
我们把这个问题通俗地讲一遍。比如你今天在一个地方见到了扎克伯格,比如在一家酒吧好了,你想知道他今天的心情是郁闷还是开心。当然我们不管他看起来是开心还是郁闷还是一般,反正我们知道在他心情为i的时候来酒吧的概率是P(i,1),去公园的时候是P(i,2), 去公司的概率是P(i,3)。以此类推。我们在5天里看到了他的序列:酒吧->酒吧->公园->公园->公司,我们希望知道他这五天里的心情是什么样的。
在这个问题下,转移概率和表现概率必须是清楚的。为了解决这个问题,我们假设概率转移矩阵如下:
表现矩阵(事实上叫做混淆矩阵)如下:
但是我们还没有确定初始的各个概率π,
那么就这样P(good) = 0.5, P(bad) = 0.2, P(normal) = 0.3,
即π = (0.5, 0.3, 0.2)
现在我们可以根据序列求他的心情了。
我们用Hi表示第i+1天扎克伯格的心情(i从0开始计数), P表示产生序列的概率;
第一天: 酒吧: P=P(bar|H0)*P(H0), H0最可能是bad,因为概率是0.6*0.2 = 0.12, 在三种心情里可能性最大。
第二天:酒吧->酒吧 要计算这个序列的概率,序列的概率为:
P = P(H0)*P(bar|H0) * P(H1|H0) * P(bar|H1),
我们看到必须确认H0和H1,以使得该概率最大,但是这样是不是就说明第一天得到的H0的结果没用了呢?
并不是。
我们用Pr(t, Hk)表示在序列的概率,这个序列就是时刻t的序列,Hk代表不同的心情。
我们可以看到,当t-1的取各个可能的值Ht-1,得到概率Pr(t-1,Ht-1),意味着Pr(t-1)各个取值已经计算过,这时Pr(t)的结果一定可以用到Pr(t-1)的计算结果,这样以后都不用每次都计算之前的序列概率了。
比如,我们可以得到Pr(t, Ht)=Pr(t-1,Ht-1)*P(Ht|Ht-1)*P(Ot|Ht),我们只需要依次计算后面跟Ht相关的结果,就可以得到最好的概率了。
这里t=1, Ot为bar,可以求P=Pr(0,H0)*P(H1|H0)*P(bar|H1),只需求最后两项和各个H0取值下P(H0)*P(bar|H0)的相乘结果, 得到H1=bad, P = 0.2 * 0.6 * 0.375 * 0.6为最大。
依次类推,我们就可以得到最终最可能的隐藏序列H0,H1,...。这就是我们解决的问题。
以上我们用到的算法叫做Viterbi算法,虽然最初是为了解决信道通信的问题,但是它在语音识别中也是非常经典和重要的一个算法[1]。
2.评估问题
由扎克伯格的例子我们已经想到了一个问题,假如我们没有见到扎克伯格,我也不知道他想干什么,但是我突然很闲,想先去一下酒吧,然后去一下公园云云,最后看看我这个活动轨迹跟扎克伯格一样的概率是多少,要怎么办?
事实上这个问题比上个问题简单一些,而且它一般并不是用来看你跟名人的相似度的。严谨地说,我们知道了一个模型的参数,想要知道一个已知序列出现的概率。这可以用来判断模型是否出错,比如跟实际产生的序列频率相差太大,或者实际中出现了什么异常,比如某个人在赌场里偷换了骰子,出老千等等。
解决这个问题可以用穷举的方法。说白了,我们不需要知道最可能的隐藏序列,但是要把可能产生该序列的所有情况的概率加起来得到结果。
当然了,这种方法在计算上是行不通的,因为它用的是简单的穷举方法,计算时间呈指数增长。我们在计算概率的时候有很多是重复计算的,通过合理的方法可以大量地减少计算时间,解决这个问题采用的是前向算法[1]。
我们分两步,第一步是计算:
这里S是H0的可能状态。
第二步:
我们计算第t步(t>1)的总概率怎么算呢?事实是现在的前面的序列为
o0o1o2...ot-1,我们用Pr(t, x)表示最大标号为t而且实际状态为x的序列的概率, 则从Pr(t-1,i)到Pr(t, j),我们用求和的公式可以得到
为什么公式是这样的?
因为前一个序列发生的概率,我们的第t个状态只取决于前一个状态t-1,但是第t-1个状态不确定, 所以要计算:单个隐藏状态下的序列概率X隐藏状态转移概率X表现概率,再把所有状态下的概率都加起来。
每一次迭代的时候我们要计算所有状态j下的)并且把结果写下来(在计算机里是保存下来,这样到下一步才能用来计算,最后得到最终的概率。当然,最后一步我们求出所有状态j的概率后需要将它们求和。
得到概率之后,你就可以用它来判断数据的观察序列出现的概率,如果数据够多,你可以推测这个序列是否正常,并且进行进一步的研究。
3.学习问题
隐马尔科夫模型的三个基本问题中,第三个HMM参数学习的问题是最难的。参数学习是通过推导和计算得到模型参数的近似值。在HMM模型里,参数由{π,M,P}组成,其中π是初始的状态概率,M,P是我们在1中讲到的两个概率矩阵。
我们之前知道转移概率,表现概率(混淆矩阵),但是现在没有了,这也是事实上现实中遇到的最多的问题。我们需要直接通过观察序列来得到模型的参数,来使得P(O|λ)最大。
P(O|)这个概率看起来有点抽象,但是其实就是我们之前求过的,整个序列的出现概率。注意我们需要根据序列O1O2...Ot寻找所有的M,P;模型中隐藏变量的种类是清楚的。对于给定的观察序列O,没有一种方法可以精确地找到一组隐马尔科夫模型参数使概率P(O|λ)最大。
因而,学者们退而求其次。不能使P(O|λ)全局最优,就寻求使其局部最优的解决方法,而前向-后向算法(又称之为Baum-Welch算法)就成了隐马尔科夫模型学习问题的一种替代(近似)解决方法[4]。
Baum-Welch算法本质上是EM算法的一个特例。不妨说一下EM算法,它是通过迭代修改模型参数,来得到近似的最优解,尽管它不能保证得到全局的参数最优 [5]。
所谓迭代修改,可以近似理解成,我们先把现在的结果当成事实模型,用来看它的效果,如果有误差,通过一个方法修改参数,再把参数代入原模型。如此往复,直到参数最后接近不变(收敛)[5]。
我们在这里不做详细的推导,一方面也是因为它的理解有些困难。
假设在我们的模型里,观察序列下标为0~T, 状态的所有下标为1到N。
简单来说:这个算法设计了几个变量,最基础的两个是一个前向变量,一个后向变量。计算序列为O0O1...Ot、t时刻状态为i的序列概率;而计算序列Ot+1Ot+2...OT在t时刻状态为i的序列概率。我们之前在前向算法中其实就用到了。
.
接着,算法设计了另外两个变量,
这两个参数在模型中可以更新模型的参数,反过来又被影响产生变化,这样就可以进行迭代、更新参数了。要解释这个方法的有效性,应该需要用到更多的数学理论。
四、隐马尔科夫模型应用举例
1.自然语言处理
隐马尔科夫模型本来就是为了处理语音和语言问题,所以我们先看一下语音问题中用到这个模型的地方。
语音识别
语音识别我们现在知道的不少了,对普通的大众来说,语音识别是最直接接触到人工智能的领域之一。从手机软件的语音拨号,到科大讯飞的语音识别系统,再到苹果助理Siri,对话机器人,都或多或少地用到了语音识别的功能。
语音识别并没有想象的那么容易,它会遇到很多问题。事实上它不是一个简单的对录下来的声音进行分析的过程,单单是声音信号的保存就要用到很多的数学处理。我们保存的声音信号是比特的数字信号。信号有波形,有频率,它的形状保存下来变成了振幅和频率的数字信号。第一种想法,我们可以用用波形匹配字符吗?这种想法是因为波形相似,则发音是一样的。不过同一个发音,实际字符经常是不同的,同一个字符也可能发音不准确。
尽管如此,我们还是考虑到语音识别中的两个序列了,一个是字符序列,一个是我们的声音序列,从声音序列分析得到字符序列我们就可以进行后续的句子含义分析了。这就是第二种想法。
根据我们之前的介绍,隐马尔可夫模型是可以分析观察序列得到隐含序列的。但是单纯地使用马尔科夫模型是不对的,我们并不知道马尔科夫模型里的概率,也即一个声音怎么就对应到汉字"西湖",怎么就对应到英文"Moon River"了。
应对这个问题,学者们不打算用一蹴而就的方法,能够根据一个简单的概率估计就算出四海皆准的概率表,而是通过大量的数据进行统计并且通过其他方法修正。这种数据的方法体现的是一种经验法则,但是在实际应用中有它的用武之地。
因此,我们用马尔科夫模型进行语音识别之前,要使用字符串-语音对应的数据库,在对模型进行训练之后才将其应用到识别之中。实际的学术界中,通常把通过数据进行模型参数修正的方法称为训练。
数据库从哪儿来?在《数学之美》中讲到了这件事,语言学家马库斯认识到建立标准语料库(corpus)对语言研究的重要性。建立语料库,可以类似这样:从《华尔街日报》中选取一些真实的英语语句,进行词性标注,再加入语法树构建。有了文字语料库,还可以继续添加语音,机器翻译的语料库,供世界上的学者研究[6]。
在隐马尔科夫模型中,我们提到了三种概率的参数,而获得概率的方法当然不是全靠猜的,这里面要用到一些概率估计的方法。在上世纪90年代,其核心框架就是用隐马尔科模型对语音的时序进行建模,而用高斯混合模型(GMM)对语音的概率进行建模。而在2006年著名学者辛顿提出深度神经网络(DNN)的模型之后,人们普遍采用了DNN来替换GMM,以提高模型的效果[7]。
语音处理过程[7]
其他语言处理问题
在文本的处理中给词语进行词性标注、命名实体(人名、地名、机构名)的标注,这个可以用来给计算机对输入语句的含义分析,从而可以让电脑拥有更加智能的表现,比如对话系统或者问答系统的实现。同样地,这些问题也是可以由隐马尔科夫模型参与解决的。还有一些打字软件为了追求好的效果也会用到隐马尔可夫模型。
2.蛋白质序列观测
序列分析
生物中用到大量数据的地方有很多,因此也就有了生物信息学。对于蛋白质的功能研究来说,生物信息是结合得很紧密的。在目前的生物信息学研究中,我们根据蛋白质序列得到的不仅仅是蛋白质的结构,而且还跟遗传学的亲源关系,蛋白质功能的研究有很大的关系。
如果你学过生物学,那么你应该知道生物的大分子蛋白质是由一些更小的分子合成的,氨基酸的组成成分和顺序是合成大分子蛋白质的必要条件。当然除此之外还有空间结构问题,一个相同序列的蛋白质可能有完全不同的性质,原因就是它的空间结构不一样。蛋白质 有空间结构,还分成至少三级的空间结构(可能有四级)[8],低级的通过折叠形成高级的结构。因此,根据蛋白质的序列研究并不是理所当然的。
蛋白质的四级结构[9]
蛋白质数据库
蛋白质的氨基酸序列是一个观测序列,对于不同的蛋白质来说,它的产生概率显然不是固定的。在生物学内部,对蛋白质会有一个标准的蛋白质表示方法,也就是用一个氨基酸序列来表示它。
场景应用
我们设想两个场景。
场景一,一个生物系的教授现在有了一种蛋白酶的样本,他通过各种手段得到了蛋白质的序列,但是想知道它的结构长得什么样。至于为什么要看它的结构,生物知识告诉我们,酶是一种受体,它作用的物质跟它的结构一般要能"互补"。利用隐马尔科夫模型在数据集上训练得到的结果,我们可以预测该蛋白质的结构。
场景二,医生发现,在一个病人体内产生很多不常见的蛋白质,他猜测是因为某些未知的病理导致蛋白质发生异常,但是他没办法猜测蛋白质的种类,看到空间结构也没用。于是他把问题交给研究员。研究员利用数据库多次对比,查到了跟它相似的一些蛋白质,并且知道了它的可能病变过程。
这就是蛋白质序列的两个应用HMM的场景:结构预测和多序列结构对比[10]。有些人可能还会想到用HMM来进行新药的研制。具体的应用可能是多种多样,但是不管怎样,我们应该也没办法用HMM造出一只恐龙的所有蛋白。
其他生物信息问题
除了蛋白质,还有DNA、RNA可以分析。而且并不像表面上看的那样简单,DNA、RNA由于突变的问题跟蛋白质有一定的区别。
3.其他方面的应用
量化交易
一部分金融界的人会采用HMM辅助预测量化交易的趋势,当然,他们用到的HMM往往复杂度并不在问题的抽象,而在数学处理上,用到的模型还经常混合了其他的模型。
人脸识别、手势识别
在计算机视觉中当然也可以用到HMM, 比如一张人脸照片让你识别它的表情,一个手势的动作让你识别它的含义等等,这些也都是被称作模式识别的一些应用。
结语
我们通过扎克伯格介绍了隐马尔科夫模型的基本问题,举了几个简单的例子并且讲解了隐马尔科夫模型的应用,了解到该模型的强大。用这个模型作为近似,能帮我们有效地解决一些问题,而且如果在未来使用语音识别系统的时候,也不要忘了有HMM的功劳。
当然这不意味着隐马尔科夫模型是万能的。每个模型只是一些现象的抽象,要解决问题还是得具体问题具体分析。由于问题的多种多样,有时候问题本身就比模型有趣得多。
参考文献
[1] 隐马尔可夫模型(HMM)攻略
http://blog.csdn.net/likelet/article/details/7056068
[2]关于马尔科夫随机场MRF 的思考
http://blog.sina.com.cn/s/blog_82a790120101ab6p.html
[3] 如何用简单易懂的例子解释隐马尔可夫模型?
https://www.zhihu.com/question/20962240
[4] HMM学习最佳范例七:前向-后向算法4
http://www.52nlp.cn/hmm-learn-best-practices-seven-forward-backward-algorithm-4
[5] HMM进阶(6)——Baum-Welch算法
http://blog.sina.com.cn/s/blog_8267db980102wpvz.html
[6] 吴军.数学之美[M]北京:人民邮电出版社,2012:198,199
[7] 语音识别系统及科大讯飞最新实践
http://www.weidu8.net/wx/1004147209047264
[8] Protein primary structure
https://en.wikipedia.org/wiki/Protein_primary_structure
[9] 卜东波,陈 翔,王志勇.蛋白质结构预测方法综述
http://download.bioon.com.cn/upload/month_1001/20100116_479b2d9726a8f6181eacEJ11PiiX4NHw.attach.pdf
[10]崔岩, 黄积涛. 蛋白质拓扑结构Alignment与相似性打分的算法[J]. 天津理工大学学报, 2000, 16(2):35-39.