lucene构建同义词分词器
2024-08-26 06:32:27
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;
} @Override
public 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<String> 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<String>();
this.samewordContext=samewordContext;
} @Override
public 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 exception
e.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;
} }
最新文章
- PHP缓存技术
- Amazon AWS 架设EC2服务器(datizi)fanqiang (更新手机VPN/L2TP设置)
- 捉虫记(四)线程安全导致的HighCpu
- js模版引擎handlebars.js实用教程——循环中使用索引
- Android 如何解决数据库多线程锁的问题
- Python小爬虫-自动下载三亿文库文档
- Link-local address
- GWT用frame调用JSP
- 14.6.3.1 The InnoDB Buffer Pool
- ulimit开启coredump时核心转储
- 制作Orcad的变种BOM(Variant BOM)
- 用for while 成绩的有效输入
- CSS3学习笔记-1:CSS样式继承
- pip 安装问题
- SQL函数总结
- PHP连接MySQL数据库的三种方式(mysql、mysqli、pdo)
- is,as,类库
- CentOS 系统 git clone出错
- python3 设置滚动条
- python模块之time模块