用hmmlearn学习隐马尔科夫模型HMM
在之前的HMM系列中,我们对隐马尔科夫模型HMM的原理以及三个问题的求解方法做了总结。本文我们就从实践的角度用Python的hmmlearn库来学习HMM的使用。关于hmmlearn的更多资料在官方文档有介绍。
1. hmmlearn概述
hmmlearn安装很简单,"pip install hmmlearn"即可完成。
hmmlearn实现了三种HMM模型类,按照观测状态是连续状态还是离散状态,可以分为两类。GaussianHMM和GMMHMM是连续观测状态的HMM模型,而MultinomialHMM是离散观测状态的模型,也是我们在HMM原理系列篇里面使用的模型。
对于MultinomialHMM的模型,使用比较简单,"startprob_"参数对应我们的隐藏状态初始分布$\Pi$, "transmat_"对应我们的状态转移矩阵$A$, "emissionprob_"对应我们的观测状态概率矩阵$B$。
对于连续观测状态的HMM模型,GaussianHMM类假设观测状态符合高斯分布,而GMMHMM类则假设观测状态符合混合高斯分布。一般情况下我们使用GaussianHMM即高斯分布的观测状态即可。以下对于连续观测状态的HMM模型,我们只讨论GaussianHMM类。
在GaussianHMM类中,"startprob_"参数对应我们的隐藏状态初始分布$\Pi$, "transmat_"对应我们的状态转移矩阵$A$, 比较特殊的是观测状态概率的表示方法,此时由于观测状态是连续值,我们无法像MultinomialHMM一样直接给出矩阵$B$。而是采用给出各个隐藏状态对应的观测状态高斯分布的概率密度函数的参数。
如果观测序列是一维的,则观测状态的概率密度函数是一维的普通高斯分布。如果观测序列是$N$维的,则隐藏状态对应的观测状态的概率密度函数是$N$维高斯分布。高斯分布的概率密度函数参数可以用$\mu$表示高斯分布的期望向量,$\Sigma$表示高斯分布的协方差矩阵。在GaussianHMM类中,“means”用来表示各个隐藏状态对应的高斯分布期望向量$\mu$形成的矩阵,而“covars”用来表示各个隐藏状态对应的高斯分布协方差矩阵$\Sigma$形成的三维张量。
2. MultinomialHMM实例
下面我们用我们在HMM系列原理篇中的例子来使用MultinomialHMM跑一遍。
完整代码参见我的github:https://github.com/ljpzzz/machinelearning/blob/master/natural-language-processing/hmm.ipynb
首先建立HMM的模型:
import numpy as np
from hmmlearn import hmm states = ["box 1", "box 2", "box3"]
n_states = len(states) observations = ["red", "white"]
n_observations = len(observations) start_probability = np.array([0.2, 0.4, 0.4]) transition_probability = np.array([
[0.5, 0.2, 0.3],
[0.3, 0.5, 0.2],
[0.2, 0.3, 0.5]
]) emission_probability = np.array([
[0.5, 0.5],
[0.4, 0.6],
[0.7, 0.3]
]) model = hmm.MultinomialHMM(n_components=n_states)
model.startprob_=start_probability
model.transmat_=transition_probability
model.emissionprob_=emission_probability
现在我们来跑一跑HMM问题三维特比算法的解码过程,使用和原理篇一样的观测序列来解码,代码如下:
seen = np.array([[0,1,0]]).T
logprob, box = model.decode(seen, algorithm="viterbi")
print("The ball picked:", ", ".join(map(lambda x: observations[x], seen)))
print("The hidden box", ", ".join(map(lambda x: states[x], box)))
输出结果如下:
('The ball picked:', 'red, white, red')
('The hidden box', 'box3, box3, box3')
可以看出,结果和我们原理篇中的手动计算的结果是一样的。
也可以使用predict函数,结果也是一样的,代码如下:
box2 = model.predict(seen)
print("The ball picked:", ", ".join(map(lambda x: observations[x], seen)))
print("The hidden box", ", ".join(map(lambda x: states[x], box2)))
大家可以跑一下,看看结果是否和decode函数相同。
现在我们再来看看求HMM问题一的观测序列的概率的问题,代码如下:
print model.score(seen)
输出结果是:
-2.03854530992
要注意的是score函数返回的是以自然对数为底的对数概率值,我们在HMM问题一中手动计算的结果是未取对数的原始概率是0.13022。对比一下:$$ln0.13022 \approx -2.0385$$
现在我们再看看HMM问题二,求解模型参数的问题。由于鲍姆-韦尔奇算法是基于EM算法的近似算法,所以我们需要多跑几次,比如下面我们跑三次,选择一个比较优的模型参数,代码如下:
import numpy as np
from hmmlearn import hmm states = ["box 1", "box 2", "box3"]
n_states = len(states) observations = ["red", "white"]
n_observations = len(observations)
model2 = hmm.MultinomialHMM(n_components=n_states, n_iter=20, tol=0.01)
X2 = np.array([[0,1,0,1],[0,0,0,1],[1,0,1,1]])
model2.fit(X2)
print model2.startprob_
print model2.transmat_
print model2.emissionprob_
print model2.score(X2)
model2.fit(X2)
print model2.startprob_
print model2.transmat_
print model2.emissionprob_
print model2.score(X2)
model2.fit(X2)
print model2.startprob_
print model2.transmat_
print model2.emissionprob_
print model2.score(X2)
结果这里就略去了,最终我们会选择分数最高的模型参数。
以上就是用MultinomialHMM解决HMM模型三个问题的方法。
3. GaussianHMM实例
下面我们再给一个GaussianHMM的实例,这个实例中,我们的观测状态是二维的,而隐藏状态有4个。因此我们的“means”参数是$4 \times 2$的矩阵,而“covars”参数是$4 \times 2 \times 2$的张量。
建立模型如下:
startprob = np.array([0.6, 0.3, 0.1, 0.0])
# The transition matrix, note that there are no transitions possible
# between component 1 and 3
transmat = np.array([[0.7, 0.2, 0.0, 0.1],
[0.3, 0.5, 0.2, 0.0],
[0.0, 0.3, 0.5, 0.2],
[0.2, 0.0, 0.2, 0.6]])
# The means of each component
means = np.array([[0.0, 0.0],
[0.0, 11.0],
[9.0, 10.0],
[11.0, -1.0]])
# The covariance of each component
covars = .5 * np.tile(np.identity(2), (4, 1, 1)) # Build an HMM instance and set parameters
model3 = hmm.GaussianHMM(n_components=4, covariance_type="full") # Instead of fitting it from the data, we directly set the estimated
# parameters, the means and covariance of the components
model3.startprob_ = startprob
model3.transmat_ = transmat
model3.means_ = means
model3.covars_ = covars
注意上面有个参数covariance_type,取值为"full"意味所有的$\mu,\Sigma$都需要指定。取值为“spherical”则$\Sigma$的非对角线元素为0,对角线元素相同。取值为“diag”则$\Sigma$的非对角线元素为0,对角线元素可以不同,"tied"指所有的隐藏状态对应的观测状态分布使用相同的协方差矩阵$\Sigma$
我们现在跑一跑HMM问题一解码的过程,由于观测状态是二维的,我们用的三维观测序列, 所以这里的 输入是一个$3 \times 2$的矩阵,代码如下:
seen = np.array([[1.1,2.0],[-1,2.0],[3,7]])
logprob, state = model3.decode(seen, algorithm="viterbi")
print state
输出结果如下:
[0 0 1]
再看看HMM问题一对数概率的计算:
print model3.score(seen)
输出如下:
-41.1211281377
以上就是用hmmlearn学习HMM的过程。希望可以帮到大家。
(欢迎转载,转载请注明出处。欢迎沟通交流: liujianping-ok@163.com)
用hmmlearn学习隐马尔科夫模型HMM的更多相关文章
- 隐马尔科夫模型HMM学习最佳范例
谷歌路过这个专门介绍HMM及其相关算法的主页:http://rrurl.cn/vAgKhh 里面图文并茂动感十足,写得通俗易懂,可以说是介绍HMM很好的范例了.一个名为52nlp的博主(google ...
- 隐马尔科夫模型HMM(一)HMM模型
隐马尔科夫模型HMM(一)HMM模型基础 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比 ...
- 隐马尔科夫模型HMM
崔晓源 翻译 我们通常都习惯寻找一个事物在一段时间里的变化规律.在很多领域我们都希望找到这个规律,比如计算机中的指令顺序,句子中的词顺序和语音中的词顺序等等.一个最适用的例子就是天气的预测. 首先,本 ...
- 隐马尔科夫模型 HMM(Hidden Markov Model)
本科阶段学了三四遍的HMM,机器学习课,自然语言处理课,中文信息处理课:如今学研究生的自然语言处理,又碰见了这个老熟人: 虽多次碰到,但总觉得一知半解,对其了解不够全面,借着这次的机会,我想要直接搞定 ...
- 猪猪的机器学习笔记(十七)隐马尔科夫模型HMM
隐马尔科夫模型HMM 作者:樱花猪 摘要: 本文为七月算法(julyedu.com)12月机器学习第十七次课在线笔记.隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它用来 ...
- 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率
隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比算法 ...
- 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数
隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比算法 ...
- 隐马尔科夫模型HMM(四)维特比算法解码隐藏状态序列
隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数 隐马尔科夫模型HMM(四)维特比算法解码隐藏状态 ...
- 机器学习之隐马尔科夫模型HMM(六)
摘要 隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它用来描述一个含有隐含未知参数的马尔科夫过程.其难点是从可观察的参数中确定该过程的隐含参数,然后利用这些参数来作进一步 ...
随机推荐
- ArrayList 进阶方法之ListIterator
同样看的都是jdk1.8 中 ArrayList中的源码,整理测试一下而已ListIterator(int index)方法,返回指定下标(包含该下标)后的值,此时index位置的元素就是新列表迭代器 ...
- MOSFET使用与H桥驱动问题
0.小叙闲言 最开始学习三极管的时候,很注重它的工作原理,后来到了实际应用,就直接把三极管或MOSFET直接当作一个开关器件使用.直到前这几天,接触到MOSFET组成的H桥驱动电路时,发现它纯当作一个 ...
- js闭包(closure),个人理解
一.闭包概念理解 各种专业文献上对js"闭包"(closure)定义非常抽象,贼难看懂.我的理解是,闭包就是能够读取某函数内部变量的函数.由于在Javascript语言中只有在函数 ...
- 设计模式之“Observer”注疏#01
原文首发于我的微信公众号:GeekArtT. Observer设计模式是为了解决"信息同步更新"的问题而存在的.它试图解决这样一个问题:如果有"一堆对象"都跟随 ...
- zoj1610线段树区间覆盖
链接https://vjudge.net/contest/66989#problem/F 坑爹的线段树,一直用区间更新做,做了半天一点眉目都没有,只好搜题解,感觉好堕落,经常不会做就搜题解,以后一定要 ...
- 极光的开源礼物「Aurora IMUI」
今日,奉上我们拙作,仅为开源世界献出绵薄之力. Aurora IMUI,一个通用的即时通讯(IM)UI 库.不局限于任何 IM SDK. 本 UI 库提供了消息列表.输入视图等常用组件. 初心 过去的 ...
- 【iOS UI】UINavigationController
1.UINavigationController介绍 1.1简介 UINavigationController可以翻译为导航控制器,在iOS里经常用到. 下面的图显示了导航控制器的流程.最左侧是根视图 ...
- 基于ZKWeb + Angular 4.0的开源管理后台Demo
这是一套基于ZKWeb网页框架和Angular 4.0编写的开源管理后台Demo,实现了前后端分离和模块化开发, 地址是: https://github.com/zkweb-framework/ZKW ...
- [玩耍]C++控制台扫雷
其实是大一还不会GUI时闲着无聊写的.都是硬编码,也不支持自定义棋盘大小,现在看看这代码惨不忍睹.下载地址:http://download.csdn.net/download/xienaoban/98 ...
- [刷题]算法竞赛入门经典(第2版) 5-16/UVa212 - Use of Hospital Facilities
题意:模拟患者做手术. 其条件为:医院有Nop个手术室.准备手术室要Mop分钟,另有Nre个恢复用的床.准备每张床要Mre分钟,早上Ts点整医院开张,从手术室手术完毕转移到回复床要Mtr分钟.现在医院 ...