关于几种中文分词的比对

目前lucene自身提供的StandardAnalyzer已经具备中文分词的功能,但是不一定能够满足大多数应用的需要。 

另外网友谈的比较多的中文分词器还有: 

CJKAnalyzer 

ChineseAnalyzer 

IK_CAnalyzer(MIK_CAnalyzer) 

还有一些热心网友自己写的比较不错的分词器在此就不说了,有兴趣的可以自己研究研究。 

以上三个中文分词器并不是lucene2.2.jar里提供的。 

CJKAnalyzer和ChineseAnalyzer分别是lucene-2.2.0目录下contrib目录下analyzers的lucene-analyzers-2.2.0.jar提供的。分别位于cn和cjk目录。 

IK_CAnalyzer(MIK_CAnalyzer)是基于分词词典,目前最新的1.4版本是基于lucene2.0开发的。以上分词器各有优劣,比较如下: 

import   java.io.Reader; 

import   java.io.StringReader; 

import   org.apache.lucene.analysis.Analyzer; 

import   org.apache.lucene.analysis.StopFilter; 

import   org.apache.lucene.analysis.Token; 

import   org.apache.lucene.analysis.TokenFilter; 

import   org.apache.lucene.analysis.TokenStream; 

import   org.apache.lucene.analysis.cjk.CJKAnalyzer; 

import   org.apache.lucene.analysis.cn.ChineseAnalyzer; 

import   org.apache.lucene.analysis.standard.StandardAnalyzer; 

import   org.mira.lucene.analysis.IK_CAnalyzer; 

import   org.mira.lucene.analysis.MIK_CAnalyzer; 

 

public   class   All_Test   { 

          private   static   String   string   =   "中华人民共和国在1949年建立,从此开始了新中国的伟大篇章。 "; 

          public   static   void   Standard_Analyzer(String   str)   throws   Exception{ 

                        Analyzer   analyzer   =   new   StandardAnalyzer();                   

                        Reader   render   =   new   StringReader(str);                   

                        StopFilter   stopFilter   =   (StopFilter)   analyzer.tokenStream( " ",   render  ); 

                        System.out.println( "=====StandardAnalyzer==== "); 

                        System.out.println( "分析方法:默认没有词只有字(一元分词) "); 

                        Token   token;                   

                      while   ((token   =   stopFilter.next())   !=   null)   {                   

                                    System.out.println(token.termText());                   

                        }               

            } 

          public   static   void   CJK_Analyzer(String   str)   throws   Exception{ 

                        Analyzer   analyzer   =   new   CJKAnalyzer();                   

                        Reader   render   =   new   StringReader(str);                   

                        StopFilter   stopFilter   =   (StopFilter)   analyzer.tokenStream( " ",   render); 

                        System.out.println( "=====CJKAnalyzer==== "); 

                        System.out.println( "分析方法:交叉双字分割(二元分词) "); 

                        Token   token;                   

                      while   ((token   =   stopFilter.next())   !=   null)   {                   

                                    System.out.println(token.termText());                   

                        }                

            } 

          public   static   void   Chiniese_Analyzer(String   str)   throws   Exception{ 

                        Analyzer   analyzer   =   new   ChineseAnalyzer();                   

                        Reader   render   =   new   StringReader(str);                   

                        TokenFilter   tokenFilter   =   (TokenFilter)   analyzer.tokenStream( " ",   render); 

                        System.out.println( "=====chinese   analyzer==== "); 

                        System.out.println( "分析方法:基本等同StandardAnalyzer(一元分词) "); 

                        Token   token;                   

                      while   ((token   =   tokenFilter.next())   !=   null)   {                   

                                    System.out.println(token.termText());                   

                        }               

            } 

          public   static   void   ik_CAnalyzer(String   str)   throws   Exception{ 

//                     Analyzer   analyzer   =   new   MIK_CAnalyzer(); 

                        Analyzer   analyzer   =   new   IK_CAnalyzer(); 

                        Reader   reader   =   new   StringReader(str);   

                        TokenStream   tokenStream   =   (TokenStream)analyzer.tokenStream( " ",   reader); 

                        System.out.println( "=====IK_CAnalyzer==== "); 

                        System.out.println( "分析方法:字典分词,正反双向搜索 "); 

                        Token   token;         

                      while   ((token   =   tokenStream.next())   !=   null)   {         

                                  System.out.println(tokenStream.termText());         

                        }         

            } 

          public   static   void   main(String[]   args)   throws   Exception{ 

                        String   str   =   string; 

                        System.out.println( "我们测试的字符串是: "+str); 

 

                        Standard_Analyzer(str); 

                        CJK_Analyzer(str); 

                        Chiniese_Analyzer(str); 

                        ik_CAnalyzer(str); 

            } 

 

分词结果如下: 

我们测试的字符串是:中华人民共和国在1949年建立,从此开始了新中国的伟大篇章。 

=====StandardAnalyzer==== 

分析方法:默认没有词只有字(一元分词) 

中 

华 

人 

民 

共 

和 

国 

在 

1949 

年 

建 

立 

从 

此 

开 

始 

了 

新 

中 

国 

的 

伟 

大 

篇 

章 

=====CJKAnalyzer==== 

分析方法:交叉双字分割(二元分词) 

中华 

华人 

人民 

民共 

共和 

和国 

国在 

1949 

年建 

建立 

从此 

此开 

开始 

始了 

了新 

新中 

中国 

国的 

的伟 

伟大 

大篇 

篇章 

=====chinese   analyzer==== 

分析方法:基本等同StandardAnalyzer(一元分词) 

中 

华 

人 

民 

共 

和 

国 

在 

年 

建 

立 

从 

此 

开 

始 

了 

新 

中 

国 

的 

伟 

大 

篇 

章 

=====IK_CAnalyzer==== 

分析方法:字典分词,正反双向搜索 

中华人民共和国 

中华人民 

中华 

华人 

人民共和国 

人民 

人 

共和国 

共和 

1949年 

建立 

从此 

开始 

新中国 

中国 

伟大 

大篇 

篇章 

如果   ik_CAnalyzer(String   str)   里采用 

Analyzer   analyzer   =   new   MIK_CAnalyzer(); 

那么该方法的分词结果是: 

 

中华人民共和国 

1949年 

建立 

从此 

开始 

新中国 

伟大 

大篇 

篇章 

 

可以看到各种分词结果各不相同,根据应用的需要可以选择合适的分词器。 

关于IKAnalyzer的介绍可以参考: 

http://blog.csdn.net/dbigbear/archive/2007/01/24/1492380.aspx

http://topic.csdn.net/u/20070714/13/84db902a-9128-4b1b-8dd8-a631f15db931.html

 

 

//测试"庖丁解牛"中文分词器的分词效果     

    public class PaodingAnalyzer { 

        public static void main(String[] args) throws Exception { 

            Analyzer analyzer = new PaodingAnalyzer(); 

            String  indexStr = "我的QQ号码是38334641"; 

            StringReader reader = new StringReader(indexStr); 

            TokenStream ts = analyzer.tokenStream(indexStr, reader); 

            Token t = ts.next(); 

            while (t != null) { 

                System.out.print(t.termText()+"  "); 

                t = ts.next(); 

            } 

        } 

    } 

分词结果:我的  qq  号码  38334641   

如果把indexStr换成是"中华人民共和国万岁" ,那么分词结果为: 

中华  华人  人民  共和  共和国  万岁   


你可能感兴趣的:(中文分词)