一、引言:
中文分词一直是自然语言处理的一个痛处,早在08年的时候,就曾经有项目涉及到相关的应用(Lunce构建全文搜索引擎),那时的痛,没想到5年后的今天依然存在,切分效果、扩展支持、业务应用等方面依然不甚理想。收费的版本不提了,原因自不必言表,开源版本中,发现之前曾经活跃的版本,大多已经没落(好几年没更新了),存活下来的寥寥无几。我是一个守旧的人,评估版本的选择有些保守,至少目前为止,只看1.0正式版本之后的版本,0.XX的不在考虑范围之内,用了一个周末的时间,对比了十多款的样子,个人感觉源于中科院ICTCLAS的smartcn和IKAnanlyzer效果还是不错的。
二、结果对比
2.1 原始文本
"lucene分析器使用分词器和过滤器构成一个“管道”,文本在流经这个管道后成为可以进入索引的最小单位,因此,一个标准的分析器有两个部分组成,一个是分词器tokenizer,它用于将文本按照规则切分为一个个可以进入索引的最小单位。另外一个是TokenFilter,它主要作用是对切出来的词进行进一步的处理(如去掉敏感词、英文大小写转换、单复数处理)等。lucene中的Tokenstram方法首先创建一个tokenizer对象处理Reader对象中的流式文本,然后利用TokenFilter对输出流进行过滤处理"; 2.2 smartcn
lucen分析器使用分词器和过滤器构成一个管道文本流经这个管道后成为可以进入索引最小单位因此一个标准分析器有两个部分组成一个分词器token它用于将文本按照规则切分为一个个可以进入索引最小单位另外一个tokenfilt它主要作用对切出来词进行进一步处理如去掉敏感词英文大小写转换单复数处理等lucen中tokenstram方法首先创建一个token对象处理reader对象中式文本然后利用tokenfilt对输出进行过滤处理
2.3 IKanalyzer
lucene分析器分析器使使用分词器分词器和过滤器过滤滤器构成一个一个管道文本在流经这个管道后成为可以进入索引的最小单位因此一个一个标准的分析器分析器有两个两个部分分组组成一个是一个一个是分词器分词器tokenizer它用用于将文本按照规则切分切分为一个个一个一个个个个可以进入索引的最小单位另外一个是一个一个是tokenfilter它主要作用用是对切出来切出切出来的词进行行进进一步进一一步一步的处理如去掉敏感词英文大小写大小小写转换单复数处理等lucene中的tokenstram方法首先创建一个一个tokenizer对象处理reader对象中的流式文本然后利用tokenfilter对输出流进进行过滤处理
三、smartcn示例程序
代码语言:javascript复制1 package dictTest;
2
3 import java.util.Iterator;
4
5 import org.apache.lucene.analysis.TokenStream;
6 import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
7 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
8 import org.apache.lucene.analysis.util.CharArraySet;
9 import org.apache.lucene.util.Version;
10
11 public class SmartChineseAnalyzerTest {
12
13 public static void main(String[] args) {
14 try {
15 // 要处理的文本
16 String text = "lucene分析器使用分词器和过滤器构成一个“管道”,文本在流经这个管道后成为可以进入索引的最小单位,因此,一个标准的分析器有两个部分组成,一个是分词器tokenizer,它用于将文本按照规则切分为一个个可以进入索引的最小单位。另外一个是TokenFilter,它主要作用是对切出来的词进行进一步的处理(如去掉敏感词、英文大小写转换、单复数处理)等。lucene中的Tokenstram方法首先创建一个tokenizer对象处理Reader对象中的流式文本,然后利用TokenFilter对输出流进行过滤处理";
17 //String text = "目前我已经用了lucene4.0,虽然是alpha版,但是也是未来的第一步。但是IKAnalyzer不支持lucene4,如果作者在,是否有计划对4支持?何时支持?";
18 // 自定义停用词
19 String[] self_stop_words = { "的", "在","了", "呢", ",", "0", ":", ",", "是", "流" };
20 CharArraySet cas = new CharArraySet(Version.LUCENE_46, 0, true);
21 for (int i = 0; i < self_stop_words.length; i ) {
22 cas.add(self_stop_words[i]);
23 }
24
25 // 加入系统默认停用词
26 Iterator<Object> itor = SmartChineseAnalyzer.getDefaultStopSet().iterator();
27 while (itor.hasNext()) {
28 cas.add(itor.next());
29 }
30
31
32 // 中英文混合分词器(其他几个分词器对中文的分析都不行)
33 SmartChineseAnalyzer sca = new SmartChineseAnalyzer(Version.LUCENE_46, cas);
34
35 TokenStream ts = sca.tokenStream("field", text);
36 CharTermAttribute ch = ts.addAttribute(CharTermAttribute.class);
37
38 ts.reset();
39 while (ts.incrementToken()) {
40 System.out.print(ch.toString() "\");
41 }
42 ts.end();
43 ts.close();
44 } catch (Exception ex) {
45 ex.printStackTrace();
46 }
47 }
48
49 }
四、IKanalyzer示例程序
代码语言:javascript复制1 package dictTest;
2
3 import org.wltea.analyzer.*;
4 import org.apache.lucene.analysis.Analyzer;
5 import org.apache.lucene.analysis.TokenStream;
6 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
7 import org.wltea.analyzer.lucene.*;
8
9 public class IKAnalyzerTest {
10
11 public static void main(String[] args) {
12 // TODO Auto-generated method stub
13 Analyzer ik = new IKAnalyzer();
14 try{
15 String text = "lucene分析器使用分词器和过滤器构成一个“管道”,文本在流经这个管道后成为可以进入索引的最小单位,因此,一个标准的分析器有两个部分组成,一个是分词器tokenizer,它用于将文本按照规则切分为一个个可以进入索引的最小单位。另外一个是TokenFilter,它主要作用是对切出来的词进行进一步的处理(如去掉敏感词、英文大小写转换、单复数处理)等。lucene中的Tokenstram方法首先创建一个tokenizer对象处理Reader对象中的流式文本,然后利用TokenFilter对输出流进行过滤处理";
16 TokenStream ts = ik.tokenStream("field", text);
17
18 CharTermAttribute ch = ts.addAttribute(CharTermAttribute.class);
19
20 ts.reset();
21 while (ts.incrementToken()) {
22 //System.out.println(ch.toString());
23 System.out.print(ch.toString() "\");
24 }
25 ts.end();
26 ts.close();
27
28 } catch (Exception ex) {
29 ex.printStackTrace();
30 }
31
32 }
33 }
五、结论
1.二者分词效果,相比其他已经不错,都值得肯定;
2.smartcn为Lucene4.6版本自带(之前版本也有),中文分词不错,英文分词有问题,Lucene分词后变成了Luncn;
3.IKAnalyzer分词后的碎片太多,可以和人工分析效果做对比;
4.从自定义词库的角度考虑,因为smartcn在Lucene4.6中的版本,目前不支持自定义词库,成为致命缺陷,只能放弃。