隐马尔可夫模型(HMM)学习笔记一
学习了李航的《统计学习方法》中隐马尔可夫模型(Hidden Markov Model, HMM),这里把自己对HMM的理解进行总结(大部分是书本原文,O(∩_∩)O哈哈~,主要是想利用python将其实现一遍,这样印象深刻一点儿),并利用python将书本上的例子运行一遍。HMM是可用于标注问题的统计学习模型,描述由隐藏的马尔科夫链随机生成观测序列的过程,属于生成模型。HMM在语音识别、自然语言处理、生物信息、模式识别等领域都有着广泛的应用。
一、隐马尔可夫模型的定义
HMM由初始概率分布、状态转移概率分布A以及观测概率分布B三部分确定。HMM模型可以用三元符号表示,即:。A、B、称为HMM的三要素。
设Q是所有可能的状态的集合,V是所有可能的观测的集合。其中,N是可能的状态数,M是可能的观测数。这里观测状态v是可见的,状态q是不可见的。记I是长度为T的状态序列,O是对应的观测序列,。
1、则可定义状态转移概率矩阵B如下:
其中是在时刻t处于状态 qi 的条件下在时刻t+1转移到状态 qj 的概率。
2、观测概率矩阵B定义如下:
其中是在时刻t处于状态 qj 的条件下生成观测 vk 的概率。
3、初始状态概率向量如下:
其中是时刻t=1处于状态qj的概率。
二、HMM的两个假设
1、齐次马尔科夫性假设。即隐藏的马尔科夫链在任意时刻 t 的状态只与前一时刻的状态有关,与时刻 t 也无关。
。
2、观测独立性假设。即任意时刻的观测只和该时刻的马尔科夫链的状态有关,与其他观测即状态无关。
。
例题:例子采用书本上的盒子和球模型。
分析:这里一共四个盒子,则表示所有可能的状态有四种Q={盒子1,盒子2,盒子3,盒子4},N=4。球的颜色只有红白两种,即所有可能的观测为V={红,白},M=2。
用python中的列表分别表示可能的状态集合Q和观测集合V,用字典存储初始概率分布、状态转移概率分布和观测概率分布。
# 所有可能的状态集合
states = ['盒子1', '盒子2', '盒子3', '盒子4']
# 所有可能的观测集合
observations = ['红球', '白球'] # 初始状态概率分布pi
Pi = {'盒子1':0.25, '盒子2':0.25, '盒子3':0.25, '盒子4':0.25}
# 状态转移概率A
A = {'盒子1':{'盒子1':0, '盒子2':1, '盒子3':0, '盒子4':0},
'盒子2':{'盒子1':0.4, '盒子2':0, '盒子3':0.6, '盒子4':0},
'盒子3':{'盒子1':0, '盒子2':0.4, '盒子3':0, '盒子4':0.6},
'盒子4':{'盒子1':0, '盒子2':0, '盒子3':0.5, '盒子4':0.5}
}
# 观测概率分布B
B = {'盒子1':{'红球':0.5, '白球':0.5},
'盒子2':{'红球':0.3, '白球':0.7},
'盒子3':{'红球':0.6, '白球':0.4},
'盒子4':{'红球':0.8, '白球':0.2}
}
为了后面方便处理,这里引入python的numpy库将Pi、A和B转换为矩阵和向量形式。
import numpy as np
# 将初始状态概率转换成向量形式
Pi = np.array([Pi[x] for x in Pi])
print('初始状态pi:', Pi) # 将初始概率分布转换为矩阵形式
trans_A = np.array([A[x][y] for x in A for y in A[x]]) A = trans_A.reshape((len(A), -1))
print('状态转移概率分步A:', A) # 将观测概率分布转换成矩阵形式
trans_B = np.array([B[x][y] for x in B for y in B[x]])
B = trans_B.reshape((len(B), -1))
print('观测概率分布B:', B)
观测序列的生成过程
根据隐马尔可夫模型定义,可以将一个长度为T的观测序列的生成过程描述如下:
算法(观测序列的生成)
输入:隐马尔可夫模型,观测序列长度
输出:观测序列。
(1)按照初始状态分布产生状态
(2)令t=1
(3)按照状态的观测概率分布生成
(4)按照状态的状态转移概率分布产生状态
令;如果则转步(3);否则,终止。
分析:对于按照某个概率分布生成状态,这里采用python中的np.random.multinomial函数按照多项式分布,生成数据,然后再利用np.where得到满足条件的元素对应的下标。定义观测序列生成函数generation_observation。
# 定义生成观测序列的函数
def generation_observation(pi, A, B, T):
def random_res(probs):
"""
1.np.random.multinomial:
按照多项式分布,生成数据
>>> np.random.multinomial(20, [1/6.]*6, size=2)
array([[3, 4, 3, 3, 4, 3],
[2, 4, 3, 4, 0, 7]])
For the first run, we threw 3 times 1, 4 times 2, etc.
For the second, we threw 2 times 1, 4 times 2, etc.
2.np.where:
>>> x = np.arange(9.).reshape(3, 3)
>>> np.where( x > 5 )
(array([2, 2, 2]), array([0, 1, 2]))
"""
return np.where(np.random.multinomial(1,probs) == 1)[0][0] observation_data = np.zeros(T, dtype=int) # 初始化生成的观测序列
observation_states = np.zeros(T, dtype=int) # 观测序列对应的状态
observation_states[0] = random_res(pi) # 根据初始状态分布产生状态1
observation_data[0] = random_res(B[observation_states[0]]) # 由状态1生成对应的观测值
for i in range(1, T):
observation_states[i] = random_res(A[observation_states[i-1]]) # 由前一个状态转变到下一个状态
observation_data[i] = random_res(B[observation_states[i]])
return observation_data, observation_states observation_data, observation_states = generation_observation(Pi, A, B, 10)
print(observation_data, observation_states) print('观测序列:', [observations[i] for i in observation_data])
print('状态序列:', [states[i] for i in observation_states])
三、隐马尔可夫模型的3个基本问題
1、概率计算问题。给定模型和观测序列,计算在模型下观测序列O出现的概率。
2、学习问题。己知观测序列,估计模型参数,使得在该模型下观测序列概率最大。即用极大似然估计的方法估计参数。
3、预测问题,也称为解码(decoding)问题。已知模型和观测序列,求对给定观测序列条件概率最大的状态序列。即给定观测序列,求最有可能的对应的状态序列。
问题1 概率计算问题
如果直接采用直接计算法的话,需要列举所有长度为T的状态序列 I,然后求出 I 与观测序列O的联合概率,最后再对所有可能的状态序列求和,得到序列O在HMM模型下生成的概率。这样时间复杂度是O(TNT)阶的,这种算法观测序列长度很长的话计算量太大,所以采用前向、后向算法计算概率。
(1)前向算法
首先定义(前向概率)给定隐马尔可夫模型,定义到时刻t为止的观测序列为且状态为的概率为前向概率,记作
输入:隐马尔可夫模型,观测序列;
输出:观测序列概率。
(1)初值
(2)递推对
(3)终止
由于到了时间T,一共有N种状态发转移到最后那个观测,所以最终的结果要将这些概率加起来。而每次递推都是在前一次的基础上做的,所以只需累加O(T)次,所以总体复杂度是O(N2T)。
分析:前向概率矩阵alpha是N*T维的,可以先用零初始化,之后再按照前向算法一步一步对其值进行替换。定义前向算法方法forward_compute。再利用例题10.2对其进行验证。
def forward_compute(pi, A, B, o_seq):
T = len(o_seq)
N = A.shape[0]
alpha = np.zeros((N, T)) # 初始化alpha矩阵 N*T维
# print(alpha)
# print(B[:, o_seq[0]])
alpha[:, 0] = pi*B[:, o_seq[0]] # step1 初值
for t in range(1, T):
alpha[:, t] = alpha[:, t-1].dot(A) * B[:, o_seq[t]] # step2 递推
# print(alpha)
return np.sum(alpha[:, T-1]), alpha # step3 终止 对时刻T的alpha求和
# 测试 例题10.2
A = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]])
Pi = np.array([0.2, 0.4, 0.4])
B = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]])
o_seq = [0, 1, 0] # 红、白、红 prob, alpha = forward_compute(Pi, A, B, o_seq)
print('观测概率为:', prob)
print('alpha:', alpha)
(2)后向算法
定义后向概率为给定隐马尔可夫模型,定义在时刻t状态为的条件下,从t+1到T的部分观测序列为的概率为后向概率,记作
可以用递推的方法求得后向概率及观测序列概率。
算法(观测序列概率的后向算法)
输入:隐马尔可夫模型,观测序列:
输出:观测序列概率
(1)初值
根据定义,从T+1到T的部分观测序列其实不存在,所以硬性规定这个值是1。
(2)递推。对
aij表示状态i转移到j的概率,bj表示发射Ot+1,表示j后面的序列对应的后向概率。
(3)终止
最后的求和是因为,在第一个时间点上有N种后向概率都能输出从2到T的观测序列,所以乘上输出O1的概率后求和得到最终结果。
分析:前向概率矩阵beta也是N*T维的,可以先用零初始化,之后再按照前向算法一步一步对其值进行替换。定义前向算法方法backward_compute。再利用例题10.2对其进行验证。
def backword_compute(pi, A, B, o_seq):
T = len(o_seq)
beta = np.zeros((A.shape[0], T)) # 初始化beta矩阵 beta[:, T-1] = np.ones(A.shape[0]) # step1 初值
for t in range(T-2, -1, -1):
beta[:, t] = np.sum(A*B[:, o_seq[t+1]]*beta[:, t+1], axis=1) # step2 递推 res_prop = np.sum(pi*B[:, o_seq[0]]*beta[:,0], axis=0) # 求观测序列概率
# print(beta)
return res_prop, beta
# 测试 例题10.2
A = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]])
Pi = np.array([0.2, 0.4, 0.4])
B = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]])
o_seq = [0, 1, 0] # 红、白、红
prob, beta = backword_compute(Pi, A, B, o_seq)
print('观测概率:', prob)
print('beta:', beta)
隐马尔可夫模型(HMM)学习笔记一的更多相关文章
- 隐马尔科夫模型HMM学习最佳范例
谷歌路过这个专门介绍HMM及其相关算法的主页:http://rrurl.cn/vAgKhh 里面图文并茂动感十足,写得通俗易懂,可以说是介绍HMM很好的范例了.一个名为52nlp的博主(google ...
- 用hmmlearn学习隐马尔科夫模型HMM
在之前的HMM系列中,我们对隐马尔科夫模型HMM的原理以及三个问题的求解方法做了总结.本文我们就从实践的角度用Python的hmmlearn库来学习HMM的使用.关于hmmlearn的更多资料在官方文 ...
- 基于隐马尔科夫模型(HMM)的地图匹配(Map-Matching)算法
文章目录 1. 1. 摘要 2. 2. Map-Matching(MM)问题 3. 3. 隐马尔科夫模型(HMM) 3.1. 3.1. HMM简述 3.2. 3.2. 基于HMM的Map-Matchi ...
- 隐马尔科夫模型(HMM)的概念
定义隐马尔科夫模型可以用一个三元组(π,A,B)来定义:π 表示初始状态概率的向量A =(aij)(隐藏状态的)转移矩阵 P(Xit|Xj(t-1)) t-1时刻是j而t时刻是i的概率B =(bij) ...
- 隐马尔科夫模型HMM(一)HMM模型
隐马尔科夫模型HMM(一)HMM模型基础 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比 ...
- HMM:隐马尔可夫模型HMM
http://blog.csdn.net/pipisorry/article/details/50722178 隐马尔可夫模型 隐马尔可夫模型(Hidden Markov Model,HMM)是统计模 ...
- 隐马尔可夫模型HMM与维特比Veterbi算法(二)
隐马尔可夫模型HMM与维特比Veterbi算法(二) 主要内容: 前向算法(Forward Algorithm) 穷举搜索( Exhaustive search for solution) 使用递归降 ...
- 隐马尔可夫模型HMM与维特比Veterbi算法(一)
隐马尔可夫模型HMM与维特比Veterbi算法(一) 主要内容: 1.一个简单的例子 2.生成模式(Generating Patterns) 3.隐藏模式(Hidden Patterns) 4.隐马尔 ...
- 隐马尔可夫模型HMM
隐马尔可夫模型HMM的探究 1 HMM基本概念1.1 定义1.2 观测序列生成过程1.3 HMM的三个问题2 概率计算算法2.1 直接计算算法2.2 前向算法forward algorithm2.3 ...
- 隐马尔科夫模型HMM
崔晓源 翻译 我们通常都习惯寻找一个事物在一段时间里的变化规律.在很多领域我们都希望找到这个规律,比如计算机中的指令顺序,句子中的词顺序和语音中的词顺序等等.一个最适用的例子就是天气的预测. 首先,本 ...
随机推荐
- soanr - 企业用户角色管理
首先sonar支持群组 即 支持企业角色权限管理,其次sonar支持单项目用户权限管理 即 外包,客户,外编人员用户权限管理. (视图内可看到源码) 按照 管路员.产品/项目管理.产品/项目开发.外包 ...
- Excel转Json
参考: Excel2JSON Excel转JSON Excel另存为JSON的技巧 (office的插件) excel2json 游戏程序员的自我修养 (其他人写的工具) Excel转JSON格式- ...
- Unity3D笔记 英保通十 射线碰撞器检测
射线碰撞检测可以用来检测方向和距离: 通过Physics.RayCast光线投射来实现:常用于射击利用发射的射线来判断.还有对战中刀剑交战中.. 一.要涉及到RayCast和RayCastHit 1. ...
- iOS - 使用苹果自带的UIVideoEditController进行视频编辑
UIVideoEditorController类包含了由系统提供的界面,使用户可以交互式的剪切视频.UIVideoEditorController对象处理用户的交互并且提供把编辑后的视频的文件系统路径 ...
- zabbix监控tcp状态
Tcp的连接状态对于我们web服务器来说是至关重要的,从TCP的连接状态中可以看出网络的连接情况,服务器的压力情况,对服务器的并发有很好的直观反映:尤其是并发量ESTAB:或者是syn_recv值,假 ...
- 二步实现 远程连接 阿里云SqlServer 2012 数据库服务器
前言:在使用 阿里云 上的一些产品时,遇到不少坑. 安装IIS 时,遇到 因买的配置过低,虚拟内存不足,而导致 IIS 总是安装失败: 现在 在上面安装了个 Sql Sever 2012,远程老是 不 ...
- 基于Docker部署nodejs应用
基于Docker部署nodejs应用 背景 公司基于Vue.js的项目最近需要部署到云端,因此需要先行在公司内部Docker环境下验证相关技术,因而有本文之前提. 本文展示在Docker容器中,应用部 ...
- 使用TensorFlow Serving优化TensorFlow模型
使用TensorFlow Serving优化TensorFlow模型 https://www.tensorflowers.cn/t/7464 https://mp.weixin.qq.com/s/qO ...
- PHP使用 zip 扩展压缩文件
在公司遇到一个问题,是使用zip打包用户的上传文件,提供集体下载. -- 第一个想法就是使用exec在Linux进行打包.但是...exec方法吧,你懂得,我不太愿意使用这个函数. -- 于是上网查找 ...
- 非常可乐---hdu 1495(BFS)
http://acm.hdu.edu.cn/showproblem.php?pid=1495 题意: 有3个杯子a b c:a=b+c:然后刚开始时只有a是满的,其它为空的,然后a b c三个之间互相 ...