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 相关文章推荐
Django静态资源URL STATIC_ROOT的配置方法
Nov 08 Python
列举Python中吸引人的一些特性
Apr 09 Python
Python抓取淘宝下拉框关键词的方法
Jul 08 Python
python验证码识别的示例代码
Sep 21 Python
python实现SOM算法
Feb 23 Python
python使用Matplotlib绘制分段函数
Sep 25 Python
python中property属性的介绍及其应用详解
Aug 29 Python
pygame实现俄罗斯方块游戏(AI篇1)
Oct 29 Python
python实现滑雪者小游戏
Feb 22 Python
Python 改变数组类型为uint8的实现
Apr 09 Python
解决pycharm debug时界面下方不出现step等按钮及变量值的问题
Jun 09 Python
Python如何读写二进制数组数据
Aug 01 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
9个PHP开发常用功能函数小结
2011/07/15 PHP
php微信公众平台开发之微信群发信息
2016/09/13 PHP
基于jquery的点击链接插入链接内容的代码
2012/07/31 Javascript
使用jQuery解决IE与FireFox下createElement方法的差异
2013/11/14 Javascript
使用jQuery.wechat构建微信WEB应用
2014/10/09 Javascript
浅析javascript 定时器
2014/12/23 Javascript
Google 地图类型详解及示例代码
2016/08/06 Javascript
javascript九宫格图片随机打乱位置的实现方法
2017/03/15 Javascript
详解axios在vue中的简单配置与使用
2017/05/10 Javascript
简单谈谈React中的路由系统
2017/07/25 Javascript
Vue.js表单标签中的单选按钮、复选按钮和下拉列表的取值问题
2017/11/22 Javascript
通过fastclick源码分析彻底解决tap“点透”
2017/12/24 Javascript
Angular2学习笔记之数据绑定的示例代码
2018/01/03 Javascript
详解多页应用 Webpack4 配置优化与踩坑记录
2018/10/16 Javascript
Angular封装搜索框组件操作示例
2019/04/25 Javascript
微信小程序按钮点击跳转页面详解
2019/05/06 Javascript
[03:03]2014DOTA2西雅图国际邀请赛 Alliance战队巡礼
2014/07/07 DOTA
Python的Django框架中的URL配置与松耦合
2015/07/15 Python
11月编程语言排行榜 Python逆袭C#上升到第4
2017/11/15 Python
python实现txt文件格式转换为arff格式
2018/05/31 Python
tensorflow转换ckpt为savermodel模型的实现
2020/05/25 Python
pandas之分组groupby()的使用整理与总结
2020/06/18 Python
pycharm 使用tab跳出正在编辑的括号(){}{}等问题
2021/02/26 Python
CSS中越界问题的经典解决方案【推荐】
2016/04/19 HTML / CSS
Koral官方网站:女性时尚运动服
2019/04/10 全球购物
简短的公司员工自我评价分享
2013/11/13 职场文书
九年级政治教学反思
2014/02/06 职场文书
《我要的是葫芦》教学反思
2014/02/23 职场文书
爱护草坪标语
2014/06/24 职场文书
“九一八事变纪念日”国旗下讲话稿
2014/09/14 职场文书
2014年最新个人对照检查材料范文
2014/09/25 职场文书
2015年为民办实事工作总结
2015/05/26 职场文书
师范生见习自我总结
2015/06/23 职场文书
教师节获奖感言
2015/07/31 职场文书
2016年母亲节广告语
2016/01/28 职场文书
CSS实现鼠标悬浮动画特效
2023/05/07 HTML / CSS