HMM(隐马尔可夫模型)是用来描述隐含未知参数的统计模型,举一个经典的例子:一个东京的朋友每天根据天气{下雨,天晴}决定当天的活动{公园散步,购物,清理房间}中的一种,我每天只能在twitter上看到她发的推“啊,我前天公园散步、昨天购物、今天清理房间了!”,那么我可以根据她发的推特推断东京这三天的天气。在这个例子里,显状态是活动,隐状态是天气。

马尔可夫模型的学习笔记。

简单的介绍下马尔科夫链,描述的是状态空间中经过一个状态到另一个状态的转换的随机过程,该过程要求具备“无记忆”的性质,即下一状态的概率分布智能友当前状态觉得,在时间序列中它前面的事件均与之无关。

HMM

从天气模型来说明。

在这个马尔可夫模型中,存在三个状态,sunny,rainy,cloudy,图示中的箭头所向意味着状态之间的相互转换。
状态转移矩阵A:

weather sunny rainy cloudy
sunny 0.6 0.1 0.3
rainy 0.4 0.5 0.1
cloudy 0.2 0.5 0.3

假设某一天有三种不同的行为,散步、购物和收拾房间,但是这些行为受天气的影响。如下表格来描述,观测矩阵B:

Weahter\action walk shop tidy
sunny 0.6 0.3 0.1
rainy 0.1 0.4 0.5
cloudy 0.3 0.4 0.3

此外还有初始状态概率向量Pi,即为第一天不同天气的概率。观测序列,即为观测值(此处为干了什么)
到此HMM基本要素:

  1. 初始概率向量π
  2. 状态转移矩阵
  3. 观测矩阵
  4. 观测序列

现在利用HMM来解决实际问题:
第一个问题,现在模型已知,你的朋友连续三天做的事情分别是:购物,散步和收拾。
根据模型计算产生这些行为的概率是多少,很简单的概率计算。

  • 第一种计算方法,枚举法。
    计算出所有可能的类型,总共有3^3 种类型,其时间复杂度为N^T 。这种情况如果是观测序列变大,计算量会变得非常大。
from numpy import *
class HMM:
def __init__(self):
self.A = array([[0.6,0.1,0.3],[0.4,0.5,0.1],[0.2,0.5,0.1]])#状态矩阵
self.B = array([[0.6,0.3,0.1],[0.1,0.4,0.5],[0.3,0.4,0.3]])#状态转移矩阵
self.Pi = array([0.4,0.4,0.2])#初始概率
self.o = [0,1,2]#观测序列
self.ol = len(self.o)#观测序列长度
self.m = len(self.A)#状态集合个数
self.n = len(self.B[0])#观测项目个数
def enumeration(self):
tmp = 0
for i in range(self.m):
for k in range(self.m):
for j in range():
tmp += self.Pi[i]*self.B[i][self.o[0]]*self.A[i][k]*self.B[k][self.o[1]]*self.A[k][j]*self.B[j][self.o[2]]
print tmp
if __name__ == '__main__':
RUN = HMM()
RUN.enumeration()
  • 第二种解决方法是前向算法。
    前向变量αt(i):在t时刻,HMM输出序列为O1O2..OT,在第t时刻位于状态si的概率。
    在这个问题中,
    1. 在t1时刻,a1(1) = πsunny Bsunny(shop) , a1(2) = πrainy Brainy(shop) , a1(3) = πcloudy* Bcloudy(shop)
    2. 在t2时刻,a2(1) = a1(1) A1(1) Bsunny(walk) , a2(2) = a1(2) A1(2) Brainy(walk) , a2(3) = a1(3)* A1(3)Bcloudy(walk)
    3. ……以此类推,P(O|M) = an(1) + an(2) +…+an(n)

计算某一时间的某个状态的前向变量需要看前一时刻的N个状态,此时的时间复杂度为O(N),而每个时刻有N个状态,又有T个观测向量,所以时间复杂度为O(N^2 T)

def forward(self):
self.x = array(zeros((self.ol,self.m))
for i in range(self.m):
self.x[0][i] = self.Pi[i]*self.B[i][self.o[0]]
for x in range(1,self.ol):
for y in range(self.m):
tmp = 0
for k in range(self.m):
tmp += self.x[x-1][y]*self.A[k][i]
self.x[i][y] = tmp*self.B[i][self.o[j]]
res = 0
for i in range(self.m):
res += self.x[self.t-1][i]
print self.x #前向概率矩阵
print res #最终可能概率
  • 第三种解决方法是后向算法
    先介绍后向变量βt(i):给定模型μ=(A,B,π),在时间t 状态为Si的前提下,输出序列为O1O2..OT的概率,即βt(i)=P(Ot+1Ot+2…OT|qt=Si,μ)。
    后向概率的直观解释就是在t-1时刻输出到t时刻Ot状态下的概率。这里是参考网址
def reverse(self):
self.x = array(zeros((self.ol,self.m))
for i in range(self.m):
self.x[self.ol-1][i] = 1 #Ot+1为必然事件所以为1
j = self.ol -2
while j >=0:
for i in range(self.m):
for v in range(self.m):
self.x[j][i] = self.A[i][v]*self.B[v][self.o[j+1]]*self.x[j+1][v]
j = j - 1
print self.x #后向矩阵
res = 0
for i in range(self.m):
res += self.Pi[i]*self.B[i][self.o[0]]*self.x[0][i]
print res #输出结果

第二个问题,根据你的朋友的行为,猜测这几天最有可能的天气是怎样。

  • 有两个解决方法,第一个是算出每种状态下的发生概率,取最大的一个。但是这个方法忽略了状态之间的可转移性,有可能在两个状态下转移概率为0

  • 第二种解决方法是维特比算法,定义维特比变量δt(i):在时间t,HMM沿着一条路径到达状态si,并输出观测序列O=O(1)O(2)…Oa(T)的最大概率:δt(i) = max P(q1q2…qt=si,O1O2…Ot|μ)

def viterbi(self):
self.q = array(zeros((self.ol,self.m))#最大概率记录矩阵
self.w = array(zeros((self.ol,self.m))#前一状态矩阵
self.L = array(zeros(self.ol))
for i in range(self.m):
self.q[0][i] = self.Pi[i] * self.B[i][self.o[0]]
self.w[0][i] = 0
for k in range(1,self.ol):
for i in range(self.m):
self.q[k,i] = self.B[i][self.o[k]] * array([self.q[k-1][j] * self.A[j][i] for i in range(self.m)]).argmax()
self.w[k,i] = array([self.q[k-1][j] * self.A[j][i] for j in range(self.m)]).argmax()
P = self.q[self.ol-1].max()
print P #发生这种行为的最大概率
self.L[self.ol - 1] = delta[self.ol - 1].argmax()#获得最大概率的index,此个index记录了上一最大概率所处状态。
for i in range(self.ol -2, -1, -1):
I[t] = self.w[i + 1, self.L[i + 1]] # 从后往前,
print I

应用

输入预测

HMM模型有三个组成,μ = (A,B,π)。隐马尔科夫模型python实现简单拼音输入法

  • 统计初始化概率矩阵π,也就是找出所有文字出现在句首的概率。也就是你打开手机输入法后不作任何输出第一排显示的问题。
  • 状态转移矩阵A,假设你点击了一个字,输入法就要根据输入内容来预测你下一个想输入的字来更新推荐栏。
  • 发射概率矩阵,在输出拼音的情况下,根据使用频率来推荐字。

    解决生物学问题

    预测5‘剪切位点

Eddy SR. What is a hidden Markov model? Nat Biotechnol. 2004;22(10):1315-1316. doi:10.1038/nbt1004-1315.

hidden_states = [E,5,I]
obervations = [A,C,G,T]

transition E 5 I
E 0.9 0.1 0
5 0 0 1
I 0 0.9 0.1
emission A C G T
E 0.25 0.25 0.25 0.25
5 0.05 0 0.95 0
I 0.4 0.1 0.1 0.4

解释下该图,假设你有一个DNA序列,同时包含了内含子(I)和外显子(E)。我们要进行5’的剪切位点的预测,假设我们已建立HMM模型μ=(A,B,π),该图最上面已经包含了所有的状态转移矩阵A、观测状态矩阵和初始概率π,要进行预测的DNA序列中的每个碱基就是我们的观测向量。和上面解决天气模型一直,已知动作判断天气,现在是已知序列判断那个是外显子和内含子的分界岭,输出概率最大的一个,一般使用lgP表示。
同样的我们可以预测新物种的基因编码区,基因的结构域,

前向算法伪代码:

To use the example follow these steps :

  1. Enter a number of valid observed states in the input field.
  2. Press 'Set' to initialise the matrix.
  3. Use either 'Run' or 'Step' to make the calculations.
    • 'Run' will calculate the 's for each and every node and return the probability of the HMM.
    • 'Step' will calculate the  value for the next node only. Its value is displayed in the output window.

HMM(隐马尔可夫模型)不断学习中的更多相关文章

  1. HMM隐马尔可夫模型(词语粘合)

    HMM用于自然语言处理(NLP)中文分词,是用来描述一个含有隐含未知参数的马尔可夫过程,其目的是希望通过求解这些隐含的参数来进行实体识别,说简单些也就是起到词语粘合的作用. HMM隐马尔可夫模型包括: ...

  2. HMM隐马尔可夫模型来龙去脉(一)

    目录 隐马尔可夫模型HMM学习导航 一.认识贝叶斯网络 1.概念原理介绍 2.举例解析 二.马尔可夫模型 1.概念原理介绍 2.举例解析 三.隐马尔可夫模型 1.概念原理介绍 2.举例解析 四.隐马尔 ...

  3. HMM隐马尔可夫模型来龙去脉(二)

    目录 前言 预备知识 一.估计问题 1.问题推导 2.前向算法/后向算法 二.序列问题 1.问题推导 2.维特比算法 三.参数估计问题 1.问题推导 2.期望最大化算法(前向后向算法) 总结 前言 H ...

  4. HMM隐马尔科夫模型

    这是一个非常重要的模型,凡是学统计学.机器学习.数据挖掘的人都应该彻底搞懂. python包: hmmlearn 0.2.0 https://github.com/hmmlearn/hmmlearn ...

  5. 机器学习-HMM隐马尔可夫模型-笔记

    HMM定义 1)隐马尔科夫模型 (HMM, Hidden Markov Model) 可用标注问题,在语音识别. NLP .生物信息.模式识别等领域被实践证明是有效的算法. 2)HMM 是关于时序的概 ...

  6. 自然语言处理(1)-HMM隐马尔科夫模型基础概念(一)

    隐马尔科夫模型HMM 序言 文本序列标注是自然语言处理中非常重要的一环,我先接触到的是CRF(条件随机场模型)用于解决相关问题,因此希望能够对CRF有一个全面的理解,但是由于在学习过程中发现一个算法像 ...

  7. HMM 隐马尔科夫模型

    参考如下博客: http://www.52nlp.cn/itenyh%E7%89%88-%E7%94%A8hmm%E5%81%9A%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8 ...

  8. 隐马尔科夫模型(HMM)的概念

    定义隐马尔科夫模型可以用一个三元组(π,A,B)来定义:π 表示初始状态概率的向量A =(aij)(隐藏状态的)转移矩阵 P(Xit|Xj(t-1)) t-1时刻是j而t时刻是i的概率B =(bij) ...

  9. HMM:隐马尔可夫模型HMM

    http://blog.csdn.net/pipisorry/article/details/50722178 隐马尔可夫模型 隐马尔可夫模型(Hidden Markov Model,HMM)是统计模 ...

  10. 详解隐马尔可夫模型(HMM)中的维特比算法

    笔记转载于GitHub项目:https://github.com/NLP-LOVE/Introduction-NLP 4. 隐马尔可夫模型与序列标注 第3章的n元语法模型从词语接续的流畅度出发,为全切 ...

随机推荐

  1. Date 时间 日期 常用方法函数

    转载自https://www.cnblogs.com/lcngu/p/5154834.html 一.java.util.Date对象用来表示时间,基本方法如下: Date mDate = new Da ...

  2. mybatis知识点(已掌握)

    1.${} 和 #{} 的区别? ${} 直接显示传入数据,不能防止sql注入,一般用于传数据库对象(比如表名). #{} 传入数据被当成字符串,自动加上双引号,防止sql注入. 2.有哪些Execu ...

  3. XFF的学习+修改源码--Are you in class

    这几天有做天枢CTF的“Are you in class”的题目,虽然以前了解过XFF,但还是没有很好地应用,而且最后居然掉进了一个大坑,且听我细细讲来.   打开题目,首先有个提示“在不在学校主要看 ...

  4. Jmeter录制APP脚本

    启动 jmeter.bat 在 Test Plan 下 添加 Thread Group 在 WorkBench 下 添加 HTTP(S) Test Script Recorder: 配置 Global ...

  5. vue使用日期时间插件layDate

    项目中需要用到日期时间插件,尝试用bootstrap.element的时间插件都各有各的报错,对于一个菜鸟来说真的是很痛苦啊.终于,最后用了layDate实现了需要的功能 最终效果: 使用步骤: 1. ...

  6. 【Linux 进程】exec族函数详解

    exec族的组成: 在Linux中,并不存在一个exec()的函数形式,exec指的是一组函数,一共有6个,分别是: #include <unistd.h> extern char **e ...

  7. 如何开发简单的javaweb项目,jsp+javabean+servlet

    一.相关的软件下载和环境配置 1.下载并配置JDK. 2.下载eclipse. 3.下载并配置apache-tomcat(服务器). 4.下载MySQL(数据库). 5.下载Navicat for M ...

  8. JS编程题练习

    JS编程题练习 1. 两个数组合并成一个数组排序返回 先依次比较两个数组,按照小的就传入新的数组.当这次比较完之后可能有一个数组的长度很长,留下一些数组,然后在新数组的末尾插入即可. function ...

  9. AngularJS——第2章 模块化

    第2章 模块化 使用AngularJS构建应用时是以模块化的方式组织的,即将整个应用划分成多个小模块,各个模块有各自的职责,最终实现完整的应用. 2.1 定义应用 通过为任一HTML标签添加ng-ap ...

  10. clickableSpan实现textView文字部分点击有响应

    先定义一个clickableSpan的子类 class MyClickText extends ClickableSpan{ private Context context; public MyCli ...