一、引言
HMM对于自然语言处理和语音识别等方面有着重大意义,其三个经典问题
- 在已知序列的情况下推理出隐藏序列
- 参数估计
- 计算可能序列的边缘概率
在诸多文章中被提及,但是对于如何求解却很少提及!
本文主要通过一个简单的小例子说明如何在已知序列的情况下推理出隐藏序列。
二、模型引入
为了模型的使用做如下假设
- 观测序列和隐含序列有关系
- 序列符合马尔科夫过程
模型图概览
分析
- 隐含序列范围 :state [a,b,c]
- 观测序列范围 :observe [1,2,3]
为了根据观测序列求出隐含的序列,必须求出三个参数,分别如下
- 参数1:
:表示隐含序列每一位的为序列开头的概率,比如有4个序列
a,b,c
a,c,c
b,a,c
c,a,b
如序列a,b,c的初始概率
- 参数2:隐含序列之间的转移概率矩阵
仍以状态a,b,c的序列为例,a->a转移了0次,a->b转移了2次...
a | b | c | |
---|---|---|---|
a | 0 | 2 | 2 |
b | 1 | 0 | 1 |
c | 1 | 0 | 1 |
那么为:
a | b | c | |
---|---|---|---|
a | 0 | 0.5 | 0.5 |
b | 0.5 | 0 | 0.5 |
c | 0.5 | 0 | 0.5 |
- 参数3:隐含序列到观测序列的发射概率矩阵
如隐含序列和观测序列的对应关系如下:
a,b,c->1,2,3
a,c,c->1,3,2
b,a,c->2,2,3
c,a,b->1,1,2
a->1发射了3次,a->2发射了1次...
1 | 2 | 3 | |
---|---|---|---|
a | 3 | 1 | 0 |
b | 0 | 3 | 0 |
c | 1 | 1 | 2 |
那么为:
1 | 2 | 3 | |
---|---|---|---|
a | 0.75 | 0.25 | 0 |
b | 0 | 1 | 0 |
c | 0.25 | 0.25 | 0.5 |
到此为止模型的三个参数处理完毕,根据三个参数+维特比算法就可以根据输入值求出预测值,比如输入一个序列 2,1,1,那么需要计算的表格是
a | b | c | |
---|---|---|---|
2 | |||
1 | ... | ... | |
1 | ... | ... | ... |
在首行,根据初始概率和发射概率进行初始化
首先计算序列2,1,1的首位2的状态有可能是a,b,c的概率
首位的影响因素为两个,一个是a,b,c分别为首的概率,一个是隐含状态a,b,c可能生成观测值1,2,3的概率,那么
从第二行开始,使用发射概率和来自有状态转移的最大概率进行概率填充,并记录最大概率来自方状态确定路径,特别说明一下(以为例):
表示在观测值为1的条件下隐含状态为a的概率,在此不仅要考虑a发射为1的概率,还要考虑上一个状态a,b,c转移为a的概率,基于动态规划的思想,确保局部路径最优,还要考虑上一个状态的最终概率
三、实战预测
- 安装环境
pip install hmmlearn
- 根据
二
的方法计算模型参数 - 导入hmmlearn
from hmmlearn import hmm
- 模型求解
model=hmm.MultinomialHMM(n_components=隐含状态数量)
model.startprob_=startP
model.transmat_=tranP
model.emissionprob_=emitP
预测结果=model.predict(输入序列.reshape(-1,1))
本文如果有什么错误还望大神指正!