理论知识:《统计学习方法》第10章 隐马尔科夫模型

一、HMM算法矩阵写法

前向算法

P(O∣λ)=πTBo1ABo2ABo3⋯ABoT(1,1,1)TP(O| \lambda) = \pi^TB_{o_1} A B_{o_2}AB_{o_3} \cdots AB_{o_T}(1,1,1)^TP(O∣λ)=πTBo1​​ABo2​​ABo3​​⋯ABoT​​(1,1,1)T

后向算法

P(O∣λ)=(1,1,1)BoTTAT⋯Bo3TATBo2TATBo1TπP(O| \lambda) = (1,1,1) B_{o_T}^TA^T\cdots B_{o_3}^TA^TB_{o_2}^TA^TB_{o_1}^T\piP(O∣λ)=(1,1,1)BoT​T​AT⋯Bo3​T​ATBo2​T​ATBo1​T​π

说明:可以看到前向算法和后向算法只是差了一个转置

二、定义HiddenMarkov类

下面python代码用的是上面的矩阵形式的递推公式(比较简洁)

class HiddenMarkov(object):def __init__(self):
#         self.N = None  # 状态数
#         self.M = None  # 观测数
#         self.T = None  # 序列长度
#         self.A = None  # 状态转移矩阵 (N,N)
#         self.B = None  # 概率转移矩阵 (N,M)
#         self.pi = None # 初始状态向量 (N,)self.alpha = None self.beta = None # self.deltas = None 在__init__里面不加这行也行# self.psis = None# =========== 前向算法 =============def forward(self, A, B, pi, O, N, T):# 做numpy运算前建议先把每个变量的shape打印出来看一看,不要自己在那瞎猜# print(A.shape) # (3,3)# print(pi.shape) # (3,)# print(O.shape) # (T,)# print(B[:,O[0]].shape) # (3,)#  print(A.shape,pi.shape,O.shape,B[:,O[0]].shape) #        (3, 3)   (3,)     (3,)      (3,)self.alpha = []# 初始化alpha1a1 = pi * B[:,O[0]] # (3,) * (3,)self.alpha.append(a1) # B[:,O[0]]表示[0.5,0.4,0.7]print(f"alpha{1} {a1}")for i in range(1, T):ai = np.dot(self.alpha[i - 1], A) * B[:, O[i]] # np.dot((3,),(3,3)) * (3,) = (3,)self.alpha.append(ai) # 利用numpy的性质,B[:,O[i]]相当于对角矩阵print(f"alpha{i + 1} {ai}")print("")print(f"前向算法:在模型lamda下观测序列O出现的概率 P(O|lamda)={np.sum(self.alpha[T-1]):.6f}")print("")# =========== 后向算法 =============def backward(self, A, B, pi, O, N, T):self.beta = [] # [betaT, ..., beta1] 注意列表beta中元素的顺序与实际相反# 初始化beta1b1 = np.ones(N)self.beta.append(b1)print(f"beta{T} {b1}")for i in range(1, T):bi = np.dot(self.beta[i - 1] * B[:,O[T - i]], A.T) # np.dot((3,)*(3,), (3,3)) = (3,)self.beta.append(bi)print(f"beta{T - i} {bi}")print("")print(f"后向算法:在模型lamda下观测序列O出现的概率 P(O|lamda)={np.sum(self.beta[T - 1] * B[:, O[0]] * pi):.6f}")# =========== 维比特算法 =============def viterbi(self, A, B, pi, O):T = len(O) # 3 序列长度N = A.shape[0] # 4 状态数self.deltas = [] self.psis = []delta = pi * B[:,O[0]]print(f"delta{1} : {delta}")self.deltas.append(delta) # delta[0]表示实际的delta1向量self.psis.append(np.zeros(N))print(f"psi{1}   : {[0,0,0]}")for i in range(1,T): # 循环 T - 1次tmp = delta.reshape(3,1) * Adelta = np.max(tmp, axis = 0) * B[:,O[i]]print(f"delta{i + 1} : {delta}")self.deltas.append(delta) # 加入delta_i+1向量psi = np.argmax(tmp, axis = 0) + 1 # 加入psi_i+1向量 print(f"psi{i + 1}   : {psi}")self.psis.append(psi)print("")# 回溯,求最优路径path = []last = np.argmax(self.deltas[-1]) + 1 # 得到i4* 盒子号path.append(last)for j in range(T - 1, 0, -1):last = self.psis[j][last - 1] # 这时不用再+1了,因为psis中本来就算盒子号path.append(last) print(f"最优路径为: {path[::-1]}") # 逆序输出

三、习题演练

统计学习方法 P200 例10.2

import numpy as npA = 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 = np.array([0.2,0.4,0.4])
A = A.reshape(3,3)
B = B.reshape(3,2)
O = np.array([0,1,0]) # 观测序列 0表示红,1表示白N = 3
T = 3HMM = HiddenMarkov()
HMM.forward(A, B, pi, O, N, T)
HMM.backward(A, B, pi, O, N, T)
alpha1 [0.1  0.16 0.28]
alpha2 [0.077  0.1104 0.0606]
alpha3 [0.04187  0.035512 0.052836]前向算法:在模型lamda下观测序列O出现的概率 P(O|lamda)=0.130218beta3 [1. 1. 1.]
beta2 [0.54 0.49 0.57]
beta1 [0.2451 0.2622 0.2277]后向算法:在模型lamda下观测序列O出现的概率 P(O|lamda)=0.130218

统计学习方法 P213 习题10.1

import numpy as npA = 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 = np.array([0.2,0.4,0.4])
A = A.reshape(3,3)
B = B.reshape(3,2)
O = np.array([0,1,0,1]) # 观测序列 0表示红,1表示白N = 3
T = 4HMM = HiddenMarkov()
HMM.forward(A, B, pi, O, N, T)
HMM.backward(A, B, pi, O, N, T)
alpha1 [0.1  0.16 0.28]
alpha2 [0.077  0.1104 0.0606]
alpha3 [0.04187  0.035512 0.052836]
alpha4 [0.0210779  0.02518848 0.01382442]前向算法:在模型lamda下观测序列O出现的概率 P(O|lamda)=0.060091beta4 [1. 1. 1.]
beta3 [0.46 0.51 0.43]
beta2 [0.2461 0.2312 0.2577]
beta1 [0.112462 0.121737 0.104881]后向算法:在模型lamda下观测序列O出现的概率 P(O|lamda)=0.060091

统计学习方法 P213 习题10.2 前后向算法

import numpy as npA = np.array([0.5, 0.1, 0.4, 0.3,0.5,0.2, 0.2,0.2,0.6])
B = np.array([0.5, 0.5, 0.4, 0.6, 0.7, 0.3])
pi = np.array([0.2,0.3,0.5])
A = A.reshape(3,3)
B = B.reshape(3,2)
O = np.array([0,1,0,0,1,0,1,1]) # 观测序列 0表示红,1表示白N = 3
T = 8HMM = HiddenMarkov()
HMM.forward(A, B, pi, O, N, T)
HMM.backward(A, B, pi, O, N, T)print("")
print(f"最终答案:\nP(i4 = q3 | O, lamda) = {HMM.alpha[4 - 1][2] * HMM.beta[4][2] / np.dot(HMM.alpha[4 - 1] , HMM.beta[4]):.6f}")
alpha1 [0.1  0.12 0.35]
alpha2 [0.078  0.084  0.0822]
alpha3 [0.04032  0.026496 0.068124]
alpha4 [0.0208668  0.01236192 0.04361112]
alpha5 [0.0114321  0.01019392 0.01109573]
alpha6 [0.00549669 0.00338373 0.00928834]
alpha7 [0.00281056 0.00245952 0.00253453]
alpha8 [0.00132502 0.00121063 0.00094105]前向算法:在模型lamda下观测序列O出现的概率 P(O|lamda)=0.003477beta8 [1. 1. 1.]
beta7 [0.43 0.51 0.4 ]
beta6 [0.1861 0.2415 0.1762]
beta5 [0.105521 0.100883 0.111934]
beta4 [0.04586531 0.05280909 0.04280618]
beta3 [0.02556442 0.02343448 0.02678985]
beta2 [0.01482964 0.01227214 0.01568294]
beta1 [0.00632569 0.00684706 0.00577855]后向算法:在模型lamda下观测序列O出现的概率 P(O|lamda)=0.003477最终答案:
P(i4 = q3 | O, lamda) = 0.536952

P213 习题10.3 维比特算法

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 = np.array([0.2, 0.4, 0.4])
O = [0, 1, 0, 1] # 红,白,红,白
HMM = HiddenMarkov()
HMM.viterbi(A, B, pi, O)
print()
print(HMM.deltas)
print(HMM.psis)
delta1 : [0.1  0.16 0.28]
psi1   : [0, 0, 0]
delta2 : [0.028  0.0504 0.042 ]
psi2   : [3 3 3]
delta3 : [0.00756 0.01008 0.0147 ]
psi3   : [2 2 3]
delta4 : [0.00189  0.003024 0.002205]
psi4   : [1 2 3]最优路径为: [3, 2, 2, 2][array([0.1 , 0.16, 0.28]), array([0.028 , 0.0504, 0.042 ]), array([0.00756, 0.01008, 0.0147 ]), array([0.00189 , 0.003024, 0.002205])]
[array([0., 0., 0.]), array([3, 3, 3]), array([2, 2, 3]), array([1, 2, 3])]

参考资料:fendu79/lihang-code/

《统计学习方法》第10章 隐马尔科夫模型 HMM算法 纯Python代码实现 + 前后向算法矩阵形式 + 课后习题答案相关推荐

  1. 第九章 隐马尔科夫模型HMM

    文章目录 1 隐马尔科夫模型定义 2 概率计算算法 2.1 前向概率 2.2 概率计算 3 学习算法 3.1 EM算法 3.2EM在HMM 4 预测算法 1 隐马尔科夫模型定义 隐马尔科夫模型是一个s ...

  2. 一、隐马尔科夫模型HMM

    隐马尔科夫模型HMM(一)HMM模型基础 隐马尔科夫模型(Hidden Markov Model,以下简称HMM)是比较经典的机器学习模型了,它在语言识别,自然语言处理,模式识别等领域得到广泛的应用. ...

  3. 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数

    在本篇我们会讨论HMM模型参数求解的问题,这个问题在HMM三个问题里算是最复杂的.在研究这个问题之前,建议先阅读这个系列的前两篇以熟悉HMM模型和HMM的前向后向算法,以及EM算法原理总结,这些在本篇 ...

  4. 复现经典:《统计学习方法》第 10 章 隐马尔可夫模型

    本文是李航老师的<统计学习方法>[1]一书的代码复现. 作者:黄海广[2] 备注:代码都可以在github[3]中下载. 我将陆续将代码发布在公众号"机器学习初学者", ...

  5. Python语音基础操作--10.2隐马尔科夫模型的孤立字识别

    <语音信号处理试验教程>(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的.使用CSDN博客查看帮助文件 ...

  6. python地图匹配_基于隐马尔科夫模型(HMM)的地图匹配(Map-Matching)算法

    1. 摘要 本篇博客简单介绍下用隐马尔科夫模型(Hidden Markov Model, HMM)来解决地图匹配(Map-Matching)问题.转载请注明网址. 2. Map-Matching(MM ...

  7. 【NLP】用于语音识别、分词的隐马尔科夫模型HMM

    大家好,今天介绍自然语言处理中经典的隐马尔科夫模型(HMM).HMM早期在语音识别.分词等序列标注问题中有着广泛的应用. 了解HMM的基础原理以及应用,对于了解NLP处理问题的基本思想和技术发展脉络有 ...

  8. 隐马尔科夫模型 HMM 与 语音识别 speech recognition (1):名词解释

    0.引言 想在 CSDN 上看一下隐马尔科夫模型,简称HMM(Hidden Markov Model)的例子,找了几篇博文,却发现大部分都是转载的,转载的还没有出处,文中的表述与逻辑也看的人晕头转向, ...

  9. 隐马尔科夫模型 (HMM) 算法介绍及代码实现

    Table of Contents Hidden Markov Model (隐马尔科夫模型) 定义 基本问题 前向算法 算法流程 实现代码 后向算法 算法流程 实现代码 Viterbi算法 算法流程 ...

最新文章

  1. vue如何使用原生js写动画效果_深入理解 Vuejs 动画效果
  2. jQuery图片延迟加载插件jQuery.lazyload
  3. 计算机报临时用户,大师练习win10系统添加临时登录账户win10电脑临时账户的办法?...
  4. java面试要点---oracle,mysql,DB2数据库的分页
  5. java如何使用md5加密_Java中MD5加密
  6. 图片显示不出时显示默认图片
  7. 扫描文件怎么设置到服务器,如何为扫描仪添加局域网功能
  8. excel如何把顺序倒过来_在excel中怎么使文字颠倒顺序反过来显示呢?
  9. swift 使用Moya进行网络请求
  10. 不要害怕超级人工智能
  11. 纯CSS调整select选择框高度,兼容IE/Firefox/Opera/Safair/Chrome
  12. 深圳监控安装上门服务简介
  13. 微信小程序支付错误提示“商户号mch_id或sub_mch_id不存在”
  14. 宽带认证失败连接服务器无响应,路由器宽带账号认证失败的解决办法
  15. grad-cam一直无法画比较合适的图的原因
  16. PAT乙级_1068 万绿丛中一点红 (20 分)_python
  17. JavaWeb-Servlet(上)
  18. 浪漫主义时期交响曲 聆听记录
  19. quartz所需表的说明
  20. 【博学谷学习记录】超强总结,用心分享|js语法基础(一)

热门文章

  1. 【论文分享】EMNLP 2020 自然语言理解
  2. 2. 关于DRL的一些经验
  3. nanopc-t4移植linux,NanoPC-T4试用体验一:Nano PC T4 开箱上电
  4. NPN和PNP传感器区别及接线
  5. KUBO编程将惊艳亮相2020迪拜世博会
  6. 转:免费电子书籍下载站点
  7. 继续教育关于计算机教学设计,2013年继续教育培训资料汇集(一):课堂教学设计模板(V9.1版)...
  8. 小码哥考研技巧(求背单词长度的最大期望)
  9. 使用Winclone 7 Pro创建,自定义和部署Winclone软件包的方法
  10. 石油测井主要的五大方法