1、分析的基本概念
分析(Analysis),在lucene中指的是将域(Field)文本转换成最基本的索引表示单元——项(Term)的过程。在搜索过程中,这些项用于决定什么样的文档能够匹配查词条件。
分析器对分析操作进行了封装,它通过执行若干操作,将文本转化成语汇单元,这个处理过程也称为语汇单元化过程(tokenization),而从文本中提取的文本块称为语汇单元(token)。词汇单元与它的域名结合后,就形成了项。
2、哪里需要使用分词器
建立索引的时候:
1 2 3 4 5 6 7 8 |
// 索引文件的保存位置 Directory dir = FSDirectory.open(new File(indexStorePath)); // 分析器 Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_9); // 配置类 IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_4_9, analyzer); iwc.setOpenMode(OpenMode.CREATE);// 创建模式 OpenMode.CREATE_OR_APPEND 添加模式 writer = new IndexWriter(dir, iwc); |
这时候设定一个IndexWriter的默认分词器。
向索引库中写文档内容的时候:
1 |
writer.addDocument(doc, new SimpleAnalyzer(Version.LUCENE_49)); |
这时候可以单独为这个文档指定分词器。
其实看一眼只有一个doc参数的addDocument方法,也可以看出他调用了这个两个参数的方法,第二个参数设置为默认的给定的分词器了。
使用QueryParser生成Query对象的时候:
1 2 3 4 |
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_4_9); QueryParser parser = new QueryParser(Version.LUCENE_4_9, field, analyzer); // 将关键字包装成Query对象 query = parser.parse(keyword); |
3、常用分词器介绍
WhitespaceAnalyzer
仅仅是去掉了空格,没有其他任何操作,不支持中文。
SimpleAnalyzer
讲除了字母以外的符号全部去除,并且讲所有字符变为小写,需要注意的是这个分词器同样把数据也去除了,同样不支持中文。
StopAnalyzer
这个和SimpleAnalyzer类似,不过比他增加了一个的是,在其基础上还去除了所谓的stop words,比如the, a, this这些。这个也是不支持中文的。
StandardAnalyzer
英文方面的处理和StopAnalyzer一样的,对中文支持,使用的是单字切割。
CJKAnalyzer
这个支持中日韩,前三个字母也就是这三个国家的缩写。这个对于中文基本上不怎么用吧,对中文的支持很烂,它是用每两个字作为分割,分割方式个人感觉比较奇葩,我会在下面比较举例。
SmartChineseAnalyzer
中文的分词。比较标准的中文分词,对一些搜索处理的并不是很好。
对中文支持的几个分词器切分示例
举例句子:“我是中国人”
StandardAnalyzer:我-是-中-国-人
CJKAnalyzer:我是-是中-中国-国人
SmartChineseAnalyzer:我-是-中国-人
可以看出,SmartChineseAnalyzer认为中国是一个词,而中国人不是一个词而是两个词。CJK的分词比较奇葩,而StandardAnalyzer的分词就是一个字一个词。
IKAnalyzer
不得不说,中文的分词器还是需要中国人自己开发,因为只有自己才最了解自己的语言。中文分词我非常推荐使用IKAnalyzer,对于中文分词比较精准,我们这里使用的是Lucene4.9的版本,所以需要下载使用FF的版本,意思是for four才是给我们4.x用的。
4、我这里在总结一下各种中文分词的对比
下面部分参考自福林雨博客。
1. 基本介绍:
paoding:Lucene中文分词“庖丁解牛” Paoding Analysis
imdict:imdict智能词典所采用的智能中文分词程序
mmseg4j: 用 Chih-Hao Tsai 的 MMSeg 算法 实现的中文分词器
ik:采用了特有的“正向迭代最细粒度切分算法”,多子处理器分析模式
2. 开发者及开发活跃度:
基本上所有分词都已经好几年没有更新了。
3. 用户自定义词库:
paoding :支持不限制个数的用户自定义词库,纯文本格式,一行一词,使用后台线程检测词库的更新,自动编译更新过的词库到二进制版本,并加载
imdict :暂时不支持用户自定义词库。但 原版 ICTCLAS 支持。支持用户自定义 stop words
mmseg4j :自带sogou词库,支持名为 wordsxxx.dic, utf8文本格式的用户自定义词库,一行一词。不支持自动检测。 -Dmmseg.dic.path
ik : 支持api级的用户词库加载,和配置级的词库文件指定,无 BOM 的 UTF-8 编码,\r\n 分割。不支持自动检测。
4. 速度(基于官方介绍,非自己测试)
paoding :在PIII 1G内存个人机器上,1秒 可准确分词 100万 汉字
imdict :483.64 (字节/秒),259517(汉字/秒)
mmseg4j : complex 1200kb/s左右, simple 1900kb/s左右
ik :具有50万字/秒的高速处理能力
5. 算法和代码复杂度
paoding :svn src 目录一共1.3M,6个properties文件,48个java文件,6895 行。使用不用的 Knife 切不同类型的流,不算很复杂。
imdict :词库 6.7M(这个词库是必须的),src 目录 152k,20个java文件,2399行。使用 ICTCLAS HHMM隐马尔科夫模型,“利用大量语料库的训练来统计汉语词汇的词频和跳转概率,从而根据这些统计结果对整个汉语句子计算最似然(likelihood)的切分”
mmseg4j : svn src 目录一共 132k,23个java文件,2089行。MMSeg 算法 ,有点复杂。
ik : svn src 目录一共6.6M(词典文件也在里面),22个java文件,4217行。多子处理器分析,跟paoding类似,歧义分析算法还没有弄明白。
6. 文档
paoding :几乎无。代码里有一些注释,但因为实现比较复杂,读代码还是有一些难度的。
imdict : 几乎无。 ICTCLAS 也没有详细的文档,HHMM隐马尔科夫模型的数学性太强,不太好理解。
mmseg4j : MMSeg 算法 是英文的,但原理比较简单。实现也比较清晰。
ik : 有一个pdf使用手册,里面有使用示例和配置说明。
7. 其它
paoding :引入隐喻,设计比较合理。search 1.0 版本就用的这个。主要优势在于原生支持词库更新检测。主要劣势为作者已经不更新甚至不维护了。
imdict :进入了 lucene trunk,原版 ictclas 在各种评测中都有不错的表现,有坚实的理论基础,不是个人山寨。缺点为暂时不支持用户词库。
mmseg4j : 在complex基础上实现了最多分词(max-word),但是还不成熟,还有很多需要改进的地方。
ik : 针对Lucene全文检索优化的查询分析器IKQueryParser
目前看来个人建议首选IK,其次paoding。(我的建议,大家参考)
本文发表自赵伊凡BLOG
©原创文章,转载请注明来源: 赵伊凡's Blog
©本文链接地址: 5、Lucene4.9学习笔记——Lucene分析及分词器
“5、Lucene4.9学习笔记——Lucene分析及分词器”的30个回复