hanlp自然言语处理包的人名辨认代码解析

图灵汇官网

HanLP的矩阵词典nr.txt中包含393个单字姓氏。据袁义达在《中国三大姓氏统计方法》中的研究,当代中国最常见的100个姓氏涵盖了全国约87%的人口。因此,在nr.txt中,我们只保留这100个常见姓氏作为姓氏角色,其余的姓氏角色将被移除。经过筛选,nr.txt中保留的具有姓氏角色的单字共有97个。

这些姓氏列表如下:

丁 万 乔 于 任 何 余 侯 傅 冯 刘 卢 史 叶 吕 吴 周 唐 夏 姚

姜 孔 孙 孟 宋 尹 崔 常 康 廖 张 彭 徐 戴 方 易 曹 曾 朱 李

杜 杨 林 梁 武 段 毛 江 汤 汪 沈 潘 熊 王 田 白 石 秦 程 罗

胡 苏 范 萧 董 蒋 薛 袁 许 谢 谭 贺 贾 赖 赵 邓 邱 邵 邹 郑

郝 郭 金 钟 钱 阎 陆 陈 雷 韩 顾 马 高 魏 黄 黎 龚

[b]实验效果[/b]

在姓氏过滤之前,各命名实体的识别准确率为: - nr: 33% - ns: 83% - nt: 43%

过滤姓氏之后,准确率变为: - nr: 36% - ns: 83% - nt: 81%

在未启用分层隐马尔可夫模型预测机构名和地名的情况下,nt的提升主要是因为许多原本不属于人名的词语不再被误认为人名,因此nt的识别准确率有所提高。错误识别的人名中,常见的100个姓氏很少出现,大多数可能是由于HanLP中的其他词典引起的干扰。

隐马尔可夫模型在分词和词性标注方面表现良好,但直接应用于实体识别却不理想。这是因为每个词的词性标记是有限的,而人名识别中,名字部分可以包含任意词语,这使得发射矩阵中的某些词变得无关紧要。如果仅依赖四种标记之间的转移概率来确定最佳标记序列,效果会受到影响。因此,通过引入角色标记,引入先验知识,如某些字只能作为姓氏,某些字常作为名字的首字或尾字,可以显著提高识别准确率。

[b]以下是HanLP人名识别的主要流程[/b]

  1. 使用匹配法找出所有可能的分词路径,并将它们存储在变量wordNetAll中。
  2. 利用Viterbi算法找到最优的分词路径,主要依赖用户自定义词典和核心词典,并将结果存储在变量vertexList中。
  3. 角色观察,即根据发射概率矩阵列出vertexList中每个词语可能对应的角色标记,通过roleObserve(...)方法实现。
  4. 角色标注,利用Viterbi算法求出最优的角色标记序列,通过viterbiComputeSimply(...)方法实现。
  5. 根据形式匹配规则从角色序列中提取人名,形式匹配规则定义在NRPattern类中。

在需要高精度且时间紧迫的情况下,最有效的方法是仅保留常用的姓氏,并使用最有可能的2gram角色标记模式。此外,在人名识别过程中,如果预测语料与训练语料在文体上有较大差异,上下文信息可能不仅无效,甚至会产生干扰。尽管机器学习和深度学习在文本分类和实体识别等领域存在泛化能力的问题,但这些问题很难通过算法完全解决。

本文来源: 图灵汇 文章作者: 张珂珂