Hidden Markov Model
Table of Contents
1. 隐马尔可夫模型简介
隐马尔可夫模型(Hidden Markov Model, HMM)是一个著名的概率模型,可应用于词性标注、语音识别、中文分词等等方面。
下面介绍一个简单的 HMM 模型例子(摘自其 wikipedia )。
Alice 和 Bob 是好朋友,他们不在一个城市,每天通过电话了解对方当天作了什么。Bob 仅仅对三种活动感兴趣(一天仅做一个活动):散步,购物,清理房间。他选择做哪件事只凭当天的天气。Alice 对于 Bob 所住的地方的天气情况并不了解,但是他知道总的趋势。在 Bob 告诉 Alice 每天所做的事情基础上,Alice 想要猜测 Bob 所在地的天气情况。
可以简单地认为天气的运行就像一个马尔可夫链。其有两个状态 “雨”和“晴”,但 Alice 是无法直接观察它们,也就是说,它们对于 Alice 是隐藏的。每天,Bob 有一定的概率进行下列活动:“散步”,“购物”,或“清理房间”。因为 Bob 会告诉 Alice 他的活动,所以这些活动就是 Alice 的观察数据。这整个系统就是一个隐马尔可夫模型。
Alice 可以通过“观察数据”(Bob 的活动)预测出最可能的“状态数据”(Bob 所在地市天气)。这是隐马尔可夫模型的主要问题之一,可以用“维特比”算法解决。
参考:
http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/html_dev/main.html
http://www.52nlp.cn/hmm-learn-best-practices-and-cui-johnny-blog
1.1. HMM 的正式描述
隐马尔可夫模型描述一个隐藏的马尔可夫链随机生成不可观测的状态随机序列,再由各个状态生成一个观测而产生观测随机序列的过程。 隐藏的马尔可夫链随机生成的状态的序列,称为状态序列(state sequence);每个状态生成一个观测,而由此产生的观测的随机序列,称为观察序列(observation sequence)。序列的每一个位置又可以看作是一个时刻。
隐马尔可夫模型由三个要素决定:初始状态概率分布、状态转移概率分布以及观测概率分布。
隐马尔可夫模型的形式定义如下:
设
其中,
其中,
其中,
其中,
隐马尔可夫模型由初始状态概率向量
状态转移概率矩阵
对于前面“Alice 预测其朋友 Bob 所在城市的天气”的例子,可以建立下面的 HMM 模型:
状态的集合(天气情况):
观测的集合(Bob 的活动):
初始状态概率向量:
状态转移概率矩阵
观测概率矩阵
上面模型可用图 1 表示。
Figure 1: HMM 模型示意图
1.2. HMM 的 2 个基本假设
从隐马尔可夫模型的定义知,HMM 作了 2 个基本假设:
(1) 齐次马尔可夫性假设。即假设隐藏的马尔可夫链在任意时刻
(2) 观测独立性假设。即假设任意时刻的观测只依赖于该时刻的马尔可夫链的状态,与其他观测及状态无关。
1.3. HMM 的 3 个基本问题
对于隐马尔可夫模型,有 3 个基本问题。
(1) 概率计算问题。已知模型
(2) 学习问题。已知观测序列
(3) 预测问题(又称解码问题)。已知模型
后面将讨论这 3 个问题。
2. 维特比算法
维特比算法(Viterbi algorithm)解决的是隐马尔可夫模型中的解码问题——通过观测序列寻找最可能的隐藏状态序列。
假设有下面 HMM,模型中“观测序列”为海藻湿度,有四种情况:{dry, dryish, damp, soggy},隐藏的“状态序列”为天气,有三种情况:{Sunny, Cloudy, Rainy}。
假设连续三天观察海藻湿度依次为:干燥(dry)、湿润(damp)、湿透(soggy),如何推断这三天最可能的天气情况?
Figure 2: HMM 模型,Viterbi 算法实例
最直接的想法是穷举法:遍历所有的天气组合(27 种)。最可能的天气情况就是下面这些概率中其值最大的那个所对应的天气情况。
但是穷举效率很低,当观察序列比较长时根本不可行。
下面介绍的维特比算法利用 HMM 模型的特点加快解码的效率。
参考:
http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/html_dev/viterbi_algorithm/s1_pg1.html
2.1. Viterbi 算法分析
Viterbi 算法是一种动态规划算法。
定义
在某个固定时刻中,每一个状态,都有一个到达该状态的最可能路径。以前面介绍的“海藻湿度和天气”为例,在
Figure 3: 每个状态都有一个到达它的“最可能路径”
特别地,如果共有
2.1.1. 递归计算“局部最佳路径”的概率(动态规划算法)
下面将介绍如何利用
先考虑
上式中,
现在考虑
下面考虑计算
Figure 4: 通过 t-1 时刻的“局部最佳路径”计算 t 时刻的“局部最佳路径”
即有:
HMM 模型中,有个齐次马尔可夫假设,即任意时刻
上式中,
类似地,可得:
显然,
2.1.2. 回溯得到最优路径
通过一个辅助变量,我们可以方便地回溯得到最优路径。
定义
上式中,
这样,如果共有
得到
至此,我们得到了最终的“解码序列”。
2.1.3. Viterbi 算法的形式描述
Viterbi 算法的完整分析在前面已经介绍了。下面把 Viterbi 算法总结如下:
输入:HMM 模型参数
输出:最有可能的对应状态序列(最优路径)
Viterbi 算法步骤:
(1) 初始化:
(2) 递归求解当
(3) 上面的计算结束后,求最优路径的概率
(4) 回溯得到最优路径,依次求
2.2. Viterbi 算法实例
以“Alice 预测其朋友 Bob 所在城市的天气”为例,其对应的 HMM 模型如图 1 所示,为方便查看,重复如图 5 所示。
Figure 5: HMM 模型示意图
假设 Alice 观测到 Bob 连续三天的行动分别为:‘Walk’, ‘Shop’, ‘Clean’,请推测 Bob 所在城市这三天最可能的天气情况。
直接使用 Viterbi 算法即可,计算过程如下:
(1) 初始化
在
上式中,
同时,记
(2) 求解当
当
上式中,
上面两条概率最大路径,分别记录路径上的前一个状态:
类似地,当
“到达某状态最可能路径”的前一个状态:
(3) 结束,求最优路径的最后一个状态(下式中
即最后一个状态为‘Rainy’
(4) 回溯求最优路径。公式为
所以,最后得到的最优路径为:‘Sunny’, ‘Rainy’, ‘Rainy’。求解过程如图 6 所示。
Figure 6: “最优路径”求解过程
说明 1:‘Walk’, ‘Shop’, ‘Clean’解码成了:‘Sunny’, ‘Rainy’, ‘Rainy’。但如果只进行了前两次观察‘Walk’, ‘Shop’,从上图容易知道(因为 0.0432 大于 0.0384),对应的最优路径为:‘Sunny’, ‘Sunny’(而不是‘Sunny’, ‘Rainy’)。
说明 2:上图中的路径记录着
Figure 7: 回溯得到“最优路径”(摘自:http://ee163.caltech.edu/old/2005/handouts/viterbi.pdf)
2.3. Viterbi 算法实现
下面的代码摘自(可以从这个链接找到完整的测试程序):http://www.kanungo.com/software/software.html#umdhmm
/* Viterbi algorithm * http://www.kanungo.com/software/software.html#umdhmm */ typedef struct { int N; /* number of states; Q={1,2,...,N} */ int M; /* number of observation symbols; V={1,2,...,M}*/ double **A; /* A[1..N][1..N]. a[i][j] is the transition prob of going from state i at time t to state j at time t+1 */ double **B; /* B[1..N][1..M]. b[j][k] is the probability of of observing symbol k in state j */ double *pi; /* pi[1..N] pi[i] is the initial state distribution. */ } HMM; void Viterbi(HMM *phmm, int T, int *O, double **delta, int **psi, int *q, double *pprob) { int i, j; /* state indices */ int t; /* time index */ int maxvalind; double maxval, val; /* 1. Initialization */ for (i = 1; i <= phmm->N; i++) { delta[1][i] = phmm->pi[i] * (phmm->B[i][O[1]]); psi[1][i] = 0; } /* 2. Recursion */ for (t = 2; t <= T; t++) { for (j = 1; j <= phmm->N; j++) { maxval = 0.0; maxvalind = 1; for (i = 1; i <= phmm->N; i++) { val = delta[t-1][i]*(phmm->A[i][j]); if (val > maxval) { maxval = val; maxvalind = i; } } delta[t][j] = maxval*(phmm->B[j][O[t]]); psi[t][j] = maxvalind; } } /* 3. Termination */ *pprob = 0.0; q[T] = 1; for (i = 1; i <= phmm->N; i++) { if (delta[T][i] > *pprob) { *pprob = delta[T][i]; q[T] = i; } } /* 4. Path (state sequence) backtracking */ for (t = T - 1; t >= 1; t--) q[t] = psi[t+1][q[t+1]]; }
3. 概率计算算法
已知 HMM 模型
最直接的方法是按概率公式直接计算,通过列举所有可能的长度为
下面介绍 Forward–backward algorithm ,用“前向算法”或“后向算法”可以有效地计算观测序列的概率。
参考:
《统计学习方法,李航著》第 10 章 隐马尔可夫模型
3.1. 前向算法(动态规划算法)
和 Viterbi 算法类似,前向算法也是一种动态规划算法。
首先定义“前向概率”:HMM 模型
前向算法描述如下(如果理解了 Viterbi 算法,那么前向算法也比较好理解):
(1) 初值(
(2) 递推,对于
上面递归式可以用图 8 解释:
Figure 8: 前向算法中递归求解前向概率
(3) 终止
参考:
http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/html_dev/forward_algorithm/s1_pg1.html
http://www.52nlp.cn/hmm-learn-best-practices-five-forward-algorithm-1