`

[Lucene] 使用Lucene创建自定义的词干分析器

阅读更多

代码主要来源: 《Collective Intelligence 实战》

Lucene版本: 4.6.1

原来的代码是基于2.2写的,很多东西已经变了。现在用4.6.1重现实现一遍

 

 

package impl;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.core.LowerCaseFilter;
import org.apache.lucene.analysis.core.StopFilter;
import org.apache.lucene.analysis.en.PorterStemFilter;
import org.apache.lucene.analysis.standard.StandardTokenizer;
import org.apache.lucene.analysis.synonym.SynonymFilter;
import org.apache.lucene.analysis.synonym.SynonymMap;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.util.CharArraySet;
import org.apache.lucene.util.CharsRef;
import org.apache.lucene.util.Version;

public class PorterStemStopWordAnalyzer extends Analyzer {

	// 自定义停用词
	private static final String[] stopWords = {"and", "of", "the", "to", "is", "their", "can", "all"};
	public PorterStemStopWordAnalyzer() {
	}

	@Override
	protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
		// 创建一个分词器
		Tokenizer tokenizer = new StandardTokenizer(Version.LUCENE_46, reader);
		
		// 创建一系列的分词过滤器
		TokenFilter lowerCaseFilter = new LowerCaseFilter(Version.LUCENE_46, tokenizer);
		TokenFilter synonymFilter = new SynonymFilter(lowerCaseFilter, getSynonymMap(), true);
		TokenFilter stopFilter = new StopFilter(Version.LUCENE_46, synonymFilter, buildCharArraySetFromArry(stopWords));
		TokenFilter stemFilter = new PorterStemFilter(stopFilter);
		
		// TokenStream的包装类 在2.2之中 是TokenStream
		return new TokenStreamComponents(tokenizer, stemFilter);
	}
	
	// 将数组转成lucene可识别的CharArraySet对象 CharArraySet类似java.util.set
	private CharArraySet buildCharArraySetFromArry(String[] array) {
		CharArraySet set = new CharArraySet(Version.LUCENE_46, array.length, true);
		for(String value : array) {
			set.add(value);
		}
		return set;
	}
	
	// 创建一个同义词表
	private SynonymMap getSynonymMap() {
		String base1 = "fast";
		String syn1 = "rapid";
		
		String base2 = "slow";
		String syn2 = "sluggish";
		
		SynonymMap.Builder sb = new SynonymMap.Builder(true);
		sb.add(new CharsRef(base1), new CharsRef(syn1), true);
		sb.add(new CharsRef(base2), new CharsRef(syn2), true);
		SynonymMap smap = null;
		try {
			smap = sb.build();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return smap;
	}
	
	// 测试方法
	public static void testPorterStemmingAnalyzer() throws IOException {
		Analyzer analyzer = new PorterStemStopWordAnalyzer();
		String text = "Collective intelligence and Web2.0, fast and rapid";
		Reader reader = new StringReader(text);
		TokenStream ts = null;
		try {
			ts = analyzer.tokenStream(null, reader);
			ts.reset();
			while(ts.incrementToken()) {
				CharTermAttribute ta = ts.getAttribute(CharTermAttribute.class);  
				System.out.println(ta.toString());
			}
		} catch (IOException e) {
			e.printStackTrace();
		} 
		
	}
	
	public static void main(String[] args) throws IOException {
		testPorterStemmingAnalyzer();
	}

}

 

 

注意:

(1) TokenStream在初始化之后需要reset一次,不然会抛出异常

(2) 将TokenStream 转成Token 常用的一个方法就是使用CharTermAttribute

除了CharTermAttribute 还有其他的Attribute: 比如FlagsAttribute ...

(3) 使用到的类库可以参考上一篇文章:http://rangerwolf.iteye.com/admin/blogs/2011535

(4) 在createComponents方法之中使用了一个同义词过滤器,在构造这个过滤器的时候是通过getSynonymMap方法进行的。在测试样本之中的 fast and rapid 解析完成之后的结果如下:

fast
rapid
rapid

 相当于有两个rapid! 可能是因为这是因为synonymFilter在stopFilter之前运行。

根据java doc 文档的秒速,同义词过滤器应该尽早的运行。比如second rule.

做了另外的一个测试:

String base3 = "Collective Intelligence";
String syn3 = "CI";
sb.add(new CharsRef(base3), new CharsRef(syn3), true);

 即将Collective Intelligence 跟CI 同义

同样的样本的运行结果完全不变! 

说明无法对词长度为2的词组进行同义词~

分享到:
评论

相关推荐

    java lucene 实现分词和词干抽取

    用java实现的,利用了lucene里面的standardAnalyzer分析器实现的分词,可以去停用词,再利用波特算法实现 词干提取 最后排序 和词频统计输出

    Lucene使用教程

    - **简单分析器(SimpleAnalyzer)**:只将文本分割成单词,不进行词干化或停用词过滤。 - **自定义分析器**:根据具体需求定制的分析器,可以通过组合多个TokenFilter实现更复杂的功能。 **3.2 文档(Document)**...

    lucene3源码分析

    ### Lucene3源码分析知识点概述 #### 一、全文检索的基本原理 ##### 1. 总论 全文检索系统是一种高效的信息检索技术,能够帮助用户在海量文档中快速找到包含特定关键词的信息。Lucene是Java领域内最受欢迎的全文...

    Lucene_3.0_原理与代码分析

    分析器可以是内置的也可以是由用户自定义的。 4. **Document(文档)**:表示索引中的单个文档。每个文档都是一组字段的集合,其中每个字段可以有不同的值。 5. **Field(字段)**:构成文档的基本单元。字段可以...

    Lucene+3.0+原理与代码分析完整版

    **JavaCC** 是一个用于生成词法分析器和语法分析器的工具,**QueryParser** 则是 Lucene 提供的一个用于解析查询字符串的类。 #### 九、Lucene 查询对象 **查询对象**是 Lucene 中用于表示查询逻辑的数据结构,...

    Lucene+3.0+原理与代码分析

    12. **扩展性与定制化**:Lucene的架构允许用户自定义分词器、过滤器、评分函数等,以适应特定的需求。 通过深入学习《Lucene 3.0 原理与代码分析》,开发者不仅可以掌握Lucene的基础用法,还能了解其内部工作流程...

    Lucene索引数据分析器

    总结起来,Lucene索引数据分析器是开发人员的强大工具,它通过`IndexAPI.dll`提供的接口对文本进行高效索引,使用`IndexReader.exe`进行数据查询,最终以表格形式展示结果,便于开发者理解和利用数据。通过深入理解...

    lucene_jar包

    Lucene提供了多种预定义的分析器,如StandardAnalyzer,以及自定义分析器的可能性。 - **文档(Documents)**: 在Lucene中,每个文档都是一个包含字段(Fields)的对象。字段可以设置为可搜索、可存储或两者兼有。 ...

    lucene-analysis.jar

    除了预定义的分析器,"lucene-analysis.jar"还提供了自定义分析器的基础框架。开发者可以根据具体需求,组合使用Tokenizers(分词器)、TokenFilters(过滤器)和CharFilters(字符过滤器)来构建个性化的分析流程。...

    lucene 原理与代码分析

    《Lucene原理与代码分析》深入探讨了几乎最新版本的Lucene的工作机制和代码实现细节,为理解全文搜索引擎的核心技术提供了宝贵的资源。以下是对该文件关键知识点的详细解析: ### 全文检索的基本原理 #### 总论 ...

    lucene原理与代码分析完整版

    Lucene提供了多种内置的分词器,同时也支持自定义分词器。 #### 九、Lucene的事务性和实时索引构建 Lucene虽然主要用于离线索引构建,但也支持一定程度上的事务性操作和实时索引更新。这对于需要频繁更新索引的...

    lucene3.0.3搜索的使用示例

    Lucene 3.0.3提供了多种内置分析器,如StandardAnalyzer,它处理英文文本,移除停用词和标点符号。 4. **Document** 和 **Field** 类:Document是Lucene中的基本数据结构,代表一个要被索引的完整文档。每个文档...

    Lucene学习源码.rar

    Lucene内置了多种分词器,如StandardAnalyzer、SimpleAnalyzer等,也可自定义。 5. 查询解析器(QueryParser):将用户的查询字符串转换为内部表示,用于与索引进行匹配。 6. 搜索器(Searcher):执行搜索操作,...

    lucene全文搜素实例 java lucene 实例

    3. **分析器选择**:根据需求选择合适的分析器,例如 `StandardAnalyzer` 适用于大多数情况,但若需处理中文,可能需要使用 `SmartChineseAnalyzer` 或其他支持中文的分析器。 4. **构建查询**:使用 `QueryParser`...

    Lucene简单使用需要的jar

    `lucene-analyzers-common-7.2.1.jar`包含了一些常见的文本分析器,如英文分析器,它会处理停用词、词干提取等。 3. **查询解析**:`lucene-queryparser-7.2.1.jar`则包含了查询解析器,负责将用户输入的查询字符串...

    lucene源码和程序

    Lucene提供了多种内置分析器,如标准分析器(StandardAnalyzer),也可以自定义分析器以适应特定需求。 5. **搜索(Search)**:用户通过Query对象提交查询,Lucene会使用索引来找到匹配的文档。查询可以是简单的...

    lucene演示需要的数据

    1. **文档分析**:Lucene使用分析器将原始输入转换为可索引的术语。分析器可以定制以适应不同的语言和领域需求。 2. **字段和类型**:每个文档由多个字段组成,如标题、正文、作者等。每个字段可以指定其类型,如...

    Lucene In Action中文版第三章

    在《Lucene In Action中文版第三章》中,读者将深入了解到如何配置和使用标准分析器(Standard Analyzer)、自定义分析器以及针对不同语言的分析器,例如中文分析器。对于中文,由于没有明显的空格分隔,需要特殊的...

    基于Lucene3.6进行全文检索的小案例

    在Lucene 3.6中,可以自定义分析器以适应不同的语言和文本需求。 4. **查询解析器(Query Parser)**:将用户输入的查询字符串转化为Lucene能够理解的查询对象。 5. **搜索器(Searcher)**:搜索器是实际执行查询...

    lucene in action 电子版

    - **高级分析技巧**:介绍了如何通过组合不同的分析器来提高搜索质量,例如去除停用词、进行词干提取等。 - **章节5:高级搜索技术** - **布尔搜索**:讨论了基于布尔逻辑的查询方式,如AND、OR、NOT操作符的应用...

Global site tag (gtag.js) - Google Analytics