zzzhc's Blog

stay curious

Lucene中文分词器比较

当前支持lucene 3.1的中文分词器

  • mmseg4j mmseg4j 用 Chih-Hao Tsai 的 MMSeg 算法(http://technology.chtsai.org/mmseg/ )实现的中文分词器,并实现 lucene 的 analyzer 和 solr 的TokenizerFactory 以方便在Lucene和Solr中使用。
  • paoding Paoding’s Knives 中文分词具有极 高效率 和 高扩展性 。引入隐喻,采用完全的面向对象设计,构思先进。 高效率:在PIII 1G内存个人机器上,1秒 可准确分词 100万 汉字。 采用基于 不限制个数 的词典文件对文章进行有效切分,使能够将对词汇分类定义。 能够对未知的词汇进行合理解析
  • ik-analyzer IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出了3个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IKAnalyzer3.0则发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。
  • imdict imdict-chinese-analyzer 是imdict智能词典的智能中文分词模块,算法基于隐马尔科夫模型(Hidden Markov Model, HMM),是中国科学院计算技术研究所的ictclas中文分词程序的重新实现(基于Java),可以直接为lucene搜索引擎提供简体中文分词支持。 已加入lucene contributor, smartcn.

支持的特性

name CharTermAttribute OffsetAttribute TypeAttribute PositionIncrementAttribute KeywordAttribute
mmseg4j Y Y Y N N
paoding Y Y Y N N
ik-analyzer Y Y N N N
imdict Y Y Y N Y

性能比较

本机cpu: Intel® Core™2 Duo CPU P8600 @ 2.40GHz

name speed(chars/second)
StandardAnalyzer 5227272
mmseg4j 771812
paoding 847145
ik-analyzer 657142
imdict 269242

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//CNAnalyzerBenchmark.java
import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Iterator;

import net.paoding.analysis.analyzer.PaodingAnalyzer;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.util.Attribute;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.chenlb.mmseg4j.analysis.MMSegAnalyzer;

public class CNAnalyzerBenchmark {

    public static void main(String[] args) throws IOException {
        IKAnalyzer ikAnalyzer = new IKAnalyzer();
        testAnalyzer(ikAnalyzer);

        MMSegAnalyzer mmsegAnalyzer = new MMSegAnalyzer();
        testAnalyzer(mmsegAnalyzer);

        PaodingAnalyzer paodingAnalyzer = new PaodingAnalyzer();
        testAnalyzer(paodingAnalyzer);

        SmartChineseAnalyzer smartChineseAnalyzer = new SmartChineseAnalyzer(
                Version.LUCENE_31, false);
        testAnalyzer(smartChineseAnalyzer);

        StandardAnalyzer standardAnalyzer = new StandardAnalyzer(
                Version.LUCENE_31, new HashSet<String>());
        testAnalyzer(standardAnalyzer);
    }

    static void testAnalyzer(Analyzer a) throws IOException {
        String data = "中文(chinese)与西方语言最大的区别" + "就在于语句的词汇之间没有明显的分词界限,"
                + "但是计算机自然语言处理是按词汇来进行分析的," + "因此中文分词的效果直接影响中文检索和自然语言处理的准确性。";
        StringBuilder ss = new StringBuilder();
        for (int i = 0; i < 10000; i++) {
            ss.append(data);
        }
        String s = ss.toString();

        long startTime = System.currentTimeMillis();

        String attributes = "";
        TokenStream stream = a.tokenStream("", new StringReader(s));
        Iterator<Class<? extends Attribute>> iterator = stream
                .getAttributeClassesIterator();
        while (iterator.hasNext()) {
            Class<? extends Attribute> attrClass = iterator.next();
            attributes += " " + attrClass.getSimpleName();
        }
        stream = a.tokenStream("", new StringReader(s));
        while (stream.incrementToken()) {
        }
        long endTime = System.currentTimeMillis();
               System.out.println(a.getClass().getSimpleName() + " attributes: "
                   + attributes);
               double seconds = (endTime - startTime) / 1000.0;
               System.out.println("chars=" + s.length() +
                       ",time=" + seconds + "seconds" +
                      ",speed=" + (int) (s.length() / seconds) + "chars/second"
               );
    }
}

Comments