python+HMM之维特比解码
来源:互联网 发布:手风琴特效js 编辑:程序博客网 时间:2024/04/29 15:30
HMM 回顾
《统计学习方法》 p.174
隐马尔科夫模型(HMM)有三个基本的问题
- (1)概率计算问题。给定模型
λ=(A,B,Pi) 和观测序列O(o1,o2,...,oT) ,计算在模型λ 下观测序列O 的概率P(O|λ) - (2)学习问题。已知观测序列
O(o1,o2,...,oT) ,估计模型λ=(A,B,Pi) 的参数,使得在该模型下观测序列概率P(O|λ) 最大。即用极大似然估计的方法估计参数。 - (3)预测问题,也称为解码问题。已知模型
λ=(A,B,Pi) 和观测序列O(o1,o2,...,oT) ,求对给定观测序列条件概率P(I|O) 最大的状态序列I=(i1,i2,...,iT) ,即给定观测序列,求最有可能的对应的状态序列。
维特比译码
《统计学习方法》 p.186
问题类型:
(3)预测问题。已知模型 lambda = (A, B, Pi) 和观测序列,求最优的状态序列.
问题描述:
一共有三个盒子 <=> 状态集合 Q = {1,2,3}
盒子里边装着 红色 和 白色 两种颜色的球 <=> 观测集合 V = {红,白}
从盒子中有放回的取 3 次球,颜色分别为 O=(红,白,红),问取球的盒子顺序最可能是什么?
注意:代码中所有下标从 0 开始,而课本中问题描述是从 1 开始。
import numpy as np# 模型参数A = np.asarray([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]]) # 转移矩阵B = np.asarray([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]])Pi = np.asarray([0.2, 0.4, 0.4]).transpose()O = np.asarray([0,1,0]) T = O.shape[0]N = A.shape[0] # 状态数p_nodes = Pi * B[:, O[0]] # 记录每个节点的路径概率path_nodes = list() # 记录每个节点的路径# 计初始化路径for node in xrange(N): path_nodes.append([node])# T 个时刻for step in xrange(1, T): for this_node in xrange(N): # 计算每个节点的新概率 p_news = list() for last_node in xrange(N): p_trans = A[last_node, this_node] # 转移概率 p_out = B[this_node, O[step]] # 输出概率 p_new = p_nodes[last_node] * p_trans * p_out p_news.append(p_new) p_nodes[this_node] = np.max(p_news) # 更新节点路径概率 last_index = np.argmax(p_news) # 更新节点路径 temp = path_nodes[last_index][:] temp.append(this_node) path_nodes[this_node] = tempprint p_nodes # 最有一步每个节点的概率print path_nodes max_index = np.argmax(p_nodes)max_path = path_nodes[max_index]print max_path # 最优路径
[ 0.00756 0.01008 0.0147 ][[2, 2, 0], [2, 2, 1], [2, 2, 2]][2, 2, 2]
实际项目中,一般都是通过对概率取对数,将乘法转为加法进行求解的。但是,要注意转移概率为 0 的特殊情况,下面不考虑这种情况。
############################### 维特比译码# 《统计学习方法》 p.186############################## 模型参数A = np.asarray([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]]) # 转移矩阵B = np.asarray([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]])Pi = np.asarray([0.2, 0.4, 0.4]).transpose()A = np.log(A)B = np.log(B)Pi = np.log(Pi)O = np.asarray([0,1,0]) # 观测序列def Viterbi_decode(A, B, Pi, O): """维特比解码,所有概率为对数概率。 输入: A: N×N 的转移矩阵 B: N×M 的输出矩阵 Pi: list, 初始状态概率分布 O: list, 观测序列 返回: max_path: list, 最优路径。 """ T = O.shape[0] N = A.shape[0] # 状态数 p_nodes = Pi + B[:, O[0]] # 记录每个节点的路径概率 path_nodes = list() # 记录每个节点的路径 # 计初始化路径 for node in xrange(N): path_nodes.append([node]) # T 个时刻 for step in xrange(1, T): for this_node in xrange(N): # 计算每个节点的新概率 p_news = list() for last_node in xrange(N): p_trans = A[last_node, this_node] # 转移概率 p_out = B[this_node, O[step]] # 输出概率 p_new = p_nodes[last_node] + p_trans + p_out p_news.append(p_new) p_nodes[this_node] = np.max(p_news) # 更新节点路径概率 last_index = np.argmax(p_news) # 更新节点路径 temp = path_nodes[last_index][:] temp.append(this_node) path_nodes[this_node] = temp max_index = np.argmax(p_nodes) max_path = path_nodes[max_index] return max_pathmax_path = Viterbi_decode(A, B, Pi, O)print max_path
[2, 2, 2]
在 TensorFlow入门(六) 双端 LSTM 实现序列标注(分词)最后部分使用了维特比解码。和这里有些区别:
- 初始路径概率
pnodes=Pi+B[:,O[0]] , 改成使用 Bi-LSTM 模型输出的分类概率 - 输出概率
pout=B[thisnode,O[step]] , 改成使用 Bi-LSTM 模型输出的分类概率
阅读全文
0 0
- python+HMM之维特比解码
- HMM之维特比算法
- HMM之维特比算法
- HMM算法之维特比算法
- HMM之维特比算法
- HMM之维特比算法
- HMM学习2之维特比算法(转)
- HMM条件下的 前向算法 和 维特比解码
- HMM:隐马尔科夫模型-维特比算法
- HMM学习,维特比算法
- 动态规划之隐含马尔可夫模型(HMM)和维特比算法(Viterbi Algorithm)
- HMM学习最佳范例六:维特比算法1
- HMM学习最佳范例六:维特比算法2
- HMM学习最佳范例六:维特比算法3
- HMM学习最佳范例六:维特比算法4
- HMM学习最佳范例六:维特比算法5
- HMM 自学教程(六)维特比算法
- HMM学习最佳范例六:维特比算法1
- Photoshop简单几步搞定人物磨皮-非插件版
- 虚继承与虚基类的本质(介绍的非常详细)
- Android不编译某个模块
- linux下安装php的imagick扩展模块(附php升级脚本)
- 设计模式之结构型-桥接模式(10)
- python+HMM之维特比解码
- Android图片缓存之Glide进阶
- 微信小程序开发实践
- 第十章 图像分割(1至3节)
- 与mycat 官方培训DB 不得不说的缘分
- 小甜点,RecyclerView 之 ItemDecoration 讲解及高级特性实践
- 安卓源码阅读--源码编译
- struts2学习--返回json格式字符串
- 异数OS 2017 DPDK 峰会观后感