用隐马尔可夫模型(HMM)做命名实体识别——NER系列(一)
原博python2写的,文末是我改的python3代码
隐马尔可夫模型,看上去,和序列标注问题是天然适配的,所以自然而然的,早期很多做命名实体识别和词性标注的算法,都采用了这个模型。
这篇文章我将基于码农场的这篇文章《层叠HMM-Viterbi角色标注模型下的机构名识别》,来做解读。但原文中的这个算法实现是融入在HanLP里面的。不过他也有相应的训练词典,所以我在这篇文章里面也给出一个python实现,做一个简单的单层HMM模型,来识别机构名。
代码地址:https://github.com/lipengfei-558/hmm_ner_organization
1.隐马尔可夫模型(HMM)
隐马尔可夫模型(Hidden Markov Model,HMM),是一个统计模型。
关于这个模型,这里有一系列很好的介绍文章:http://www.52nlp.cn/category/hidden-markov-model
隐马尔可夫模型有三种应用场景,我们做命名实体识别只用到其中的一种——求观察序列的背后最可能的标注序列。
即根据输入的一系列单词,去生成其背后的标注,从而得到实体。
2.在序列标注中应用隐马尔可夫模型
HMM中,有5个基本元素:{N,M,A,B,π},我结合序列标志任务对这5个基本元素做一个介绍:
- N:状态的有限集合。在这里,是指每一个词语背后的标注。
- M:观察值的有限集合。在这里,是指每一个词语本身。
- A:状态转移概率矩阵。在这里,是指某一个标注转移到下一个标注的概率。
- B:观测概率矩阵,也就是发射概率矩阵。在这里,是指在某个标注下,生成某个词的概率。
- π:初始概率矩阵。在这里,是指每一个标注的初始化概率。
而以上的这些元素,都是可以从训练语料集中统计出来的。最后,我们根据这些统计值,应用维特比(viterbi)算法,就可以算出词语序列背后的标注序列了。
命名实体识别本质上就是序列标注,只需要自己定义好对应的标签以及模式串,就可以从标注序列中提取出实体块了。
3.实战:用HMM实现中文地名识别
3.1 参考论文以及网站
- 张华平, 刘群. 基于角色标注的中国人名自动识别研究[J]. 计算机学报, 2004, 27(1):85-91.
- 俞鸿魁, 张华平, 刘群. 基于角色标注的中文机构名识别[C]// Advances in Computation of Oriental Languages–Proceedings of the, International Conference on Computer Processing of Oriental Languages. 2003.
- 俞鸿魁, 张华平, 刘群,等. 基于层叠隐马尔可夫模型的中文命名实体识别[J]. 通信学报, 2006, 27(2):87-94.
码农场:层叠HMM-Viterbi角色标注模型下的机构名识别
3.2 任务
命名实体识别之中文机构名的识别。
3.3 语料
HanLP(https://github.com/hankcs/HanLP/releases)提供的语料:
我用的是data-for-1.3.3.zip
,百度网盘下载地址:
https://pan.baidu.com/s/1o8Rri0y
下载后解压,我们要用的语料路径如下:
\data-for-1.3.3\data\dictionary\organization
其中,里面有两个我们要用到的语料文件,nt.txt
和nt.tr.txt
。这两个文件的数据统计自人民日报语料库。
① nt.txt:
词语标注统计词典,比如里面有一行是这样的:
会议 B 163 C 107 A 10
意思是,会议这个词作为B标签出现了163次,作为C标签出现了107次,作为A标签出现了10次.
② nt.tr.txt:
标签转移矩阵。如下图:
即,每一个标签转移到另一个标签的次数。比如第二行第四列的19945,代表着【A标签后面接着是C标签】出现了19945次。
以上语料我都提取出来放到代码目录的./data
下了。
3.4 代码实现
代码的思路很直观,只要按照上面第2部分所说的,准备好5元组数据,然后用viterbi算法解码即可。
3.4.1 N:状态的有限集合
在机构名识别的这个任务中,论文《基于角色标注的中文机构名识别》把状态(角色)定义为以下集合:
然而在HanLP的语料中,只有以下的标签,有多出来的,又不一样的:
A,B,C,D,F,G,I,J,K,L,M,P,S,W,X,Z
经过我的整理,完整的状态(角色)集合如下:
角色 | 意义 | 例子 |
A | 上文 | 参与亚太经合组织的活动 |
B | 下文 | 中央电视台报道 |
X | 连接词 | 北京电视台和天津电视台 |
C | 特征词的一般性前缀 | 北京电影学院 |
F | 特征词的人名前缀 | 何镜堂纪念馆 |
G | 特征词的地名性前缀 | 交通银行北京分行 |
K | 特征词的机构名、品牌名前缀 |
中共中央顾问委员会
美国摩托罗拉公司 |
I | 特征词的特殊性前缀 |
中央电视台
中海油集团 |
J | 特征词的简称性前缀 | 巴政府 |
D | 机构名的特征词 | 国务院侨务办公室 |
Z | 非机构成分 | |
L | 方位词 |
上游
东 |
M | 数量词 | 36 |
P | 数量+单位(名词) |
三维
两国 |
W | 特殊符号,如括号,中括号 |
()
【】 |
S | 开始标志 | 始##始 |
本程序以上面我整理的这个表格的状态角色为准(因为HanLP的语料词典里面就是这样定义的)。
3.4.2 M:观察值的有限集合
在这里,观察值就是我们看到的每个词。
不过有一个地方要注意一下,在语料词典nt.txt
中,除了所有词语之外,还有下面8个特殊词语:
- 始##始
- 末##末
- 未##串
- 未##人
- 未##团
- 未##地
- 未##数
- 未##时
这些词语可以在层叠HMM中发挥作用,加进去可以提高识别精度,因为很多机构名里面都有人名和地名。
在使用我的这份代码之前,你可以用分词工具先识别出相关的词性,然后将对应命中的词语替换为上面的8个特殊词语,再调用函数,精确率会大大提高。
3.4.3 A:状态转移概率矩阵
在这里,它是指某一个标注转移到下一个标注的概率。
generate_data.py
的generate_transition_probability()
函数就是干这事的,它会生成一个transition_probability.txt
,即转移概率矩阵。
3.4.4 B:观测概率矩阵(发射概率矩阵)
在这里,他是指在某个标注下,生成某个词的概率。
generate_data.py
的generate_emit_probability()
函数就是干这事的,它会生成一个emit_probability.txt
,即观测概率矩阵(发射概率矩阵)。
3.4.5 π:初始概率矩阵
在这里,它是指每一个标注的初始化概率。
generate_data.py
的genertate_initial_vector()
函数就是干这事的,它会生成一个initial_vector.txt
,即初始概率矩阵。
3.4.6 维特比(viterbi)算法解码
这部分代码是参考《统计方法》里面的实现写的,做了些调整,使之可以适用于这个机构名识别的任务。函数为viterbi()
,位于OrgRecognize.py
里面。
使用这个函数,就能获得最佳标注序列。
3.4.7 匹配标注序列,得到机构名
在3.4.6里面,我们可以得到一个标注序列,哪些标注代表着实体呢?
HanLP作者整理了一个nt.pattern.txt
(我也放置在./data/nt.pattern.txt
下了),里面是所有可能是机构名的序列模式串(有点粗暴,哈哈),然后用Aho-Corasick算法来进行匹配。
为了简单起见突出重点,我的代码实现里,用的是循环遍历匹配,具体的实现在OrgRecognize.py
里面的get_organization
,函数的作用是,输入原词语序列、识别出来的标注序列和序列模式串,输出识别出来的机构名实体。
3.4.8 使用程序
代码地址:https://github.com/lipengfei-558/hmm_ner_organization
环境以及依赖:
- python2.7
- jieba分词(可选)
首先,运行以下脚本,生成transition_probability.txt
,emit_probability.txt
以及initial_vector.txt
:
python generate_data.py
然后,运行
python OrgRecognize.py
就可以了,不出意外,“中海油集团在哪里”这句话,会识别出“中海油集团”这个机构实体。
具体输入的句子逻辑,可以在main函数里面灵活修改,也可以结合jieba一起用。另外,python2.7的中文编码问题要注意了,如果你的输出序列很奇怪,很有可能是编码问题。
4.总结、待改进
用HMM来实现的命名实体识别算法,关键在于标签的自定义,你需要人工定义尽可能多的标签,然后在训练语料集里面自动标注这些标签,这也是最麻烦的地方。标注完语料集,生成HMM中的转移概率、初始概率、发射概率就很简单了,就是纯粹的统计。
整个模型也没什么参数,用这些统计的数字即可计算。
算法可能可以改进的点如下:
- 针对命名实体的维特比(viterbi)算法中,如果遇到未登录词,默认发射概率为0。我们可以额外引入相似度机制来解决这个问题,比如利用同义词表或者词向量相似度,我们找到和未登录词相似、同时也在观测概率矩阵里面出现的词语,用这个词语的发射概率(或者对其乘一个缩放系数),来代替未登录词的发射概率。
- 初始化概率对最终效果的影响有待考证。因为初始化概率影响着单词序列第一个词的标注,假如,仅仅用发射概率来决定第一个词的标注,效果会不会更好?
HMM算法默认只考虑前一个状态(词)的影响,忽略了更多上下文信息(特征)。后来的MEMM、CRF,都是循序渐进的改进方法。传统机器学习方法里面,CRF是主流,下一篇我会继续介绍CRF在命名实体识别任务上的应用。
代码和语料: https://github.com/uestcwm/NER/tree/master/HMM
用隐马尔可夫模型(HMM)做命名实体识别——NER系列(一)相关推荐
- 用隐马尔可夫模型(HMM)做命名实体识别——NER系列(二)
上一篇文章里<用规则做命名实体识别--NER系列(一)>,介绍了最简单的做命名实体识别的方法–规则.这一篇,我们循序渐进,继续介绍下一个模型--隐马尔可夫模型. 隐马尔可夫模型,看上去,和 ...
- 隐马尔可夫模型(HMM)实现命名实体识别(NER)
隐马尔可夫模型(HMM)实现命名实体识别(NER) 一.命名实体识别(Named Entity Recognition,NER) 识别文本中具有特定意义的实体,包括人名.地名.机构名.专有名词等等 在 ...
- viterbi维特比算法和隐马尔可夫模型(HMM)
阅读目录 隐马尔可夫模型(HMM) 回到目录 隐马尔可夫模型(HMM) 原文地址:http://www.cnblogs.com/jacklu/p/7753471.html 本文结合了王晓刚老师的ENG ...
- 机器学习知识点(二十五)Java实现隐马尔科夫模型HMM之jahmm库
1.隐马尔可夫模型HMM的应用场景,关乎于序列和状态变化的都可以. 发现java有可库,专为开发HMM,可惜只能在CSDN上有得下载. 2.jahmm是java开发隐马尔科夫模型的一个j ...
- 机器学习知识点(二十四)隐马尔可夫模型HMM维特比Viterbi算法Java实现
1.隐马尔可夫模型HMM 学习算法,看中文不如看英文,中文喜欢描述的很高深. http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/ht ...
- 隐马尔科夫模型HMM自学 (3)
Viterbi Algorithm 本来想明天再把后面的部分写好,可是睡觉今天是节日呢?一时情不自禁就有打开电脑.......... 找到可能性最大的隐含状态序列 崔晓源 翻译 多数情况下,我们都希望 ...
- 隐马尔科夫模型HMM自学 (2)
HMM 定义 崔晓源 翻译 HMM是一个三元组 (,A,B). the vector of the initial state probabilities; the state transitio ...
- 隐马尔科夫模型HMM自学(1)
介绍 崔晓源 翻译 我们通常都习惯寻找一个事物在一段时间里的变化规律.在很多领域我们都希望找到这个规律,比如计算机中的指令顺序,句子中的词顺序和语音中的词顺序等等.一个最适用的例子就是天气的预测. 首 ...
- 【NLP】用于语音识别、分词的隐马尔科夫模型HMM
大家好,今天介绍自然语言处理中经典的隐马尔科夫模型(HMM).HMM早期在语音识别.分词等序列标注问题中有着广泛的应用. 了解HMM的基础原理以及应用,对于了解NLP处理问题的基本思想和技术发展脉络有 ...
最新文章
- 级联人脸检测--Detecting Faces Using Inside Cascaded Contextual CNN
- 全国计算机三级哪个容易一点,给考三级网络的朋友们一点儿真诚的建议
- 使用互斥体使程序只运行一个
- python线性加权模型_局部加权之线性回归(1) - Python实现
- 使用juniversalchardet做字符编码识别
- 02-linux下 yum安装R环境和Rserve安装
- android webview圆角,Android 实现一个通用的圆角布局
- 手里有200万,如何理财?
- win2003 程序时间提供程序 NtpClient错误解决
- Websockets 介绍和应用
- 单片机毕业设计 stm32车牌识别系统
- Ubuntu启用root权限
- c语言整型常量后加l或u,《软考程序员》整型常量
- XPDL学习与分享 二 XPDL整体结构
- 数据结构与算法学习---数据结构篇(线性表)(默然回首,夯实基础)
- windows 定时任务:schtasks,定时关闭网易云音乐
- Day 1: 音标学习
- meta20 无法安装 google play_安卓万能安装谷歌三件套的方法
- JavaCV开发详解专栏文章目录(JavaCV速查手册)
- 从零开始搭建Node.js, Express, Ejs, Mongodb服务器
热门文章
- Android复习笔记(12) -handler的使用
- 工具分享(1):FTP暴力破解工具 [Python多线程版]
- 初识ARM(内核、SoC)
- warframe内部服务器暂时不可用,warframe内部服务器暂时不可用 | 手游网游页游攻略大全...
- 两台电脑通过网线连接,并共享网络的方法
- java togglebutton_双状态按钮控件ToggleButton的使用
- WPF 控件专题 TreeView控件详解
- s3c2410串口驱动不能发信号,是三星公司写的驱动有问题吗?还是select系统函数有问题?
- asp.net1074-瑜伽管理系统——毕业设计
- scrollTop 用法讲解