先放一张找到的算法流程图:

上图解释

A:状态转移概率矩阵,Aij表示状态i到状态j转换的概率,即P(state=j | state=i)。下面代码中以P表示。

B:观测矩阵,Bij表示给定状态i,观测结果为j的概率。即P(observation=j | state=i)

π:初始时状态概率分布,表示各状态出现的概率。代码中以pi表示。

O:输入的观测序列。

:表示经过节点(时刻t,状态state=i)的局部最优路径到此节点时对应的概率,即给定X=(x1,...xt,...xn)子序列(x1,x2,...xt)时,对应的最佳状态序列(末状态state=i)的概率值。

下面代码中以delta表示

:跟上面相关。表示上面最优路径经过的节点的上一个状态id。下面代码中以w表示。

1式理解:右边为状态state=i出现的概率乘以(状态i下观测到O[t=1]的概率)

2式理解:当前节点概率值,为(上一时刻各节点概率值乘以状态转换概率)的最大值,再乘以状态state=i时观测到O[t]的概率。这就是动态规划的思想了。

以上,熟悉隐马尔可夫模型的话,理解应该没问题了。

-------------------------------------------------------------------------

下面进入代码部分:

import  numpy as np
def my_viterbi(O,P,B,pi):
'''
O:观测序列
P:状态转移矩阵,Pij表示状态i到j转换的条件概率
B:观测矩阵,Bij表示状态i下观测到Oj的条件概率
pi:初始的状态概率分布 return:各个时刻选择的状态id
''' set_O=list(set(O))
# 观测结果有多少种类
class_observe=len(set_O)
# 将观测序列one-hot化,不然会超过索引
for i in range(len(O)):
O[i]=set_O.index(O[i])
# 进行若干检查
assert class_observe==B.shape[1],'观测序列与观测矩阵的观测结果维度不一致!'
assert P.shape[0]==B.shape[0],'转移矩阵与观测矩阵的状态维度不一致!'
assert P.shape[0]==len(pi),'转移矩阵与状态分布的状态维度不一致!'
sequence_len=len(O)# 观测序列长度,即有多少个时刻t
states_per_time=P.shape[0]# 每个时刻有多少个状态,这里假设相同。实际可以不同,不同的话,应该要给出每个时刻对应的状态集合。这里默认所有状态
# 记录(局部)最优路径中节点(t时刻状态s)的概率值,当记录完毕后,逆序寻找最优节点即可
delta=np.zeros((sequence_len,states_per_time))
# 记录经过t时刻状态s的局部最优路径的前一个状态id
w=np.zeros((sequence_len,states_per_time))
# 初始化
for s in range(states_per_time):
delta[0,s]=pi[s]*B[s,O[0]]# 即状态概率分布乘以观测矩阵对应元素,得到0时刻各状态对应概率值
for t in range(1,sequence_len):
for s in range(states_per_time):
delta[t,s]=np.max([delta[t-1,s_]*P[s_,s] for s_ in range(states_per_time)])*B[s,O[t]]
w[t,s]=np.argmax([delta[t-1,s_]*P[s_,s] for s_ in range(states_per_time)])
max_sequence_prob=np.max(delta[-1,:])
res=np.zeros(sequence_len).astype(np.int32)
res[-1]=np.argmax(delta[-1,:])
for t in range(sequence_len-2,-1,-1):
res[t]=w[t+1,res[t+1]]
return res,max_sequence_prob # 状态转移矩阵
P=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]])
# 观测序列,假设有2种观察结果,比如扔硬币,从0开始
O=np.array([2,3,3])
# 初始时各个状态出现的概率
pi=np.array([0.2,0.4,0.4])
res,prob=my_viterbi(O, P, B, pi)
print(res)

输出:

array([2,1,1])

总结

涉及到的知识点为隐马尔可夫模型和动态规划。比较简单。

维特比算法及python实现的更多相关文章

  1. 【机器学习】【条件随机场CRF-2】CRF的预测算法之维特比算法(viterbi alg) 详解 + 示例讲解 + Python实现

    1.CRF的预测算法条件随机场的预测算法是给定条件随机场P(Y|X)和输入序列(观测序列)x,求条件概率最大的输出序列(标记序列)y*,即对观测序列进行标注.条件随机场的预测算法是著名的维特比算法(V ...

  2. 维特比算法Python实现

    前言 维特比算法是隐马尔科夫问题的一个基本问题算法.维特比算法解决的问题是已知观察序列,求最可能的标注序列. 什么是维特比算法? 维特比算法尽管是基于严格的数学模型的算法,但是维特比算法毕竟是算法,因 ...

  3. 维特比算法(Viterbi)及python实现样例

    维特比算法(Viterbi) 维特比算法 维特比算法shiyizhong 动态规划算法用于最可能产生观测时间序列的-维特比路径-隐含状态序列,特别是在马尔可夫信息源上下文和隐马尔科夫模型中.术语“维特 ...

  4. 维特比算法(Viterbi)-实例讲解(暴力破解+代码实现)

    1.简介 维特比算法是一个通用的求序列最短路径的动态规划算法,也可以用于很多其他问题,比如:文本挖掘.分词原理.既然是动态规划算法,那么就需要找到合适的局部状态,以及局部状态的递推公式.在HMM中,维 ...

  5. Machine Learning系列--维特比算法

    维特比算法(Viterbi algorithm)是在一个用途非常广的算法,本科学通信的时候已经听过这个算法,最近在看 HMM(Hidden Markov model) 的时候也看到了这个算法.于是决定 ...

  6. Java实现:抛开jieba等工具,写HMM+维特比算法进行词性标注

    一.前言:词性标注 二.经典维特比算法(Viterbi) 三.算法实现 四.完整代码 五.效果演示: 六.总结 一.前言:词性标注 词性标注(Part-Of-Speech tagging, POS t ...

  7. 维特比算法(Viterbi Algorithm)

      寻找最可能的隐藏状态序列(Finding most probable sequence of hidden states) 对于一个特殊的隐马尔科夫模型(HMM)及一个相应的观察序列,我们常常希望 ...

  8. HMM 自学教程(六)维特比算法

    本系列文章摘自 52nlp(我爱自然语言处理: http://www.52nlp.cn/),原文链接在 HMM 学习最佳范例,这是针对 国外网站上一个 HMM 教程 的翻译,作者功底很深,翻译得很精彩 ...

  9. 八大排序算法的 Python 实现

    转载: 八大排序算法的 Python 实现 本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个 ...

随机推荐

  1. VUE-文本-事件-属性指令

    一.Vue文本指令 文本指令: 1.{{ }} 2.v-text:不能解析html语法的文本,会原样输出 3.v-html:能解析html语法的文本 4.v-once:处理的标签的内容只能被解析一次 ...

  2. BZOJ 2157: 旅游 (树链剖分+线段树)

    树链剖分后线段树维护区间最大最小值与和. 支持单点修改与区间取反. 直接写个区间取反标记就行了.线段树板题.(200行6000B+ 1A警告) #include <cstdio> #inc ...

  3. Vim常用插件命令手册

    此文章记录了,笔者使用的插件中的主要命令. junegunn/vim-plug :PlugInstall 安装插件 :PlugClean 清理插件 :PlugUpgrade 升级插件管理器 :Plug ...

  4. win10本机安装rabbitMQ

    在win10环境下安装RabbitMQ的步骤 第一步:下载并安装erlang 原因:RabbitMQ服务端代码是使用并发式语言Erlang编写的,安装Rabbit MQ的前提是安装Erlang. 下载 ...

  5. delphi将一个list中包含的元素,从另一个中删除,如果在另一个中存在的话

    Function StrList_Del(StrList,DelStrList:String):String; //将DelStrList中包含的元素,从Strlist中删除,如果在Strlist中存 ...

  6. Spring——代理工厂实现增强

    借助Spring IOC的机制,为ProxyFactory代理工厂的属性实现依赖注入,这样做的优点是可配置型高,易用性好. 1.创建抽象主题 public interface ProService { ...

  7. find命令不递归查询子目录

    [root@dbrg-2 test]# find .  ! -name "." -type d -prune -o -type f -name "*.jpg" ...

  8. Mac 10.15 关闭SIP

    升级Mac后SIP开启了,根目录不能创建文件了 关闭 sip,终端输入 sudo mount -uw / 在我们开发过程中,有时候我们安装一些工具软件需要将文件拷贝到系统限制更改的文件夹中,甚至有时需 ...

  9. 黑马在线教育项目---15-16、datatables插件

    黑马在线教育项目---15-16.datatables插件 一.总结 一句话总结: datatables插件也比较好用,引入好插件的js和css后,核心代码也就是插件的初始化,如果要修改配置可以百度 ...

  10. 离线安装nuget包EPPlus

    1先去https://www.nuget.org/packages/EPPlus/4.1.0下载,epplus.4.1.0.nupkg 2找到本地文件位置:H:\DOWNLOAD\ 3在vs的程序包管 ...