文章目录

  • 一、理论描述
  • 二、算法描述
  • 三、详例描述
    • 具体过程
      • 分析题目
      • 数据预处理
        • 转移概率矩阵:
        • 发射概率矩阵:
      • HMM+维特比算法进行词性标注
        • 开始进行词性标注:
          • The:
          • bear:
          • is:
          • on:
          • the:
          • move:
          • 标注结果
  • 四、软件演示(完整代码及运行结果)
    • 关键代码
    • 完整代码
    • 运行结果
  • 五、参考链接
    • python实现
    • Java实现

一、理论描述

  • 隐马尔可夫模型是马尔可夫链的一种,它的状态不能直接观察到,但能通过观测向量序列观察到,每个观测向量都是通过某些概率密度分布表现为各种状态,每一个观测向量是由一个具有相应概率密度分布的状态序列产生。所以,隐马尔可夫模型是一个双重随机过程----具有一定状态数的隐马尔可夫链和显示随机函数集。自20世纪80年代以来,HMM被应用于语音识别,取得重大成功。到了90年代,HMM还被引入计算机文字识别和移动通信核心技术“多用户的检测”。HMM在生物信息科学、故障诊断等领域也开始得到应用。

  • HMM 是一个五元组(O,Q,O0,A,B) :
    O:{o1 … ot } 是状态集合,也称为观测序列
    Q:{q1 … qv } 是一组输出结果,也称隐序列
    aij =P(qj |qi ): 转移概率分布
    bij =P(oj |qi ): 发射概率分布
    O0是初始状态,有些还有终止状态

  • 维特比算法是以部分最优去获得全局最优,每个节点保存的是当前节点的局部最优概率,依据最后一个时刻中概率最高的状态,逆向找其路径中的上一个最大部分最优路径,从而找到整个最优路径。

二、算法描述

观察序列长度 T,状态个数N
for 状态s from 1 to N:do//计算每个状态的概率,相当于计算第一观察值的隐状态t=1v[s,1] = a(0,s)*b(O1|s) //初始状态概率 * 发射概率//回溯保存最大概率状态back[s,1]=0
//计算每个观察(词语)取各个词性的概率,保存最大者
for from 观察序列第二个 to T do:for 状态s from 1 to N:do//当前状态由前一个状态*转移*发射(该状态/词性下词t的概率),保存最大者v[s,t]=max v[i,t-1]*a[i,s]*b(Ot | s)//保存回溯点,该点为前一个状态转移到当前状态的最大概率点back[s,t]=arg{1,N} max v[i,t-1]*a(i,s)
//最后
v[T]=max v[T]
back[T] = arg{1,N} max v[T]
//回溯输出隐状态序列

三、详例描述

题目:

假定初始概率为:
AT BEZ IN NN VB PERIOD
[0.2 0.1 0.1 0.2 0.3 0.1]

依据以上两个表格,使用 HMM 和 和 Viterbi 算法标注下面的句子。

The bear is on the move

具体过程

分析题目

分析该例子,可知

观测序列O为: O:{The, bear, is, on, the, move}
隐序列Q为:Q:{AT,BEZ,IN,NN,VB,PERIOD}

假设:

数据预处理

上面的两个原始表格中:
第一个表格在进行数据平滑(表格中每个数+1)后、再对每个数以该表格各个数相加的即得到 转移概率矩阵

而第二个表格需要先将表格转置,再对数据进行平滑(表格中每个数+1)、将每个数以该表格各个数相加的即得到发射概率矩阵

将第一个表格中数据平滑后得到如下矩阵:

将第二个表格中数据(进行转置处理后)平滑后得到如下矩阵:

将处理后的两个矩阵中数值分别求和后,将每个单元格内的数以各自对应矩阵求和后的值,得到转移概率矩阵和发射概率矩阵:

转移概率矩阵:

发射概率矩阵:

解释:
上面两个矩阵中,
例如转移概率Z[AT][AT]=4.47E-06,Z[BEZ][IN]=0.00191,
发射概率F[AT][BEAR]=7.4551E-06,F[VB][MOVE]=0.000999

HMM+维特比算法进行词性标注

假设:

初始概率P0
概率P
转移概率Z
发射概率F

隐序列的初始概率为:

表格整体结构:

开始进行词性标注:

The:

bear:


is:


on:


the:


move:


标注结果

由上述过程可知{The, bear, is, on, the, move}最后的标注结果为:

[‘the/AT’, ‘bear/NN’, ‘is/BEZ’, ‘on/IN’, ‘the/AT’, ‘move/NN’]

四、软件演示(完整代码及运行结果)

关键代码

维特比算法相关关键代码:

def vierbi(obs, states, start_p, trans_p, emit_p):""":param obs:     观察序列    K:param states:  隐藏状态    S:param start_p: 初始概率    π:param trans_p: 转移概率    A:param emit_p:  发射概率    B:return:"""# 路径概率表 V[时间][隐状态] = 概率V = [{}]# 一个中间变量,代表当前状态是哪个隐状态path = {}# 初始化初始状态 t=0for y in states:V[0][y] = start_p[y] * emit_p[y][obs[0]]path[y] = [y]# 对t>0 跑一遍维特比算法for t in range(1, len(obs)):V.append({})newpath = {}for y in states:# 概率 隐状态 =  前状态是y0的概率 * y0转移到y的概率 * y表现为当前状态的概率(prob, state) = max([(V[t - 1][y0] * trans_p[y0][y] * emit_p[y][obs[t]], y0) for y0 in states])# 记录最大概率V[t][y] = prob# 记录路径newpath[y] = path[state] + [y]# 不需要保存旧路径path = newpathprint_dptable(V)(prob, state) = max([(V[len(obs) - 1][y], y) for y in states])return prob, path[state]

完整代码

(python实现)

# -*- coding:utf-8 -*-"""
维特比算法的实现
HMM 五个重要元素
S 隐藏序列的集合
K 输出状态或观测状态的集合
π对应隐藏状态的的初始概率
A 隐藏状态的转移概率 是一个N*M的概率矩阵
B 隐藏状态到观测状态的混淆矩阵,是一个N*M的发射概率的矩阵
"""# 隐藏序列 S
# states = ("Rainy", "Sunny")
states = ('AT', 'BEZ', 'IN','NN','VB','PERIOD')# 观测序列 K
# observations = ('walk', 'shop', 'clean')
observations = ("the", "bear","is","on","the","move")# print(observations)
# print(result)
# 初始概率 π
# start_probability = {'Rainy': 0.6, "Sunny": 0.4}
start_probability = {'AT':0.2, 'BEZ':0.1, 'IN':0.1,'NN':0.2,'VB':0.3,'PERIOD':0.1}sumA = 223499
# 转移概率 A
transition_probability = {# 'Rainy': {"Rainy": 0.7, "Sunny": 0.3},# "Sunny": {"Rainy": 0.4, "Sunny": 0.6}"AT": {'AT': 1/sumA, 'BEZ': 1/sumA, 'IN': 1/sumA,'NN': 48636/sumA,'VB': 1/sumA,'PERIOD': 20/sumA},"BEZ": {'AT': 1974/sumA, 'BEZ': 1/sumA, 'IN': 427/sumA,'NN': 188/sumA,'VB': 1/sumA,'PERIOD': 39/sumA},"IN": {'AT': 43323/sumA, 'BEZ': 1/sumA, 'IN': 1326/sumA,'NN': 17315/sumA,'VB': 1/sumA,'PERIOD': 186/sumA},"NN": {'AT': 1068/sumA, 'BEZ': 3721/sumA, 'IN': 42471/sumA,'NN': 11774/sumA,'VB': 615/sumA,'PERIOD': 21393/sumA},"VB": {'AT': 6073/sumA, 'BEZ': 43/sumA, 'IN': 4759/sumA,'NN': 1477/sumA,'VB': 130/sumA,'PERIOD': 1523/sumA},"PERIOD": {'AT': 8017/sumA, 'BEZ': 76/sumA, 'IN': 4657/sumA,'NN': 1330/sumA,'VB': 955/sumA,'PERIOD': 1/sumA}
}
# print(transition_probability['AT']['AT'])sumB = 134136
# 发射概率  B
emission_probability = {"AT": {'the': 69017/sumB, 'bear': 1/sumB, 'is': 1/sumB,'on': 1/sumB,'the': 69017/sumB,'move': 1/sumB},"BEZ": {'the': 1/sumB, 'bear': 1/sumB, 'is': 10066/sumB,'on': 1/sumB,'the': 1/sumB,'move': 1/sumB},"IN": {'the': 1/sumB, 'bear': 1/sumB, 'is': 1/sumB,'on': 5485/sumB,'the': 1/sumB,'move': 1/sumB},"NN": {'the': 1/sumB, 'bear': 11/sumB, 'is': 1/sumB,'on': 1/sumB,'the': 1/sumB,'move': 37/sumB},"VB": {'the': 1/sumB, 'bear': 44/sumB, 'is': 1/sumB,'on': 1/sumB,'the': 1/sumB,'move': 134/sumB},"PERIOD": {'the': 1/sumB, 'bear': 1/sumB, 'is': 1/sumB,'on': 1/sumB,'the': 1/sumB,'move': 1/sumB}
}def print_dptable(V):print("     ")for i in range(len(V)): print("%7d" % i, end="")print()for y in V[0].keys():# print("%.5s: " % y, end=" ")print("%-.30s: " % y, end=" ")for t in range(len(V)):# print("%.7s" % V[t][y], end=" ")print("%-.30s" % V[t][y], end=" ")print()def vierbi(obs, states, start_p, trans_p, emit_p):""":param obs:     观察序列    K:param states:  隐藏状态    S:param start_p: 初始概率    π:param trans_p: 转移概率    A:param emit_p:  发射概率    B:return:"""# 路径概率表 V[时间][隐状态] = 概率V = [{}]# 一个中间变量,代表当前状态是哪个隐状态path = {}# 初始化初始状态 t=0for y in states:V[0][y] = start_p[y] * emit_p[y][obs[0]]path[y] = [y]# 对t>0 跑一遍维特比算法for t in range(1, len(obs)):V.append({})newpath = {}for y in states:# 概率 隐状态 =  前状态是y0的概率 * y0转移到y的概率 * y表现为当前状态的概率(prob, state) = max([(V[t - 1][y0] * trans_p[y0][y] * emit_p[y][obs[t]], y0) for y0 in states])# 记录最大概率V[t][y] = prob# 记录路径newpath[y] = path[state] + [y]# 不需要保存旧路径path = newpathprint_dptable(V)(prob, state) = max([(V[len(obs) - 1][y], y) for y in states])return prob, path[state]# print(vierbi(observations,
#                   states,
#                   start_probability,
#                   transition_probability,
#                   emission_probability
#                   ))result_org = observations
tag = vierbi(observations,states,start_probability,transition_probability,emission_probability)
print(tag)
result = []
for i in range(len(result_org)):result.append(result_org[i]+"/"+tag[1][i])print("例句:")
print(observations)
print("标注结果:")
print(result)

运行结果

例句(‘the’, ‘bear’, ‘is’, ‘on’, ‘the’, ‘move’)的标注结果为:
[‘the/AT’, ‘bear/NN’, ‘is/BEZ’, ‘on/IN’, ‘the/AT’, ‘move/NN’]

五、参考链接

python实现

viterbi-algorithm 维特比算法的例子解析

Java实现

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

隐马尔可夫模型HMM+维特比算法(Viterbi Algorithm)进行词性标注代码实现(自然语言处理课程第二次作业)相关推荐

  1. 机器学习知识点(二十四)隐马尔可夫模型HMM维特比Viterbi算法Java实现

    1.隐马尔可夫模型HMM    学习算法,看中文不如看英文,中文喜欢描述的很高深.    http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/ht ...

  2. 【Python自然语言处理】隐马尔可夫模型中维特比(Viterbi)算法解决商务选择问题实战(附源码 超详细必看)

    需要源码请点赞关注收藏后评论区留言私信~~~ 一.统计分词 统计分词基本逻辑是把每个词语看做由单字组成,利用统计学原理计算连接字在不同文本中出现的次数,以此判断相连字属于特定词语的概率. 二.隐马尔可 ...

  3. 隐马尔科夫模型和维特比算法

    隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它用来描述一个含有隐含未知参数的马尔可夫过程.其难点是从可观察的参数中确定该过程的隐含参数.然后利用这些参数来作进一步的分析 ...

  4. 【隐马尔可夫模型】维特比算法matlab实现

    %隐马尔可夫模型维特比算法:求最优路径I %输入模型(A,B,pai),观测O=(o1,o2,...oT) %A状态转移概率矩阵 %B观测概率矩阵 %pai初始状态概率矩阵 %T总时刻,N状态数 %Q ...

  5. 隐马尔科夫模型HMM之Baum-Welch算法Python代码实现

    ☕️ 本文系列文章汇总: (1)HMM开篇:基本概念和几个要素 (2)HMM计算问题:前后向算法 代码实现 (3)HMM学习问题:Baum-Welch算法 (4)  HMM预测问题:维特比算法 本篇算 ...

  6. 中文分词与马尔科夫模型之二:隐马尔科夫模型与维特比

    转载自:http://blog.sina.com.cn/s/blog_68ffc7a40100uebv.html 前面一篇博客讲到了中文分词的机械分词算法,这种算法实现相对比较简单,但是分词效果还是有 ...

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

    阅读目录 隐马尔可夫模型(HMM) 回到目录 隐马尔可夫模型(HMM) 原文地址:http://www.cnblogs.com/jacklu/p/7753471.html 本文结合了王晓刚老师的ENG ...

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

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

  9. 用隐马尔可夫模型(HMM)做命名实体识别——NER系列(二)

    上一篇文章里<用规则做命名实体识别--NER系列(一)>,介绍了最简单的做命名实体识别的方法–规则.这一篇,我们循序渐进,继续介绍下一个模型--隐马尔可夫模型. 隐马尔可夫模型,看上去,和 ...

最新文章

  1. Redux 入门教程(二):中间件与异步操作
  2. Android 再谈handler
  3. 对于java反射的理解
  4. 全国计算机等级考试暨南大学,9月暨南大学计算机等级考试报名时间通知
  5. keil debug如何在watch直接修改变量值_python日志记录系列教程,内置logging模块(一),直接使用logging模块的基础日志记录
  6. Windows环境下基于python3 + selenium构建网络爬虫
  7. 新能源维修和计算机应用哪个好,在买新能源车之前 这些事你应该先知道
  8. Linux中inode值是什么?
  9. OpenCV-计算二维矢量幅值cv::magnitude
  10. 模拟登陆webqq总结(一)
  11. mysql添加开机自启_初始化mysql并设置开机自动启动
  12. thinkphp 5 验证码错误,可能与session保存路径不同有关
  13. stony大学计算机科学找工作,如果我本科四年在加州大学洛杉矶分校安德森商学院就读,毕业后我实在当地找工作好还是回国比较好?哪个待...
  14. 关于if 判断中null为什写前边和在使用equals方法进行判断是为什么要 “1“.equals(str)
  15. WSUS将Hyper-V Server 2019视为Windows 10
  16. 推荐8款插件,浏览器使用体验上升500%
  17. Let the Flames Begin(约瑟夫环)
  18. css基础--弹性布局
  19. 硬盘数据恢复基础知识:二次开盘
  20. potplayer 播放下一个视频时,保持当前屏幕大小不变(锁定播放屏幕尺寸)

热门文章

  1. 谷歌浏览器登录不了账号_苹果账号也要开发“一键登录”,位置还要在谷歌和脸书上面?...
  2. ESP32 Secure Boot和Flash加密
  3. C++中std的使用和作用
  4. CNN+LSTM:看图说话
  5. C++作业:乘法口算练习
  6. 国内40多家金融机构数据被窃,多家知名基金上榜
  7. Flash幻灯片制作步骤
  8. 用 Java 做个“你画手机猜”的安卓小游戏
  9. 模型交易平台产品介绍
  10. Fluent UDF教程——壁面温度设定,实现动态高斯热源的施加,DEFINE_PROFILE宏讲解