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实现猜数字游戏(无重复数字)示例分享
Mar 29 Python
python输出指定月份日历的方法
Apr 23 Python
Python引用模块和查找模块路径
Mar 17 Python
python 设置文件编码格式的实现方法
Dec 21 Python
python监控进程脚本
Apr 12 Python
彻彻底底地理解Python中的编码问题
Oct 15 Python
python对Excel的读取的示例代码
Feb 14 Python
Python greenlet和gevent使用代码示例解析
Apr 01 Python
Pycharm中配置远程Docker运行环境的教程图解
Jun 11 Python
Django 构建模板form表单的两种方法
Jun 14 Python
Python连接mysql数据库及简单增删改查操作示例代码
Aug 03 Python
Django haystack实现全文搜索代码示例
Nov 28 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
destoon官方标签大全
2014/06/20 PHP
PHP新特性详解之命名空间、性状与生成器
2017/07/18 PHP
PHP fclose函数用法总结
2019/02/15 PHP
EXTJS内使用ACTIVEX控件引起崩溃问题的解决方法
2010/03/31 Javascript
用jquery存取照片的具体实现方法
2013/06/30 Javascript
js中把JSON字符串转换成JSON对象最好的方法
2014/03/21 Javascript
js使用栈来实现10进制转8进制与取除数及余数
2014/06/11 Javascript
Javascript基于对象三大特性(封装性、继承性、多态性)
2016/01/04 Javascript
使用nvm管理不同版本的node与npm的方法
2017/10/31 Javascript
vue + vuex todolist的实现示例代码
2018/03/09 Javascript
浅析vue给不同环境配置不同打包命令
2018/08/17 Javascript
详解小程序循环require之坑
2019/03/08 Javascript
vue中get请求如何传递数组参数的方法示例
2019/11/08 Javascript
在vue-cli中引入lodash.js并使用详解
2019/11/13 Javascript
Python实现的批量下载RFC文档
2015/03/10 Python
python正则表达式之作业计算器
2016/03/18 Python
Django自定义插件实现网站登录验证码功能
2017/04/19 Python
Python生成密码库功能示例
2017/05/23 Python
浅谈django开发者模式中的autoreload是如何实现的
2017/08/18 Python
python抓取网页中链接的静态图片
2018/01/29 Python
python指定写入文件时的编码格式方法
2018/06/07 Python
python 中字典嵌套列表的方法
2018/07/03 Python
tensorflow 实现数据类型转换
2020/02/17 Python
PageFactory设计模式基于python实现
2020/04/14 Python
Python如何优雅删除字符列表空字符及None元素
2020/06/25 Python
python删除指定列或多列单个或多个内容实例
2020/06/28 Python
亚洲最大旅游体验平台:KKday
2017/10/21 全球购物
美国睫毛、眉毛精华液领导品牌:RevitaLash Cosmetics
2018/03/26 全球购物
2014年高考决心书
2014/03/11 职场文书
《生命 生命》教学反思
2014/04/19 职场文书
委托书怎么写
2014/07/31 职场文书
改革共识倡议书
2014/08/29 职场文书
副乡长民主生活会个人对照检查材料思想汇报
2014/10/01 职场文书
大一新生检讨书
2014/10/29 职场文书
维稳工作承诺书
2015/01/20 职场文书
MYSQL优化之数据表碎片整理详解
2022/04/03 MySQL