4.中文分词

Lucene 默认情况下(即使用 StandardAnalyzer 的时候)对中文进行单字分词,即为每个字建立索引。

文档中有 JE IK 分词器的介绍和实例。

1.       分词方法

l         单字分词

l         二分法:把一段文字的每两个相邻的字算作一个词。如“我爱你中国”,将被分为“我爱”、“爱你”、“你中”、“中国”

l         词典法:建立词典文件,词典与文字段落匹配,词典和匹配算法是关键

l         语义法:

2.       Lucene 分词器

2.1 二分法分词器

Lucene 软件包的 contrib/analyzers 目录下有一个名为 lucene-analyzers-2.1.0.jar 的文件,其中含有二分法分词器 CJKAnalyzer ,只需将此文件加入编译路径即可使用。

注意:要把 C:/lucene/contrib/analyzers/lucene-analyzers-2.1.0.jar 加入到 CLASSPATH

实例一:对字符串进行分词

       // UseCJK.java

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

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

import java.io.StringReader;

 

public class UseCJK{

public static void main(String args[]) throws java.io.IOException{

        String s = " 我爱伟大的祖国,我爱壮丽的中华 ";

        StringReader sr = new StringReader(s);

       

        CJKTokenizer cjk = new CJKTokenizer(sr); // 参数

        org.apache.lucene.analysis.Token t = null;

       

        while((t=cjk.next())!=null){

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

        }

}

}

 

//C:/java>java UseCJK

// 我爱 | 爱伟 | 伟大 | 大的 | 的祖 | 祖国 | 我爱 | 爱壮 | 壮丽 | 丽的 | 的中 | 中华 ||

示例二:用 CJK 分词器对目录下文件建索引

//CJKDirIndexer.java 对目录下文件建索引,使用 CJKIndexer 二分法分词器

 

import java.io.*;

import tool.FileText; // 自定义的类,获取文件内容

import tool.FileList; // 列目录类

 

import org.apache.lucene.document.Document;

import org.apache.lucene.document.Field;

import org.apache.lucene.index.IndexWriter;

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

import org.apache.lucene.analysis.cjk.CJKAnalyzer; // 引入的分词器不同

 

public class CJKDirIndexer{

       public static void main(String args[]) throws java.io.IOException{

              String indexPath = "index";

              IndexWriter indexWriter = new IndexWriter(indexPath,new CJKAnalyzer());    // 使用的分词器不同

             

              String strFile[] = FileList.getFiles("c:/java/doc");        

              for(int i=0;i<strFile.length;i++)

              {

                            Document doc = new Document();

                            File f = new File(strFile[i]);

                            String name = f.getName();

                            Field field1 = new Field("name",name,Field.Store.YES,Field.Index.TOKENIZED);

                            doc.add(field1);

                           

                            String content = FileText.getText(f);

                            Field field2 = new Field("content",content,Field.Store.YES,Field.Index.TOKENIZED);

                            doc.add(field2);

                           

                            String path = f.getPath();

                            Field field3 = new Field("path",path,Field.Store.YES,Field.Index.NO);

                            doc.add(field3);     

                            indexWriter.addDocument(doc);

              }

              indexWriter.close();

              System.out.println("CJK Index Created");                 

       }

}

实例三:检索,差别不大

//CJKSearcher.java

import org.apache.lucene.analysis.cjk.CJKAnalyzer; // 引入 CJK 分词器

import org.apache.lucene.index.*;

import org.apache.lucene.search.*;

import org.apache.lucene.document.*;

 

public class CJKSearcher

{

       public static void main(String[] args) throws java.io.IOException

       {

              String indexPath = "index";

              String searchField = "content";

              String searchPhrase = " 大禹 "; // 关键词,双字

              StringBuffer sb = new StringBuffer("");

 

              //IndexSearcher

              IndexSearcher searcher = new IndexSearcher(indexPath);

             

              //Term & Query

              Term t = new Term(searchField, searchPhrase);

              Query q = new TermQuery(t);

             

              //Hits

              Hits hs = searcher.search(q);

             

              int num = hs.length();

             

              //view details

              for(int i=0;i<num;i++)

              {

                    

                     //get document

                     Document doc = hs.doc(i);

                    

                     //field name

                     Field fname = doc.getField("name");

                     sb.append("name:" + "/n");

                     sb.append(fname.stringValue() + "/n");

                    

                     //field content

                     Field fcontent = doc.getField("content");

                     sb.append("content:" + "/n");

                     sb.append(fcontent.stringValue().substring(0,50) + "/n");

                    

                     sb.append("------------------- " + "/n");

              }

             

              searcher.close();

             

              System.out.print(sb);           

       }

}

 

2.2 Lucene 自带的中文分词器

中文分词器 ChineseAnalyer ,也在 contrib/analyzers 目录下 lucene-analyzers-2.1.0.jar 文件中

注意: ChineseAnalyer 是单字分词

示例: UseCN.java 字符串分词

//UseCN.java

 

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

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

import java.io.StringReader;

 

public class UseCN

{

       public static void main(String[] args) throws java.io.IOException

       {

              String s = " 我爱我伟大的老爸老妈,我爱我壮丽的中华! ";

              StringReader sr = new StringReader(s);

             

              ChineseTokenizer cn = new ChineseTokenizer(sr);

              org.apache.lucene.analysis.Token t = null;

             

              while( (t=cn.next()) !=null )

              {

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

              }

       }

}

 

//C:/java>java UseCN

// | | | | | | | | | | | | | | | | | |

 

2.3   NGram 分词器

NGram 分词器也在 contrib/analyzers 目录下 lucene-analyzers-2.1.0.jar 文件中

同时进行单字分词和二分法分词

//UseCN.java

 

//import org.apache.lucene.analysis.ngram.NGramAnalyzer;

import org.apache.lucene.analysis.ngram.NGramTokenizer;

import java.io.StringReader;

 

public class UseNGram

{

       public static void main(String[] args) throws java.io.IOException

       {

              String s = " 我爱我伟大的老爸老妈,我爱我壮丽的中华! ";

              StringReader sr = new StringReader(s);

             

              NGramTokenizer cn = new NGramTokenizer(sr);

              org.apache.lucene.analysis.Token t = null;

             

              while( (t=cn.next()) !=null )

              {

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

              }

       }

}

//C:/java>java UseNGram

// | | | | | | | | | | | | | | | | | | | | 我爱 | 爱我 | 我伟 | 伟大 |

// 大的 | 的老 | 老爸 | 爸老 | 老妈 | 妈, | ,我 | 我爱 | 爱我 | 我壮 | 壮丽 | 丽的 | 的中 | 中华 | 华! |

 

2.4   JE 分词器

http://www.jesoft.cn/ 下载

需要将 je-analysis-1.5.1.jar 放到编译路径中 (classpath)

由中科院提供的中文极易分词器。比较完善的中文分词器,使用简单,维护容易

引入分词器:

import jeasy.analysis.MMAnalyzer;

功能:去除停用词

l         创建对象:

MMAnalyzer mm = new MMAnalyzer();

也可以传递一个参数,设定正向匹配的最大长度

MMAnalyzer mm = new MMAnalyzer(4);

最大匹配长度为 4

l         MMAnalyzer.addDictionary(Reader reader);

增加一个新词典,采用每行一个词的读取方式(注意:多线程状态下分词效果不可预料)

l         MMAnalyzer.addWord(String newWord);

增加一个新词

l         MMAnalyzer.clear()

删除词库中的全部词语

l         MMAnalyzer.contains(String word);

判断词库中是否包含该词

l         MMAnalyzer.removeWord(String word)

从词库中移除该词

l         MMAnalyzer.size()

获得当前词库中包含词语总数。

//UseJE.java

 

import jeasy.analysis.MMAnalyzer;

 

public class UseJE

{

       public static void main(String[] args) throws java.io.IOException

       {

              String s = " 我爱我伟大的老爸老妈,我爱我壮丽的中华! ";  

              MMAnalyzer mm = new MMAnalyzer();

              System.out.print(mm.segment(s,"|"));

       }

}

 

//C:/java>java UseJE

// | 爱我 | 伟大 | 老爸 | 老妈 | | 爱我 | 壮丽 | 中华 |

 

2.5   IK 分词器

IK 分词器,又称 Lucene 中文分词公用组件。

实现了以词典分词为基础的正反向全切分算法,将 IKAnalyzer.jar 放到编译路径即可。

该分词器包括两个分析器:

l         MIK_CAnalyzer 使用最大全切分算法,

l         IK_CAnalyzer 使用细粒度全切分算法。

引入分词器:

l         import org.mira.lucene.analysis.MIK_CAnalyzer

l         import org.mira.lucene.analysis.IK_CAnalyzer;

IKAnalyzer 是一个开源的,基于 java 语言开发的轻量级的中文分词工具包。从 2006 12 月推出 1.0 版开始, IKAnalyzer 已经推出 3 个大版本。最初,它是以开源项目 Luence 为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的 IKAnalyzer3.0 则发展为 面向 Java 的公用分词组件,独立于 Lucene 项目,同时提供了对 Lucene 的默认优化实现。

IKAnalyzer3.0 特性 :

采用了特有的“正向迭代最细粒度切分算法“,具有 60 万字 / 秒的高速处理能力。

采用了多子处理器分析模式,支持:英文字母( IP 地址、 Email URL )、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。

优化的词典存储,更小的内存占用。支持用户词典扩展定义

针对 Lucene 全文检索优化的查询分析器 IKQueryParser( 作者吐血推荐 ) ;采用歧义分析算法优化查询关键字的搜索排列组合,能极大的提高 Lucene 检索的命中率。注意: IKQueryParser在IK3.0之后版本中出现

// UseIK.java IK 分词器

import org.mira.lucene.analysis.IK_CAnalyzer; // 引入 IK 分词器

import org.apache.lucene.analysis.TokenStream;

import java.io.*;

 

public class UseIK{

       public static void main(String args[]) throws java.io.IOException{

              String s = " 我爱伟大的祖国,我爱壮丽的中华 ";

              StringReader sr = new StringReader(s);

             

              IK_CAnalyzer ik = new IK_CAnalyzer(); // 创建分词器

             

              TokenStream ts = ik.tokenStream("*",sr);   

              org.apache.lucene.analysis.Token t = null;

             

              while((t=ts.next())!=null){

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

              }

       }

}

 

//C:/java>java UseIK

// | 爱伟 | 伟大 | 大的 | 祖国 | | 爱壮丽 | 壮丽 | 中华 |

 

经验证, IK比MIK的切分粒度要小

C:/java>java UseIK
我|爱我|我|伟大|大的|老爸|老妈|我|爱我|我|壮丽|中华民族|中华|民族|
C:/java>java UseMI
我|爱我|伟大|大的|老爸|老妈|我|爱我|壮丽|中华民族|
 

 

2.6   其它分词器

中科院做了个分词器,是 dll 组件形式,想要在 java 中使用需要 JNI. 

现在的主流分词器都是大量统计的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值