HMM-前向后向算法理解与实现(python)

HMM-维特比算法理解与实现(python)

解码问题

  • 给定观测序列 \(O=O_1O_2...O_T\),模型 \(\lambda (A,B,\pi)\),找到最可能的状态序列 \(I^∗=\{i^∗_1,i^∗_2,...i^∗_T\}\)

近似算法

  • 在每个时刻 \(t\) 选择最可能的状态,得到对应的状态序列

根据HMM-前向后向算法计算时刻 \(t\) 处于状态 \(i^*_t\) 的概率:

\[i^∗_t=argmax[\gamma_t(i)],t=1,2,...T\\
\gamma_t(i) = \frac{\alpha_{i}(t) \beta_{i}(t)}{\sum_{i=1}^{N} \alpha_{i}(t) \beta_{i}(t)}
\]

但是无法保证得到的解是全局最优解

维特比算法

维特比算法的基础可以概括为下面三点(来源于吴军:数学之美):

  1. 如果概率最大的路径经过篱笆网络的某点,则从起始点到该点的子路径也一定是从开始到该点路径中概率最大的。

  2. 假定第 t 时刻有 k 个状态,从开始到 t 时刻的 k 个状态有 k 条最短路径,而最终的最短路径必然经过其中的一条。

  3. 根据上述性质,在计算第 t+1 时刻的最短路径时,只需要考虑从开始到当前的k个状态值的最短路径和当前状态值到第 t+1 时刻的最短路径即可。如求t=3时的最短路径,等于求t=2时,从起点到当前时刻的所有状态结点的最短路径加上t=2t=3的各节点的最短路径。

通俗理解维特比算法,对上面三点加深理解

假如你从S和E之间找一条最短的路径,最简单的方法就是列出所有可能的路径 (\(O(T^N)\)),选出最小的,显然时间复杂度太高。怎么办?(摘自[3])

使用维特比算法

S到A列的路径有三种可能:S-A1,S-A2,S-A3,如下图

S-A1,S-A2,S-A3 中必定有一个属于全局最短路径。继续往右,到了B列

对B1:

会产生3条路径:

S-A1-B1,S-A2-B1,S-A3-B1

假设S-A3-B1是最短的一条,删掉其他两条。得到

对B2:

会产生3条路径:

S-A1-B2,S-A2-B2,S-A3-B2

假设S-A1-B2是最短的一条,删掉其他两条。得到

对B3:

会产生3条路径:

S-A1-B3,S-A2-B3,S-A3-B3

假设S-A2-B3是最短的一条,删掉其他两条。得到

现在我们看看对B列的每个节点有哪些,回顾维特比算法第二点

假定第 t 时刻有 k 个状态,从开始到 t 时刻的 k 个状态有 k 条最短路径,而最终的最短路径必然经过其中的一条

B列有三个节点,所以会有三条最短路径,最终的最短路径一定会经过其中一条。如下图

同理,对C列,会得到三条最短路径,如下图

到目前为止,仍然无法确定哪条属于全局最短。最后,我们继续看E节点

最终发现最短路径为S-A1-B2-C3-E

数学描述

在上述过程中,对每一列(每个时刻)会得到对应状态数的最短路径。在数学上如何表达?记录路径的最大概率值 $ \delta_t(i)$ 和对应路径经过的节点 \(\psi_t(i)\)。

定义在时刻 \(t\) 状态为 \(i\) 的所有单条路径中概率最大值为

\[\delta_{t}(i)=\max _{i_{1}, i_{2}, \ldots, i_{t-1}} P\left(i_{t}=i, i_{t-1}, \ldots, i_{1}, o_{t}, \ldots, o_{1} | \lambda\right), i=1,2, \ldots, N
\]

递推公式

\[\begin{aligned} \delta_{t+1}(i) &=\max _{i_{1}, i_{2}, \ldots, i_{t}} P\left(i_{t+1}=i, i_{t}, \ldots, i_{1}, o_{t+1}, \ldots, o_{1} | \lambda\right) \\ &=\max _{1 \leq j \leq N}\left[\delta_{t}(j) a_{j i}\right] b_{i}\left(o_{t+1}\right), i=1,2, \ldots, N ; t=1,2, \ldots, T-1 \end{aligned}
\]

定义在时刻 \(t\) 状态为 \(i\) 的所有单条路径中,概率最大路径的第 \(t - 1\) 个节点为

\[\psi_{t}(i)=\arg \max _{1 \leq j \leq N}\left[\delta_{t-1}(j) a_{j i}\right], i=1,2, \ldots, N
\]

维特比算法步骤:

​ step1:初始化

\[\begin{aligned}&\delta_{1}(i)=\pi_{i} b_{i}\left(o_{1}\right), i=1,2, \ldots, N\\&\psi_{1}(i)=0, i=1,2, \ldots, N\\\end{aligned}
\]

​ step2:递推,对 \(t=2,3,...,T\)

\[\delta_{t}(i)=\max _{1 \leq j \leq N}\left[\delta_{t-1}(j) a_{j i}\right] b_{i}\left(o_{t}\right), i=1,2, \ldots, N \\\psi_{t}(i)=\arg \max _{1 \leq j \leq N}\left[\delta_{t-1}(j) a_{j i}\right], i=1,2, \ldots, N \\
\]

​ step3:计算时刻 \(T\) 最大的 \(\delta_T(i)\) ,即为最可能隐藏状态序列出现的概率。计算时刻\(T\)最大的 \(\psi_T(i)\) ,即为时刻\(T\)最可能的隐藏状态。

\[P^{*}=\max _{1 \leq i \leq N} \delta_{T}(i) \quad i_{T}^{*}=\arg \max _{1 \leq i \leq N} \delta_{T}(i)
\]

​ step4:最优路径回溯,对\(t=T-1,...,1\)

\[i_{t}^{*}=\psi_{t+1}\left(i_{t+1}^{*}\right)\\I^*=(i_{1}^{*},i_{2}^{*},...,i_{T}^{*})
\]

代码实现

假设从三个 袋子 {1,2,3}中 取出 4 个球 O={red,white,red,white},模型参数\(\lambda = (A,B,\pi)\) 如下,计算状态序列,即取出的球来自哪个袋子

#状态 1 2 3
A = [[0.5,0.2,0.3],
[0.3,0.5,0.2],
[0.2,0.3,0.5]] pi = [0.2,0.4,0.4] # red white
B = [[0.5,0.5],
[0.4,0.6],
[0.7,0.3]]
def hmm_viterbi(A,B,pi,O):
T = len(O)
N = len(A[0]) delta = [[0]*N for _ in range(T)]
psi = [[0]*N for _ in range(T)] #step1: init
for i in range(N):
delta[0][i] = pi[i]*B[i][O[0]]
psi[0][i] = 0 #step2: iter
for t in range(1,T):
for i in range(N):
temp,maxindex = 0,0
for j in range(N):
res = delta[t-1][j]*A[j][i]
if res>temp:
temp = res
maxindex = j delta[t][i] = temp*B[i][O[t]]#delta
psi[t][i] = maxindex #step3: end
p = max(delta[-1])
for i in range(N):
if delta[-1][i] == p:
i_T = i #step4:backtrack
path = [0]*T
i_t = i_T
for t in reversed(range(T-1)):
i_t = psi[t+1][i_t]
path[t] = i_t
path[-1] = i_T return delta,psi,path 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]]
pi = [0.2,0.4,0.4]
O = [0,1,0,1]
hmm_viterbi(A,B,pi,O)

结果

references:

[1]https://www.cnblogs.com/kaituorensheng/archive/2012/12/04/2802140.html

[2] https://blog.csdn.net/hudashi/java/article/details/87875259

[3] https://www.zhihu.com/question/20136144

HMM-维特比算法理解与实现(python)的更多相关文章

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

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

  2. HMM——维特比算法(Viterbi algorithm)

    1. 前言维特比算法针对HMM第三个问题,即解码或者预测问题,寻找最可能的隐藏状态序列: 对于一个特殊的隐马尔可夫模型(HMM)及一个相应的观察序列,找到生成此序列最可能的隐藏状态序列. 也就是说给定 ...

  3. 详解隐马尔可夫模型(HMM)中的维特比算法

    笔记转载于GitHub项目:https://github.com/NLP-LOVE/Introduction-NLP 4. 隐马尔可夫模型与序列标注 第3章的n元语法模型从词语接续的流畅度出发,为全切 ...

  4. 隐马尔科夫模型HMM(四)维特比算法解码隐藏状态序列

    隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数 隐马尔科夫模型HMM(四)维特比算法解码隐藏状态 ...

  5. 维特比算法Python实现

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

  6. viterbi维特比算法和隐马尔可夫模型(HMM)

    隐马尔可夫模型(HMM) 原文地址:http://www.cnblogs.com/jacklu/p/7753471.html 本文结合了王晓刚老师的ENGG 5202 Pattern Recognit ...

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

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

  8. HMM-前向后向算法理解与实现(python)

    目录 基本要素 HMM三大问题 概率计算问题 前向算法 后向算法 前向-后向算法 基本要素 状态 \(N\)个 状态序列 \(S = s_1,s_2,...\) 观测序列 \(O=O_1,O_2,.. ...

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

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

随机推荐

  1. python爬虫实例,一小时上手爬取淘宝评论(附代码)

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 1 明确目的 通过访问天猫的网站,先搜索对应的商品,然后爬取它的评论数据. ...

  2. prefetch 和 preload 及 webpack 的相关处理

    使用预取和预加载是网站性能和用户体验提升的一个很好的途径,本文介绍了使用 prefetch 和 prefetch 进行预取和预加载的方法,并使用 webpack 进行实现 Link 的链接类型 < ...

  3. MapReduce基本认识

    MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算. 主要由Split.Map.Partition.Sort.Combine(需要自己写).Merge.Reduce组成,一般来 ...

  4. win10好用的桌面工具分享+网盘下载链接

    1.Everything Everything是voidtools开发的一款文件搜索工具,官网描述为“基于名称实时定位文件和目录(Locate files and folders by name in ...

  5. js 实现淘宝放大镜功能,可更改配置参数 带完整版解析代码[magnifier.js]

    前言:         本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽.         本篇文章为您分析一下原生JS写淘宝放大镜效果 基本功能: 运 ...

  6. Linux发送邮件命令mail,mutt

    邮件常常是Linux下监控报警手段之一.Linux下的mail命令可以方便,快速的完成发送邮件. 1. Linux发邮件2种常见客户端命令 1.1 mail命令(推荐) 语法: 无邮件正文 mail ...

  7. HTML入门(HB、DW)

    一.文字内容 <b></b>  <strong></strong>     /*加粗 <i></i>   <em>& ...

  8. MyBaties一级缓存

    2019独角兽企业重金招聘Python工程师标准>>> 一.一级缓存简介 在系统代码的运行中,我们可能会在一个数据库会话中,执行多次查询条件完全相同的Sql,鉴于日常应用的大部分场景 ...

  9. USACO Training Section 1.3混合牛奶 Mixing Milk

    题目描述 由于乳制品产业利润很低,所以降低原材料(牛奶)价格就变得十分重要.帮助Marry乳业找到最优的牛奶采购方案. Marry乳业从一些奶农手中采购牛奶,并且每一位奶农为乳制品加工企业提供的价格是 ...

  10. linux多线程同步的四种方式

    1. 在并发情况下,指令执行的先后顺序由内核决定.同一个线程内部,指令按照先后顺序执行,但不同线程之间的指令很难说清楚是哪一个先执行.如果运行的结果依赖于多线程执行的顺序,那么就会形成竞争条件,每次运 ...