在这里插入图片描述

评估问题

隐马尔可夫模型中包含一个评估问题:已知模型参数,计算某一特定输出序列的概率。通常使用forward算法解决。

比如计算活动序列{读书,做清洁,散步,做清洁,散步}出现的概率,就属于评估问题。
如果穷举的话,观察序列会有2(晴or雨)^5种,需要分别计算它们出现的概率,然后找出概率最大的。

穷举法中有很多重复计算,向前算法就是利用已有的结果,减少重复计算。

向前算法借助于一个矩阵Q[LEN][M],其中M是所有隐藏状态的种数,Q[i][j]表示从第0天到第i天,满足观察序列,且第i天隐藏状态为Sj时的所有可能的隐藏序列的概率之和。最终所求结果为Q[LEN-1][0]+…+Q[LEN-1][M-1],即最后一天,所有隐藏状态下,分别满足观察序列的概率值之和。

向前算法

向前变量图示

向后算法

向后算法变量图示

前向-后向算法

解码问题 Viterbi算法

解码问题是:已知模型参数,寻找最可能的能产生某一特定输出序列O(LEN)的隐含状态的序列。通常使用Viterbi算法解决。

观察序列长度为LEN,隐藏状态序列长度是M,如果采用穷举法,就有M^LEN种可能的隐藏状态序列,我们要计算每一种隐藏状态到指定观察序列的概率,最终选择概率最大的。

穷举法中有很多重复计算,Viterbi算法就是利用已有的结果,减少重复计算。跟评估问题非常相似,不同点在于评估算的是和,解码算的是最大值。

Viterbi算法主要就是在计算一个矩阵Q[LEN][M],其中Q[i][j]表示从第0天到第i天,满足观察序列,且第i天隐藏状态为Sj的所有可能的隐藏序列的概率的最大值。另外还要建立一个矩阵Path[LEN][M],用来记录状态序列中某一状态之前最可能的状态。

举个例子,假如指定观察序列是{读书,做卫生,散步,做卫生,散步},求出现此观察序列最可能的状态序列是什么。

Q[0][0]=p(第一天读书 , 第一天晴)=p(天晴)*p(读书|天晴) Path[0][0]=-1;
Q[0][1]=p(第一天读书 , 第一天下雨)=p(下雨)*p(读书|下雨) Path[0][1]=-1;

关键是从第二天开始,Q[1][0]表示:满足“第一天读书 且 第二做清洁 且 第二天晴”的所有可能的隐藏序列的概率的最大值。那么满足“第一天读书 且 第二做清洁 且 第二天晴”的所有可能的隐藏序列有哪些呢?

第二天是必须满足晴天的,第二天之前的状态可以任意变。则所有可能的隐藏序列就是“晴 晴”和“雨 晴”。实际上考虑第三天(及第三天以后)时,并不需要考虑“所有”可能的隐藏序列,而只需要考虑第二天的不同状态取值,这是因为马氏过程有无后效性–t时刻所处状态的概率只和t-1时刻的状态有关,而与t-1时刻之前的状态无关。

Q[1][0]=

max{ p(第一天晴, 第一天读书 , 第二天晴, 第二天做卫生) ,p(第一天下雨 且 第一天读书 且 第二天晴, 第二天做卫生) }

=max{ p(第一天读书, 第一天晴)*p(天晴转天晴),p(第一天读书, 第一天下雨)*p(下雨转天晴) } * p(做卫生|天晴)

=max{ Q[0][0]*A[0][0],Q[0][1]*A[1][0] } * B[0][2]

假如Q[0][0]*A[0][0] < Q[0][1]*A[1][0],则Path[1][0]=1;假如Q[0][0]*A[0][0] > Q[0][1]*A[1][0],则Path[1][0]=0。

Q[1][1]= ……
…… ……
可以看到计算Q矩阵的每i行时都用到了第i-1行的结果。

Viterbi算法词性标注

问题:已知已标记好词性的语料库,现给定一个句子S,求这个句子的词性Z。

根据朴素贝叶斯:P(词性|单词) = P(单词|词性)P(词性) 得到公式:

我们称给定句子为观测序列,需要求的词性为状态序列,A为观测概率矩阵,B为初始状态,C为状态转移概率矩阵,根据如上公式知道参数 = (A,B,pi),即可求得状态序列。


向前算法代码

#-*-coding:utf-8-*-
__author__ = 'ZhangHe'
def forward(N,M,A,B,P,observed):p = 0.0#观测变量数目LEN = len(observed)#中间概率LEN*MQ = [([0]*N) for i in range(LEN)]#第一个观测变量的概率,隐藏状态的初始概率乘上隐藏状态到观测变量的条件概率。for j in range(N):Q[0][j] = P[j]*B[j][observation.index(observed[0])]#第一个之后的观测变量,首先从前一天的每个隐藏状态,转移到当前隐藏状态的概率求和,然后乘上当前隐藏状态到观测变量的条件概率。for i in range(1,LEN):for j in range(N):sum = 0.0for k in range(N):sum += Q[i-1][k]*A[k][j]Q[i][j] = sum * B[j][observation.index(observed[i])]for i in range(N):p += Q[LEN-1][i]return p
# 3 种隐藏层状态:sun cloud rain
hidden = []
hidden.append('sun')
hidden.append('cloud')
hidden.append('rain')
N = len(hidden)
# 4 种观察层状态:dry dryish damp soggy
observation = []
observation.append('dry')
observation.append('damp')
observation.append('soggy')
M = len(observation)
# 初始状态矩阵(1*N 第一天是sun,cloud,rain的概率)
P = (0.3,0.3,0.4)
# 状态转移矩阵A(N*N 隐藏层状态之间互相转变的概率)
A=((0.2,0.3,0.5),(0.1,0.5,0.4),(0.6,0.1,0.3))
# 混淆矩阵B(N*M 隐藏层状态对应的观测层状态的概率)
B=((0.1,0.5,0.4),(0.2,0.4,0.4),(0.3,0.6,0.1))
#假设观察到一组序列为observed,输出HMM模型(N,M,A,B,P)产生观察序列observed的概率
observed = ['dry']
print forward(N,M,A,B,P,observed)
observed = ['damp']
print forward(N,M,A,B,P,observed)
observed = ['dry','damp']
print forward(N,M,A,B,P,observed)
observed = ['dry','damp','soggy']
print forward(N,M,A,B,P,observed)

向后算法代码

#-*-coding:utf-8-*-
__author__ = 'ZhangHe'
def forward(N,M,A,B,P,observed):p = 0.0#观察到的状态数目LEN = len(observed)#中间概率LEN*MQ = [([0]*N) for i in range(LEN)]#令最后时刻所有状态的后向变量为1for j in range(N):Q[LEN-1][j] = 1# 最后时刻之前的状态,Q[i][j]=sum(第i天的当前状态Sj转移到第i+1天的状态Sk的转移概率,# 乘上第i+1天的状态Sk生成观测变量Oi+1观测概率,再乘上第i+1天Sk状态的概率   for  k  in   N)for i in range(LEN-2,-1,-1):for j in range(N):sum = 0.0for k in range(N):sum += A[j][k]*B[k][observation.index(observed[i+1])]*Q[i+1][k]Q[i][j] = sum for i in range(N):p += Q[0][i]return p
# 3 种隐藏层状态:sun cloud rain
hidden = []
hidden.append('sun')
hidden.append('cloud')
hidden.append('rain')
N = len(hidden)
# 4 种观察层状态:dry dryish damp soggy
observation = []
observation.append('dry')
observation.append('damp')
observation.append('soggy')
M = len(observation)
# 初始状态矩阵(1*N第一天是sun,cloud,rain的概率)
P = (0.3,0.3,0.4)
# 状态转移矩阵A(N*N 隐藏层状态之间互相转变的概率)
A=((0.2,0.3,0.5),(0.1,0.5,0.4),(0.6,0.1,0.3))
# 混淆矩阵B(N*M 隐藏层状态对应的观察层状态的概率)
B=((0.1,0.5,0.4),(0.2,0.4,0.4),(0.3,0.6,0.1))
#假设观察到一组序列为observed,输出HMM模型(N,M,A,B,P)产生观察序列observed的概率
observed = ['dry']
print(forward(N,M,A,B,P,observed))
observed = ['damp']
print(forward(N,M,A,B,P,observed))
observed = ['dry','damp']
print(forward(N,M,A,B,P,observed))
observed = ['dry','damp','soggy']
print(forward(N,M,A,B,P,observed))

viterbi算法代码

def viterbi(N,M,A,B,P,hidden,observed):sta = []LEN = len(observed)Q = [([0]*N) for i in range(LEN)]path = [([0]*N) for i in range(LEN)]#第一天计算,状态的初始概率*隐藏状态到观察状态的条件概率for j in range(N):Q[0][j]=P[j]*B[j][observation.index(observed[0])]path[0][j] = -1# 第一天以后的计算# 前一天的每个状态转移到当前状态的概率最大值# *# 隐藏状态到观察状态的条件概率for i in range(1,LEN):for j in range(N):max = 0.0index = 0for k in range(N):if(Q[i-1][k]*A[k][j] > max):max = Q[i-1][k]*A[k][j]index = kQ[i][j] = max * B[j][observation.index(observed[i])]path[i][j] = index#找到最后一天天气呈现哪种观察状态的概率最大max = 0.0idx = 0for i in range(N):if(Q[LEN-1][i]>max):max = Q[LEN-1][i]idx = iprint "最可能隐藏序列的概率:"+str(max)sta.append(hidden[idx])#逆推回去找到每天出现哪个隐藏状态的概率最大for i in range(LEN-1,0,-1):idx = path[i][idx]sta.append(hidden[idx])sta.reverse()return sta;
# 3 种隐藏层状态:sun cloud rain
hidden = []
hidden.append('sun')
hidden.append('cloud')
hidden.append('rain')
N = len(hidden)
# 4 种观察层状态:dry dryish damp soggy
observation = []
observation.append('dry')
observation.append('damp')
observation.append('soggy')
M = len(observation)
# 初始状态矩阵(1*N第一天是sun,cloud,rain的概率)
P = (0.3,0.3,0.4)
# 状态转移矩阵A(N*N 隐藏层状态之间互相转变的概率)
A=((0.2,0.3,0.5),(0.1,0.5,0.4),(0.6,0.1,0.3))
# 混淆矩阵B(N*M 隐藏层状态对应的观察层状态的概率)
B=((0.1,0.5,0.4),(0.2,0.4,0.4),(0.3,0.6,0.1))
#假设观察到一组序列为observed,输出HMM模型(N,M,A,B,P)产生观察序列observed的概率
observed = ['dry','damp','soggy']
print viterbi(N,M,A,B,P,hidden,observed)

参考:
http://www.cnblogs.com/CheeseZH/ 作者:ZH奶酪——张贺
博客园(华夏35度)http://www.cnblogs.com/zhangchaoyang 作者:张朝阳

HMM模型 forward backward viterbi算法相关推荐

  1. 隐马尔可夫模型中的Viterbi算法zz

    隐马尔可夫模型中的Viterbi算法zz 这篇文章简单描述一下Viterbi算法--一年之前我听过它的名字,直到两周之前才花了一点时间研究了个皮毛,在这里做个简单检讨.先用一句话来简单描述一下:给出一 ...

  2. 详细推导HMM模型之:EM算法

    详细推导HMM模型+直观例子+项目应用(三):EM算法进行参数估计 HMM模型介绍 HMM参数估计 两种使用情景 需要EM的情景 EM算法求解HMM中的参数 回顾前向和后向算法 A.B.π\piπ的估 ...

  3. 隐马尔科夫模型(HMM)模型训练:Baum-Welch算法

    在上一篇博客中隐马尔科夫模型(HMM)原理详解,对隐马尔科夫模型的原理做了详细的介绍.今天,我们要对其中的模型训练算法Baum-Welch做一个实现,Baum-Welch算法可以在不知道状态序列的情况 ...

  4. 中文分词和HMM模型

    目录 一.中文分词 1.1 切分方案的标识 数据结构 1.2 Trie树 1.3 DAG(有向无环图) 1.4 概率模型 N元模型 1.5 jieba分词 中文分词流程 jieba登录词词库加载 ji ...

  5. python自然语言处理实战核心技术与算法——HMM模型代码详解

    本人初学NLP,当我看着<python自然语言处理实战核心技术与算法>书上这接近200行的代码看着有点头皮发麻,于是我读了接近一天基本把每行代码的含义给读的个七七八八,考虑到可能会有人和我 ...

  6. 中文分词之HMM模型详解

    文章转载自: http://yanyiwu.com/work/2014/04/07/hmm-segment-xiangjie.html HMM(Hidden Markov Model): 隐式马尔科夫 ...

  7. viterbi算法通俗理解

    文章目录 viterbi算法是什么 手动理解 缺点分析 算法详解 算法推论 viterbi与隐马尔可夫 隐马尔科夫链的三个基本问题 隐马尔科夫链的五元组 更详细的解释 代码实现 实现 测试 参考 vi ...

  8. 语音识别维特比解码_HMM连续语音识别中Viterbi算法的优化及应用

    HMM 连续语音识别中 Viterbi 算法的优化及应用 袁俊 [期刊名称] <电子技术> [年 ( 卷 ), 期] 2001(028)002 [摘要] 基于 HMM 连续语音识别系统声学 ...

  9. HMM模型与viterbi算法

    2021SC@SDUSC HMM(Hidden Markov Model): 隐式马尔科夫模型.HMM 模型可以应用在很多领域,所以它的模型参数描述一般都比较抽象,HMM 的典型介绍就是这个模型是一个 ...

最新文章

  1. Mysql数据库事务详解
  2. leetcode算法题--除数博弈★
  3. SpringBoot是如何解析HTTP参数的?
  4. 科大星云诗社动态20220103
  5. centos 安装低版本内核_Linux 升级内核
  6. 迪杰斯特拉算法 php,Dijkstra算法的复杂度
  7. 万物互联之~RPC专栏
  8. 熊猫tv新功能介绍_熊猫简单介绍
  9. java jtextfield 事件_java – 处理JTextField中的编辑事件
  10. jquery modile 笔记
  11. keepalived+LVS 详解(2) -- keepalived.conf解析
  12. Codeforces 741D dsu on tree
  13. 034 Rust死灵书之为Vec实现Drain
  14. 进程和线程常见的19个问题
  15. java实现rsa加解密算法_JAVA实现RSA加密解密 非对称算法
  16. 小学二年级计算机课游戏,小学体育课游戏_求10种左右适合小学一二年级学生体育课上做的游戏...
  17. HTML特效代码汇总
  18. 鸿蒙系统网络连接设置ip,网络ip地址错误解决方法
  19. Ansys·Icem·T型喷管的网格生成
  20. 用 python 合并不同传感器返回的轴承信号小波变换时频图

热门文章

  1. 老照片特效 php,ps老照片效果
  2. 服务器红帽操作系统安装,怎么安装red hat操作系统
  3. How to set up the esp-hosted SDK compilation environment for ESP32-C3
  4. 华东理工大学计算机学院考研考什么,华东理工大学计算机专业基础综合2020考研考试大纲...
  5. 计算机毕业设计springboot交通事故档案管理平台ryug8源码+系统+程序+lw文档+部署
  6. 计算机视觉算法实习生:大厂面试经历(百度、京东、滴滴、字节、美团,旷视,快手,小米)
  7. 为什么选择软件测试这个岗位?(面经)
  8. 【原创】Windows Docker 设置阿里云镜像加速
  9. android手机用户,ZDC:2011年Android手机用户使用行为研究报告
  10. 请更换备份电池 pos机_POS机报错58终端无效的快速处理方法!