澳门新葡亰平台游戏网站7个优秀的开源中文分词库推荐,实用性强!

本文的目标有两个:

纵观整个开源领域,陆陆续续做中文分词的也有不少,不过目前仍在维护的且质量较高的并不多。下面整理了一些个人认为比较优秀的中文分词库,以供大家参考使用。

1)ICTCLAS

1、学会使用11大Java开源中文分词器

1、jieba —— Python 中文分词组件

“结巴”中文分词,做最好的 Python 中文分词组件。

特性

  • 支持三种分词模式:

    • 精确模式,试图将句子最精确地切开,适合文本分析;

    • 全模式,把句子中所有的可以成词的词语都扫描出来,
      速度非常快,但是不能解决歧义;

    • 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。

  • 支持繁体分词

  • 支持自定义词典

算法

  • 基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图

  • 采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合

  • 对于未登录词,采用了基于汉字成词能力的 HMM 模型,使用了 Viterbi 算法

代码示例

# encoding=utf-8 import jiebaseg_list = jieba.cut("我来到北京清华大学", cut_all=True)print("Full Mode: " + "/ ".join) # 全模式 seg_list = jieba.cut("我来到北京清华大学", cut_all=False)print("Default Mode: " + "/ ".join) # 精确模式 seg_list = jieba.cut("他来到了网易杭研大厦") # 默认是精确模式 print(", ".join)seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") # 搜索引擎模式 print(", ".join)

输出:

: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学: 我/ 来到/ 北京/ 清华大学:他, 来到, 了, 网易, 杭研, 大厦 (此处,“杭研”并没有在词典中,但是也被Viterbi算法识别出来了): 小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造

最早的中文开源分词项目之一,由中科院计算所的张华平、刘群所开发,采用C/C++编写,算法基于《基于多层隐马模型的汉语词法分析研究》。其中开

2、对比分析11大Java开源中文分词器的分词效果

2、HanLP —— 汉语言处理包

HanLP是一系列模型与算法组成的NLP工具包,由大快搜索主导并完全开源,目标是普及自然语言处理在生产环境中的应用。HanLP具备功能完善、性能高效、架构清晰、语料时新、可自定义的特点。

HanLP提供下列功能:

  • 中文分词

    • HMM-Bigram(速度与精度最佳平衡;一百兆内存)

      • 最短路分词、N-最短路分词
    • 由字构词(侧重精度,可识别新词;适合NLP任务)

      • 感知机分词、CRF分词
    • 词典分词(侧重速度,每秒数千万字符;省内存)

      • 极速词典分词
    • 所有分词器都支持:

      • 索引全切分模式

      • 用户自定义词典

      • 兼容繁体中文

      • 训练用户自己的领域模型

  • 词性标注

    • HMM词性标注

    • 感知机词性标注、CRF词性标注

  • 命名实体识别

    • 基于HMM角色标注的命名实体识别

      • 中国人名识别、音译人名识别、日本人名识别、地名识别、实体机构名识别
    • 基于线性模型的命名实体识别

      • 感知机命名实体识别、CRF命名实体识别
  • 关键词提取

    • TextRank关键词提取
  • 自动摘要

    • TextRank自动摘要
  • 短语提取

    • 基于互信息和左右信息熵的短语提取
  • 拼音转换

    • 多音字、声母、韵母、声调
  • 简繁转换

    • 简繁分歧词(简体、繁体、臺灣正體、香港繁體)
  • 文本推荐

    • 语义推荐、拼音推荐、字词推荐
  • 依存句法分析

    • 基于神经网络的高性能依存句法分析器

    • MaxEnt依存句法分析

  • 文本分类

    • 情感分析
  • word2vec

    • 词向量训练、加载、词语相似度计算、语义运算、查询、KMeans聚类

    • 文档语义相似度计算

  • 语料库工具

    • 默认模型训练自小型语料库,鼓励用户自行训练。所有模块提供训练接口,语料可参考OpenCorpus。

在提供丰富功能的同时,HanLP内部模块坚持低耦合、模型坚持惰性加载、服务坚持静态提供、词典坚持明文发布,使用非常方便,同时自带一些语料处理工具,帮助用户训练自己的模型。

源版本为FreeICTCLAS,最新API调用版本为NLPIR/ICTCLAS2014分词系统(NLPIR分词系统前身为2000年发布的

本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那要用的人结合自己的应用场景自己来判断。

2、HanLP —— 汉语言处理包

HanLP是一系列模型与算法组成的NLP工具包,由大快搜索主导并完全开源,目标是普及自然语言处理在生产环境中的应用。HanLP具备功能完善、性能高效、架构清晰、语料时新、可自定义的特点。

HanLP提供下列功能:

  • 中文分词

    • HMM-Bigram(速度与精度最佳平衡;一百兆内存)

      • 最短路分词、N-最短路分词
    • 由字构词(侧重精度,可识别新词;适合NLP任务)

      • 感知机分词、CRF分词
    • 词典分词(侧重速度,每秒数千万字符;省内存)

      • 极速词典分词
    • 所有分词器都支持:

      • 索引全切分模式

      • 用户自定义词典

      • 兼容繁体中文

      • 训练用户自己的领域模型

  • 词性标注

    • HMM词性标注

    • 感知机词性标注、CRF词性标注

  • 命名实体识别

    • 基于HMM角色标注的命名实体识别

      • 中国人名识别、音译人名识别、日本人名识别、地名识别、实体机构名识别
    • 基于线性模型的命名实体识别

      • 感知机命名实体识别、CRF命名实体识别
  • 关键词提取

    • TextRank关键词提取
  • 自动摘要

    • TextRank自动摘要
  • 短语提取

    • 基于互信息和左右信息熵的短语提取
  • 拼音转换

    • 多音字、声母、韵母、声调
  • 简繁转换

    • 简繁分歧词(简体、繁体、臺灣正體、香港繁體)
  • 文本推荐

    • 语义推荐、拼音推荐、字词推荐
  • 依存句法分析

    • 基于神经网络的高性能依存句法分析器

    • MaxEnt依存句法分析

  • 文本分类

    • 情感分析
  • word2vec

    • 词向量训练、加载、词语相似度计算、语义运算、查询、KMeans聚类

    • 文档语义相似度计算

  • 语料库工具

    • 默认模型训练自小型语料库,鼓励用户自行训练。所有模块提供训练接口,语料可参考OpenCorpus。

在提供丰富功能的同时,HanLP内部模块坚持低耦合、模型坚持惰性加载、服务坚持静态提供、词典坚持明文发布,使用非常方便,同时自带一些语料处理工具,帮助用户训练自己的模型。

ICTCLAS词法分析系统,从2009年开始,为了和以前工作进行大的区隔,并推广NLPIR自然语言处理与信息检索共享平台,调整命名为NLPIR分

11大Java开源中文分词器,不同的分词器有不同的用法,定义的接口也不一样,我们先定义一个统一的接口:

3、Jcseg —— 轻量级 Java 中文分词器

Jcseg 是基于 mmseg
算法的一个轻量级中文分词器,同时集成了关键字提取,关键短语提取,关键句子提取和文章自动摘要等功能,并且提供了一个基于
Jetty 的 web 服务器,方便各大语言直接 http 调用,同时提供了最新版本的
lucene, solr, elasticsearch 的分词接口!Jcseg 自带了一个
jcseg.properties
文件用于快速配置而得到适合不同场合的分词应用,例如:最大匹配词长,是否开启中文人名识别,是否追加拼音,是否追加同义词等!

核心功能:

  • 中文分词:mmseg 算法 + Jcseg 独创的优化算法,四种切分模式。

  • 关键字提取:基于 textRank 算法。

  • 关键短语提取:基于 textRank 算法。

  • 关键句子提取:基于 textRank 算法。

  • 文章自动摘要:基于 BM25+textRank 算法。

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

  • 命名实体标注:基于词库+,电子邮件,网址,大陆手机号码,地名,人名,货币,datetime
    时间,长度,面积,距离单位等。

  • Restful api:嵌入 jetty 提供了一个绝对高性能的 server
    模块,包含全部功能的http接口,标准化 json
    输出格式,方便各种语言客户端直接调用。

中文分词模式:

六种切分模式

  • .简易模式:FMM 算法,适合速度要求场合。

  • .复杂模式:MMSEG 四种过滤算法,具有较高的歧义去除,分词准确率达到了
    98.41%。

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

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

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

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

词系统)

/**
 * 获取文本的所有分词结果, 对比不同分词器结果
 * @author 杨尚川
 */
public interface WordSegmenter {
    /**
     * 获取文本的所有分词结果
     * @param text 文本
     * @return 所有的分词结果,去除重复
     */
    default public Set<String> seg(String text) {
        return segMore(text).values().stream().collect(Collectors.toSet());
    }
    /**
     * 获取文本的所有分词结果
     * @param text 文本
     * @return 所有的分词结果,KEY 为分词器模式,VALUE 为分词器结果
     */
    public Map<String, String> segMore(String text);
}

4、sego —— Go 中文分词

sego 是一个 Go 中文分词库,词典用双数组 trie(Double-Array Trie)实现,
分词器算法为基于词频的最短路径加动态规划。

支持普通和搜索引擎两种分词模式,支持用户词典、词性标注,可运行 JSON RPC
服务。

分词速度单线程 9MB/s,goroutines 并发 42MB/s(8核 Macbook Pro)。

示例代码:

package main import ( "fmt" "github.com/huichen/sego" ) func main() { // 载入词典 var segmenter sego.Segmenter segmenter.LoadDictionary("github.com/huichen/sego/data/dictionary.txt") // 分词 text := []byte("中华人民共和国中央人民政府") segments := segmenter.Segment // 处理分词结果 // 支持普通模式和搜索模式两种分词,见代码中SegmentsToString函数的注释。 fmt.Println(sego.SegmentsToString(segments, false)) }

FreeICTCLAS源代码地址为:

从上面的定义我们知道,在Java中,同样的方法名称和参数,但是返回值不同,这种情况不可以使用重载。

5、 FoolNLTK —— 可能是最准的开源中文分词

中文处理工具包

特点

  • 可能不是最快的开源中文分词,但很可能是最准的开源中文分词

  • 基于 BiLSTM 模型训练而成

  • 包含分词,词性标注,实体识别, 都有比较高的准确率

  • 用户自定义词典

  • 可训练自己的模型

  • 批量处理

定制自己的模型

get clone https://github.com/rockyzhengwu/FoolNLTK.git cd FoolNLTK/train

分词

import fooltext = "一个傻子在北京" print(fool.cut # ['一个', '傻子', '在', '北京']

这两个方法的区别在于返回值,每一个分词器都可能有多种分词模式,每种模式的分词结果都可能不相同,第一个方法忽略分词器模式,返回所有模式的所有不重复分词结果,第二个方法返回每一种分词器模式及其对应的分词结果。

6、Ansj 中文分词 —— 基于 n-Gram+CRF+HMM 的中文分词的 Java 实现

Ansj 中文分词是一个基于 n-Gram+CRF+HMM 的中文分词的 java
实现。分词速度达到每秒钟大约200万字左右(mac
air下测试),准确率能达到96%以上。目前实现了中文分词、中文姓名识别、用户自定义词典、关键字提取、自动摘要、关键字标记等功能,可以应用到自然语言处理等方面,适用于对分词效果要求高的各种项目。

下面是一个简单的分词效果,仅做参考:

[脚下/f, 的/uj, 一大/j, 块/q, 方砖/n, 地面/n][长春/ns, 市长/n, 春节/t, 讲话/n][结婚/v, 的/uj, 和/c, 尚未/d, 结婚/v, 的/uj][结合/v, 成/v, 分子/n, 时/ng][旅游/vn, 和/c, 服务/vn, 是/v, 最/d, 好/a, 的/uj][邓颖/nr, 超生/v, 前/f, 最/d, 喜欢/v, 的/uj, 一个/m, 东西/n][中国/ns, 航天/n, 官员/n, 应邀/v, 到/v, 美国/ns, 与/p, 太空/s, 总署/n, 官员/n, 开会/v][上海/ns, 大学城/n, 书店/n][北京/ns, 大/a, 学生/n, 前来/v, 应聘/v][中外/j, 科学/n, 名著/n][为/p, 人民/n, 服务/vn][独立自主/i, 和/c, 平等互利/l, 的/uj, 原则/n][为/p, 人民/n, 办/v, 公益/n][这/r, 事/n, 的/uj, 确定/v, 不/d, 下来/v][费孝/nr, 通向/v, 人大常委会/nt, 提交/v, 书面/b, 报告/n][aaa/en, 分/q, 事实上/l, 发货/v, 丨/null, 和/c, 无/v, 哦/e, 喝/vg, 完/v, 酒/n][不好意思/a, 清清爽爽/z][长春市/ns, 春节/t, 讲话/n][中华人民共和国/ns, 万岁/n, 万岁/n, 万万岁/n][检察院/n, 鲍绍/nr, 检察长/n, 就是/d, 在/p, 世/ng, 诸葛/nr, ./m, 像/v, 诸葛亮/nr, 一样/u, 聪明/a][长春市/ns, 长春/ns, 药店/n][乒乓球拍/n, 卖/v, 完/v, 了/ul][计算机/n, 网络管理员/n, 用/p, 虚拟机/userDefine, 实现/v, 了/ul, 手机/n, 游戏/n, 下载/v, 和/c, 开源/v, 项目/n, 的/uj, 管理/vn, 金山/nz, 毒霸/nz][长春市/ns, 长春/ns, 药店/n][胡锦涛/nr, 与/p, 神/n, 九/m, 航天员/n, 首次/m, 实现/v, 天地/n, 双向/d, 视频/n, 通话/v][mysql/en, 不/d, 支持/v, /null, 同台/v, 机器/n, 两个/m, mysql/en, 数据库/n, 之间/f, 做/v, 触发器/n][孙建/nr, 是/v, 一个/m, 好/a, 人/n, ./m, 他/r, 和/c, 蔡晴/nr, 是/v, 夫妻/n, 两/m, /null, ,/null, 对于/p, 每/r, 一本/m, 好书/n, 他/r, 都/d, 原意/n, 一一/d, 读取/v, ../m, 他们/r, 都/d, 很/d, 喜欢/v, 元宵/n, ./m, 康燕/nr, 和/c, 他们/r, 住/v, 在/p, 一起/s, ./m, 我/r, 和/c, 马春亮/nr, ,/null, 韩鹏飞/nr, 都/d, 是/v, 好/a, 朋友/n, ,/null, 不/d, 知道/v, 什么/r, 原因/n][一年/m, 有/v, 三百六十五个/m, 日出/v, /null, 我/r, 送/v, 你/r, 三百六十五个/m, 祝福/vn, /null, 时钟/n, 每天/r, 转/v, 了/ul, 一千四百四十圈/m, 我/r, 的/uj, 心/n, 每天/r, 都/d, 藏/v, 着/uz, /null, 一千四百四十多个/m, 思念/v, /null, 每/r, 一天/m, 都/d, 要/v, 祝/v, 你/r, 快快乐乐/z, /null, /null, 每/r, 一分钟/m, 都/d, 盼望/v, 你/r, 平平安安/z, /null, 吉祥/n, 的/uj, 光/n, 永远/d, 环绕/v, 着/uz, 你/r, /null, 像/v, 那/r, 旭日东升/l, 灿烂/a, 无比/z, /null][学校/n, 学费/n, 要/v, 一次性/d, 交/v, 一千元/m][发展/vn, 中国/ns, 家庭/n, 养猪/v, 事业/n][安徽省/ns, 是/v, 一个/m, 发展/vn, 中/f, 的/uj, 省/n][北京理工大学/nt, 办事处/n]

(ICTCLAS Version 1.0 for
Linux)

在这里,需要注意的是我们使用了Java8中的新特性默认方法,并使用stream把一个map的value转换为不重复的集合。

7、word 分词 —— Java 分布式中文分词组件

word 分词是一个 Java
实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用 ngram
模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录词。能通过自定义配置文件来改变组件行为,能自定义用户词库、自动检测词库变化、支持大规模分布式环境,能灵活指定多种分词算法,能使用refine功能灵活控制分词结果,还能使用词频统计、词性标注、同义标注、反义标注、拼音标注等功能。提供了10种分词算法,还提供了10种文本相似度算法,同时还无缝和
Lucene、Solr、ElasticSearch、Luke 集成。注意:word1.3 需要 JDK1.8 。

分词算法效果评估:

1、word分词 最大Ngram分值算法:分词速度:370.9714 字符/毫秒行数完美率:66.55% 行数错误率:33.44% 总的行数:2533709 完美行数:1686210 错误行数:847499字数完美率:60.94% 字数错误率:39.05% 总的字数:28374490 完美字数:17293964 错误字数:110805262、word分词 最少词数算法:分词速度:330.1586 字符/毫秒行数完美率:65.67% 行数错误率:34.32% 总的行数:2533709 完美行数:1663958 错误行数:869751字数完美率:60.12% 字数错误率:39.87% 总的字数:28374490 完美字数:17059641 错误字数:113148493、word分词 全切分算法:分词速度:62.960262 字符/毫秒行数完美率:57.2% 行数错误率:42.79% 总的行数:2533709 完美行数:1449288 错误行数:1084421字数完美率:47.95% 字数错误率:52.04% 总的字数:28374490 完美字数:13605742 错误字数:147687484、word分词 双向最大最小匹配算法:分词速度:462.87158 字符/毫秒行数完美率:53.06% 行数错误率:46.93% 总的行数:2533709 完美行数:1344624 错误行数:1189085字数完美率:43.07% 字数错误率:56.92% 总的字数:28374490 完美字数:12221610 错误字数:161528805、word分词 双向最小匹配算法:分词速度:967.68604 字符/毫秒行数完美率:46.34% 行数错误率:53.65% 总的行数:2533709 完美行数:1174276 错误行数:1359433字数完美率:36.07% 字数错误率:63.92% 总的字数:28374490 完美字数:10236574 错误字数:181379166、word分词 双向最大匹配算法:分词速度:661.148 字符/毫秒行数完美率:46.18% 行数错误率:53.81% 总的行数:2533709 完美行数:1170075 错误行数:1363634字数完美率:35.65% 字数错误率:64.34% 总的字数:28374490 完美字数:10117122 错误字数:182573687、word分词 正向最大匹配算法:分词速度:1567.1318 字符/毫秒行数完美率:41.88% 行数错误率:58.11% 总的行数:2533709 完美行数:1061189 错误行数:1472520字数完美率:31.35% 字数错误率:68.64% 总的字数:28374490 完美字数:8896173 错误字数:194783178、word分词 逆向最大匹配算法:分词速度:1232.6017 字符/毫秒行数完美率:41.69% 行数错误率:58.3% 总的行数:2533709 完美行数:1056515 错误行数:1477194字数完美率:30.98% 字数错误率:69.01% 总的字数:28374490 完美字数:8792532 错误字数:195819589、word分词 逆向最小匹配算法:分词速度:1936.9575 字符/毫秒行数完美率:41.42% 行数错误率:58.57% 总的行数:2533709 完美行数:1049673 错误行数:1484036字数完美率:31.34% 字数错误率:68.65% 总的字数:28374490 完美字数:8893622 错误字数:1948086810、word分词 正向最小匹配算法:分词速度:2228.9465 字符/毫秒行数完美率:36.7% 行数错误率:63.29% 总的行数:2533709 完美行数:930069 错误行数:1603640字数完美率:26.72% 字数错误率:73.27% 总的字数:28374490 完美字数:7583741 错误字数:20790749

最后,如果有想一起学习python,爬虫开发,可以来一下我的python群【
784758214
】,内有安装包和学习视频资料免费分享,好友都会在里面交流,分享一些学习的方法和需要注意的小细节,每天也会准时的讲一些项目实战案例。找工作什么最重要?看中的还是你的实战经验

下面我们利用这11大分词器来实现这个接口:

1、word分词器

@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    for(SegmentationAlgorithm segmentationAlgorithm : SegmentationAlgorithm.values()){
        map.put(segmentationAlgorithm.getDes(), seg(text, segmentationAlgorithm));
    }
    return map;
}
private static String seg(String text, SegmentationAlgorithm segmentationAlgorithm) {
    StringBuilder result = new StringBuilder();
    for(Word word : WordSegmenter.segWithStopWords(text, segmentationAlgorithm)){
        result.append(word.getText()).append(" ");
    }
    return result.toString();
}

NLPIR/ICTCLAS2014 API下载地址为:

2、Ansj分词器

@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();

    StringBuilder result = new StringBuilder();
    for(Term term : BaseAnalysis.parse(text)){
        result.append(term.getName()).append(" ");
    }
    map.put("BaseAnalysis", result.toString());

    result.setLength(0);
    for(Term term : ToAnalysis.parse(text)){
        result.append(term.getName()).append(" ");
    }
    map.put("ToAnalysis", result.toString());

    result.setLength(0);
    for(Term term : NlpAnalysis.parse(text)){
        result.append(term.getName()).append(" ");
    }
    map.put("NlpAnalysis", result.toString());

    result.setLength(0);
    for(Term term : IndexAnalysis.parse(text)){
        result.append(term.getName()).append(" ");
    }
    map.put("IndexAnalysis", result.toString());

    return map;
}

3、Stanford分词器

private static final StanfordCoreNLP CTB = new StanfordCoreNLP("StanfordCoreNLP-chinese-ctb");
private static final StanfordCoreNLP PKU = new StanfordCoreNLP("StanfordCoreNLP-chinese-pku");
private static final PrintStream NULL_PRINT_STREAM = new PrintStream(new NullOutputStream(), false);
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    map.put("Stanford Beijing University segmentation", seg(PKU, text));
    map.put("Stanford Chinese Treebank segmentation", seg(CTB, text));
    return map;
}
private static String seg(StanfordCoreNLP stanfordCoreNLP, String text){
    PrintStream err = System.err;
    System.setErr(NULL_PRINT_STREAM);
    Annotation document = new Annotation(text);
    stanfordCoreNLP.annotate(document);
    List<CoreMap> sentences = document.get(CoreAnnotations.SentencesAnnotation.class);
    StringBuilder result = new StringBuilder();
    for(CoreMap sentence: sentences) {
        for (CoreLabel token: sentence.get(CoreAnnotations.TokensAnnotation.class)) {
            String word = token.get(CoreAnnotations.TextAnnotation.class);;
            result.append(word).append(" ");
        }
    }
    System.setErr(err);
    return result.toString();
}

其他版本:

4、FudanNLP分词器

private static CWSTagger tagger = null;
static{
    try{
        tagger = new CWSTagger("lib/fudannlp_seg.m");
        tagger.setEnFilter(true);
    }catch(Exception e){
        e.printStackTrace();
    }
}
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    map.put("FudanNLP", tagger.tag(text));
    return map;
}

(a) 在FreeICTCLAS基础上,由吕震宇老师根据开源版C++改写成的C#版。

5、Jieba分词器

private static final JiebaSegmenter JIEBA_SEGMENTER = new JiebaSegmenter();
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    map.put("INDEX", seg(text, SegMode.INDEX));
    map.put("SEARCH", seg(text, SegMode.SEARCH));
    return map;
}
private static String seg(String text, SegMode segMode) {
    StringBuilder result = new StringBuilder();                
    for(SegToken token : JIEBA_SEGMENTER.process(text, segMode)){
        result.append(token.word.getToken()).append(" ");
    }
    return result.toString(); 
}

下载地址为:

6、Jcseg分词器

private static final JcsegTaskConfig CONFIG = new JcsegTaskConfig();
private static final ADictionary DIC = DictionaryFactory.createDefaultDictionary(CONFIG);
static {
    CONFIG.setLoadCJKSyn(false);
    CONFIG.setLoadCJKPinyin(false);
}
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();

    map.put("复杂模式", segText(text, JcsegTaskConfig.COMPLEX_MODE));
    map.put("简易模式", segText(text, JcsegTaskConfig.SIMPLE_MODE));

    return map;
}
private String segText(String text, int segMode) {
    StringBuilder result = new StringBuilder();        
    try {
        ISegment seg = SegmentFactory.createJcseg(segMode, new Object[]{new StringReader(text), CONFIG, DIC});
        IWord word = null;
        while((word=seg.next())!=null) {         
            result.append(word.getValue()).append(" ");
        }
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
    return result.toString();
}

(原版)

7、MMSeg4j分词器

private static final Dictionary DIC = Dictionary.getInstance();
private static final SimpleSeg SIMPLE_SEG = new SimpleSeg(DIC);
private static final ComplexSeg COMPLEX_SEG = new ComplexSeg(DIC);
private static final MaxWordSeg MAX_WORD_SEG = new MaxWordSeg(DIC);
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    map.put(SIMPLE_SEG.getClass().getSimpleName(), segText(text, SIMPLE_SEG));
    map.put(COMPLEX_SEG.getClass().getSimpleName(), segText(text, COMPLEX_SEG));
    map.put(MAX_WORD_SEG.getClass().getSimpleName(), segText(text, MAX_WORD_SEG));
    return map;
}
private String segText(String text, Seg seg) {
    StringBuilder result = new StringBuilder();
    MMSeg mmSeg = new MMSeg(new StringReader(text), seg);        
    try {
        Word word = null;
        while((word=mmSeg.next())!=null) {       
            result.append(word.getString()).append(" ");
        }
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    }
    return result.toString();
}

(支持多线程版)

8、IKAnalyzer分词器

@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();

    map.put("智能切分", segText(text, true));
    map.put("细粒度切分", segText(text, false));

    return map;
}
private String segText(String text, boolean useSmart) {
    StringBuilder result = new StringBuilder();
    IKSegmenter ik = new IKSegmenter(new StringReader(text), useSmart);        
    try {
        Lexeme word = null;
        while((word=ik.next())!=null) {          
            result.append(word.getLexemeText()).append(" ");
        }
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    }
    return result.toString();
}

(b) 对ICTCLAS分词系统代码及SharpICTCLAS代码理解可参考:

9、Paoding分词器

private static final PaodingAnalyzer ANALYZER = new PaodingAnalyzer();
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();

    map.put("MOST_WORDS_MODE", seg(text, PaodingAnalyzer.MOST_WORDS_MODE));
    map.put("MAX_WORD_LENGTH_MODE", seg(text, PaodingAnalyzer.MAX_WORD_LENGTH_MODE));

    return map;
}
private static String seg(String text, int mode){
    ANALYZER.setMode(mode);
    StringBuilder result = new StringBuilder();
    try {
        Token reusableToken = new Token();
        TokenStream stream = ANALYZER.tokenStream("", new StringReader(text));
        Token token = null;
        while((token = stream.next(reusableToken)) != null){
            result.append(token.term()).append(" ");
        }
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
    return result.toString();          
}

10、smartcn分词器

private static final SmartChineseAnalyzer SMART_CHINESE_ANALYZER = new SmartChineseAnalyzer();
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    map.put("smartcn", segText(text));
    return map;
}
private static String segText(String text) {
    StringBuilder result = new StringBuilder();
    try {
        TokenStream tokenStream = SMART_CHINESE_ANALYZER.tokenStream("text", new StringReader(text));
        tokenStream.reset();
        while (tokenStream.incrementToken()){
            CharTermAttribute charTermAttribute = tokenStream.getAttribute(CharTermAttribute.class);
            result.append(charTermAttribute.toString()).append(" ");
        }
        tokenStream.close();
    }catch (Exception e){
        e.printStackTrace();
    }
    return result.toString();
}

11、HanLP分词器

private static final Segment N_SHORT_SEGMENT = new NShortSegment().enableCustomDictionary(false).enablePlaceRecognize(true).enableOrganizationRecognize(true);
private static final Segment DIJKSTRA_SEGMENT = new DijkstraSegment().enableCustomDictionary(false).enablePlaceRecognize(true).enableOrganizationRecognize(true);
@Override
public Map<String, String> segMore(String text) {
    Map<String, String> map = new HashMap<>();
    map.put("标准分词", standard(text));
    map.put("NLP分词", nlp(text));
    map.put("索引分词", index(text));
    map.put("N-最短路径分词", nShort(text));
    map.put("最短路径分词", shortest(text));
    map.put("极速词典分词", speed(text));
    return map;
}
private static String standard(String text) {
    StringBuilder result = new StringBuilder();
    StandardTokenizer.segment(text).forEach(term->result.append(term.word).append(" "));
    return result.toString();
}
private static String nlp(String text) {
    StringBuilder result = new StringBuilder();
    NLPTokenizer.segment(text).forEach(term->result.append(term.word).append(" "));
    return result.toString();
}
private static String index(String text) {
    StringBuilder result = new StringBuilder();
    IndexTokenizer.segment(text).forEach(term->result.append(term.word).append(" "));
    return result.toString();
}
private static String speed(String text) {
    StringBuilder result = new StringBuilder();
    SpeedTokenizer.segment(text).forEach(term->result.append(term.word).append(" "));
    return result.toString();
}
private static String nShort(String text) {
    StringBuilder result = new StringBuilder();
    N_SHORT_SEGMENT.seg(text).forEach(term->result.append(term.word).append(" "));
    return result.toString();
}
private static String shortest(String text) {
    StringBuilder result = new StringBuilder();
    DIJKSTRA_SEGMENT.seg(text).forEach(term->result.append(term.word).append(" "));
    return result.toString();
}

现在我们已经实现了本文的第一个目的:学会使用11大Java开源中文分词器。

最后我们来实现本文的第二个目的:对比分析11大Java开源中文分词器的分词效果,程序如下:

public static Map<String, Set<String>> contrast(String text){
    Map<String, Set<String>> map = new LinkedHashMap<>();
    map.put("word分词器", new WordEvaluation().seg(text));
    map.put("Stanford分词器", new StanfordEvaluation().seg(text));
    map.put("Ansj分词器", new AnsjEvaluation().seg(text));
    map.put("HanLP分词器", new HanLPEvaluation().seg(text));
    map.put("FudanNLP分词器", new FudanNLPEvaluation().seg(text));
    map.put("Jieba分词器", new JiebaEvaluation().seg(text));
    map.put("Jcseg分词器", new JcsegEvaluation().seg(text));
    map.put("MMSeg4j分词器", new MMSeg4jEvaluation().seg(text));
    map.put("IKAnalyzer分词器", new IKAnalyzerEvaluation().seg(text));
    map.put("smartcn分词器", new SmartCNEvaluation().seg(text));
    return map;
}
public static Map<String, Map<String, String>> contrastMore(String text){
    Map<String, Map<String, String>> map = new LinkedHashMap<>();
    map.put("word分词器", new WordEvaluation().segMore(text));
    map.put("Stanford分词器", new StanfordEvaluation().segMore(text));
    map.put("Ansj分词器", new AnsjEvaluation().segMore(text));
    map.put("HanLP分词器", new HanLPEvaluation().segMore(text));
    map.put("FudanNLP分词器", new FudanNLPEvaluation().segMore(text));
    map.put("Jieba分词器", new JiebaEvaluation().segMore(text));
    map.put("Jcseg分词器", new JcsegEvaluation().segMore(text));
    map.put("MMSeg4j分词器", new MMSeg4jEvaluation().segMore(text));
    map.put("IKAnalyzer分词器", new IKAnalyzerEvaluation().segMore(text));
    map.put("smartcn分词器", new SmartCNEvaluation().segMore(text));
    return map;
}
public static void show(Map<String, Set<String>> map){
    map.keySet().forEach(k -> {
        System.out.println(k + " 的分词结果:");
        AtomicInteger i = new AtomicInteger();
        map.get(k).forEach(v -> {
            System.out.println("t" + i.incrementAndGet() + " 、" + v);
        });
    });
}
public static void showMore(Map<String, Map<String, String>> map){
    map.keySet().forEach(k->{
        System.out.println(k + " 的分词结果:");
        AtomicInteger i = new AtomicInteger();
        map.get(k).keySet().forEach(a -> {
            System.out.println("t" + i.incrementAndGet()+ " 、【"   + a + "】t" + map.get(k).get(a));
        });
    });
}
public static void main(String[] args) {
    show(contrast("我爱楚离陌"));
    showMore(contrastMore("我爱楚离陌"));
}

运行结果如下:

********************************************
word分词器 的分词结果:
    1 、我 爱 楚离陌 
Stanford分词器 的分词结果:
    1 、我 爱 楚 离陌 
    2 、我 爱 楚离陌 
Ansj分词器 的分词结果:
    1 、我 爱 楚离 陌 
    2 、我 爱 楚 离 陌 
HanLP分词器 的分词结果:
    1 、我 爱 楚 离 陌 
smartcn分词器 的分词结果:
    1 、我 爱 楚 离 陌 
FudanNLP分词器 的分词结果:
    1 、我 爱楚离陌
Jieba分词器 的分词结果:
    1 、我爱楚 离 陌 
Jcseg分词器 的分词结果:
    1 、我 爱 楚 离 陌 
MMSeg4j分词器 的分词结果:
    1 、我爱 楚 离 陌 
IKAnalyzer分词器 的分词结果:
    1 、我 爱 楚 离 陌 
********************************************

********************************************
word分词器 的分词结果:
    1 、【全切分算法】  我 爱 楚离陌 
    2 、【双向最大最小匹配算法】  我 爱 楚离陌 
    3 、【正向最大匹配算法】  我 爱 楚离陌 
    4 、【双向最大匹配算法】  我 爱 楚离陌 
    5 、【逆向最大匹配算法】  我 爱 楚离陌 
    6 、【正向最小匹配算法】  我 爱 楚离陌 
    7 、【双向最小匹配算法】  我 爱 楚离陌 
    8 、【逆向最小匹配算法】  我 爱 楚离陌 
Stanford分词器 的分词结果:
    1 、【Stanford Chinese Treebank segmentation】    我 爱 楚离陌 
    2 、【Stanford Beijing University segmentation】  我 爱 楚 离陌 
Ansj分词器 的分词结果:
    1 、【BaseAnalysis】  我 爱 楚 离 陌 
    2 、【IndexAnalysis】 我 爱 楚 离 陌 
    3 、【ToAnalysis】    我 爱 楚 离 陌 
    4 、【NlpAnalysis】   我 爱 楚离 陌 
HanLP分词器 的分词结果:
    1 、【NLP分词】   我 爱 楚 离 陌 
    2 、【标准分词】  我 爱 楚 离 陌 
    3 、【N-最短路径分词】    我 爱 楚 离 陌 
    4 、【索引分词】  我 爱 楚 离 陌 
    5 、【最短路径分词】  我 爱 楚 离 陌 
    6 、【极速词典分词】  我 爱 楚 离 陌 
smartcn分词器 的分词结果:
    1 、【smartcn】   我 爱 楚 离 陌 
FudanNLP分词器 的分词结果:
    1 、【FudanNLP】  我 爱楚离陌
Jieba分词器 的分词结果:
    1 、【SEARCH】    我爱楚 离 陌 
    2 、【INDEX】 我爱楚 离 陌 
Jcseg分词器 的分词结果:
    1 、【简易模式】  我 爱 楚 离 陌 
    2 、【复杂模式】  我 爱 楚 离 陌 
MMSeg4j分词器 的分词结果:
    1 、【SimpleSeg】 我爱 楚 离 陌 
    2 、【ComplexSeg】    我爱 楚 离 陌 
    3 、【MaxWordSeg】    我爱 楚 离 陌 
IKAnalyzer分词器 的分词结果:
    1 、【智能切分】  我 爱 楚 离 陌 
    2 、【细粒度切分】  我 爱 楚 离 陌 
********************************************

完整代码看这里

(c)
ictclas4j中文分词系统是sinboy在FreeICTCLAS的基础上完成的一个java开源分词项目,简化了原分词程序的复杂度。

下载地址为:

(d) ICTCLAS Python调用

Python下调用NLPIR(ICTCLAS2013)可参考:

Python wrapper for ICTCLAS 2015 可参考:

(一个外国小哥搞得,还有文档介绍

2)MMSEG

采用Chih-Hao Tsai的MMSEG算法(A Word Identification System for Mandarin
Chinese Text Based on Two Variants of the Maximum Matching
Algorithm)。MMSeg 算法有两种分词方法:Simple(only forward maximum
matching)和Complex(three-word chunk maximum matching and 3 additional
rules to solve ambiguities),都是基于正向最大匹配,Complex
加了四个规则过虑。

源代码下载地址为:

注:

(a) LibMMSeg
是Coreseek.com为Sphinx全文搜索引擎设计的中文分词软件包,其在GPL协议下发行的中文分词法,也是采用Chih-Hao
Tsai的MMSEG算法。LibMMSeg 采用C++开发,同时支持Linux平台和Windows平台。

源代码下载地址为:

(b)
friso是使用c语言开发的一个中文分词器,使用流行的mmseg算法实现。支持对UTF-8/GBK编码的切分,绑定了php扩展和sphinx
token插件

三种切分模式:(1).简易模式:FMM算法 (2).复杂模式-MMSEG四种过滤算法
(3)检测模式:只返回词库中已有的词条

源代码下载地址为:

(c) MMSEG4J 是基于MMSeg 算法的Java开源中文分词组件,提供lucene和solr
接口

源代码下载地址为:

(d) RMMSeg is written in pure Ruby. RMMSegis an implementation of MMSEG
word segmentation algorithm. It is based on two variants of maximum
matching algorithms.

源代码下载地址为:

(e) rmmseg-cpp is a re-written of the original RMMSeggem in C++, the
core part is written in C++ independent of Ruby. It ismuch faster and
cosumes much less memory than RMMSeg. The interface of rmmseg-cpp is
almost identical to RMMSeg.

源代码下载地址为:

(f) pymmseg-cpp is a Python interface to rmmseg-cpp.

源代码下载地址为:

3)IKAnalyzer

IKAnalyzer是一个开源基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出
了3个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本IKAnalyzer3.0采用了特有的“正向迭代最细粒度切分算法“,已发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。

源代码下载地址为:

4)FNLP(FudanNLP)

FudanNLP主要是为中文自然语言处理而开发的工具包(现已更名为FNLP),功能包含信息检索(文本分类、新闻聚类),中文处理(中文分词、词性标注、实体名识别、关键词抽取、依存句法分析
时间短语识别),结构化学习(在线学习、层次分类、聚类)。从功能的角度而言,FNLP与著名的Python自然语言处理工具包NLTK较为类似,但后者对中文处理的能力较差。FNLP采用Java编写,可轻松运行在各种不同的平台之上。

源代码下载地址为:

5)NiuParser

中文句法语义分析系统NiuParser支持中文句子级的自动分词、词性标注、命名实体识别、组块识别、成分句法分析、依存句法分析和语义角色标注七大语言分析技术。所有代码采用C++语言开发,不包含任何其它开源代码。NiuParser系统可以免费用于研究目的,但商业用途需获得商业授权许可。

源代码下载地址为:

6) LTP

语言技术平台(Language Technology
Platform,LTP)是提供包括中文分词、词性标注、命名实体识别、依存句法分析、语义角色标注等丰富、
高效、精准的自然语言处理技术。LTP制定了基于XML的语言处理结果表示,并在此基础上提供了一整套自底向上的丰富而且高效的中文语言处理模块(包括词法、句法、语义等6项中文处理核心技术),以及基于动态链接库(Dynamic
Link Library, DLL)的应用程序接口、可视化工具,并且能够以网络服务(Web
Service)的形式进行使用。

源代码下载地址为:

注:

(a) LTP的分词模块(LTP-CWS)基于结构化感知器(Structured

Perceptron)算法构建,支持用户自定义词典,适应不同用户的需求;另外还新增了个性化(增量式)训练功能,用户可以根据自己的实际需求,如对新

领域的文本进行分词等,自行标注少量句子的分词结果(比如对LTP分词结果的修正),LTP分词模块可以重新训练一个更好应对新领域的分词器,进一步提高

新领域上分词的准确率。

源代码下载地址为:

(b) pyltp是LTP的Python封装

源代码下载地址为:

7)Ansj中文分词

基于google语义模型+条件随机场模型的中文分词的java实现,实现了.中文分词.
中文姓名识别 .
用户自定义词典。Ansj是基于ictclas工具的java实现,基本上重写了所有的数据结构和算法。使用开源版的ictclas词典.并且进行了部分的人工优化。

源代码下载地址为:

8) jieba中文分词

jieba”结巴”分词为Python
中文分词组件,支持三种分词模式:(a)精确模式,试图将句子最精确地切开,适合文本分析;(b)全模式,把句子中所有的可以成词的词语都扫描出来,
速度非常快,但是不能解决歧义;(c)搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。另外jieba分词支持繁体分词和自定义词典。

算法主要包括:基于Trie树结构实现高效的词图扫描,生成句子中汉字构成的有向无环图(DAG);采用了记忆化搜索实现最大概率路径的计算,
找出基于词频的最大切分组合;对于未登录词,采用了基于汉字位置概率的模型,使用了Viterbi算法。

源代码下载地址为:

注:

(a)模型数据生成,参见:

(b)CppJieba是”结巴”中文分词的C++版本,代码细节详见:

(c) cppjiebapy is a wrap for cppjieba by swig.
若想使用python来调用cppjieba,可查阅:

(d) jieba分词学习笔记,参见:

9)HanLP

HanLP是由一系列模型与算法组成的Java汉语言处理工具包,提供中文分词、词性标注、命名实体识别、依存句法分析、关键词提取、自动摘要、短语提取、拼音、简繁转换等完备的功能。CRFSegment支持自定义词典,自定义词典的优先级高于核心词典。

源代码下载地址为:

10)BosonNLP

BosonNLP是一家初创公司提供的API SDK调用接口。功能包括:Tokenization and
part of speech

tagging, named-entity recognition, tokenization and compute word weight,

automatic detection of opinions embodied in text, work out the

grammatical structure of sentences, categorization

the given articles, Get relative words.

API下载地址为:

11)Pullword在线抽词

Pullword是永久免费的基于深度学习的中文在线抽词

API调用Pullword,包含python,R等语言,参见:

12)sogo在线分词

sogo在线分词采用了基于汉字标注的分词方法,主要使用了线性链链CRF(Linear-chain
CRF)模型。词性标注模块主要基于结构化线性模型(Structured Linear Model)

在线使用地址为:

13)THULAC

THULAC(THU Lexical Analyzer for
Chinese)是清华开源的一套中文词法分析工具包,主要包括中文分词和词性标注功能。该工具包使用了基于词图(word
lattice)的重排序算法(re-ranking method).

源代码下载地址为:

最后的彩蛋:

(1) CRF分词训练工具:

CRFsuite ()

CRF++  ()

wapiti () or ()

chinesesegmentor () or
 ()

CRF decoder
包含CRF++软件包中分词解码器部分,简化了CRF++复杂代码结构,清除了分词解码器不需要的代码,大大提高了分词解码器的可读性和可懂度。
下载地址:

(2) 中文分词器分词效果评估对比,参见:

(3)中文词典开源项目(CC-CEDICT)

一份以汉语拼音为中文辅助的汉英辞典,可用于中文分词使用,而且不存在版权问题。Chrome中文版就是使用的这个词典进行中文分词的。

数据及文档下载地址为:

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图