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 相关文章推荐
35个Python编程小技巧
Apr 01 Python
python去除所有html标签的方法
May 05 Python
python实现二分查找算法
Sep 21 Python
Python基于分水岭算法解决走迷宫游戏示例
Sep 26 Python
10 行 Python 代码教你自动发送短信(不想回复工作邮件妙招)
Oct 11 Python
详解Python中的测试工具
Jun 09 Python
安装好Pycharm后如何配置Python解释器简易教程
Jun 28 Python
python 内置函数汇总详解
Sep 16 Python
在django-xadmin中APScheduler的启动初始化实例
Nov 15 Python
Python 剪绳子的多种思路实现(动态规划和贪心)
Feb 24 Python
python计算Content-MD5并获取文件的Content-MD5值方式
Apr 03 Python
python基础之爬虫入门
May 10 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
php排序算法(冒泡排序,快速排序)
2012/10/09 PHP
php添加数据到xml文件的简单例子
2016/09/08 PHP
PHP实现移除数组中为空或为某值元素的方法
2017/01/07 PHP
select 控制网页内容隐藏于显示的实现代码
2010/05/25 Javascript
jquery插件 autoComboBox 下拉框
2010/12/22 Javascript
jquery异步请求实例代码
2011/06/21 Javascript
hover的用法及live的用法介绍(鼠标悬停效果)
2013/03/29 Javascript
jQuery防止click双击多次提交及传递动态函数或多参数
2014/04/02 Javascript
jQuery多项选项卡的实现思路附样式及代码
2014/06/03 Javascript
3种Jquery限制文本框只能输入数字字母的方法
2014/12/03 Javascript
node.js中的http.response.addTrailers方法使用说明
2014/12/14 Javascript
AngularJS身份验证的方法
2016/02/17 Javascript
BootStrap 智能表单实战系列(十)自动完成组件的支持
2016/06/13 Javascript
js中 计算两个日期间的工作日的简单实例
2016/08/08 Javascript
jQuery中delegate()方法的用法详解
2016/10/13 Javascript
微信小程序开发之大转盘 仿天猫超市抽奖实例
2016/12/08 Javascript
浅谈对Angular中的生命周期钩子的理解
2017/07/31 Javascript
vue中添加mp3音频文件的方法
2018/03/02 Javascript
jQuery实现百度图片移入移出内容提示框上下左右移动的效果
2018/06/05 jQuery
解决vue打包报错Unexpected token: punc的问题
2020/10/24 Javascript
nuxt.js 在middleware(中间件)中实现路由鉴权操作
2020/11/06 Javascript
jquery实现点击左右按钮切换图片
2021/01/27 jQuery
Python中的字典遍历备忘
2015/01/17 Python
对Python中type打开文件的方式介绍
2018/04/28 Python
Python中的Django基本命令实例详解
2018/07/15 Python
python进阶之多线程对同一个全局变量的处理方法
2018/11/09 Python
python解析含有重复key的json方法
2019/01/22 Python
PYTHON如何读取和写入EXCEL里面的数据
2019/10/28 Python
Python3爬虫关于代理池的维护详解
2020/07/30 Python
System.Array.CopyTo()和System.Array.Clone()有什么区别
2016/06/20 面试题
建筑工程实习自我鉴定
2013/09/19 职场文书
大众服装店创业计划书范文
2014/01/01 职场文书
介绍信模板
2015/01/31 职场文书
2015年大学迎新工作总结
2015/07/16 职场文书
MySQL安装后默认自带数据库的作用详解
2021/04/27 MySQL
python flappy bird小游戏分步实现流程
2022/02/15 Python