HMM(隐马尔可夫模型)不断学习中
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基本要素:
- 初始概率向量π
- 状态转移矩阵
- 观测矩阵
- 观测序列
现在利用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的概率。
在这个问题中,- 在t1时刻,a1(1) = πsunny Bsunny(shop) , a1(2) = πrainy Brainy(shop) , a1(3) = πcloudy* Bcloudy(shop)
- 在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)
- ……以此类推,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 :
- Enter a number of valid observed states in the input field.
- Press 'Set' to initialise the matrix.
- 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.
- 'Run' will calculate the
HMM(隐马尔可夫模型)不断学习中的更多相关文章
- HMM隐马尔可夫模型(词语粘合)
HMM用于自然语言处理(NLP)中文分词,是用来描述一个含有隐含未知参数的马尔可夫过程,其目的是希望通过求解这些隐含的参数来进行实体识别,说简单些也就是起到词语粘合的作用. HMM隐马尔可夫模型包括: ...
- HMM隐马尔可夫模型来龙去脉(一)
目录 隐马尔可夫模型HMM学习导航 一.认识贝叶斯网络 1.概念原理介绍 2.举例解析 二.马尔可夫模型 1.概念原理介绍 2.举例解析 三.隐马尔可夫模型 1.概念原理介绍 2.举例解析 四.隐马尔 ...
- HMM隐马尔可夫模型来龙去脉(二)
目录 前言 预备知识 一.估计问题 1.问题推导 2.前向算法/后向算法 二.序列问题 1.问题推导 2.维特比算法 三.参数估计问题 1.问题推导 2.期望最大化算法(前向后向算法) 总结 前言 H ...
- HMM隐马尔科夫模型
这是一个非常重要的模型,凡是学统计学.机器学习.数据挖掘的人都应该彻底搞懂. python包: hmmlearn 0.2.0 https://github.com/hmmlearn/hmmlearn ...
- 机器学习-HMM隐马尔可夫模型-笔记
HMM定义 1)隐马尔科夫模型 (HMM, Hidden Markov Model) 可用标注问题,在语音识别. NLP .生物信息.模式识别等领域被实践证明是有效的算法. 2)HMM 是关于时序的概 ...
- 自然语言处理(1)-HMM隐马尔科夫模型基础概念(一)
隐马尔科夫模型HMM 序言 文本序列标注是自然语言处理中非常重要的一环,我先接触到的是CRF(条件随机场模型)用于解决相关问题,因此希望能够对CRF有一个全面的理解,但是由于在学习过程中发现一个算法像 ...
- 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 ...
- 隐马尔科夫模型(HMM)的概念
定义隐马尔科夫模型可以用一个三元组(π,A,B)来定义:π 表示初始状态概率的向量A =(aij)(隐藏状态的)转移矩阵 P(Xit|Xj(t-1)) t-1时刻是j而t时刻是i的概率B =(bij) ...
- HMM:隐马尔可夫模型HMM
http://blog.csdn.net/pipisorry/article/details/50722178 隐马尔可夫模型 隐马尔可夫模型(Hidden Markov Model,HMM)是统计模 ...
- 详解隐马尔可夫模型(HMM)中的维特比算法
笔记转载于GitHub项目:https://github.com/NLP-LOVE/Introduction-NLP 4. 隐马尔可夫模型与序列标注 第3章的n元语法模型从词语接续的流畅度出发,为全切 ...
随机推荐
- typedef void(*Func)(void)的简单用途
typedef void(*Func)(void)的用途 用法的好处: 定义一个函数指针类型. 例子: 有三个类型相似或功能相似的函数: void TASK1(void) { printf(" ...
- NYOJ-1058 DFS部分求和
原题链接 本题思路:暴力深搜,具体见代码. #include <iostream> #include <stack> using namespace std; + ; int ...
- 多线程通信(wait和notify)
线程通信概念: 线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体,线程间的通信就成为整体的必用方式之一.当线程存在通信指挥,系统间的交互性会更强大,在提高CPU利用率的同时 ...
- echarts中国地图散点涟漪效果
echarts中国地图例子:http://gallery.echartsjs.com/editor.html?c=effectScatter-map 代码: var data = [{ name: ' ...
- vm参数配置的理解
-denv=dev表示将服务器的级别 设置为开发环境 所有错误的内容都会打印在控制台上 //The-Denv = dev statement creates a system property nam ...
- 10.19JS日记
1.函数 关键词(function) var是js的关键字,用于声明变量,声明在内存模块完成,定义(=)是在执行模块完成 var可以在内存模块提前完成(js代码执行前),所以有变量提升这个功能 c ...
- linux通过speedtest-cli测试服务器网速
1.git clone speedtest源码 git clone https://github.com/sivel/speedtest-cli.git 2.运行speedtest.py cd spe ...
- Introduction to 3D Game Programming with DirectX 11 翻译--开篇
Direct3D 11简介 Direct3D 11是一个渲染库,用于在Windows平台上使用现代图形硬件编写高性能3D图形应用程序.Direct3D是一个windows底层库,因为它的应用程序编程接 ...
- Codeforces 545E. Paths and Trees 最短路
E. Paths and Trees time limit per test: 3 seconds memory limit per test: 256 megabytes input: standa ...
- a[i++]
今天才知道,a[i++]到底是什么意思:: 其实也很简单了,就是a[i]的值还是a[i],然后i自增1: 把这篇博客当作平常各种错题博客吧,把各种从网上抄的代码不懂的地方写到这个地方算了 ====== ...