本篇文章将重点讲解HanLP的ViterbiSegment分词器类,而不涉及感知机和条件随机场分词器,也不涉及基于字的分词器。因为这些分词器都不是我们在实践中常用的,而且ViterbiSegment也是作者直接封装到HanLP类中的分词器,作者也推荐使用该分词器,同时文本分类包以及其他一些自然语言处理任务包中的分词器也都间接使用了ViterbiSegment分词器。

今天的文章还会介绍各分词词典文件的使用位置以及作用,相信小伙伴们看了今天的文章应该不会再在github上提出干预自定义不生效的问题了。进入正题,本篇的内容比较多,建议收藏后再细读。

1. 分词器配置变量

分词器的相关配置定义在Config.java类中,这里我们将分词相关的所有配置变量列于下表

这种配置类什么时候实例化呢,不用想肯定是分词开始前就会实例化,拿HanLP类中的ViterbiSegment分词类举例。该类的继承关系用如下图所示:

由继承关系图可以看到,只要实例化ViterbiSegment则首先会执行Segment()初始化,在该方法中实例化分词器配置对象config。这些配置变量都是公有变量,因此可以在ViterbiSegment类实例化为对象后直接在外部修改。那么什么时候来使用这些配置变量呢,当然是在分词的时候,具体是哪个类的哪个方法呢,当然是ViterbiSegment类的List<Term> segSentence(char[] sentence)方法。

另外请注意上边的3个类,所有ViterbiSegment的分词方法都集中在这3个类中。

2. 词典的使用条件和先后顺序(也介绍分词流程)

我们知道了词典配置变量使用的位置后,就可以确定每个词典的使用条件了以及每个词典的使用顺序

1. 词语粗分

(1)构建词图

对应方法为void generateWordNet(final WordNet wordNetStorage),在此方法中系统使用CoreNatureDictionary.txt文件切分出所有可能的分词路径。此时如果配置变量useCustomDictionary为true,则将CustomDictionary.txt中的词也考虑进来,说明CustomDictionary.txt优先级会高。另外大家可以看到CoreNatureDictionary.txt实际上也充当了隐马词性标注的发射矩阵,里边某些多词性词也列出了词性序列以及各词性对应的频次。

(2)用户定制词典干预

如果配置变量useCustomDictionary为true,即需要使用CustomDictionary.txt进行干预,则执行下边对应的方法,否则跳过该步骤。用户词典干预根据是否进行全切分有两种不同方法:当配置变量indexMode>0时,即系统处于全切分模式时,对应方法为

List<Vertex> combineByCustomDictionary(List<Vertex> vertexList, DoubleArrayTrie<CoreDictionary.Attribute> dat, final WordNet wordNetAll),

如果indexMode=0,即系统处于普通分词模式,对应方法为

List<Vertex> combineByCustomDictionary(List<Vertex> vertexList, DoubleArrayTrie<CoreDictionary.Attribute> dat)。

从调用的方法我们不难看出,全切分时系统会根据CustomDictionary.txt添加分词路径。而普通切分时,系统会根据CustomDictionary.txt合并路径。这也就是为什么有的时候明明已经在CustomDictionary.txt中添加了新词却不生效的原因,因为一旦根据CoreNatureDictionary.txt构建了词图就不会再有新的路径插到已有分词路径中间,此时就去查找并修改CoreNatureDictionary.txt中的相关字或词吧。

(3)维特比选择最优路径

对应方法为List<Vertex> viterbi(WordNet wordNet),至此就得到了一个粗分的分词结果。需要注意HanLP的Viterbi分词只是用viterbi方法求解最优路径,并不是隐马。

3. 数字识别

如果配置变量numberQuantifierRecognize为true,则在粗分结果的基础上进行数字合并操作,否则直接跳过该步。对应方法为

void mergeNumberQuantifier(List<Vertex> termList, WordNet wordNetAll, Config config)。

4. 实体识别

配置变量ner为true时,则需要进行各种实体的识别,继续向下执行。需要注意该变量受其他实体识别变量影响,只要其他任意实体配置变量为true,则ner就会为true。如果ner为false,则跳过下边各项实体识别继续词性标注环节。

(1)中国人名识别

执行此步,配置变量nameRecognize必须为true。调用方法为

PersonRecognition.recognition(vertexList, wordNetOptimum, wordNetAll)。人名使用隐马,因此有转移矩阵nr.tr.txt和发射矩阵nr.txt。由于HanLP不提供训练语料,我们自己也很难得到有角色标注的语料,因此我们一般只修改nr.txt文件,删除nr.txt.bin文件后生效。

(2)音译人名识别

执行此步,配置变量translatedNameRecognize必须为true。调用方法为

TranslatedPersonRecognition.recognition(vertexList, wordNetOptimum, wordNetAll)。需要注意音译人名的识别没有用隐马,就是匹配分词法。涉及到的词典为nrf.txt,如果用户修改该词典,则需要删除nrf.txt.trie.dat使其生效。

(3)日本人名识别

执行此步,配置变量japaneseNameRecognize必须为true。调用方法为

JapanesePersonRecognition.recognition(vertexList, wordNetOptimum, wordNetAll)。需要注意日本人名的识别没有用隐马,就是匹配分词法。涉及到的词典为nrj.txt,如果用户修改该词典,则需要删除nrj.txt.trie.dat和nrj.txt.value.dat使其生效。

(4)地名识别

执行此步,配置变量placeRecognize必须为true。调用方法为

PlaceRecognition.recognition(vertexList, wordNetOptimum, wordNetAll)。地名使用隐马,因此有转移矩阵ns.tr.txt和发射矩阵ns.txt。由于HanLP不提供训练语料,我们自己也很难得到有角色标注的语料,因此我们一般只修改ns.txt文件,删除ns.txt.bin文件后生效。

(5)机构名识别

执行此步,配置变量organizationRecognize必须为true。调用方法为

OrganizationRecognition.recognition(vertexList, wordNetOptimum, wordNetAll)。注意这里在调用机构名识别之前先进行了一次识别,也就是层叠隐马,而人名和地名的识别就是普通的隐马。机构名的识别使用层叠隐马,涉及的文件有转移矩阵nt.tr.txt和发射矩阵nt.txt。由于HanLP不提供训练语料,我们自己也很难得到有角色标注的语料,因此我们一般只修改nt.txt文件,删除ns.txt.bin文件后生效。机构名的识别需要人名地名识别具有较高准确率。

至此,分词流程已全部介绍了。

还需要注意下边的内容

其他没有在系统中使用的词典有

机构名词典.txt

全国地名大全.txt

人名词典.txt

上海地名.txt

现代汉语补充词库.txt

这些词典是对系统中的词典的更新记录,如果你添加了新的人名、地名、机构名可以在这里添加保存。

另外,如果需要添加人名、地名、机构名可以直接在CoreNatureDictionary.txt中添加,最好是3字以上实体,

如果要去掉错误识别的命名实体可以直接在相应的nr.txt,ns.txt,nt.txt中添加。

3. 多线程分词

HanLP的ViterbiSegment分词器类是支持多线程的,线程数量由配置变量threadNumber决定的,该变量默认为1。HanLP作者说ViterbiSegmet分词效率最高的原因肯定也有ViterbiSegment分词器支持多线程分词这个因素。另外由于ViterbiSegment分词器内部所具有的相关命名实体功能,因此这些命名实体识别的效率也会很高。在哪里实现的多线程分词呢,在Segment类的List<Term> seg(String text)这个方法中实现的,需要注意HanLP的多线程分词指的是一次输入了一个长文本,而不是一次处理多个输入文本。

本文分享自 baiziyu 的专栏,正文内容已经做了部分修改,便于大家阅读,欢迎一起交流学习!

HanLP分词工具中的ViterbiSegment分词流程的更多相关文章

  1. Python分词工具——pyhanlp

    本文为本人学习pyhanlp的笔记,大多知识点来源于GitHubhttps://github.com/hankcs/HanLP/blob/master/README.md,文中的demo代码来源于该G ...

  2. Lucene.net(4.8.0)+PanGu分词器问题记录一:分词器Analyzer的构造和内部成员ReuseStategy

    前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...

  3. 分词工具比较及使用(ansj、hanlp、jieba)

    一.分词工具 ansj.hanlp.jieba 二.优缺点 1.ansj 优点: 提供多种分词方式 可直接根据内部词库分出人名.机构等信息 可构造多个词库,在分词时可动态选择所要使用的词库缺点: 自定 ...

  4. 中文分词工具简介与安装教程(jieba、nlpir、hanlp、pkuseg、foolnltk、snownlp、thulac)

    2.1 jieba 2.1.1 jieba简介 Jieba中文含义结巴,jieba库是目前做的最好的python分词组件.首先它的安装十分便捷,只需要使用pip安装:其次,它不需要另外下载其它的数据包 ...

  5. Hanlp中N最短路径分词详细介绍

    N-最短路径 是中科院分词工具NLPIR进行分词用到的一个重要算法,张华平.刘群老师在论文<基于N-最短路径方法的中文词语粗分模型>中做了比较详细的介绍.该算法算法基本思想很简单,就是给定 ...

  6. hanlp分词工具应用案例:商品图自动推荐功能的应用

    本篇分享一个hanlp分词工具应用的案例,简单来说就是做一图库,让商家轻松方便的配置商品的图片,最好是可以一键完成配置的. 先看一下效果图吧: 商品单个推荐效果:匹配度高的放在最前面 这个想法很好,那 ...

  7. 中文分词工具探析(一):ICTCLAS (NLPIR)

    1. 前言 ICTCLAS是张华平在2000年推出的中文分词系统,于2009年更名为NLPIR.ICTCLAS是中文分词界元老级工具了,作者开放出了free版本的源代码(1.0整理版本在此). 作者在 ...

  8. 开源中文分词工具探析(四):THULAC

    THULAC是一款相当不错的中文分词工具,准确率高.分词速度蛮快的:并且在工程上做了很多优化,比如:用DAT存储训练特征(压缩训练模型),加入了标点符号的特征(提高分词准确率)等. 1. 前言 THU ...

  9. 开源中文分词工具探析(五):Stanford CoreNLP

    CoreNLP是由斯坦福大学开源的一套Java NLP工具,提供诸如:词性标注(part-of-speech (POS) tagger).命名实体识别(named entity recognizer ...

随机推荐

  1. MySQL Group Replication-MGR集群简介

    简介 MySQL Group Replication(简称MGR)字面意思是mysql组复制的意思,但其实他是一个高可用的集群架构,暂时只支持mysql5.7和mysql8.0版本. 是MySQL官方 ...

  2. 028_切割 Nginx 日志文件(防止单个文件过大,后期处理很困难)

    mkdir /data/scriptsvim /data/scripts/nginx_log.sh #!/bin/bashlogs_path="/usr/local/nginx/logs/& ...

  3. About IndexDB

    http://blog.csdn.net/bd_zengxinxin/article/details/7758317 HTML5 - Storage 客户端存储 http://html5demos.t ...

  4. 2019CCPC-江西省赛

    目录 Contest Info Solutions A. Cotree C.Trap D.Wave F.String G. Traffic H.Rng I. Budget J. Worker K. C ...

  5. crm-权限管理

    1 用户登录 设置session 将权限存放在session中 2 设置中间件,进行拦截 0 添加白名单,判断是否在白名单上 1 判断是否登录 2 权限过滤

  6. 检查errno

    转自 http://blog.csdn.net/todd911/article/details/9132095 很多库函数,特别是那些与操作系统有关的,当执行失败时会通过一个名称为errno的外部变量 ...

  7. Til the Cows Come Home ( POJ 2387) (简单最短路 Dijkstra)

    problem Bessie is out in the field and wants to get back to the barn to get as much sleep as possibl ...

  8. java试题复盘——11月13日

    上: 10. AccessViolationException异常触发后,下列程序的输出结果为(   A   ) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 AccessViol ...

  9. 去除IntelliJ IDEA对重复代码的检测

    方法1:  方法2:(比较简便) 

  10. chrome console控制台引入jquery库

    var jqueryJs=document.createElement('script');jqueryJs.setAttribute("type","text/Java ...