- 浏览: 106614 次
- 性别:
- 来自: 吉林
文章分类
最新评论
lucene第三步,分词
出自:http://blog.csdn.net/wxwzy738/article/details/8799656 的整理
1
、
2、语汇单元的结构解释
3、同义词的设计思路
4、分词器的比较和测试
[java]
view plaincopy
- packageorg.lucene.test;
- importjava.io.File;
- importjava.io.IOException;
- importorg.apache.lucene.analysis.Analyzer;
- importorg.apache.lucene.analysis.SimpleAnalyzer;
- importorg.apache.lucene.analysis.StopAnalyzer;
- importorg.apache.lucene.analysis.WhitespaceAnalyzer;
- importorg.apache.lucene.analysis.standard.StandardAnalyzer;
- importorg.apache.lucene.document.Document;
- importorg.apache.lucene.document.Field;
- importorg.apache.lucene.index.CorruptIndexException;
- importorg.apache.lucene.index.IndexReader;
- importorg.apache.lucene.index.IndexWriter;
- importorg.apache.lucene.index.IndexWriterConfig;
- importorg.apache.lucene.index.Term;
- importorg.apache.lucene.search.IndexSearcher;
- importorg.apache.lucene.search.ScoreDoc;
- importorg.apache.lucene.search.TermQuery;
- importorg.apache.lucene.search.TopDocs;
- importorg.apache.lucene.store.Directory;
- importorg.apache.lucene.store.RAMDirectory;
- importorg.apache.lucene.util.Version;
- importorg.junit.Test;
- importorg.lucene.util.AnalyzerUtils;
- importorg.lucene.util.MySameAnalyzer;
- importorg.lucene.util.MyStopAnalyzer;
- importcom.chenlb.mmseg4j.analysis.MMSegAnalyzer;
- publicclassTestAnalyzer{
- /**
- *几种分词器在英文分词下面的比较
- */
- @Test
- publicvoidtest01(){
- //标准分词器
- Analyzera1=newStandardAnalyzer(Version.LUCENE_35);
- //停用词分词器
- Analyzera2=newStopAnalyzer(Version.LUCENE_35);
- //简单分词器
- Analyzera3=newSimpleAnalyzer(Version.LUCENE_35);
- //空格分词器
- Analyzera4=newWhitespaceAnalyzer(Version.LUCENE_35);
- Stringtxt="thisismyhouse,Iamcomefromyunnangzhaotong,"+
- "Myemailisynkonghao@gmail.com,MyQQis707807876";
- AnalyzerUtils.displayToken(txt,a1);
- //[my][house][i][am][come][from][yunnang][zhaotong][my][email][ynkonghao][gmail.com][my][qq][707807876]
- AnalyzerUtils.displayToken(txt,a2);
- //[my][house][i][am][come][from][yunnang][zhaotong][my][email][ynkonghao][gmail][com][my][qq]
- AnalyzerUtils.displayToken(txt,a3);
- //[this][is][my][house][i][am][come][from][yunnang][zhaotong][my][email][is][ynkonghao][gmail][com][my][qq][is]
- AnalyzerUtils.displayToken(txt,a4);
- //[this][is][my][house,I][am][come][from][yunnang][zhaotong,My][email][is][ynkonghao@gmail.com,My][QQ][is][707807876]
- }
- /**
- *几种分词器在中文分词下面的比较
- */
- @Test
- publicvoidtest02(){
- //标准分词器
- Analyzera1=newStandardAnalyzer(Version.LUCENE_35);
- //停用词分词器
- Analyzera2=newStopAnalyzer(Version.LUCENE_35);
- //简单分词器
- Analyzera3=newSimpleAnalyzer(Version.LUCENE_35);
- //空格分词器
- Analyzera4=newWhitespaceAnalyzer(Version.LUCENE_35);
- Stringtxt="我来自云南昭通昭阳区师专";
- AnalyzerUtils.displayToken(txt,a1);
- //[我][来][自][云][南][昭][通][昭][阳][区][师][专]
- AnalyzerUtils.displayToken(txt,a2);
- //[我来自云南昭通昭阳区师专]
- AnalyzerUtils.displayToken(txt,a3);
- //[我来自云南昭通昭阳区师专]
- AnalyzerUtils.displayToken(txt,a4);
- //[我来自云南昭通昭阳区师专]
- }
- /**
- *打印分词的详细信息
- */
- @Test
- publicvoidtest03(){
- //标准分词器
- Analyzera1=newStandardAnalyzer(Version.LUCENE_35);
- //停用词分词器
- Analyzera2=newStopAnalyzer(Version.LUCENE_35);
- //简单分词器
- Analyzera3=newSimpleAnalyzer(Version.LUCENE_35);
- //空格分词器
- Analyzera4=newWhitespaceAnalyzer(Version.LUCENE_35);
- Stringtxt="howareyouthankyou";
- AnalyzerUtils.displayAllToken(txt,a1);
- AnalyzerUtils.displayAllToken(txt,a2);
- AnalyzerUtils.displayAllToken(txt,a3);
- AnalyzerUtils.displayAllToken(txt,a4);
- }
- /**
- *停用词的测试
- */
- @Test
- publicvoidtest04(){
- Analyzera1=newMyStopAnalyzer(newString[]{"I","you","hate"});
- Analyzera2=newStopAnalyzer(Version.LUCENE_35);
- Stringtxt="howareYouthAnk'syouIhateyou";
- AnalyzerUtils.displayToken(txt,a1);
- AnalyzerUtils.displayToken(txt,a2);
- }
- /**
- *中文分词测试
- *使用词库分词,自己可扩展词库
- */
- @Test
- publicvoidtest05(){
- //Analyzera1=newMMSegAnalyzer();//未加入该分词器自带的词库
- //[我][来][自][云][南][昭][通][昭][阳][区][师][专]
- //导入分词的词典便有词库
- Analyzera1=newMMSegAnalyzer(newFile("D:\\Workspaces\\03_lucene_analyzer\\mmseg4j-1.8.4\\data"));
- //[我][来自][云南][昭][通][昭][阳][区][师专]
- //可以在data文件下面的words-my.dic扩展自己的词典,比如加了昭通,分词结果为:
- //[我][来自][云南][昭通][昭][阳][区][师专]
- Stringtxt="我来自云南昭通昭阳区师专";
- AnalyzerUtils.displayToken(txt,a1);
- }
- /**
- *同义词测试
- *@throwsIOException
- *@throwsCorruptIndexException
- */
- @Test
- publicvoidtest06()throwsCorruptIndexException,IOException{
- Analyzera1=newMySameAnalyzer();
- Stringtxt="我来自中国云南昭通昭阳区师专";
- AnalyzerUtils.displayAllToken(txt,a1);
- Stringkeyword="俺";
- Directorydire=newRAMDirectory();
- IndexWriterindexWriter=newIndexWriter(dire,newIndexWriterConfig(Version.LUCENE_35,a1));
- Documentdoc=newDocument();
- doc.add(newField("content",txt,Field.Store.YES,Field.Index.ANALYZED));
- indexWriter.addDocument(doc);
- indexWriter.close();
- IndexSearchersearch=newIndexSearcher(IndexReader.open(dire));
- TopDocstopDoc=search.search(newTermQuery(newTerm("content",keyword)),10);
- ScoreDoc[]scoreDoc=topDoc.scoreDocs;
- for(ScoreDocscore:scoreDoc){
- Documentdoc1=search.doc(score.doc);
- System.out.println(doc1.get("content"));
- }
- }
- }
5、扩展自己的停用词分词器
[java]
view plaincopy
- packageorg.lucene.util;
- importjava.io.IOException;
- importjava.io.Reader;
- importjava.util.Set;
- importorg.apache.lucene.analysis.Analyzer;
- importorg.apache.lucene.analysis.LetterTokenizer;
- importorg.apache.lucene.analysis.LowerCaseFilter;
- importorg.apache.lucene.analysis.StopAnalyzer;
- importorg.apache.lucene.analysis.StopFilter;
- importorg.apache.lucene.analysis.TokenStream;
- importorg.apache.lucene.analysis.Tokenizer;
- importorg.apache.lucene.analysis.tokenattributes.CharTermAttribute;
- importorg.apache.lucene.util.Version;
- /**
- *扩展自己的停用词分词器
- *@authoruser
- *
- */
- publicclassMyStopAnalyzerextendsAnalyzer{
- privateSetstops;
- publicMyStopAnalyzer(String[]sws){
- //会自动将字符串数组转化为Set
- stops=StopFilter.makeStopSet(Version.LUCENE_35,sws,true);
- //把原来的停用词给加进来
- stops.addAll(StopAnalyzer.ENGLISH_STOP_WORDS_SET);
- }
- publicMyStopAnalyzer(){
- //获取原有的停用词
- stops.addAll(StopAnalyzer.ENGLISH_STOP_WORDS_SET);
- }
- @Override
- publicTokenStreamtokenStream(StringfieldName,Readerreader){
- System.out.println("//------------------------------------");
- Tokenizertokenizer=newLetterTokenizer(Version.LUCENE_35,reader);
- //Tokenizertokenizer=newStandardTokenizer(Version.LUCENE_35,reader);
- CharTermAttributecta=tokenizer.addAttribute(CharTermAttribute.class);
- try{
- while(tokenizer.incrementToken()){
- System.out.println(cta);
- }
- }catch(IOExceptione){
- e.printStackTrace();
- }
- System.out.println("------------------------------------\\");
- //为这个分词器设定过滤链和Tokenizer
- returnnewStopFilter(Version.LUCENE_35,
- newLowerCaseFilter(Version.LUCENE_35,
- newLetterTokenizer(Version.LUCENE_35,reader)),
- stops);
- }
- }
[java]
view plaincopy
- packageorg.lucene.util;
- importjava.io.Reader;
- importorg.apache.lucene.analysis.Analyzer;
- importorg.apache.lucene.analysis.TokenStream;
- importcom.chenlb.mmseg4j.Dictionary;
- importcom.chenlb.mmseg4j.MaxWordSeg;
- importcom.chenlb.mmseg4j.analysis.MMSegTokenizer;
- /**
- *分词器的扩展,同义词分词器
- *@authoruser
- *
- */
- publicclassMySameAnalyzerextendsAnalyzer{
- @Override
- publicTokenStreamtokenStream(StringfieldName,Readerreader){
- Dictionarydic=Dictionary.getInstance("D:\\Workspaces\\03_lucene_analyzer\\mmseg4j-1.8.4\\data");
- returnnewMySameTokenFilter(newMMSegTokenizer(newMaxWordSeg(dic),reader));
- }
- }
7、同义词过滤器的扩展
[java]
view plaincopy
- packageorg.lucene.util;
- importjava.io.IOException;
- importjava.util.HashMap;
- importjava.util.Map;
- importjava.util.Stack;
- importorg.apache.lucene.analysis.TokenFilter;
- importorg.apache.lucene.analysis.TokenStream;
- importorg.apache.lucene.analysis.tokenattributes.CharTermAttribute;
- importorg.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
- importorg.apache.lucene.util.AttributeSource;
- /**
- *同义词过滤器的扩展
- *@authoruser
- *
- */
- publicclassMySameTokenFilterextendsTokenFilter{
- privateCharTermAttributecta=null;
- privatePositionIncrementAttributepia=null;
- privateAttributeSource.Statecurrent=null;
- privateStack<String>sames=null;
- protectedMySameTokenFilter(TokenStreaminput){
- super(input);
- cta=this.addAttribute(CharTermAttribute.class);
- pia=this.addAttribute(PositionIncrementAttribute.class);
- sames=newStack<String>();
- }
- /**
- *思想如下:
- *其实每个同义词都要放在CharTermAttribute里面,但是如果直接cta.append("大陆");的话
- *那会直接把原来的词和同义词连接在同一个语汇单元里面[中国大陆],这样是不行的
- *要的是这样的效果[中国][大陆]
- *那么就要在遇到同义词的时候把当前的状态保存一份,并把同义词的数组放入栈中,
- *这样在下一个语汇单元的时候判断同义词数组是否为空,不为空的话把之前的保存的一份状态
- *还原,然后在修改之前状态的值cta.setEmpty(),然后在把同义词的值加入cta.append("大陆")
- *再把位置增量设为0,pia.setPositionIncrement(0),这样的话就表示是同义词,
- *接着把该同义词的语汇单元返回
- */
- @Override
- publicbooleanincrementToken()throwsIOException{
- while(sames.size()>0){
- //将元素出栈,并获取这个同义词
- Stringstr=sames.pop();
- //还原状态
- restoreState(current);
- cta.setEmpty();
- cta.append(str);
- //设置位置
- pia.setPositionIncrement(0);
- returntrue;
- }
- if(!input.incrementToken())returnfalse;
- if(getSameWords(cta.toString())){
- //如果有同义词将当前状态先保存
- current=captureState();
- }
- returntrue;
- }
- /*
- *使用这种方式是不行的,这种会把的结果是[中国]替换成了[大陆]
- *而不是变成了[中国][大陆]
- @Override
- publicbooleanincrementToken()throwsIOException{
- if(!input.incrementToken())returnfalse;
- if(cta.toString().equals("中国")){
- cta.setEmpty();
- cta.append("大陆");
- }
- returntrue;
- }
- */
- privatebooleangetSameWords(Stringname){
- Map<String,String[]>maps=newHashMap<String,String[]>();
- maps.put("中国",newString[]{"大陆","天朝"});
- maps.put("我",newString[]{"咱","俺"});
- String[]sws=maps.get(name);
- if(sws!=null){
- for(Strings:sws){
- sames.push(s);
- }
- returntrue;
- }
- returnfalse;
- }
- }
8、打印语汇单元的信息
[java]
view plaincopy
- packageorg.lucene.util;
- importjava.io.IOException;
- importjava.io.StringReader;
- importorg.apache.lucene.analysis.Analyzer;
- importorg.apache.lucene.analysis.TokenStream;
- importorg.apache.lucene.analysis.tokenattributes.CharTermAttribute;
- importorg.apache.lucene.analysis.tokenattributes.OffsetAttribute;
- importorg.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
- importorg.apache.lucene.analysis.tokenattributes.TypeAttribute;
- /**
- *打印语汇单元的信息
- *@authoruser
- *
- */
- publicclassAnalyzerUtils{
- publicstaticvoiddisplayToken(Stringstr,Analyzera){
- TokenStreamstream=a.tokenStream("content",newStringReader(str));
- /*
- *TokenStream相当于一条流
- *CharTermAttribute相当于一个碗
- *然后把碗丢进流里面,当碗得到一个元素后,碗又会自动流到了下
- *一个元素进行取值
- *这是一种设计模式:创建一个属性,这个属性会添加流中,
- *随着这个TokenStream增加
- */
- CharTermAttributecta=stream.addAttribute(CharTermAttribute.class);
- try{
- while(stream.incrementToken()){
- System.out.print("["+cta+"]");
- //System.out.println(stream);
- //如果直接打印Stream的话,toString打印如下:
- //(来,startOffset=1,endOffset=2,positionIncrement=1,type=<IDEOGRAPHIC>)
- }
- System.out.println();
- }catch(IOExceptione){
- e.printStackTrace();
- }
- }
- /**
- *打印详细信息的语汇单元
- *@paramstr
- *@parama
- */
- publicstaticvoiddisplayAllToken(Stringstr,Analyzera){
- TokenStreamstream=a.tokenStream("content",newStringReader(str));
- //位置增量
- PositionIncrementAttributepia=stream.addAttribute(PositionIncrementAttribute.class);
- //偏移量
- OffsetAttributeoa=stream.addAttribute(OffsetAttribute.class);
- //词元
- CharTermAttributecta=stream.addAttribute(CharTermAttribute.class);
- //分词的类型
- TypeAttributeta=stream.addAttribute(TypeAttribute.class);
- try{
- while(stream.incrementToken()){
- System.out.print(pia.getPositionIncrement()+":");
- System.out.print(cta+"["+oa.startOffset()+"-"+
- oa.endOffset()+"-"+ta.type());
- System.out.println();
- }
- System.out.println();
- }catch(IOExceptione){
- e.printStackTrace();
- }
- }
- }
工程下载路径:http://download.csdn.net/detail/wxwzy738/5284705
相关推荐
在Lucene.NET中,为了支持中文分词,通常需要结合第三方分词器,如IK Analyzer、HanLP、jieba.NET等。这些分词器具备丰富的词汇库和优秀的分词算法,能有效地对中文文本进行拆分。 - **IK Analyzer**:是一个开源的...
1. **中文分词器**:在Lucene中,针对中文的分词通常使用第三方插件,如IK Analyzer、jieba分词库或SmartChinese Analyzer。这些分词器能识别中文词汇并将其拆分为单个词元(Token)。 2. **配置分析器**:在...
Lucene本身并不直接支持中文分词,而是通过集成第三方分词器来实现。常见的中文分词器有IK Analyzer、HanLP、jieba分词等。这些分词器基于不同的分词策略,如基于词典的分词、基于统计的分词、HMM(隐马尔科夫模型)...
然而,`Lucene5`默认的分词器对中文支持不够完善,因此需要借助第三方分词工具来增强其中文处理能力。 `HanLP`(全称:High-performance Natural Language Processing)是由网易有道公司开源的一个自然语言处理工具...
在Solr中,我们可以直接配置这些第三方分词器,例如在solrconfig.xml文件中设置Analyzer,以实现对中文文档的高效索引和检索。 在使用这些中文分词器时,需要注意以下几点: 1. 配置:正确配置分词器的字典文件和...
对于中文文本的处理,分词是关键的第一步,而Lucene则是广泛使用的全文搜索引擎库。本文将深入探讨盘古分词和Lucene如何协同工作,为中文全文检索提供高效且精准的支持。 首先,让我们来了解一下盘古分词。盘古分词...
标题中的“lucene第一步---5.中文分词IKAnalyzer和高亮highlighter的使用”指出,这个主题将探讨如何在Lucene中应用IKAnalyzer进行中文分词,以及如何使用高亮器(highlighter)来突出搜索结果中的关键词。Lucene是...
在处理中文文档时,Lucene需要依赖于第三方的分词器,以便对中文文本进行有效的切分。 二、中文分词的重要性 中文分词是中文信息处理的核心环节,因为中文词汇之间没有明显的分隔符,因此需要通过特定算法将连续的...
在Java开发中,Apache Lucene是一个强大的全文搜索引擎库,但默认并不支持中文,这就需要借助第三方分词工具。本文将深入探讨如何在Lucene中结合“庖丁解牛”这一中文分词工具,实现高效、准确的中文文本处理。 一...
此外,还有如HanLP、jieba等第三方分词工具,它们提供了更丰富的分词效果和自定义功能。 二、Lucene 3.5中文分词实践 1. 安装与配置:在使用Lucene进行中文分词前,首先需要引入IK Analyzer或其他中文分词库的依赖...
而`IKAnalyzer`(Intelligent Chinese Analyzer)则是一款第三方的开源Analyzer,它具有较好的分词效果和较高的灵活性,支持自定义词典和热更新。 1. **词典分词**:无论是`SmartChineseAnalyzer`还是`IKAnalyzer`...
3. IK_CAnalyzer(MIK_CAnalyzer):这是基于Lucene 2.0开发的第三方分词器,由用户自行维护和更新。IKAnalyzer(包括MIK_CAnalyzer的改进版)以词典为基础,具有较好的分词效果和可扩展性,支持动态词典更新,适用...
在Lucene中,我们可以使用IK Analyzer、Smart Chinese Analyzer或HanLP等第三方分词器,它们都实现了基于词典的最大匹配分词策略。这些分词器通常包括以下步骤: - 读取词典:加载词典文件,构建Trie树或其他高效的...
在自然语言处理领域,中文分词是至关重要的第一步,它涉及到文本分析、信息检索、机器学习等多个方面。本文将深入探讨基于Lucene的四种中文分词器:Paoding、IK、Imdict和Mmseg4j,它们都是针对Java开发的高效、开源...
由于中文没有明显的分隔符,Lucene需要依赖第三方分词器。例如,IKAnalyzer是一个流行的开源分词器,它支持灵活的词典定制和多种分词模式,能够很好地处理常见词汇和网络用语。另一个选择是SmartChineseAnalyzer,它...
在信息检索和自然语言处理领域,分词是至关重要的第一步。Lucene,作为Java最著名的全文搜索引擎库,其强大的分词能力使得它在各种信息检索系统中广泛应用。本文将深入探讨Lucene中的分词器特性,特别是其对分词歧义...
Lucene自身的分词能力对于中文来说相对较弱,因此引入了第三方分词工具,如Paoding分词。 三、Paoding分词 Paoding(庖丁)是一款高性能、易用的中文分词工具,尤其适合大规模文本处理。它的特点包括支持多种分词...
在Lucene中,进行中文分词是通过第三方分词器来完成的,如jieba分词、IK分词等。 在Lucene中实现中文检索,我们通常会遵循以下步骤: 1. **创建索引**:首先,我们需要对要搜索的文档进行分词,然后将这些词汇和...
分词是文本处理的第一步,它将连续的字符序列分割成有意义的词语,为后续的索引和搜索操作奠定基础。不同的分词策略会直接影响到搜索引擎对用户查询的理解和匹配。 3. **Lucene中的分词器(Analyzer)** 在Lucene...
- 实现分词策略,可能包括自定义分词器或第三方分词库的集成 - 在ASP.NET Web应用程序中嵌入全文搜索功能 - 解决方案和项目结构的组织 - 使用Visual Studio进行开发和调试 为了深入理解这个Demo,开发者需要熟悉...