机器学习---HMM前向、后向和维特比算法的计算

1. HMM

import numpy as np# In[15]:class HiddenMarkov:def forward(self, Q, V, A, B, O, PI):  # 使用前向算法N = len(Q)  # 状态序列的大小M = len(O)  # 观测序列的大小alphas = np.zeros((N, M))  # alpha值T = M  # 有几个时刻,有几个观测序列,就有几个时刻for t in range(T):  # 遍历每一时刻,算出alpha值indexOfO = V.index(O[t])  # 找出序列对应的索引for i in range(N):if t == 0:  # 计算初值alphas[i][t] = PI[t][i] * B[i][indexOfO]print('alpha1(%d)=p%db%db(o1)=%f' % (i, i, i, alphas[i][t]))else:alphas[i][t] = np.dot([alpha[t - 1] for alpha in alphas], [a[i] for a in A]) * B[i][indexOfO]  # 递推()print('alpha%d(%d)=[sigma alpha%d(i)ai%d]b%d(o%d)=%f' % (t, i, t - 1, i, i, t, alphas[i][t]))# print(alphas)P = np.sum([alpha[M - 1] for alpha in alphas])  # 求和终止# alpha11 = pi[0][0] * B[0][0]    #代表a1(1)# alpha12 = pi[0][1] * B[1][0]    #代表a1(2)# alpha13 = pi[0][2] * B[2][0]   #代表a1(3)print(P)def backward(self, Q, V, A, B, O, PI):  # 后向算法N = len(Q)  # 状态序列的大小M = len(O)  # 观测序列的大小betas = np.ones((N, M))  # betafor i in range(N):print('beta%d(%d)=1' % (M, i))for t in range(M - 2, -1, -1):indexOfO = V.index(O[t + 1])  # 找出序列对应的索引for i in range(N):betas[i][t] = np.dot(np.multiply(A[i], [b[indexOfO] for b in B]), [beta[t + 1] for beta in betas])realT = t + 1realI = i + 1print('beta%d(%d)=[sigma a%djbj(o%d)]beta%d(j)=(' % (realT, realI, realI, realT + 1, realT + 1),end='')for j in range(N):print("%.2f*%.2f*%.2f+" % (A[i][j], B[j][indexOfO], betas[j][t + 1]), end='')print("0)=%.3f" % betas[i][t])# print(betas)indexOfO = V.index(O[0])P = np.dot(np.multiply(PI, [b[indexOfO] for b in B]), [beta[0] for beta in betas])print("P(O|lambda)=", end="")for i in range(N):print("%.1f*%.1f*%.5f+" % (PI[0][i], B[i][indexOfO], betas[i][0]), end="")print("0=%f" % P)def viterbi(self, Q, V, A, B, O, PI):N = len(Q)  # 状态序列的大小M = len(O)  # 观测序列的大小deltas = np.zeros((N, M))psis = np.zeros((N, M))I = np.zeros((1, M))for t in range(M):realT = t+1indexOfO = V.index(O[t])  # 找出序列对应的索引for i in range(N):realI = i+1if t == 0:deltas[i][t] = PI[0][i] * B[i][indexOfO]psis[i][t] = 0print('delta1(%d)=pi%d * b%d(o1)=%.2f * %.2f=%.2f'%(realI, realI, realI, PI[0][i], B[i][indexOfO], deltas[i][t]))print('psis1(%d)=0' % (realI))else:deltas[i][t] = np.max(np.multiply([delta[t-1] for delta in deltas], [a[i] for a in A])) * B[i][indexOfO]print('delta%d(%d)=max[delta%d(j)aj%d]b%d(o%d)=%.2f*%.2f=%.5f'%(realT, realI, realT-1, realI, realI, realT, np.max(np.multiply([delta[t-1] for delta in deltas], [a[i] for a in A])), B[i][indexOfO], deltas[i][t]))psis[i][t] = np.argmax(np.multiply([delta[t-1] for delta in deltas], [a[i] for a in A]))print('psis%d(%d)=argmax[delta%d(j)aj%d]=%d' % (realT, realI, realT-1, realI, psis[i][t]))print(deltas)print(psis)I[0][M-1] = np.argmax([delta[M-1] for delta in deltas])print('i%d=argmax[deltaT(i)]=%d' % (M, I[0][M-1]+1))for t in range(M-2, -1, -1):I[0][t] = psis[int(I[0][t+1])][t+1]print('i%d=psis%d(i%d)=%d' % (t+1, t+2, t+2, I[0][t]+1))print(I)if __name__ == '__main__':Q = [1, 2, 3]V = ['红', '白']A = [[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]]B = [[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]]# O = ['红', '白', '红', '红', '白', '红', '白', '白']O = ['红', '白', '红', '白']    #例子PI = [[0.2, 0.4, 0.4]]HMM = HiddenMarkov()
#    HMM.forward(Q, V, A, B, O, PI)HMM.backward(Q, V, A, B, O, PI)
#     HMM.viterbi(Q, V, A, B, O, PI)

隐马尔可夫模型是一个统计模型,用于描述由隐藏的状态序列和对应的观测序列组成的系统。在这

个模型中,隐藏的状态是无法直接观测到的,而只能通过观测序列来进行推断。

前向算法(Forward Algorithm):前向算法用于计算在给定观测序列下每个时间步长处于特定状态

的概率。前向算法利用动态规划的思想,通过递推计算每个时间步的前向概率。前向概率

(alpha)的计算公式为:alpha[t][j] = sum(alpha[t-1][i] * A[i][j] * B[j][O[t]]) for i in range(N)

其中,alpha[t][j]表示在时间步t处于状态j的概率,A[i][j]表示从状态i转移到状态j的概率,B[j]

[O[t]]表示在状态j下观测到序列中的第t个观测的概率。

后向算法(Backward Algorithm):后向算法用于计算在给定观测序列下每个时间步从特定状态开始

的概率。后向算法同样利用动态规划的思想,通过递推计算每个时间步的后向概率。后向概率

(beta)的计算公式为: beta[t][i] = sum(A[i][j] * B[j][O[t+1]] * beta[t+1][j]) for j in range(N),其

中,beta[t][i]表示在时间步t从状态i开始的概率,A[i][j]表示从状态i转移到状态j的概率,B[j][O[t+1]]

表示在状态j下观测到序列中的第t+1个观测的概率,beta[t+1][j]表示在时间步t+1处于状态j的概率。

维特比算法(Viterbi Algorithm):维特比算法用于找到在给定观测序列下最可能的隐藏状态序列。

维特比算法利用动态规划的思想,通过递推计算每个时间步的最大概率和对应的状态。维特比算法

中使用的两个变量是delta和psi,分别表示到达某个状态的最大概率和之前的最优状态。 delta[t][j]

= max(delta[t-1][i] * A[i][j] * B[j][O[t]]) for i in range(N)

psi[t][j] = argmax(delta[t-1][i] * A[i][j]) for i in range(N)

其中,delta[t][j]表示在时间步t到达状态j的最大概率,psi[t][j]表示在时间步t到达状态j时的最优前一

个状态,argmax表示取最大值的索引。

import numpy as np# In[15]:class HiddenMarkov:def forward(self, Q, V, A, B, O, PI):  # 使用前向算法N = len(Q)  # 状态序列的大小M = len(O)  # 观测序列的大小alphas = np.zeros((N, M))  # alpha值T = M  # 有几个时刻,有几个观测序列,就有几个时刻for t in range(T):  # 遍历每一时刻,算出alpha值indexOfO = V.index(O[t])  # 找出序列对应的索引for i in range(N):if t == 0:  # 计算初值alphas[i][t] = PI[t][i] * B[i][indexOfO]print('alpha1(%d)=p%db%db(o1)=%f' % (i, i, i, alphas[i][t]))else:alphas[i][t] = np.dot([alpha[t - 1] for alpha in alphas], [a[i] for a in A]) * B[i][indexOfO]  # 递推()print('alpha%d(%d)=[sigma alpha%d(i)ai%d]b%d(o%d)=%f' % (t, i, t - 1, i, i, t, alphas[i][t]))# print(alphas)P = np.sum([alpha[M - 1] for alpha in alphas])  # 求和终止# alpha11 = pi[0][0] * B[0][0]    #代表a1(1)# alpha12 = pi[0][1] * B[1][0]    #代表a1(2)# alpha13 = pi[0][2] * B[2][0]   #代表a1(3)print(P)def backward(self, Q, V, A, B, O, PI):  # 后向算法N = len(Q)  # 状态序列的大小M = len(O)  # 观测序列的大小betas = np.ones((N, M))  # betafor i in range(N):print('beta%d(%d)=1' % (M, i))for t in range(M - 2, -1, -1):indexOfO = V.index(O[t + 1])  # 找出序列对应的索引for i in range(N):betas[i][t] = np.dot(np.multiply(A[i], [b[indexOfO] for b in B]), [beta[t + 1] for beta in betas])realT = t + 1realI = i + 1print('beta%d(%d)=[sigma a%djbj(o%d)]beta%d(j)=(' % (realT, realI, realI, realT + 1, realT + 1),end='')for j in range(N):print("%.2f*%.2f*%.2f+" % (A[i][j], B[j][indexOfO], betas[j][t + 1]), end='')print("0)=%.3f" % betas[i][t])# print(betas)indexOfO = V.index(O[0])P = np.dot(np.multiply(PI, [b[indexOfO] for b in B]), [beta[0] for beta in betas])print("P(O|lambda)=", end="")for i in range(N):print("%.1f*%.1f*%.5f+" % (PI[0][i], B[i][indexOfO], betas[i][0]), end="")print("0=%f" % P)def viterbi(self, Q, V, A, B, O, PI):N = len(Q)  # 状态序列的大小M = len(O)  # 观测序列的大小deltas = np.zeros((N, M))psis = np.zeros((N, M))I = np.zeros((1, M))for t in range(M):realT = t+1indexOfO = V.index(O[t])  # 找出序列对应的索引for i in range(N):realI = i+1if t == 0:deltas[i][t] = PI[0][i] * B[i][indexOfO]psis[i][t] = 0print('delta1(%d)=pi%d * b%d(o1)=%.2f * %.2f=%.2f'%(realI, realI, realI, PI[0][i], B[i][indexOfO], deltas[i][t]))print('psis1(%d)=0' % (realI))else:deltas[i][t] = np.max(np.multiply([delta[t-1] for delta in deltas], [a[i] for a in A])) * B[i][indexOfO]print('delta%d(%d)=max[delta%d(j)aj%d]b%d(o%d)=%.2f*%.2f=%.5f'%(realT, realI, realT-1, realI, realI, realT, np.max(np.multiply([delta[t-1] for delta in deltas], [a[i] for a in A])), B[i][indexOfO], deltas[i][t]))psis[i][t] = np.argmax(np.multiply([delta[t-1] for delta in deltas], [a[i] for a in A]))print('psis%d(%d)=argmax[delta%d(j)aj%d]=%d' % (realT, realI, realT-1, realI, psis[i][t]))print(deltas)print(psis)I[0][M-1] = np.argmax([delta[M-1] for delta in deltas])print('i%d=argmax[deltaT(i)]=%d' % (M, I[0][M-1]+1))for t in range(M-2, -1, -1):I[0][t] = psis[int(I[0][t+1])][t+1]print('i%d=psis%d(i%d)=%d' % (t+1, t+2, t+2, I[0][t]+1))print(I)if __name__ == '__main__':Q = [1, 2, 3]V = ['红', '白']A = [[0.5, 0.2, 0.3], [0.3, 0.5, 0.2], [0.2, 0.3, 0.5]]B = [[0.5, 0.5], [0.4, 0.6], [0.7, 0.3]]# O = ['红', '白', '红', '红', '白', '红', '白', '白']O = ['红', '白', '红', '白']    #例子PI = [[0.2, 0.4, 0.4]]HMM = HiddenMarkov()
#    HMM.forward(Q, V, A, B, O, PI)
#    HMM.backward(Q, V, A, B, O, PI)HMM.viterbi(Q, V, A, B, O, PI)

前向算法(Forward Algorithm):前向算法用于计算给定观测序列下每个时刻的前向概率

(alpha),表示在当前时刻观测到特定状态的概率。通过递推计算,利用前一时刻的前向概率和

状态转移概率、发射概率来计算当前时刻的前向概率。数学公式:alpha[i][t] = PI[t][i] * B[i]

[indexOfO],其中alpha[i][t]表示在时刻t处于状态i的前向概率,PI[t][i]表示初始状态概率,B[i]

[indexOfO]表示在状态i观测到观测序列的概率。

后向算法(Backward Algorithm):后向算法用于计算给定观测序列下每个时刻的后向概率

(beta),表示从当前时刻开始,在未来时刻观测到特定状态的概率。通过递推计算,利用后一时

刻的后向概率和状态转移概率、发射概率来计算当前时刻的后向概率。数学公式:beta[i][t] = Σ(A[i]

[j] * B[j][indexOfO] * beta[j][t+1]),其中beta[i][t]表示在时刻t处于状态i的后向概率,A[i][j]表示状态i

转移到状态j的概率,B[j][indexOfO]表示在状态j观测到观测序列的概率。

维特比算法(Viterbi Algorithm):维特比算法用于找到给定观测序列下最可能的隐藏状态序列,

即根据观测序列推断出最可能的隐藏状态路径。通过动态规划的方式,利用状态转移概率、发射概

率和初始状态概率,计算每个时刻每个状态的最大概率值和对应的前一个状态。数学公式:delta[i]

[t] = max(delta[t-1][j] * A[j][i]) * B[i][indexOfO],其中delta[i][t]表示在时刻t处于状态i的最大概率值,

A[j][i]表示状态j转移到状态i的概率,B[i][indexOfO]表示在状态i观测到观测序列的概率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/259698.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024 前端面试题(GPT回答 + 示例代码 + 解释)No.114 - No.121

本文题目来源于全网收集,答案来源于 ChatGPT 和 博主(的小部分……) 格式:题目 h3 回答 text 参考大佬博客补充 text 示例代码 code 解释 quote 补充 quote 上一篇链接:2024 前端面试题(GPT回答 示例…

用HTML和CSS打造跨年烟花秀视觉盛宴

目录 一、程序代码 二、代码原理 三、运行效果 一、程序代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>跨年烟花秀</title><meta name"viewport" content"widthdevi…

Zotero不小心把分类删除怎么办?

如果不小心把Zotero中的条目删除了&#xff0c;是可以在回收站中找到的&#xff0c;但是如果把一个大分类删除了&#xff0c;那么就很难找回来了。 如果删除了也不必担心&#xff0c;可以查看Zotero官网给出的解决办法zotero_data [Zotero 文档] 我们需要定位到\Zotero\zotero…

MySQL(1/3)

基本命令行操作 命令行连接 mysql -uroot -p 回车&#xff0c;然后在下一行输入密码&#xff0c;或者直接在p后写密码 修改密码 updata mysql.user set authentication_stringpassword(原密码) where userroot and Host localhost; 刷新权限 flush privileges; 查看所有数据库…

深入理解 Vue3 中的 setup 函数

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

rocketMQ-Dashboard安装与部署

1、下载最新版本rocketMQ-Dashboard 下载地址&#xff1a;https://github.com/apache/rocketmq-dashboard 2、下载后解压&#xff0c;并用idea打开 3、修改配置 ①、修改端口及rocketmq服务的ip&#xff1a;port ②、修改访问账号、密码 3、然后启动访问&#xff1a; 4、mav…

Unity ScreenPointToRay 获取到的坐标不准确

&#x1f47e;奇奇怪怪的 &#x1f959;问题描述&#x1f96a;解决方案&#x1f37f;验证代码 &#x1f959;问题描述 使用&#xff1a;Camera.main.ScreenPointToRay 将鼠标坐标转换成射线&#xff0c;然后通过&#xff1a;Physics.Raycast 获取到射线碰撞到的坐标&#xff0…

Windows11(非WSL)安装Installing llama-cpp-python with GPU Support

直接安装&#xff0c;只支持CPU。想支持GPU&#xff0c;麻烦一些。 1. 安装CUDA Toolkit (NVIDIA CUDA Toolkit (available at https://developer.nvidia.com/cuda-downloads) 2. 安装如下物件&#xff1a; gitpythoncmakeVisual Studio Community (make sure you install t…

LeetCode 0589.N 叉树的前序遍历:深度优先搜索(DFS)

【LetMeFly】589.N 叉树的前序遍历&#xff1a;深度优先搜索(DFS) 力扣题目链接&#xff1a;https://leetcode.cn/problems/n-ary-tree-preorder-traversal/ 给定一个 n 叉树的根节点 root &#xff0c;返回 其节点值的 前序遍历 。 n 叉树 在输入中按层序遍历进行序列化表…

【开源】新生报到网站 JAVA+Vue.js+SpringBoot+MySQL

本文项目编号&#xff1a; T 002 。 \color{red}{本文项目编号&#xff1a;T002。} 本文项目编号&#xff1a;T002。 目录 1 功能模块1.1 在线交流模块1.2宿舍分配模块1.3 校园概况模块1.4 专业管理模块 2 系统展示3 核心代码3.1 图表展示3.2 查询评论3.3 新增报道 4 免责声明 …

数据结构1.0(基础)

近java的介绍&#xff0c; 文章目录 第一章、数据结构1、数据结构 &#xff1f;2、常用的数据结构数据结构&#xff1f; 逻辑结构and物理结构 第二章、数据结构基本介绍2.1、数组&#xff08;Array&#xff09;2.2、堆栈&#xff08;Stack&#xff09;2.3、队列&#xff08;Que…

云原生之容器编排实践-在K8S集群中使用Registry2搭建私有镜像仓库

背景 基于前面搭建的3节点 Kubernetes 集群&#xff0c;今天我们使用 Registry2 搭建私有镜像仓库&#xff0c;这在镜像安全性以及离线环境下运维等方面具有重要意义。 Note: 由于是测试环境&#xff0c;以下创建了一个 local-storage 的 StorageClass &#xff0c;并使用本地…

【自然语言处理】:实验4布置,预训练语言模型实现与应用

清华大学驭风计划 因为篇幅原因实验答案分开上传&#xff0c;自然语言处理专栏持续更新中&#xff0c;期待的小伙伴敬请关注 有任何疑问或者问题&#xff0c;也欢迎私信博主&#xff0c;大家可以相互讨论交流哟~~ 案例简介 2018年&#xff0c;Google提出了预训练语言模型BE…

vue+springboot登录与注册功能的实现

①首先写一个登录页面 <template> <div style"background-color: #42b983;display: flex;align-items: center;justify-content: center;height: 100vh"><div style"background-color: white;display: flex;width: 50%;height: 50%;overflow: h…

统信UOS终端:使用方法解析系列(下篇)

原文链接&#xff1a;统信UOS终端&#xff1a;使用方法解析系列&#xff08;下篇&#xff09; 亲爱的读者朋友们&#xff0c;欢迎回到我们关于统信UOS终端使用方法的系列文章。在这个系列的最后一篇中&#xff0c;我们将深入探讨一些高级功能&#xff0c;包括终端分屏、查找命令…

UE4 C++联网RPC教程笔记(一)(第1~4集)

UE4 C联网RPC教程笔记&#xff08;一&#xff09;&#xff08;第1~4集&#xff09; 前言1. 教程介绍与资源2. 自定义 Debug 功能3. Actor 的复制4. 联网状态判断 前言 本系列笔记将会对梁迪老师的《UE4C联网RPC框架开发吃鸡》教程进行个人的知识点梳理与总结&#xff0c;此课程…

Rabbitmq入门与应用(五)-延迟队列的设计与实现

延迟队列设计 在开发过程中涉及到延迟队列的应用&#xff0c;例如订单生成后有30分钟的付款时间&#xff0c;注册是有60秒的邮件或者短信的发送读取时间等。 常规使用rabbitmq设计延迟队列有两种方式 使用创建一个延迟队列阻塞消息使用延迟队列插件 Dead Letter Exchanges —…

Aster实现一台电脑当两台使——副屏使用独立win账号

前言&#xff1a;笔者每年回家&#xff0c;都面临着想要和小伙伴一起玩游戏&#xff0c;但小伙伴没有电脑/只有低配电脑的问题。与此同时&#xff0c;笔者自身的电脑是高配置的电脑&#xff0c;因此笔者想到&#xff0c;能否在自己的电脑上运行游戏&#xff0c;在小伙伴的电脑上…

如何图片无损放大?几个无损放大图片分享

在数字化时代&#xff0c;图片已经成为我们生活中不可或缺的一部分。从社交媒体上的分享&#xff0c;到专业摄影作品的展示&#xff0c;再到网页设计和平面广告的制作&#xff0c;图片的质量往往直接影响到我们的视觉体验和信息传达的效果。然而&#xff0c;有时候&#xff0c;…

2024-02-11 Unity 编辑器开发之编辑器拓展2 —— 自定义窗口

文章目录 1 创建窗口类2 显示窗口3 窗口事件回调函数4 窗口中常用的生命周期函数5 编辑器窗口类中的常用成员6 小结 1 创建窗口类 ​ 当想为 Unity 拓展一个自定义窗口时&#xff0c;只需实现继承 EditorWindow 的类即可&#xff0c;并在该类的 OnGUI 函数中编写面板控件相关的…