hanlp自然语言处理包的人名识别代码解析
HanLP发射矩阵词典nr.txt中收录单字姓氏393个。袁义达在《中国的三大姓氏是如何统计出来的》文献中指出:当代中国100个常见姓氏中,集中了全国人口的87%,根据这一数据我们只保留nr.txt中的100个常见词语的姓氏角色,其他词语去掉其姓氏角色状态。过滤后,nr.txt中具有姓氏角色的单字共计97个。列于下表:
丁 万 乔 于 任 何 余 侯 傅 冯 刘 卢 史 叶 吕 吴 周 唐 夏 姚
姜 孔 孙 孟 宋 尹 崔 常 康 廖 张 彭 徐 戴 方 易 曹 曾 朱 李
杜 杨 林 梁 武 段 毛 江 汤 汪 沈 潘 熊 王 田 白 石 秦 程 罗
胡 苏 范 萧 董 蒋 薛 袁 许 谢 谭 贺 贾 赖 赵 邓 邱 邵 邹 郑
郝 郭 金 钟 钱 阎 陆 陈 雷 韩 顾 马 高 魏 黄 黎 龚
实验效果
姓氏过滤前,各命名实体识别准确率
nr 33%
ns 83%
nt 43%
姓氏过滤后,各命名实体识别准确率
nr 36%
ns 83%
nt 81%
这里没有开层叠隐马预测机构名和地名,nt上升原因估计是由于很多不是人名的词语没被标为人名,那么nt的模式匹配规则匹配不上了,所以机构名准确率上来了。错误识别的人名,100个常用姓氏的不多,很多恐怕是HanLP里其他词表干预进来的。
隐马一般用于分词和词性标注是比较好的,为什么通常的序列标注方法也就是BIEO方法直接用到实体识别不合适呢。用词性标注为例,每一个词它所对应的词性标记子集是有限的,而这个子集相对于词性标记全集来说是小的。但是到了实体识别则不一定,拿人名来说,除了姓氏以外,名字词语部分可以填充的词语是任意的,也就是说任何词语都有可能出现在中间位置,此时发射矩阵中的某些词实际上就没有太大意义了,因为它可能等可能的由BIEO标记发出,而如果指利用四种标记之间的转移概率信息来确定最优的标记序列势必就影响效果。因此,我们通过引入角色标记,实际上这就引入了先验知识,比如某些字只能由姓氏标记产生,某些字一般情况都充当名字首字,某些字一般情况都充当名字末字,通过给这些不同情况下的字集按照其出现的位置的分布和其语法意义做角色定义,可以缩小每种角色标记可发出的词语集合,也就是每种词语(字)所对应的标记集的大小,相当于使发射概率分布不是均匀分布,那么预测的准确性肯定就得到提高了。
下边介绍一下HanLP人名识别的主要流程
1.使用使用匹配法求出各种分词路径用变量wordNetAll存储
2.用viterbi方法找到一条最优的分词路径,这里主要使用用户自定义词典以及核心词典,用序列变量vertexList存储。
3.角色观察,也就是根据发射概率矩阵列出vertexList中每个词语可能对应的角色标记。roleObserve(...)方法实现。
4.角色标注,利用viterbi方法求出最优角色标记序列。viterbiComputeSimply(...)方法实现。
5.对角色序列进行模式匹配得到人名。模式匹配定义在NRPattern类中。
在精度要求比较高且时间紧的情况下,最好的提高准确率的方法为,只保留常用姓氏,只保留最可能的2gram角色标记模式。在做人名识别时还有一个注意的点,如果你的预测语料和训练语料完全在文体上差别很大,或者说你就是在公开的训练语料上训练而不在预测语料上训练的话,基本上上下文信息是没有用处的,甚至有可能上下文信息会给实体边界标注带来干扰,我想任何机器学习包括深度学习,不管是文本分类领域还是实体识别领域都会有这种泛化能力的问题,这种问题恐怕通过算法是没法解决的,如果可以解决那么任何语种任何领域都可以使用一种模型,一劳永逸了。
hanlp自然语言处理包的人名识别代码解析的更多相关文章
- HanLP自然语言处理包介绍
支持中文分词(N-最短路分词.CRF分词.索引分词.用户自定义词典.词性标注),命名实体识别(中国人名.音译人名.日本人名.地名.实体机构名识别),关键词提取,自动摘要,短语提取,拼音转换,简繁转换, ...
- HanLP自然语言处理包开源(包含源码)
支持中文分词(N-最短路分词.CRF分词.索引分词.用户自定义词典.词性标注),命名实体识别(中国人名.音译人名.日本人名.地名.实体机构名识别),关键词提取,自动摘要,短语提取,拼音转换,简繁转换, ...
- hanlp自然语言处理包的基本使用--python
hanlp拥有:中文分词.命名实体识别.摘要关键字.依存句法分析.简繁拼音转换.智能推荐. 这里主要介绍一下hanlp的中文分词.命名实体识别.依存句法分析,这里就不介绍具体的hanlp的安装了,百度 ...
- GitHub10岁之际HanLP自然语言处理包用户量跃居榜首
在本周,GitHub终于度过了属于它自己的十周岁生日.这个在2008年由3个来自旧金山的年轻人创建的基于Git的代码托管网站,先后超越了元老级的SourceForge和背景强大的Google Code ...
- 如何编译运行HanLP自然语言处理包
master分支 对于master分支,编译方法如下: git clone https://github.com/hankcs/HanLP.git mvn install -DskipTests · ...
- HanLP-基于HMM-Viterbi的人名识别原理介绍
Hanlp自然语言处理包中的基于HMM-Viterbi处理人名识别的内容大概在年初的有分享过这类的文章,时间稍微久了一点,有点忘记了.看了 baiziyu 分享的这篇比我之前分享的要简单明了的多.下面 ...
- HanLP中人名识别分析
HanLP中人名识别分析 在看源码之前,先看几遍论文<基于角色标注的中国人名自动识别研究> 关于命名识别的一些问题,可参考下列一些issue: 名字识别的问题 #387 机构名识别错误 关 ...
- 中文自然语言处理工具HanLP源码包的下载使用记录
中文自然语言处理工具HanLP源码包的下载使用记录 这篇文章主要分享的是hanlp自然语言处理源码的下载,数据集的下载,以及将让源代码中的demo能够跑通.Hanlp安装包的下载以及安装其实之前就已经 ...
- HanLP中人名识别分析详解
HanLP中人名识别分析详解 在看源码之前,先看几遍论文<基于角色标注的中国人名自动识别研究> 关于命名识别的一些问题,可参考下列一些issue: l ·名字识别的问题 #387 l ·机 ...
随机推荐
- luogu 2052 [NOI2011]道路修建 BFS序
据说dfs会爆栈,写一个 BFS 序更新就好了~ #include <bits/stdc++.h> #define N 1000005 #define ll long long #defi ...
- Java集合总结(一):列表和队列
java中的具体容器类都不是从头构建的,他们都继承了一些抽象容器类.这些抽象容器类,提供了容器接口的部分实现,方便具体容器类在抽象类的基础上做具体实现.容器类和接口的关系架构图如下: 虚线框表示接口, ...
- c 语言延时函数
/*--- 等待x毫秒 ---*/ int sleep(unsigned long x) { clock_t c1 = clock(), c2; do { ) /* 错误 */ ; } while ( ...
- AcWing:242. 一个简单的整数问题(树状数组)
给定长度为N的数列A,然后输入M行操作指令. 第一类指令形如“C l r d”,表示把数列中第l~r个数都加d. 第二类指令形如“Q X”,表示询问数列中第x个数的值. 对于每个询问,输出一个整数表示 ...
- 手写alert弹框(一)
采用原生的JavaScript, html代码 <meta name="viewport" content="width=device-width, initial ...
- 如何规避同时使用v-if与v-for?
先将结果过滤,再用v-if循环 遇到问题:使用Vue -computed传参数不成功, 后来将参数放在compute里面方法名里再构造参数进行传递
- VUE组件如何通信
Vue父子组件如何通信? 子组件通知父组件(调用父组件方法) 在父组件使用 on(eventName)监听事件,在子组件使用emit(eventName) 触发事件 : 父组件通知子组件(调用子组件方 ...
- Kotlin中反射
枚举类成员 import kotlin.reflect.full.memberFunctions import kotlin.reflect.full.memberProperties fun mai ...
- 使用极路由进行外网映射,本地电脑做服务器,运行javaWeb项目
最近在学习javaWeb,一个项目需要android访问服务器,于是使用自己的笔记本电脑作为服务器,需要进行端口映射.使得外网可以访问自己的javaWeb项目或者网站之类的.普通路由请看:http:/ ...
- react对字符串转义成html并渲染
<div dangerouslySetInnerHTML={{__html: "字符串内容"}} />