目录
- 8.5.2 基于隐马尔可夫模型序列标注的命名实体识别
- 8.5.3 基于感知机序列标注的命名实体识别
- 8.5.4 基于条件随机场序列标注的命名实体识别
- 8.5.5 命名实体识别标准化评测
- 8.6 自定义领域命名实体识别
- 8.7 总结
8. 命名实体识别
8.1 概述
- 命名实体文本中有一些描述实体的词汇。比如人名、地名、组织机构名、股票基金、医学术语等,称为命名实体。具有以下共性:
- 数量无穷。比如宇宙中的恒星命名、新生儿的命名不断出现新组合。
- 构词灵活。比如中国工商银行,既可以称为工商银行,也可以简称工行。
- 类别模糊。有一些地名本身就是机构名,比如“国家博物馆”
- 命名实体识别识别出句子中命名实体的边界与类别的任务称为命名实体识别(Named Entity Recognition,NER)。由于上述难点,命名实体识别也是一个统计为主、规则为辅的任务。
- 对于规则性较强的命名实体,比如网址、E-mail、IBSN、商品编号等,完全可以通过正则表达式处理,未匹配上的片段交给统计模型处理。
- 对于较短的命名实体,比如人名,完全可以通过分词确定边界,通过词性标注模块确定类别
- 在另一些语料库中(如PKU等),机构名这样的复合词是拆开的,此时就需要一个专门的命名实体识别模块了
- 命名实体识别也可以转化为一个序列标注问题。具体做法是将命名实体识别附着到{B,M,E,S}标签,比如, 构成地名的单词标注为“B/ME/S- 地名”,以此类推。对于那些命名实体边界之外的单词,则统一标注为0 ( Outside )。具体实施时,HanLP做了一个简化,即所有非复合词的命名实体都标注为S,不再附着类别。这样标注集更精简,模型更小巧。
命名实体识别实际上可以看作分词与词性标注任务的集成: 命名实体的边界可以通过{B,M,E,S}
确定,其类别可以通过 B-nt
等附加类别的标签来确定。
HanLP内部提供了语料库转换工序,用户无需关心,只需要传入 PKU 格式的语料库路径即可。
8.2 基于规则的命名实体识别
这些系统属于HanLP早期设计的一部分,虽然已经落伍,但可以应付一些语料匮乏的专门领域
8.2.1 基于规则的音译人名识别
在一段待识别的文本中,若音译字符连续出现,则很有可能来自一个音译人名
- 若粗分结果中某词语的备选词性(词性由核心词典、用户词典提供)含有
nrf
(音译人名),则触发规则2); - 从该词语出发往右扫描,若遇到音译人名词库中的词语,则合并,否则终止扫描。
8.2.2 基于规则的日本人名识别
日本人名识别规则:
- 在文本中匹配日本人名的姓氏和名字,分别记作
x
和m
- 将连续的xm合并为日本人名,标注为
nrj
8.2.3 基于规则的数词英文识别
首先利用com.hankcs.hanlp.dictionary.other.CharType工具类获取每个字符的类型。
然后扫描字符串的类型数组,将类型相同的字符合并,利用其类型确定词性(数词m或英文nx等)
segment = ViterbiSegment() print(segment.seg("牛奶三〇〇克壹佰块")) print(segment.seg("牛奶300克100块")) print(segment.seg("牛奶300g100rmb"))
8.3 命名实体识别语料库
命名实体识别语料的针对性非常强,往往是人们关心什么样的命名实体,就去标注什么样的语料
1998年《人民日报》语料库
萨哈夫/nr 说/v ,/w 伊拉克/ns 将/d 同/p [联合国/nt 销毁/v 伊拉克/ns 大规模/b 杀伤性/n 武器/n 特别/a 委员会/n]/nt 继续/v 保持/v 合作/v 。/w
PKU语料库中还存在许多nz专有名词类型的复合词:
[延安/ns 供水/vn 工程/n]/nz 建成/v 通水/v
黄浦江畔/ns 的/u [东方/s 明珠/n 电视塔/n]/nz 前/f 热闹非凡/l
一九九七年/t [诺贝尔/nr 物理奖/n]/nz 获得者/n
微软命名实体识别语料库
我们藏有一册1945年6月油印的《北京文物保存保管状态之调查报告》,调查范围涉及故宫、历博、古研所、北大清华图书馆、北图、日伪资料库等二十几家,言及文物二十万件以上,洋洋三万余言,是珍贵的北京史料。
8.4 基于层叠隐马尔可夫模型的角色标注框架
该框架的识别思路与日本人名的思路类似:为构成命名实体的短词语打标签,标签序列满足某种模式则识别为某种命名实体
角色标注模块的输入是分词模块的输出,两个模块都由隐马尔可夫模型驱动,所以称为层叠隐马尔可夫模型
8.4.1 基于角色标注的中国人名识别
- 语料转换
原始语料 [这里/r, 有/v, 关天培/nr, 的/u, 有关/vn, 事迹/n, 。/w]姓名拆分 [这里/A, 有/K, 关/B, 天/C, 培/D, 的/L, 有关/A, 事迹/A, 。/A]上文成词 [这里/A, 有关/U, 天/C, 培/D, 的/L, 有关/A, 事迹/A, 。/A]添加首尾 [始##始/S, 这里/A, 有关/U, 天/C, 培/D, 的/L, 有关/A, 事迹/A, 。/A, 末##末/A] - 训练HMM
- 标注
- 模式匹配合并
粗分结果[龚/nz, 学/v, 平等/a, 领导/n]人名角色观察:[ K 1 A 1 ][龚 B 768 D 3 E 2 C 1 ][学 C 1698 D 298 L 19 E 11 K 8 B 5 ][平等 V 35 L 9 ][领导 K 238 L 47 ][ K 1 A 1 ]人名角色标注:[ /K ,龚/B ,学/C ,平等/V ,领导/K , /K]识别出人名:龚学 BC识别出人名:龚学平 BCD细分词网:0:[ ]1:[龚, 龚学, 龚学平]2:[学]3:[平, 平等]4:[等]5:[领导][龚学平/nr, 等/udeng, 领导/n]
8.4.2 基于角色标注的地名识别
8.4.2 基于角色标注的机构识别
8.5 基于序列标注的命名实体识别
命名实体的边界可以通过{B,M,E,S}
确定
其类别可以通过B-nt
等附加类别的标签来确定
8.5.1 特征提取
8.5.2 基于隐马尔可夫模型序列标注的命名实体识别
HMMNERecognizer recognizer = new HMMNERecognizer(); recognizer.train(corpus); // data/test/pku98/199801-train.txt
之前我们就介绍过隐马尔可夫模型,详细见: 4.隐马尔可夫模型与序列标注
隐马尔可夫模型命名实体识别代码见(自动下载 PKU 语料库): hmm_ner.py
https://github.com/NLP-LOVE/Introduction-NLP/tree/master/code/ch08/hmm_ner.py
运行代码后结果如下:
华北电力公司/nt 董事长/n 谭旭光/nr 和/c 秘书/n 胡花蕊/nr 来到/v 美国纽约/ns 现代/ntc 艺术/n 博物馆/n 参观/v
其中机构名“华北电力公司”、人名“谭旭光”“胡花蕊”全部识别正确。但是地名“美国纽约现代艺术博物馆”则无法识别。有以下两个原因:
- PKU 语料库中没有出现过这个样本。
- 隐马尔可夫模型无法利用词性特征。
对于第一个原因,只能额外标注一些语料。对于第二个原因可以通过切换到更强大的模型来解决。
8.5.3 基于感知机序列标注的命名实体识别
之前我们就介绍过感知机模型,详细见: 5.感知机分类与序列标注
感知机模型词性标注代码见(自动下载 PKU 语料库): perceptron_ner.py
https://github.com/NLP-LOVE/Introduction-NLP/tree/master/code/ch08/perceptron_ner.py
运行会有些慢,结果如下:
华北电力公司/nt 董事长/n 谭旭光/nr 和/c 秘书/n 胡花蕊/nr 来到/v [美国纽约/ns 现代/ntc 艺术/n 博物馆/n]/ns 参观/v
与隐马尔可夫模型相比,已经能够正确识别地名了。
8.5.4 基于条件随机场序列标注的命名实体识别
之前我们就介绍过条件随机场模型,详细见: 6.条件随机场与序列标注
条件随机场模型词性标注代码见(自动下载 PKU 语料库): crf_ner.py
https://github.com/NLP-LOVE/Introduction-NLP/tree/master/code/ch08/crf_ner.py
运行时间会比较长,结果如下:
华北电力公司/nt 董事长/n 谭旭光/nr 和/c 秘书/n 胡花蕊/nr 来到/v [美国纽约/ns 现代/ntc 艺术/n 博物馆/n]/ns 参观/v
得到了结果是一样的。
8.5.5 命名实体识别标准化评测
各个命名实体识别模块的准确率如何,并非只能通过几个句子主观感受。任何监督学习任务都有一套标准化评测方案,对于命名实体识别,按照惯例引入P、R 和 F1 评测指标。
在1998年1月《人民日报》语料库上的标准化评测结果如下:
模型 | P | R | F1 |
隐马尔可夫模型 | 79.01 | 30.14 | 43.64 |
感知机 | 87.33 | 78.98 | 82.94 |
条件随机场 | 87.93 | 73.75 | 80.22 |
值得一提的是,准确率与评测策略、特征模板、语料库规模息息相关。通常而言,当语料库较小时,应当使用简单的特征模板,以防止模型过拟合;当语料库较大时,则建议使用更多特征,以期更高的准确率。当特征模板固定时,往往是语料库越大,准确率越高。
8.6 自定义领域命名实体识别
以上我们接触的都是通用领域上的语料库,所含的命名实体仅限于人名、地名、机构名等。假设我们想要识别专门领域中的命名实体,这时,我们就要自定义领域的语料库了。
- 标注领域命名实体识别语料库
首先我们需要收集一些文本, 作为标注语料库的原料,称为生语料。由于我们的目标是识别文本中的战斗机名称或型号,所以生语料的来源应当是些军事网站的报道。在实际工程中,求由客户提出,则应当由该客户提供生语料。语料的量级越大越好,一般最低不少于数千个句子。
生语料准备就绪后,就可以开始标注了。对于命名实体识别语料库,若以词语和词性为特征的话,还需要标注分词边界和词性。不过我们不必从零开始标注,而可以在HanLP的标注基础上进行校正,这样工作量更小。
样本标注了数千个之后,生语料就被标注成了熟语料。下面代码自动下载语料库。
假设生语料中有如下句子:
米高扬设计米格-17PF:米格-17PF型战斗机比米格-17P性能更好。
HanLP的词法分析器输出如下结果:
米高扬/nr 设计/vn 米格/nr -/w 17/m PF/nx :/w 米格/nr -/w 17/m PF/nx 型/k 战斗机/n 比/p 米格/nr -/w 17/m P/nx 性能/n 更好/d 。/w
人工将其校正为:
米高扬/nr 设计/v [米格/nr -/w 17PF/m]/np :/w [米格/nr -/w 17PF/m]/np 型/k 战斗机/n 比/p [米格/nr -/w 17P/m]/np 性能/n 更好/l 。/w
样本至少标注数千个
- 训练领域模型
选择感知机作为训练算法(自动下载 战斗机 语料库): plane_ner.py
https://github.com/NLP-LOVE/Introduction-NLP/tree/master/code/ch08/plane_ner.py
运行结果如下:
下载 http://file.hankcs.com/corpus/plane-re.zip 到 /usr/local/lib/python3.7/site-packages/pyhanlp/static/data/test/plane-re.zip 100.00%, 0 MB, 552 KB/s, 还有 0 分 0 秒 米高扬/nrf 设计/v [米格/nr -/w 17/m PF/nx]/np :/w [米格/nr -/w 17/m]/np PF/n 型/k 战斗机/n 比/p [米格/nr -/w 17/m P/nx]/np 性能/n 更好/l 。/w [米格/nr -/w 阿帕奇/nrf -/w 666/m S/q]/np 横空出世/l 。/w
- 这句话已经在语料库中出现过,能被正常识别并不意外。我们可以伪造一款“米格-阿帕奇-666S”战斗机,试试模型的繁华能力,发现依然能够正确识别。
8.7 总结
从规则到统计
- 命名实体识别的规则
- 层叠隐马尔可夫模型角色标注
- 序列标注三种识别方法
作为监督学习的应用,命名实体识别离不开 - 标注语料库
- 设计特征模板
- 训练
- 评估准确率
模型能够识别出哪些命名实体完全由语料库决定。
通用语料库无法解决领域需求,领域语料库的标注非常重要。