http://www.zhihu.com/question/20962240
摘自我的博客http://blog.csdn.net/ppn029012
1. 赌场风云(背景介绍)
最近一个赌场的老板发现生意不畅,于是派出手下去赌场张望。经探子回报,有位大叔在赌场中总能赢到钱,玩得一手好骰子,几乎是战无不胜。而且每次玩骰子的时候周围都有几个保镖站在身边,让人不明就里,只能看到每次开局,骰子飞出,沉稳落地。老板根据多年的经验,推测这位不善之客使用的正是江湖失传多年的"偷换骰子大法”(编者注:偷换骰子大法,用兜里自带的骰子偷偷换掉均匀的骰子)。老板是个冷静的人,看这位大叔也不是善者,不想轻易得罪他,又不想让他坏了规矩。正愁上心头,这时候进来一位名叫HMM帅哥,告诉老板他有一个很好的解决方案。
不用近其身,只要在远处装个摄像头,把每局的骰子的点数都记录下来。
然后HMM帅哥将会运用其强大的数学内力,用这些数据推导出
1. 该大叔是不是在出千?
2. 如果是在出千,那么他用了几个作弊的骰子? 还有当前是不是在用作弊的骰子。
3. 这几个作弊骰子出现各点的概率是多少?
天呐,老板一听,这位叫HMM的甚至都不用近身,就能算出是不是在作弊,甚至都能算出别人作弊的骰子是什么样的。那么,只要再当他作弊时,派人围捕他,当场验证骰子就能让他哑口无言。
在让HMM开展调查活动之前,该赌场老板也对HMM作了一番调查。
HMM(Hidden Markov Model), 也称隐性马尔可夫模型,是一个概率模型,用来描述一个系统隐性状态的转移和隐性状态的表现概率。
系统的隐性状态指的就是一些外界不便观察(或观察不到)的状态, 比如在当前的例子里面, 系统的状态指的是大叔使用骰子的状态,即
{正常骰子, 作弊骰子1, 作弊骰子2,...}
隐性状态的表现也就是, 可以观察到的,由隐性状态产生的外在表现特点。这里就是说, 骰子掷出的点数.
{1,2,3,4,5,6}
HMM模型将会描述,系统隐性状态的转移概率。也就是大叔切换骰子的概率,下图是一个例子,这时候大叔切换骰子的可能性被描述得淋漓尽致。
很幸运的,这么复杂的概率转移图,竟然能用简单的矩阵表达, 其中a_{ij}代表的是从i状态到j状态发生的概率
当然同时也会有,隐性状态表现转移概率。也就是骰子出现各点的概率分布, (e.g. 作弊骰子1能有90%的机会掷到六,作弊骰子2有85%的机会掷到'小’). 给个图如下,
隐性状态的表现分布概率也可以用矩阵表示出来,
把这两个东西总结起来,就是整个HMM模型。
这个模型描述了隐性状态的转换的概率,同时也描述了每个状态外在表现的概率的分布。总之,HMM模型就能够描述扔骰子大叔作弊的频率(骰子更换的概率),和大叔用的骰子的概率分布。有了大叔的HMM模型,就能把大叔看透,让他完全在阳光下现形。
总结起来HMM能处理三个问题,
3.1 解码(Decoding)解码就是需要从一连串的骰子中,看出来哪一些骰子是用了作弊的骰子,哪些是用的正常的骰子。
比如上图中,给出一串骰子序列(3,6,1,2..)和大叔的HMM模型, 我们想要计算哪一些骰子的结果(隐性状态表现)可能对是哪种骰子的结果(隐性状态).
学习就是,从一连串的骰子中,学习到大叔切换骰子的概率,当然也有这些骰子的点数的分布概率。这是HMM最为恐怖也最为复杂的招数!!
3.3 估计(Evaluation)估计说的是,在我们已经知道了该大叔的HMM模型的情况下,估测某串骰子出现的可能性概率。比如说,在我们已经知道大叔的HMM模型的情况下,我们就能直接估测到大叔扔到10个6或者8个1的概率。
估计是最容易的一招,在完全知道了大叔的HMM模型的情况下,我们很容易就能对其做出估计。
现在我们有了大叔的状态转移概率矩阵A,B就能够进行估计。比如我们想知道这位大叔下一局连续掷出10个6的概率是多少? 如下
这表示的是,在一开始隐性状态(s0)为1,也就是一开始拿着的是正常的骰子的情况下,这位大叔连续掷出10个6的概率。
现在问题难就难在,我们虽然知道了HMM的转换概率,和观察到的状态V{1:T}, 但是我们却不知道实际的隐性的状态变化。
好吧,我们不知道隐性状态的变化,那好吧,我们就先假设一个隐性状态序列, 假设大叔前5个用的是正常骰子, 后5个用的是作弊骰子1.
好了,那么我们可以计算,在这种隐性序列假设下掷出10个6的概率.
但是问题又出现了,刚才那个隐性状态序列是我假设的,而实际的序列我不知道,这该怎么办。好办,把所有可能出现的隐状态序列组合全都试一遍就可以了。于是,
解码的过程就是在给出一串序列的情况下和已知HMM模型的情况下,找到最可能的隐性状态序列。
用数学公式表示就是, (V是Visible可见序列, w是隐性状态序列, A,B是HMM状态转移概率矩阵)
(公式太多,请具体看我博客中的推导 机器学习 --- 4. 大内密探HMM(隐马尔可夫)围捕赌场老千)然后又可以使用估计(4.1)中的前向推导法,计算出最大的P(w(1:T), V(1:T)).
在完成前向推导法之后,再使用后向追踪法(Back Tracking),对求解出能令这个P(w(1:T), V(1:T))最大的隐性序列.这个算法被称为维特比算法(Viterbi Algorithm).
学习是在给出HMM的结构的情况下(比如说假设已经知道该大叔有3只骰子,每只骰子有6面),计算出最有可能的模型参数.
(公式太多,请具体看我博客中的推导 机器学习 --- 4. 大内密探HMM(隐马尔可夫)围捕赌场老千)以上举的例子是用HMM对掷骰子进行建模与分析。当然还有很多HMM经典的应用,能根据不同的应用需求,对问题进行建模。
但是使用HMM进行建模的问题,必须满足以下条件,
1.隐性状态的转移必须满足马尔可夫性。(状态转移的马尔可夫性:一个状态只与前一个状态有关)
2. 隐性状态必须能够大概被估计。
在满足条件的情况下,确定问题中的隐性状态是什么,隐性状态的表现可能又有哪些.
HMM适用于的问题在于,真正的状态(隐态)难以被估计,而状态与状态之间又存在联系。
语音识别问题就是将一段语音信号转换为文字序列的过程. 在个问题里面
隐性状态就是: 语音信号对应的文字序列
而显性的状态就是: 语音信号.
HMM模型的学习(Learning): 语音识别的模型学习和上文中通过观察骰子序列建立起一个最有可能的模型不同. 语音识别的HMM模型学习有两个步骤:
1. 统计文字的发音概率,建立隐性表现概率矩阵B
2. 统计字词之间的转换概率(这个步骤并不需要考虑到语音,可以直接统计字词之间的转移概率即可)
语音模型的估计(Evaluation): 计算"是十四”,"四十四"等等的概率,比较得出最有可能出现的文字序列.
5.2 手写识别
这是一个和语音差不多,只不过手写识别的过程是将字的图像当成了显性序列.
“总所周知,在汉语中,词与词之间不存在分隔符(英文中,词与词之间用空格分隔,这是天然的分词标记),词本身也缺乏明显的形态标记,因此,中文信息处理的特有问题就是如何将汉语的字串分割为合理的词语序。例如,英文句子:you should go to kindergarten now 天然的空格已然将词分好,只需要去除其中的介词“to”即可;而“你现在应该去幼儿园了”这句表达同样意思的话没有明显的分隔符,中文分词的目的是,得到“你/现在/应该/去/幼儿园/了”。那么如何进行分词呢?主流的方法有三种:第1类是基于语言学知识的规则方法,如:各种形态的最大匹配、最少切分方法;第2类是基于大规模语料库的机器学习方法,这是目前应用比较广泛、效果较好的解决方案.用到的统计模型有N元语言模型、信道—噪声模型、最大期望、HMM等。第3类也是实际的分词系统中用到的,即规则与统计等多类方法的综合。”[1]使用HMM进行中文分词.
5.4 HMM实现拼音输入法拼音输入法,是一个估测拼音字母对应想要输入的文字(隐性状态)的过程(比如, ‘pingyin’ -> 拼音)
使用HMM实现简单拼音输入法
=0.033612
<img src="https://pic3.zhimg.com/1a89bf925b4c1af2cc17416764d1d60e_b.png" data-rawwidth="340" data-rawheight="295" class="content_image" width="340">三种算法的答案是一致的。
问题2的解决:维特比算法
维特比算法致力于寻找一条最佳路径,以便能最好地解释观测到的序列。
初始化:
初始路径:
递推,当然是要找出概率比较大的那条路径。
那么,到达第二天下雨这一状态的最佳路径,应该是:
从前有个村儿,村里的人的身体情况只有两种可能:健康或者发烧。
假设这个村儿的人没有体温计或者百度这种神奇东西,他唯一判断他身体情况的途径就是到村头我的偶像金正月的小诊所询问。
月儿通过询问村民的感觉,判断她的病情,再假设村民只会回答正常、头晕或冷。
有一天村里奥巴驴就去月儿那去询问了。
第一天她告诉月儿她感觉正常。
第二天她告诉月儿感觉有点冷。
第三天她告诉月儿感觉有点头晕。
那么问题来了,月儿如何根据阿驴的描述的情况,推断出这三天中阿驴的一个身体状态呢?
为此月儿上百度搜 google ,一番狂搜,发现维特比算法正好能解决这个问题。月儿乐了。
隐含的身体状态 = { 健康 , 发烧 }
可观察的感觉状态 = { 正常 , 冷 , 头晕 }
月儿预判的阿驴身体状态的概率分布 = { 健康:0.6 , 发烧: 0.4 }
月儿认为的阿驴身体健康状态的转换概率分布 = {
健康->健康: 0.7 ,
健康->发烧: 0.3 ,
发烧->健康:0.4 ,
发烧->发烧: 0.6
}
月儿认为的在相应健康状况条件下,阿驴的感觉的概率分布 = {
健康,正常:0.5 ,冷 :0.4 ,头晕: 0.1 ;
发烧,正常:0.1 ,冷 :0.3 ,头晕: 0.6
}
阿驴连续三天的身体感觉依次是: 正常、冷、头晕 。
已知如上,求:阿驴这三天的身体健康状态变化的过程是怎么样的?
根据 Viterbi 理论,后一天的状态会依赖前一天的状态和当前的可观察的状态。那么只要根据第一天的正常状态依次推算找出到达第三天头晕状态的最大的概率,就可以知道这三天的身体变化情况。5.结论
传不了图片,悲剧了。。。
1.初始情况:
2.求第一天的身体情况:
- P(健康) = 0.6,P(发烧)=0.4。
计算在阿驴感觉正常的情况下最可能的身体状态。
那么就可以认为第一天最可能的身体状态是:健康。
- P(今天健康) = P(健康|正常)*P(健康|初始情况) = 0.5 * 0.6 = 0.3
- P(今天发烧) = P(发烧|正常)*P(发烧|初始情况) = 0.1 * 0.4 = 0.04
3.求第二天的身体状况:
计算在阿驴感觉冷的情况下最可能的身体状态。
那么第二天有四种情况,由于第一天的发烧或者健康转换到第二天的发烧或者健康。
那么可以认为,第二天最可能的状态是:健康。
- P(前一天发烧,今天发烧) = P(发烧|前一天)*P(发烧->发烧)*P(冷|发烧) = 0.04 * 0.6 * 0.3 = 0.0072
- P(前一天发烧,今天健康) = P(健康|前一天)*P(发烧->健康)*P(冷|健康) = 0.04 * 0.4 * 0.4 = 0.0064
- P(前一天健康,今天健康) = P(发烧|前一天)*P(健康->健康)*P(冷|健康) = 0.3 * 0.7 * 0.4 = 0.084
- P(前一天健康,今天发烧) = P(健康|前一天)*P(健康->发烧)*P(冷|发烧) = 0.3 * 0.3 *.03 = 0.027
4.求第三天的身体状态:
计算在阿驴感觉头晕的情况下最可能的身体状态。
那么可以认为:第三天最可能的状态是发烧。
- P(前一天发烧,今天发烧) = P(发烧|前一天)*P(发烧->发烧)*P(头晕|发烧) = 0.027 * 0.6 * 0.6 = 0.00972
- P(前一天发烧,今天健康) = P(健康|前一天)*P(发烧->健康)*P(头晕|健康) = 0.027 * 0.4 * 0.1 = 0.00108
- P(前一天健康,今天健康) = P(发烧|前一天)*P(健康->健康)*P(头晕|健康) = 0.084 * 0.7 * 0.1 = 0.00588
- P(前一天健康,今天发烧) = P(健康|前一天)*P(健康->发烧)*P(头晕|发烧) = 0.084 * 0.3 *0.6 = 0.01512
假设你有一个住得很远的朋友,他每天跟你打电话告诉你他那天做了什么.你的朋友仅仅对三种活动感兴趣:公园散步,购物以及清理房间.他选择做什么事情只凭天气.你对于他所住的地方的天气情况并不了解,但是你知道总的趋势.在他告诉你每天所做的事情基础上,你想要猜测他所在地的天气情况.你认为天气的运行就像一个 马尔可夫链.其有两个状态 "雨"和"晴",但是你无法直接观察它们,也就是说,它们对于你是隐藏的.每天,你的朋友有一定的概率进行下列活动:"散步", "购物", 或 "清理". 因为你朋友告诉你他的活动,所以这些活动就是你的观察数据.这整个系统就是一个隐马尔可夫模型HMM.
你知道这个地区的总的天气趋势,并且平时知道你朋友会做的事情.也就是说这个隐马尔可夫模型的参数是已知的.你可以用程序语言(Python)写下来:
states = ('Rainy', 'Sunny') observations = ('walk', 'shop', 'clean') start_probability = {'Rainy': 0.6, 'Sunny': 0.4} transition_probability = { 'Rainy' : {'Rainy': 0.7, 'Sunny': 0.3}, 'Sunny' : {'Rainy': 0.4, 'Sunny': 0.6}, } emission_probability = { 'Rainy' : {'walk': 0.1, 'shop': 0.4, 'clean': 0.5}, 'Sunny' : {'walk': 0.6, 'shop': 0.3, 'clean': 0.1}, }
在这些代码中,start_probability代表了你对于你朋友第一次给你打电话时的天气情况的不确定性(你知道的只是那个地方平均起来下雨多些).在这里,这个特定的概率分布并非平衡的,平衡概率应该接近(在给定变迁概率的情况下){'Rainy': 0.571, 'Sunny': 0.429}< transition_probability 表示基于马尔可夫链模型的天气变迁,在这个例子中,如果今天下雨,那么明天天晴的概率只有30%.代码emission_probability 表示了你朋友每天做某件事的概率.如果下雨,有 50% 的概率他在清理房间;如果天晴,则有60%的概率他在外头散步.