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抓取京东图书评论数据
Aug 31 Python
彻底搞懂Python字符编码
Jan 23 Python
Python使用Django实现博客系统完整版
Sep 29 Python
使用pandas对矢量化数据进行替换处理的方法
Apr 11 Python
padas 生成excel 增加sheet表的实例
Dec 11 Python
用python一行代码得到数组中某个元素的个数方法
Jan 28 Python
pyqt5 使用label控件实时显示时间的实例
Jun 14 Python
Python一行代码解决矩阵旋转的问题
Nov 30 Python
浅谈python 调用open()打开文件时路径出错的原因
Jun 05 Python
python中对二维列表中一维列表的调用方法
Jun 07 Python
Python中如何添加自定义模块
Jun 09 Python
Python获取指定日期是"星期几"的6种方法
Mar 13 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
PHP4实际应用经验篇(2)
2006/10/09 PHP
PHP中SESSION使用中的一点经验总结
2012/03/30 PHP
ThinkPHP模板Switch标签用法示例
2014/06/30 PHP
PHP缓冲区用法总结
2016/02/14 PHP
PHP 计算两个特别大的整数实例代码
2018/05/07 PHP
PHP常用函数之根据生日计算年龄功能示例
2019/10/21 PHP
js 代码集(学习js的朋友可以看下)
2009/07/22 Javascript
Ajax+Json 级联菜单实现代码
2009/10/27 Javascript
JavaScript实现页面实时显示当前时间的简单实例
2013/07/20 Javascript
javascript实现Table间隔色以及选择高亮(和动态切换数据)的方法
2015/05/14 Javascript
简单的jQuery入门指引
2015/07/28 Javascript
JavaScript实现给定时间相加天数的方法
2016/01/25 Javascript
详解微信小程序开发之下拉刷新 上拉加载
2016/11/24 Javascript
Bootstrap源码解读表单(2)
2016/12/22 Javascript
使用Xcache缓存器加速PHP网站的配置方法
2017/04/22 Javascript
javascript自定义事件功能与用法实例分析
2017/11/08 Javascript
解决Vue.js父组件$on无法监听子组件$emit触发事件的问题
2018/09/12 Javascript
对angularjs框架下controller间的传值方法详解
2018/10/08 Javascript
redux.js详解及基本使用
2019/05/24 Javascript
JS实现图片懒加载(lazyload)过程详解
2020/04/02 Javascript
Python实现把json格式转换成文本或sql文件
2015/07/10 Python
利用python解决mysql视图导入导出依赖的问题
2017/12/17 Python
Python实现合并两个有序链表的方法示例
2019/01/31 Python
python中metaclass原理与用法详解
2019/06/25 Python
python 画图 图例自由定义方式
2020/04/17 Python
Under Armour安德玛法国官网:美国高端运动科技品牌
2018/06/29 全球购物
简述DNS进行域名解析的过程
2013/12/02 面试题
大学生预备党员自我评价分享
2013/11/16 职场文书
六查六看自查材料
2014/02/17 职场文书
进步之星获奖感言
2014/02/22 职场文书
任命书格式
2014/06/05 职场文书
2014党员学习《反腐倡廉警示教育读本》思想汇报
2014/09/13 职场文书
自我查摆剖析材料
2014/10/11 职场文书
高三英语复习计划
2015/01/19 职场文书
机动车交通事故协议书
2015/01/29 职场文书
详解Vue项目的打包方式(生成dist文件)
2022/01/18 Vue.js