阅读更多
Ansj 是一个开源的 Java 中文分词工具,基于中科院的 ictclas 中文分词算法,比其他常用的开源分词工具(如mmseg4j)的分词准确率更高。

在线演示:http://ansj.sdapp.cn/demo/seg.jsp
官网地址:http://www.ansj.org/
Github地址:https://github.com/ansjsun/ansj_seg

我们本期采访了Ansj的作者孙健,请他为大家详细介绍一下这个分词工具。

ITeye期待并致力于为国内优秀的开源项目提供一个免费的推广平台,如果你和你的团队希望将自己的开源项目介绍给更多的开发者,或者你希望我们对哪些开源项目进行专访,请告诉我们,发站内短信给ITeye管理员或者发邮件到webmaster@iteye.com即可。

先来个自我介绍吧! Top

孙健,胸无大志,没想过创业,没想过发财,只想高高兴兴写两行代码,做了近五年Java程序员,写过页面,干过运维,做过人力,忽悠过客户,擅长字符串操作,擅长数据结构和算法。现在主要从事检索、自然语言处理、数据挖掘等方面工作。

介绍一下Ansj! Top

Ansj中文分词是一款纯Java的、主要应用于自然语言处理的、高精度的中文分词工具,目标是“准确、高效、自由地进行中文分词”,可用于人名识别、地名识别、组织机构名识别、多级词性标注、关键词提取、指纹提取等领域,支持行业词典、用户自定义词典。

上面是客套话,先说明一下Ansj命名的由来吧。本来开始打算叫totoro分词(同事帮忙起的名),最后发现好多厕所中卫生洁具都叫“TOTO” ^_^

正好我注册了Ansj.org域名,于是乎,就叫这个名字吧。

你认为中文分词的难点是什么? Top

在这里说分词有点老生常谈了。的确,中文分词已经非常成熟了,但是之间有一些问题依旧比较难解。个人认为大致有以下几点吧:

1.  中文歧义的识别

比较出名的一句话“结婚的和尚未结婚的”,如果使用正向最大匹配,容易分成“结婚/的/和尚/未/结婚的”,于是有的学者试图倒过来识别,逆向匹配会大于正向。但是碰到这句“结合成分子时”,采用逆向最大匹配,则会分为“结合/成分/子时”,更有甚者像“咬了猎人的狗”这种语意不明的词语,就更不容易正确分词了。这是中文分词的软肋。下面是些典型的歧义句:

  • 交叉歧义(多种切分交织在一起):内塔内亚胡说的/确实/在理
  • 组合歧义(不同情况下切分不同):这个人/手上有痣、我们公司人手
  • 真歧义(几种切分都可以):乒乓球拍/卖/完了、乒乓球/拍卖/完了
2.  实体名识别

这个是中文分词遇到的最大的难点,也是最最紧迫的。实体名识别包括人名识别、地名识别、机构名识别,还包括有监督识别和无监督识别。有监督的还好,无监督基本是无解的,比如“王大力发球”是“王大力”还是“大力发球”,一般人都难以识别。

3.  新词热词发现

目前常用的新词发现还是一个比较有研究性的课题,虽然有些论文在准确率很高,但是大多是封闭测试,这意味着结果很难应用到实际工程中。目前Ansj采用的新词发现方式比较简单,采用了高频词的匹配方式,不使用规则,用统计重复串识别新词,根据词性去掉干扰词,虽然有一定的效果,但还是差强人意。

4.  颗粒度问题

这个就是一个规则探讨的问题了,比如“北京大学”是“北京”+“大学”还是“北京大学”,人各有志,就连同一个人不同时间的标注也有可能是有区别的,虽然这个问题严格上来说不属于技术问题,但是对分词结果的评测却有着很大的关系,Ansj采用“能识别就识别”的策略方针,所以在真正R值的时候偏低,总之一句话,适合学术的不一定适合工业,反之亦然。

简单介绍一下Ansj分词用到的算法,其分词原理是什么? Top

Ansj并非我创新,可以说是一个ictclas的Java版本,基本原理一致,只不过在分词优化算法上做了一些改进。

该算法实现分词有以下几个步骤:

  1. 全切分,原子切分;
  2. N最短路径的粗切分,根据隐马尔科夫模型和viterbi算法,达到最优路径的规划;
  3. 人名识别;
  4. 系统词典补充;
  5. 用户自定义词典的补充;
  6. 词性标注(可选)

Ansj分词的准确率大概是多少? Top

这是我采用人民日报1998年1月语料库的一个测试结果,首先要说明的是这份人工标注的语料库本身就有错误。

  • P(准确率):0.984887218571267
  • R(召回率):0.9626488103178712
  • F(综合指标F值):0.9736410471396494

在歧义、未登录词问题上,Ansj表现怎样? Top

歧异方面的处理方式自我感觉还可以,基于“最佳实践规则+统计”的方式,虽然还有一部分歧异无法识别,但是已经完全能满足工程应用了。

至于未登录词的识别,目前重点做了中文人名的识别,效果还算满意,识别方式用的“字体+前后监督”的方式,也算是目前我所知道的效果最好的一种识别方式了。

Ansj的性能如何? Top

在我的测试中,Ansj的效率已经远超ictclas的其他开源实现版本。

核心词典利用双数组规划,每秒钟能达到千万级别的粗分。在我的MacBookAir上面,分词速度大约在300w/字/秒,在酷睿i5+4G内存组装机器上,更是达到了400w+/字/秒的速度。

如何添加自定义词典? Top

Ansj已经实现了用户自定义词典的动态添加删除,当然,也支持从文件加载词典。

从硬盘加载用户自定义词典的方法:

用户自定义词典默认路径:项目目录/library/userLibrary/userLibrary.dic

格式为:[自定义词]  [词性]  [词频],如:csdn创新院  userDefine  1000,中间用TAB键隔开

原分词结果:[csdn, 创新, 院, 是, 一个, 好, 公司]

增加词典后:[csdn创新院, 是, 一个, 好, 公司]

详细内容见:用户自定义词典的添加

用户自定义词典的动态添加删除方法见:用户自定义词典的动态添加删除Demo

你在开发过程中,遇到哪些困难? Top

最大的困难是训练样本和语料库的不足,遗憾国内没有共享,大多数都是收费的,而且好贵。

你认为Ansj还需要在哪些方面进行完善? Top

我打算下一版的改进将围绕未登录词进行,采用crf来做新词的识别。当然随着系统的庞大,每次修改都要考虑效率内存占用。

虽然已经着手开始进行中,但是进展一直不快。有兴趣的同学可以多提意见,可以通过Github参与到该项目中,让我们做一个真正的Java版的高准确率分词。

Github地址:https://github.com/ansjsun/ansj_seg
  • 大小: 44.8 KB


评论 共 226 条
16 楼 fyland 2012-11-05 13:11
erliang20088 写道
fyland 写道
一看原来是用JAVA写的,马上兴趣全无!
JAVA干这种活速度实在太差了!


这是传统看法了,现在硬件提升很快,在效率和效果都能接受的情况下,用Java写一些以前C/C++的高效程序,完全没有问题。还是希望用数据说明问题~

硬件是实实在在用银子堆积起来的,同样算法的中文分词器,用C实现的也许2000块钱的机器就能非常良好的运行,用JAVA实现的也许6000块的机器都有点卡顿。
15 楼 erliang20088 2012-11-05 13:10
fyland 写道
zhangmiao_chp 写道
fyland 写道
一看原来是用JAVA写的,马上兴趣全无!
JAVA干这种活速度实在太差了!


楼上相当无知,决定系统性能的是数据结构和算法,和语言没有关系,算法提升的性能是成倍的,代码写的好不好要看你的功力强不强,和兵器有毛关系。支持楼主

到底谁无知?
同一种算法,只能用JAVA实现,而不能用C实现?
我没有否认数据结构和算法在性能方面的重要性(事实上我提都没提),我语义的环境是假设在相同算法上,用C语言实现的中文分词会比用JAVA实现的在运行速度上要快得多!在占用CPU和内存使用上,C占的优势就更不用说了!硬件那是实实在在用银子堆起来的!
JAVA唯一的优势就是开发速度。



你能免费得到C写的分词吗? 不要说开源的C写的分词,效果很差~
14 楼 fyland 2012-11-05 13:06
zhangmiao_chp 写道
fyland 写道
一看原来是用JAVA写的,马上兴趣全无!
JAVA干这种活速度实在太差了!


楼上相当无知,决定系统性能的是数据结构和算法,和语言没有关系,算法提升的性能是成倍的,代码写的好不好要看你的功力强不强,和兵器有毛关系。支持楼主

到底谁无知?
同一种算法,只能用JAVA实现,而不能用C实现?
我没有否认数据结构和算法在性能方面的重要性(事实上我提都没提),我语义的环境是假设在相同算法上,用C语言实现的中文分词会比用JAVA实现的在运行速度上要快得多!在占用CPU和内存使用上,C占的优势就更不用说了!硬件那是实实在在用银子堆起来的!
JAVA唯一的优势就是开发速度。
13 楼 erliang20088 2012-11-05 13:02
fyland 写道
一看原来是用JAVA写的,马上兴趣全无!
JAVA干这种活速度实在太差了!


这是传统看法了,现在硬件提升很快,在效率和效果都能接受的情况下,用Java写一些以前C/C++的高效程序,完全没有问题。还是希望用数据说明问题~
12 楼 fyland 2012-11-05 13:00
ansjsun 写道
fyland 写道
ansjsun 写道
fyland 写道
一看原来是用JAVA写的,马上兴趣全无!
JAVA干这种活速度实在太差了!

是运行速度.还是..开发速度?

运行速度!


那就是你偏见了...c写不好还不如java呢..很多时候看数据结构和算法..对程序优化有很大的提升空间的..这个分词速度绝对不必ict差的..

这个很简单,用其他开源的中文分词器做一个对比,比较一下分词速度和准确率!
JAVA占用CPU资源和内存就不必说了,在操作字符串方面JAVA一向效率低下!
11 楼 zhangmiao_chp 2012-11-05 13:00
fyland 写道
一看原来是用JAVA写的,马上兴趣全无!
JAVA干这种活速度实在太差了!


楼上相当无知,决定系统性能的是数据结构和算法,和语言没有关系,算法提升的性能是成倍的,代码写的好不好要看你的功力强不强,和兵器有毛关系。支持楼主
10 楼 erliang20088 2012-11-05 12:56
用过该分词组件相当不错,效果很理想,打算参考一下,也自写一个,不知道你用了多长时间完成这个分词器?
9 楼 ansjsun 2012-11-05 12:52
fyland 写道
ansjsun 写道
fyland 写道
一看原来是用JAVA写的,马上兴趣全无!
JAVA干这种活速度实在太差了!

是运行速度.还是..开发速度?

运行速度!


那就是你偏见了...c写不好还不如java呢..很多时候看数据结构和算法..对程序优化有很大的提升空间的..这个分词速度绝对不必ict差的..
8 楼 fyland 2012-11-05 12:49
ansjsun 写道
fyland 写道
一看原来是用JAVA写的,马上兴趣全无!
JAVA干这种活速度实在太差了!

是运行速度.还是..开发速度?

运行速度!
7 楼 ansjsun 2012-11-05 12:48
fyland 写道
一看原来是用JAVA写的,马上兴趣全无!
JAVA干这种活速度实在太差了!

是运行速度.还是..开发速度?
6 楼 fyland 2012-11-05 12:47
一看原来是用JAVA写的,马上兴趣全无!
JAVA干这种活速度实在太差了!
5 楼 jeffsui 2012-11-05 12:34
这个必须支持,中文分词系统!
4 楼 orange.lpai 2012-11-05 12:33
沙发!强烈支持,真心想协助打造一个开源的Java分词系统!
3 楼 wen12128 2012-11-05 12:29
值得学习
2 楼 freish 2012-11-05 12:25
good
1 楼 litaoshoujiao 2012-11-05 11:47
非常不错,顶起!

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

Global site tag (gtag.js) - Google Analytics