2.7 中文分词实战

前文提及了Ansj和Jcseg两种轻量级Java中文分词器,本节将介绍这两种分词组件的使用方法。

2.7.1 Ansj中文分词

Ansj中文分词基于n-Gram+CRF+HMM算法,用Java实现。Ansj中文分词工具的分词速度可达到大约200万字/s,准确率达96%以上。

目前Ansj中文分词工具已经实现了中文分词、中文姓名识别、用户自定义词典、关键字提取、自动摘要、关键字标记等功能,可以应用到自然语言处理等方面,适用于对分词效果要求较高的各种项目。

Ansj中文分词工具支持的分词方式有ToAnalysis(精准分词)、DicAnalysis(用户自定义词典优先策略的分词)、NlpAnalysis(带有新词发现功能的分词)、IndexAnalysis(面向索引的分词)、BaseAnalysis(最小颗粒度的分词)。

其中,ToAnalysis是Ansj分词方式的首选项。该分词方式在易用性、稳定性、准确性及分词效率上,都取得了一个不错的平衡。如果初次尝试使用Ansj,想“开箱即用”,那么建议使用ToAnalysis。

在DicAnalysis中,用户可以自定义词典优先策略。如果自定义词典足够好,或者用户对自定义词典的要求比较高,那么强烈建议使用DicAnalysis。在此种情景下,很多方面它会优于ToAnalysis的分词结果。

NlpAnalysis可以识别出未登录词。它的缺点是速度比较慢、稳定性差一些。如果需要进行未登录词识别、对文本进行分析,则首推该分词方法。

IndexAnalysis适合在Lucene等文本检索中使用,其召回率较高,准确率也较高。

BaseAnalysis则保证了最基本的分词,词语颗粒度非常小,所涉及的词大约是10万(个)左右。这种分词方式的分词速度非常快,可达到300万字/s,同时准确率也很高。不过,对于新词,这种分词方式的效果不太理想。

下面展示上述分词方式的分词API的使用和分词效果。分词API的使用如下所示:

在当前类中执行main方法,各个分词方式的运行结果如下所示。

最小颗粒度的分词

15/m,年来/t,首批/n,由/p,深海/n,探险家/n,组成/v,的/u,国际/n,团队/n,五/m,次/q,潜入/v,大西洋/ns,海底/n,3800/m,米/q,深处/s,,/w,对/p,泰坦尼克号/nz,沉船/n,残骸/n,进行/v,调查/vn,。/w,探险队/n,发现/v,,/w,虽然/c,沉船/n,的/u,部分/n,残骸/n,状况/n,良好/a,,/w,也/d,有/v,一些/m,部分/n,已/d,消失/v,在/p,大海/n,中/f,。/w,强大/a,的/u,洋流/n,、/w,盐/n,蚀/vg,和/c,细菌/n,正/d,不断/d,侵蚀/vn,着/u,这/r,艘/q,沉船/n,。/w,英/j,媒/ng,曝光/v,的/u,高清/n,图片/n,可见/v,,/w,沉船/n,的/u,部分/n,残骸/n,遭/v,腐蚀/v,情况/n,严重/a,。/w

该方式累计有效分词71个,其中单字分词结果24个。

精准分词

15/m,年来/t,首批/n,由/p,深海/n,探险家/n,组成/v,的/u,国际/n,团队/n,五次/mq,潜入/v,大西洋/ns,海底/n,3800米/mq,深处/s,,/w,对/p,泰坦尼克号/nz,沉船/n,残骸/n,进行/v,调查/vn,。/w,探险队/n,发现/v,,/w,虽然/c,沉船/n,的/u,部分/n,残骸/n,状况/n,良好/a,,/w,也/d,有/v,一些/m,部分/n,已/d,消失/v,在/p,大海/n,中/f,。/w,强大/a,的/u,洋流/n,、/w,盐/n,蚀/vg,和/c,细菌/n,正/d,不断/d,侵蚀/vn,着/u,这/r,艘/q,沉船/n,。/w,英/j,媒/ng,曝光/v,的/u,高清/n,图片/n,可见/v,,/w,沉船/n,的/u,部分/n,残骸/n,遭/v,腐蚀/v,情况/n,严重/a,。/w

该方式累计有效分词68个,其中单字分词结果21个。

用户自定义词典优先策略的分词

15/m,年来/t,首批/n,由/p,深海/n,探险家/n,组成/v,的/u,国际/n,团队/n,五次/mq,潜入/v,大西洋/ns,海底/n,3800米/mq,深处/s,,/w,对/p,泰坦尼克号/nz,沉船/n,残骸/n,进行/v,调查/vn,。/w,探险队/n,发现/v,,/w,虽然/c,沉船/n,的/u,部分/n,残骸/n,状况/n,良好/a,,/w,也/d,有/v,一些/m,部分/n,已/d,消失/v,在/p,大/a,海中/s,。/w,强大/a,的/u,洋流/n,、/w,盐/n,蚀/vg,和/c,细菌/n,正/d,不断/d,侵蚀/vn,着/u,这/r,艘/q,沉船/n,。/w,英/j,媒/ng,曝光/v,的/u,高清/n,图片/n,可见/v,,/w,沉船/n,的/u,部分/n,残骸/n,遭/v,腐蚀/v,情况/n,严重/a,。/w

该方式累计有效分词68个,其中单字分词结果21个。

面向索引的分词

15/m,年来/t,首批/n,由/p,深海/n,探险家/n,组成/v,的/u,国际/n,团队/n,五次/mq,潜入/v,大西洋/ns,海底/n,3800米/mq,深处/s,,/w,对/p,泰坦尼克号/nz,沉船/n,残骸/n,进行/v,调查/vn,。/w,探险队/n,发现/v,,/w,虽然/c,沉船/n,的/u,部分/n,残骸/n,状况/n,良好/a,,/w,也/d,有/v,一些/m,部分/n,已/d,消失/v,在/p,大海/n,中/f,。/w,强大/a,的/u,洋流/n,、/w,盐/n,蚀/vg,和/c,细菌/n,正/d,不断/d,侵蚀/vn,着/u,这/r,艘/q,沉船/n,。/w,英/j,媒/ng,曝光/v,的/u,高清/n,图片/n,可见/v,,/w,沉船/n,的/u,部分/n,残骸/n,遭/v,腐蚀/v,情况/n,严重/a,。/w

该方式累计有效分词68个,其中单字分词结果21个。

带有新词发现功能的分词

15年/t,来/v,首/m,批/q,由/p,深海/n,探险家/n,组成/v,的/u,国际/n,团队/n,五次/mq,潜入/v,大西洋/ns,海底/n,3800米/mq,深处/s,,/w,对/p,泰坦尼克号/nz,沉船/n,残骸/n,进行/v,调查/vn,。/w,探险队/n,发现/v,,/w,虽然/c,沉船/n,的/u,部分/n,残骸/n,状况/n,良好/a,,/w,也/d,有/v,一些/m,部分/n,已/d,消失/v,在/p,大海/n,中/f,。/w,强大/a,的/u,洋流/n,、/w,盐蚀/nw,和/c,细菌/n,正/d,不断/d,侵蚀/vn,着/u,这/r,艘/q,沉船/n,。/w,英媒/nw,曝光/v,的/u,高清/n,图片/n,可见/v,,/w,沉船/n,的/u,部分/n,残骸/n,遭/v,腐蚀/v,情况/n,严重/a,。/w

该方式累计有效分词67个,其中单字分词结果20个。

通过上述分词结果我们可以看到,精准分词在整体的分词效果上确实较好,在新词识别上,如上面文字中的“盐蚀”“英媒”的识别,是带有新词发现功能的分词,即NlpAnalysis的效果更好。

2.7.2 Jcseg轻量级Java中文分词器

Jcseg是基于MMSEG算法的一个轻量级中文分词器,集成了关键字提取、关键短语提取、关键句子提取和文章自动摘要等功能,并且提供了一个基于Jetty的Web服务器,方便各大语言直接HTTP调用,同时提供了最新版本的Lucene、Solr和Elasticsearch的分词接口。

此外,Jcseg还自带了一个jcseg.properties文件,用于快速配置,从而得到适合不同场合的分词应用,如最大匹配词长、是否开启中文人名识别、是否追加拼音、是否追加同义词等。

Jcseg支持的中文分词模式有六种,即简易模式、复杂模式、检测模式、检索模式、分隔符模式、NLP模式,各自特点如下。

(1)简易模式:基于FMM算法实现,适合分词速度要求较高的场合。

(2)复杂模式:基于MMSEG四种过滤算法实现,可去除较高的歧义,分词准确率达98.41%。

(3)检测模式:只返回词库中已有的词条,很适合某些应用场合。

(4)检索模式:转为细粒度切分,专为检索而生。除中文处理外(不具备中文的人名、数字识别等智能功能),其他与复杂模式一致(英文,组合词等)。

(5)分隔符模式:按照给定的字符切分词条,默认是空格,特定场合的应用。

(6)NLP模式:继承自复杂模式,更改了数字、单位等词条的组合方式,增加了电子邮件、手机号码、网址、人名、地名、货币等无限种自定义实体的识别与返回。

Jcseg的核心功能有中文分词、关键字提取、关键短语提取、关键句子提取、文章自动摘要、自动词性标注和命名实体标注,并提供了RESTful API。各个功能的介绍如下。

① 中文分词:基于MMSEG算法和Jcseg独创的优化算法实现,有四种切分模式。

② 关键字提取:基于textRank算法实现。

③ 关键短语提取:基于textRank算法实现。

④ 关键句子提取:基于textRank算法实现。

⑤ 文章自动摘要:基于BM25+textRank算法实现。

⑥ 自动词性标注:基于词库实现。目前效果不是很理想,对词性标注结果要求较高的应用不建议使用。

⑦ 命名实体标注:基于词库实现,可以识别电子邮件、网址、手机号码、地名、人名、货币、datetime时间、长度、面积、距离单位等。

⑧ RESTful API:嵌入Jetty并提供了一个绝对高性能的Server模块,包含全部功能的HTTP接口,标准化JSON输出格式,方便各种语言客户端直接调用。

Jcseg支持自定义词库。在jcseg\vendors\lexicon文件夹下,可以随便添加、删除、更改词库和词库内容,并且对词库进行了分类。此外,Jcseg还支持词库多目录加载,在配置lexicon.path时使用';'隔开多个词库目录即可。

词库中的汉字类型可以分为简体、繁体、简繁体混合类型,Jcseg可以专门适用于简体切分、繁体切分、简繁体混合切分,并且可以利用同义词实现简繁体的相互检索。Jcseg同时提供了两个简单的词库管理工具来进行简繁体的转换和词库的合并。

Jcseg还支持中英文同义词追加、同义词匹配、中文词条拼音追加。Jcseg的词库中整合了《现代汉语词典》和cc-cedict辞典中的词条,并且依据cc-cedict词典为词条标上了拼音。使用时,可以更改jcseg.properties配置文档,在分词的时候,把拼音和同义词加入分词结果中。

Jcseg还支持中文数字和中文分数识别,如“一百五十个人都来了,四十分之一的人。”中的“一百五十”和“四十分之一”均可有效识别。在输出结果时,Jcseg会自动将其转换为阿拉伯数字加入分词结果中,如150、1/40。

Jcseg支持中英混合词和英中混合词的识别,如B超、X射线、卡拉OK、奇都KTV、哆啦A梦等。此外,Jcseg还支持阿拉伯数字/小数/中文数字基本单字单位的识别,如2012年、1.75米、38.6℃、五折(Jcseg会将其转换为“5折”加入分词结果中)。

Jcseg对智能圆角半角、英文大小写转换、特殊字母识别(如Ⅰ、Ⅱ、①、⑩)等均能有效支持。

Jcseg可以配置Elasticsearch使用,具体步骤如下。

(1)拉取Jcseg工程代码并进行编译打包。其中,拉取代码的命令为git clone https://gitee.com/lionsoul/jcseg.git,如图2-7所示。

图2-7

将Jcseg工程代码拉取到本地后切换到Jcseg目录,即在DOS窗口中执行命令cd jcseg,随后在该目录下执行编译打包命令mvn package,编译执行的输出结果如图2-8所示。

图2-8

编译打包成功后,输出的内容如图2-9所示。

图2-9

(2)在Elasticsearch工程中配置Jcseg分词,具体方法如下。

先在\elasticsearch-7.2.0\plugins目录下新建文件夹jcseg,如图2-10所示。

图2-10

将(1)中打包的3个jar文件jcseg-analyzer-2.4.1.jar、jcseg-core-2.4.1.jar和jcseg-elasticsearch-2.4.1.jar复制到{ES_HOME}/plugins/jcseg目录下,如图2-11所示。

图2-11

将Jcseg工程中的配置文件\jcseg-core\jcseg.properties复制到{ES_HOME}/plugins/jcseg目录下,如图2-12所示。

图2-12

将Jcseg工程中的配置文件jcseg-elasticsearch/plugin/plugin-descriptor.properties复制到{ES_HOME}/plugins/jcseg目录下,如图2-13所示。

图2-13

将Jcseg工程中的lexicon文件夹复制到{ES_HOME}/plugins/jcseg目录下,如图2-14所示。

图2-14

随后配置jcseg.properties,主要是配置lexicon.path,以便指向正确的词库,笔者本机的配置如图2-15所示。

图2-15

启动Elasticsearch,在启动过程中会加载Jcseg,如图2-16所示。

图2-16

在DOS窗口运行以下命令,测试分词效果。

分词结果打印如下所示。