隐马尔可夫模型(Hidden Markov Model,HMM)
- 主要内容
- HMM简介
- HMM观测序列、状态序列、三要素
- HMM三个问题及其对应算法
- HMM应用
1、HMM简介
隐马尔可夫模型是可用于标注问题的统计学习模型,描述由隐藏的马尔可夫链随机生成观测序列的过程。属于生成模型(什么是生成模型?什么是判别模型?这里不过多介绍,想了解的童鞋百度会给你答案)。
2、HMM观测序列、状态序列、三要素
关于HMM的“观测序列”、“状态序列”、“三要素”的讲解,本文主要借鉴“大佬skyme——关于隐马尔可夫模型”一文的思想,通过一个实例与大家分享。
假设我手里有三个不同的骰子。第一个骰子是我们平常见的骰子(称这个骰子为D6),6个面,每个面(1,2,3,4,5,6)出现的概率是1/6。第二个骰子是个四面体(称这个骰子为D4),每个面(1,2,3,4)出现的概率是1/4。第三个骰子有八个面(称这个骰子为D8),每个面(1,2,3,4,5,6,7,8)出现的概率是1/8。
假设我现在开始掷骰子:
第一次掷骰子的时候,我随机的选取一个骰子。其实,第一次掷骰子,每个骰子都有一定的概率被我选择,且概率和为1。这就是 三要素之一的初始状态概率向量。也就是第一次掷的时候,我选择某个骰子的概率。可以表示为 [P(D6),P(D4),P(D8)] .
假设上一次掷骰子,我选择了骰子D6,那么这次掷骰子,我可以选择骰子D6、D4、D8中的一个。由上次的D6跳转到这次的D6 or D4 or D8,有一定的概率,且跳转的概率和为1。同理,假设我上次选择了D4或者D8,那么跳转到这次的D6 or D4 or D8,也是有一定的概率的。这些概率组成的矩阵,就是 三要素之一的状态转移概率矩阵。可以表示为
我每次掷骰子都有可能得到(1,2,3,4,5,6,7,8)中的一个数字,且每个骰子得到(1,2,3,4,5,6,7,8)的概率不同。这三个骰子得到(1,2,3,4,5,6,7,8)的概率组成的矩阵,就是 三要素之一的观测概率矩阵。可以表示为
假设我投掷了10次骰子,得到一串数字(1、8、2、7、3、6、4、5、1、8)。那么这串数字就是 观测序列。
观测序列中的每个数字,分别是由哪个骰子得到的呢?假设是由(D6、D8、D4、D8、D4、D6、D4、D6、D6、D8)得到的,那么这个由骰子组成的序列,就是 状态序列。这个状态序列其实就是HMM中的隐含状态链,或者说就是隐藏的马尔可夫链。
3、HMM三个问题及其对应算法
问题一,预测问题(解码问题):已知三要素、观测序列,求解概率最大的状态序列。
解决方法:维特比算法。维特比算法其实就是通过动态规划求解概率最大的路径(最优路径),这条路径就是要求解的状态序列。动态规划,相对比较简单,这里就不展开介绍了。此处直接上代码,看懂代码,就看懂维特比算法了。建议读者认真看一下此处给出的代码,非常非常容易理解。这里的代码以上面骰子的例子为背景。
//这里的变量我就不初始化啦,大概给出主体思想的代码
double Initial_Selection[3]={}; //初始状态概率向量,第一次选择某个骰子的概率
double Transition_Probability[3][3]={}; //状态转移概率矩阵,由某个骰子跳转到另一个骰子的概率
double Observation_Probability[3][8]={}; //观测概率矩阵,每个骰子得到(1,2,3,4,5,6,7,8)的概率
int Obs_vec[10]={}; //观测序列,投掷了10次骰子
int Hidden_vec[10]; //状态序列,需要求解的
int* DecodeFun()
{
double temp_MaxProbabilityVector[10]={0}; //临时变量,存储当前状态概率的最大值,知道动态规划的人都懂
Hidden_vec[0] = max(Initial_Selection); //这里边我偷懒啦,意思明白就行啦。如果观测序列的第一个值为8,那只能选择骰子D8啦;如果为1,那就选择初始状态概率向量中最大的骰子
for(int i=1; i<10; i++)
{
for(int j=0; j<3; j++)
{
if(temp_MaxProbabilityVector[i] < temp_MaxProbabilityVector[i-1]*Transition_Probability[Hidden_vec[i-1]][j]*Observation_Probability[j][Obs_vec[i]])
{
temp_MaxProbabilityVector[i] = temp_MaxProbabilityVector[i-1]*Transition_Probability[Hidden_vec[i-1]][j]*Observation_Probability[j][Obs_vec[i]];
Hidden_vec[i] = j; //保存路径(状态)
}
}
}
return Hidden_vec; //Hidden_vec即为所求解的状态序列
}
问题二:学习问题:一个问题是已知观测序列和状态序列,求解三要素,这是监督学习;另一个是已知观测序列,求解三要素,这是非监督学习。
已知观测序列以及对应的状态序列,求解三要素。可以通过极大似然估计进行求解。
已知观测序列,求解三要素。可以通过Baum-Welch算法进行求解,其实吧,这个Baum-Welch算法就是EM算法嘛。EM算法详细介绍,可以参考我之前的博客,“EM算法详解”。
问题三:概率计算问题:已知三要素,观测序列,计算在该模型下,该观测序列出现的概率。
解决方法:前向算法、后向算法。这两个算法,李航《统计学习方法》中的例子很清晰,也非常容易理解,感兴趣的可以了解一下。博主偷懒啦,这里就不详细介绍啦。
4、HMM应用
关于HMM的应用,个人认为比较广泛的是问题一的应用。比如,预测问题(通过海藻变化来预测天气:海藻的变化就是观察序列,待预测的天气就是状态序列)、解码问题(通过HMM进行中文分词,这一块儿,博主还在学习中,后续会有相关的博客进行更新)。