首页 > lucene构建同义词分词器

lucene构建同义词分词器

       lucene4.0版本号以后 已经用TokenStreamComponents 代替了TokenStream流。里面包含了filter和tokenizer

       在较复杂的lucene搜索业务场景下,直接网上下载一个作为项目的分词器,是不够的。那么怎么去评定一个中文分词器的好与差:一般来讲。有两个点。词库和搜索效率,也就是算法。

       lucene的倒排列表中,不同的分词单元有不同的PositionIncrementAttribute,假设两个词之间PositionIncrementAttribute距离为0。则为同义词;比方:我定义美国和中国这两个词在倒排列表中是同一个位置及距离为0,那么搜索美国的话,中国也能出来。

这就是同义词搜索原理。

下面代码(用mmseg的 Tokenizer 去切词之后,然后再做同义词):

先自己定义分词器:

package hhc;import java.io.Reader;import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;import com.chenlb.mmseg4j.Dictionary;
import com.chenlb.mmseg4j.MaxWordSeg;
import com.chenlb.mmseg4j.analysis.MMSegTokenizer;/*** 写一个分词器,一般能够參照原来分词器是怎么写法的* @author hhc**/
public class MySameAnalyzer extends Analyzer{//同义词private SamewordContext samewordContext=null;public MySameAnalyzer(SamewordContext samewordContext){this.samewordContext=samewordContext;}@Overridepublic TokenStream tokenStream(String fieldName, Reader reader) {// Dictionary dic=Dictionary.getInstance();return new MySameTokenFilter(new MMSegTokenizer(new MaxWordSeg(dic), reader),samewordContext);}}


然后再对TokenStream流做同义词处理

 

package hhc;import java.io.IOException;
import java.util.Stack;import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.util.AttributeSource;public class MySameTokenFilter extends TokenFilter {// 分词单元信息private CharTermAttribute cta = null;// 位置信息private PositionIncrementAttribute pia = null;// 状态private AttributeSource.State current;// 同义词集合private Stack sames = null;private SamewordContext samewordContext=null;protected MySameTokenFilter(TokenStream input,SamewordContext samewordContext) {super(input);cta = input.addAttribute(CharTermAttribute.class);pia = input.addAttribute(PositionIncrementAttribute.class);sames=new Stack();this.samewordContext=samewordContext;}@Overridepublic boolean incrementToken() throws IOException {try {if (sames!=null&&sames.size()> 0) {// 删除对象在堆栈,然后返回的对象上的函数值。而且获取这个同义词String str = sames.pop();// 还原状态restoreState(current);cta.setEmpty();cta.append(str);pia.setPositionIncrement(0);return true;}// 假设流中没有数据了。if (!input.incrementToken())return false;/*** 流中有数据的话,进行对应的同义词*/// 处理切分出来的词的信息if (existAddSameword(cta.toString())) {// 把当前状态先保存current = captureState();}} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}return true;}/*** 推断是否该分词单元存在* * @param word* @return*/private boolean existAddSameword(String word) {String[] words=samewordContext.getSameword(word);if (words != null) {for (String s : words) {sames.push(s);}return true;}return false;}}




转载于:https://www.cnblogs.com/zsychanpin/p/6789050.html

更多相关: