Python实现隐马尔可夫模型的前向后向算法的示例代码


Posted in Python onDecember 31, 2019

本篇文章对隐马尔可夫模型的前向和后向算法进行了Python实现,并且每种算法都给出了循环和递归两种方式的实现。

前向算法Python实现

循环方式

import numpy as np
def hmm_forward(Q, V, A, B, pi, T, O, p):
  """
  :param Q: 状态集合
  :param V: 观测集合
  :param A: 状态转移概率矩阵
  :param B: 观测概率矩阵
  :param pi: 初始概率分布
  :param T: 观测序列和状态序列的长度
  :param O: 观测序列
  :param p: 存储各个状态的前向概率的列表,初始为空
  """
  for t in range(T):
    # 计算初值
    if t == 0:
      for i in range(len(Q)):
        p.append(pi[i] * B[i, V[O[0]]])
    # 初值计算完毕后,进行下一时刻的递推运算
    else:
      alpha_t_ = 0
      alpha_t_t = []
      for i in range(len(Q)):
        for j in range(len(Q)):
          alpha_t_ += p[j] * A[j, i]
        alpha_t_t.append(alpha_t_ * B[i, V[O[t]]])
        alpha_t_ = 0
      p = alpha_t_t
  return sum(p)
# 《统计学习方法》书上例10.2
Q = [1, 2, 3]
V = {'红':0, '白':1}
A = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]])
B = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]])
pi = [0.2, 0.4, 0.4]
T = 3
O = ['红', '白', '红']
p = []
print(hmm_forward(Q, V, A, B, pi, T, O, p)) # 0.130218

递归方式

import numpy as np
def hmm_forward_(Q, V, A, B, pi, T, O, p, T_final):
  """
  :param T_final:递归的终止条件
  """
  if T == 0:
    for i in range(len(Q)):
      p.append(pi[i] * B[i, V[O[0]]])
  else:
    alpha_t_ = 0
    alpha_t_t = []
    for i in range(len(Q)):
      for j in range(len(Q)):
        alpha_t_ += p[j] * A[j, i]
      alpha_t_t.append(alpha_t_ * B[i, V[O[T]]])
      alpha_t_ = 0
    p = alpha_t_t
  if T >= T_final:
    return sum(p)
  return hmm_forward_(Q, V, A, B, pi, T+1, O, p, T_final)

Q = [1, 2, 3]
V = {'红':0, '白':1}
A = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]])
B = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]])
pi = [0.2, 0.4, 0.4]
T = 0
O = ['红', '白', '红']
p = []
T_final = 2 # T的长度是3,T的取值是(0时刻, 1时刻, 2时刻)
print(hmm_forward_(Q, V, A, B, pi, T, O, p, T_final))

后向算法Python实现

循环方式

import numpy as np
def hmm_backward(Q, V, A, B, pi, T, O, beta_t, T_final):
  for t in range(T, -1, -1):
    if t == T_final:
      beta_t = beta_t
    else:
      beta_t_ = 0
      beta_t_t = []
      for i in range(len(Q)):
        for j in range(len(Q)):
          beta_t_ += A[i, j] * B[j, V[O[t + 1]]] * beta_t[j]
        beta_t_t.append(beta_t_)
        beta_t_ = 0
      beta_t = beta_t_t
    if t == 0:
      p=[]
      for i in range(len(Q)):
        p.append(pi[i] * B[i, V[O[0]]] * beta_t[i])
      beta_t = p
  return sum(beta_t)
# 《统计学习方法》课后题10.1
Q = [1, 2, 3]
V = {'红':0, '白':1}
A = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]])
B = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]])
pi = [0.2, 0.4, 0.4]
T = 3
O = ['红', '白', '红', '白']
beta_t = [1, 1, 1]
T_final = 3
print(hmm_backward_(Q, V, A, B, pi, T, O, beta_t, T_final)) # 0.06009

递归方式

import numpy as np
def hmm_backward(Q, V, A, B, pi, T, O, beta_t, T_final):
  if T == T_final:
    beta_t = beta_t
  else:
    beta_t_ = 0
    beta_t_t = []
    for i in range(len(Q)):
      for j in range(len(Q)):
        beta_t_ += A[i, j] * B[j, V[O[T+1]]] * beta_t[j]
      beta_t_t.append(beta_t_)
      beta_t_ = 0
    beta_t = beta_t_t
  if T == 0:
    p=[]
    for i in range(len(Q)):
      p.append(pi[i] * B[i, V[O[0]]] * beta_t[i])
    beta_t = p
    return sum(beta_t)
  return hmm_backward(Q, V, A, B, pi, T-1, O, beta_t, T_final)
jpgQ = [1, 2, 3]
V = {'红':0, '白':1}
A = np.array([[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]])
B = np.array([[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]])
pi = [0.2, 0.4, 0.4]
T = 3
O = ['红', '白', '红', '白']
beta_t = [1, 1, 1]
T_final = 3
print(hmm_backward_(Q, V, A, B, pi, T, O, beta_t, T_final)) # 0.06009

这里我有个问题不理解,这道题的正确答案应该是0.061328,我计算出的答案和实际有一点偏差,我跟踪了代码的计算过程,发现在第一次循环完成后,计算结果是正确的,第二次循环后的结果就出现了偏差,我怀疑是小数部分的精度造成,希望有人能给出一个更好的解答,如果是代码的问题也欢迎指正。

以上所述是小编给大家介绍的Python实现隐马尔可夫模型的前向后向算法,希望对大家有所帮助!

Python 相关文章推荐
在Python上基于Markov链生成伪随机文本的教程
Apr 17 Python
Python Socket使用实例
Dec 18 Python
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
Feb 10 Python
python对绑定事件的鼠标、按键的判断实例
Jul 17 Python
Python3 批量扫描端口的例子
Jul 25 Python
解决Python设置函数调用超时,进程卡住的问题
Aug 08 Python
python中for循环变量作用域及用法详解
Nov 05 Python
Python分析微信好友性别比例和省份城市分布比例的方法示例【基于itchat模块】
May 29 Python
Pyinstaller 打包发布经验总结
Jun 02 Python
浅谈python opencv对图像颜色通道进行加减操作溢出
Jun 03 Python
在pycharm创建scrapy项目的实现步骤
Dec 01 Python
tensorflow2.0教程之Keras快速入门
Feb 20 Python
Python面向对象之私有属性和私有方法应用案例分析
Dec 31 #Python
Pycharm最新激活码2019(推荐)
Dec 31 #Python
python ftplib模块使用代码实例
Dec 31 #Python
深入了解如何基于Python读写Kafka
Dec 31 #Python
Python面向对象之继承原理与用法案例分析
Dec 31 #Python
pytorch中nn.Conv1d的用法详解
Dec 31 #Python
Python实现剪刀石头布小游戏(与电脑对战)
Dec 31 #Python
You might like
ThinkPHP关于session的操作方法汇总
2014/07/18 PHP
ThinkPHP中html:list标签用法分析
2016/01/09 PHP
QQ邮箱的一个文本编辑器代码
2007/03/14 Javascript
汉化英文版的Dreamweaver CS5并自动提示jquery
2010/11/25 Javascript
javascript学习笔记(七)利用javascript来创建和存储cookie
2011/04/08 Javascript
jQuery $.get 的妙用 访问本地文本文件
2012/07/12 Javascript
javascript中如何处理引号编码"
2013/08/15 Javascript
jquery实现两边飘浮可关闭的对联广告
2015/11/27 Javascript
原生js封装二级城市下拉列表的实现代码
2016/06/16 Javascript
jQuery UI结合Ajax创建可定制的Web界面
2016/06/22 Javascript
jQuery如何防止Ajax重复提交
2016/10/14 Javascript
基于JavaScript实现复选框的全选和取消全选
2017/02/09 Javascript
javascript实现圣旨卷轴展开效果(代码分享)
2017/03/23 Javascript
自制简易打赏功能的实例
2017/09/02 Javascript
对angularJs中$sce服务安全显示html文本的实例
2018/09/30 Javascript
微信小程序实现自动定位功能
2018/10/31 Javascript
Vue源码分析之Vue实例初始化详解
2019/08/25 Javascript
JS面向对象编程实现的Tab选项卡案例详解
2020/03/03 Javascript
js操作两个json数组合并、去重,以及删除某一项元素
2020/09/22 Javascript
Python3的urllib.parse常用函数小结(urlencode,quote,quote_plus,unquote,unquote_plus等)
2016/09/18 Python
Python tkinter模块弹出窗口及传值回到主窗口操作详解
2017/07/28 Python
Python实现按特定格式对文件进行读写的方法示例
2017/11/30 Python
Django框架模板文件使用及模板文件加载顺序分析
2019/05/23 Python
利用python开发app实战的方法
2019/07/09 Python
美国最大的袜子制造商和零售商:Renfro Socks
2017/09/03 全球购物
Radley英国官网:英国莱德利小狗包
2019/03/21 全球购物
比较一下entity bean和session bean
2013/12/27 面试题
啤酒销售实习自我鉴定
2013/09/24 职场文书
自我评价优秀范文分享
2013/11/30 职场文书
法学研究生自我鉴定范文
2013/12/04 职场文书
幼教毕业生自我鉴定
2014/01/12 职场文书
2014年团队工作总结
2014/11/24 职场文书
办公室主任个人总结
2015/02/28 职场文书
老员工辞职信范文
2015/05/12 职场文书
校运会广播稿
2015/08/19 职场文书
转变工作作风心得体会
2016/01/23 职场文书