首页 > 代码库 > HMM模型
HMM模型
通过前几时断续的学习,发现自己对HMM模型的了解还只停留在皮毛,导致在学习CRF模型并将其与最大熵模型、HMM、MEMM做比较时感觉很吃力,所以又花了两天时间使劲看了遍HMM,发现了解得确实深刻了很多,现小结一下,争取把看过的知识变成自己的,特别感谢52nlp网站http://www.52nlp.cn/和崔晓源翻译的HMM相关资料,英文学习网站http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/html_dev/main.html,中文神马的都是浮云。
每次要学习一点新的东西时,总是想迫切地知道学它是用来干嘛的,然后就是想知道它该怎么用,我觉得这是接触并接受新知识的两个最起码的原则。HMM来源于现实社会的需求,它是为人们服务的,我们通常都习惯于寻找一个事物在一段时间内的变化规律,并能在特定情况下预测下一变化,比如预测天气等。当然HMM还有一些其他的应用,后面还会提到。
既然HMM用处是具有实际意义的,那么下面我们来学习它。
实际生活中,有的时候状态的转变是固定的,如红绿灯的变化规律,下一状态是已知的,这种模式叫确定性的生成模式,而在大多数情况下状态的改变却是不确定的,如根据今天的天气推测明天的天气,这个状态的变化是不明确的,这种模式叫非确定的生成模式,通常我们更倾向于研究非确定性生成模式,所以我们用到了HMM。这里明确一个概念,n阶HMM,意思是说当前的状态只与前n个状态有关,我们通常研究的是1阶HMM,意思是当前状态只与前一状态有关,显然这是不符合现实的一个假设,但它却非常适于分析,同时要注意HMM是与时间无关的一个模型,这也是一个与现实不符的假设。(从此可看出HMM有待改进)
HMM的核心在于思想,算法与两个矩阵。
HMM的两个矩阵为状态转移矩阵(表征状态之间的转移概率)、混淆矩阵(表征特定状态下发射符号(观察值)的概率)。
根据HMM不同的应用,有不同的算法来解决。
主要是三类问题。
① 根据已知的HMM找出一个观察序列的概率—评估
这类问题是假设有若干HMM模型,对应每个模型找出给定观察序列的概率,最大概率对应的模型则是最可能生成该序列的系统。
应用:根据观察序列判断季节,语音识别。
算法——
穷举搜索举例:
对于水藻和天气的关系,我们可以用穷举搜索方法得到下面的状态转移图(trellis):
图中,sunny,cloudy,rainy表示三个状态,dry,damp,soggy表示观察值,每一列与相邻列的连线由状态转移概率决定,而观察状态和每一列的隐状态则由混淆矩阵(处于某一状态,发射某一观察值的概率)决定。如果用穷举的方法的到某一观察状态序列的概率,就要求所有可能的天气状态序列下的概率之和,这个trellis中共有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)
可见计算复杂度是很大,特别是当状态空间很大,观察序列很长时。我们可以利用概率的时间不变性解决复杂度。
递归方法(Forward Algorithm)举例:
首先定义部分概率为到达trellis中某一中间状态的概率。把长度为T的观察状态序列表示为:
在计算trellis中某一中间状态的概率时,用所有可能到达该状态的路径之和表示。
比如在t=2时间,状态为cloudy的概率可以用下面的路径计算:
用Pt ( j ) 表示在时间t时 状态j的部分概率。计算方法如下:
Pt ( j )= Pr( observation | hidden state is j ) * Pr(all paths to state j at time t)
最后的观察状态的部分概率表示,这些状态所经过的所有可能路径的概率。比如:
这表示最后的部分概率的和即为trellis中所有可能路径的和,也就是当前HMM下观察序列的概率。
我们计算部分概率的公式为:
Pt ( j )= Pr( observation | hidden state is j ) x Pr(all paths to state j at time t)
但是在初始状态,没有路径到达这些状态。那么我们就用probability乘以associated observation probability计算:
这样初始时刻的状态的部分概率就只与其自身的概率和该时刻观察状态的概率有关。
这一算法最后需要的是概率的和。
对于观察序列长度T,穷举法的复杂度为T的指数级;而Forward Algorithm的复杂度为T的线性。
手动计算过程:观察序列为Damp,Soggy,Dry,计算该模型的概率,不同的模型概率不同,概率最大的对应的则是能产生该序列的最可能模型。
状态转移矩阵A:
| Sunny | Cloudy | Rainy |
Sunny | 0.5 | 0.25 | 0.25 |
Cloudy | 0.375 | 0.125 | 0.375 |
Rainy | 0.125 | 0.675 | 0.375 |
混淆矩阵B:
| Damp | Soggy | Dry | Dryish |
Sunny | 0.15 | 0.05 | 0.6 | 0.20 |
Cloudy | 0.25 | 0.25 | 0.25 | 0.25 |
Rainy | 0.35 | 0.5 | 0.05 | 0.10 |
第一步设置观察序列,初始状态P(Sunny)=0.63,P(Cloudy)=0.17,P(Rainy)=0.20。
第二步,计算初始时刻在状态Sunny下发射符号Damp的概率Alpha1 = (0.63 * 0.15) = 0.094500005。
同理第三步,计算初始时刻在状态Cloudy下发射符号Damp的概率Alpha2 = (0.17 * 0.25) = 0.0425。
第四步,计算初始时刻在状态Rainy下发射符号Damp的概率Alpha3 = (0.2 * 0.35) = 0.07。
第五步,计算第二时刻在状态Sunny下发射符号Soggy的概率,由两部分概率决定,第二时刻到达状态Sunny的所有路径概率之和即为能到达该状态的概率,乘以Sunny发射符号Soggy的概率0.05,Alpha4 = (((0.094500005*0.5) + (0.0425*0.375) + (0.07*0.125)) * 0.05) = 0.0035968751。
同理第六,七步,得到:
Alpha5 = (((0.094500005*0.25) + (0.0425*0.125) + (0.07*0.675)) * 0.25) = 0.019046877
Alpha6 = (((0.094500005*0.25) + (0.0425*0.375) + (0.07*0.375)) * 0.5) = 0.03290625
第八,九,十步,Alpha7 = (((0.0035968751*0.5) + (0.019046877*0.375) + (0.03290625*0.125)) * 0.6) = 0.007832578
Alpha8 = (((0.0035968751*0.25) + (0.019046877*0.125) + (0.03290625*0.675)) * 0.25) = 0.0063729496
Alpha9 = (((0.0035968751*0.25) + (0.019046877*0.375) + (0.03290625*0.375)) * 0.05) = 0.001019082
最后将Alpha7,Alpha8,Alpha9相加即得该模型的概率(产生序列Damp,Soggy,Dry的概率)。
② 根据观察序列找到最有可能的隐状态序列—解码
多数情况下,我们都希望能够根据一个给定的HMM模型,根据观察状态序列找到产生这一序列的潜在的隐含状态序列。
穷举搜索方法举例:
我们可以通过穷举的方式列出所有可能隐含状态序列,并算出每一种隐状态序列组合对应的观察状态序列的概率。概率最大的那个组合对应的就是最可能的隐状态序列组合。
Pr(observed sequence | hidden state combination).
比如说上图中的trellis中,最有可能的隐状态序列是使得概率:
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) 得到最大值的序列。
同样这种穷举法的计算量太大了。为了解决这个问题,我们可以利用和Forward algorithm一样的原理--概率的时间不变性来减少计算量。
用递归方式减少复杂度 ,Viterbi算法:
在给定的观察序列和HMM模型下,我们用一种递归的方式找到最有可能的隐状态序列。同样我们定义部分概率,即在trellis中到达某一中间状态的概率。然后介绍如何在初始时刻t=1和t>1的时刻分别求解这个部分概率。但要注意,这里的部分概率是到达某一中间状态的概率最大的路径而不是所有概率之和。
部分概率和部分最优路径
看如下trellis :
对于trellis中的每个中间状态和结束状态,都存在一条到达它的最优路径。他可能是下图这样:
我们这些路径为部分最优路径,每一条 部分最优路径都对应一个关联概率--部分概率δ。与Forward algorithm不同是最有可能到达该状态的一条路径的概率。
δ (i,t)是所有序列中在t时刻以状态i终止的最大概率。当然它所对应那条路径就是部分最优路径。 δ(i,t)对于每个i,t都是存在的。这样我们就可以在时间T(序列的最后一个状态)找到整个序列的最优路径。
计算在t = 1的初始值
由于在t=1不存在任何部分最优路径,因此可以用初始状态π向量协助计算。
这一点与Forward Algorithm相同 。
计算在t > 1 的部分概率
同样我们只用t-1时刻的信息来得到t时刻的部分概率。
由此图可以看出到达X的最优路径是下面中的一条:
(sequence of states), . . ., A, X
(sequence of states), . . ., B, X
(sequence of states), . . ., C, X
我们希望找到一条概率最大的。回想马尔科夫一阶模型的假设,一个状态之和它前一时刻的状态有关。
Pr (most probable path to A) . Pr (X | A) . Pr (observation | X)
因此到达X的最大概率就是:
其中第一部分由t-1时刻的部分概率得到,第二部分是状态转移概率,第三部分是混淆矩阵中对应的概率。
根据最后得到的公式我们可以把概率的求解写成:
考虑下面trellis
现在我们可以得到到达每一个中间或者终点状态的概率最大的路径。但是我们需要采取一些方法来记录这条路径。这就需要在每个状态记录得到该状态最优路径的前一状态。记为:
这样argmax(寻找具有最大评分的参量)操作符就会选择使得括号中式子最大的索引j。
如果有人问,为什么没有乘以混淆矩阵中的观察概率因子。这是因为我们关心的是在到达当前状态的最优路径中,前一状态的信息,而与他对应的观察状态无关。
手动计算过程:给定观察序列找出最有可能的隐状态序列。
设置观察序列。
Delta1 = 0.63 * 0.15 = 0.094500005
Delta2 = 0.17 * 0.25 = 0.0425
Delta3 = 0.2 * 0.35 = 0.07
Delta4 = max ((0.094500005*0.5), (0.0425*0.375), (0.07*0.125)) * 0.05 = 0.0023625002,从前一时刻最有可能到达Sunny状态的路径(Sunny-Sunny),与该时刻发射符号Soggy概率相乘。
Delta5 = max ((0.094500005*0.25), (0.0425*0.125), (0.07*0.675)) * 0.25 = 0.011812501,最有可能到达Cloudy状态的路径(Rainy-Cloudy)。
Delta6 = max ((0.094500005*0.25), (0.0425*0.375), (0.07*0.375)) * 0.5 = 0.0131250005,最有可能到达Rainy状态的路径(Rainy-Rainy)。
Delta7 = max ((0.0023625002*0.5), (0.011812501*0.375), (0.0131250005*0.125)) * 0.6 = 0.0026578128,最有可能到达Sunny状态的路径(Cloudy-Sunny)。
Delta8 = max ((0.0023625002*0.25), (0.011812501*0.125), (0.0131250005*0.675)) * 0.25 = 0.0022148439, 最有可能到达Cloudy状态的路径(Rainy-Cloudy)。
Delta9 = max ((0.0023625002*0.25), (0.011812501*0.375), (0.0131250005*0.375)) * 0.05 = 2.4609375E-4, 最有可能到达Rainy状态的路径(Rainy-Rainy)。
每一步寻找最可能的状态转移,最后可以得到:面对观察序列Damp-Soggy-Dry,最可能的状态转移为Rainy-Cloudy-Sunny。
viterbi算法的两个优点 :
1)与Forward算法一样,它极大的降低了计算复杂度
2)viterbi会根据输入的观察序列,“自左向右”的根据上下文给出最优的理解。由于viterbi会在给出最终选择前考虑所有的观察序列因素,这样就避免了由于突然的噪声使得决策偏离正确答案。这种情况在真实的数据中经常出现。
③ 从观察序列中得出HMM—学习
这是最难的HMM应用。也就是根据观察序列和其代表的隐状态,生成一个三元组HMM (,A,B)。使这个三元组能够最好的描述我们所见的一个现象规律。
我们用forward-backward algorithm来解决在现实中经常出现的问题--转移矩阵和混淆矩阵不能直接得到的情况。
这个方向在语音处理数据库上有重要的地位。因为它可以帮助我们在状态空间很大,观察序列很长的环境下找到合适HMM模型参数:初始状态、转移概率、混淆矩阵等。
http://blog.sina.com.cn/s/blog_953f8a550100zh35.html
http://yexin218.iteye.com/blog/432120