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;
} @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;
} }
lucene构建同义词分词器的更多相关文章
- 【Lucene3.6.2入门系列】第05节_自定义停用词分词器和同义词分词器
首先是用于显示分词信息的HelloCustomAnalyzer.java package com.jadyer.lucene; import java.io.IOException; import j ...
- Apache Lucene(全文检索引擎)—分词器
目录 返回目录:http://www.cnblogs.com/hanyinglong/p/5464604.html 本项目Demo已上传GitHub,欢迎大家fork下载学习:https://gith ...
- Lucene系列四:Lucene提供的分词器、IKAnalyze中文分词器集成、扩展 IKAnalyzer的停用词和新词
一.Lucene提供的分词器StandardAnalyzer和SmartChineseAnalyzer 1.新建一个测试Lucene提供的分词器的maven项目LuceneAnalyzer 2. 在p ...
- 【原创】Lucene.Net+盘古分词器(详细介绍)
本章阅读概要 1.Lucenne.Net简介 2.介绍盘古分词器 3.Lucene.Net实例分析 4.结束语(Demo下载) Lucene.Net简介 Lucene.net是Lucene的.net移 ...
- Lucene.Net+盘古分词器(详细介绍)(转)
出处:http://www.cnblogs.com/magicchaiy/archive/2013/06/07/LuceneNet%E7%9B%98%E5%8F%A4%E5%88%86%E8%AF%8 ...
- Lucene的中文分词器IKAnalyzer
分词器对英文的支持是非常好的. 一般分词经过的流程: 1)切分关键词 2)去除停用词 3)把英文单词转为小写 但是老外写的分词器对中文分词一般都是单字分词,分词的效果不好. 国人林良益写的IK Ana ...
- Lucene的中文分词器
1 什么是中文分词器 学过英文的都知道,英文是以单词为单位的,单词与单词之间以空格或者逗号句号隔开. 而中文的语义比较特殊,很难像英文那样,一个汉字一个汉字来划分. 所以需要一个能自动识别中文语义的分 ...
- 重写lucene.net的分词器支持3.0.3.0版本
lucene.net中每个分词器都是一个类,同时有一个辅助类,这个辅助类完成分词的大部分逻辑.分词类以Analyzer结尾,辅助类通常以Tokenizer结尾.分类词全部继承自Analyzer类,辅助 ...
- Lucene.Net+盘古分词器(详细介绍)
本章阅读概要1.Lucenne.Net简介2.介绍盘古分词器3.Lucene.Net实例分析4.结束语(Demo下载)Lucene.Net简介 Lucene.net是Lucene的.net移植版本,是 ...
随机推荐
- Java多线程Master-Worker模式
Java多线程Master-Worker模式,多适用于需要大量重复工作的场景中. 例如:使用Master-Worker计算0到100所有数字的立方的和 1.Master接收到100个任务,每个任务需要 ...
- C 程序实现密码隐秘输入 linux系统可执行
读写用户输入,屏幕不回显 char *getpass( const char *prompt); getpass用于从键盘读取用户输入,但屏幕不回显. 参数prompt为屏幕提示字符. 函数返回值为用 ...
- 消息中间件ActiveMQ及Spring整合JMS的介绍
一 .消息中间件的基本介绍 1.1 消息中间件 1.1.1 什么是消息中间件 消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成.通过提供消息传递和消息排 ...
- 几种常用的ajax 跨域请求
前 言 首先,我们要明白,什么是跨域,为什么要跨域. 由于JS中存在同源策略.当请求不同协议名不同端口号下面的文件时,将会违背同源策略,无法请求成功!需要进行跨域处理! 这篇文章就为大家详细介绍一 ...
- ASP.NET Core 与 Vue.js 服务端渲染
http://mgyongyosi.com/2016/Vuejs-server-side-rendering-with-aspnet-core/ 原作者:Mihály Gyöngyösi 译者:oop ...
- JDBC之代码优化
上一次我们是先实现了JDBC对数据库的增删查改操作,然后在增加新信息过程中发现了新的问题,即当某一操作失败,为了维护数据库的一致性,我们需要回滚事务.在其中我们了解了事务的工作原理及相关代码的使用. ...
- TCP网络程序实例——服务器端与客户端交互
实例02 客户端/服务器的交互 实例位置:光盘\Code\SL\14\02 视频位置:光盘\Video\14\ ◆ 服务器端 创建服务器端项目Server,在Main方法中创建TCP连接对象:然后监听 ...
- HTML5原生拖拽/拖放⎡Drag & Drop⎦详解
前言 拖放(drap && drop)在我们平时的工作中,经常遇到.它表示:抓取对象以后拖放到另一个位置.目前,它是HTML5标准的一部分.我从几个方面学习并实践这个功能. 拖放的流程 ...
- flex布局元素操作详情
之前布局一直用的是 position,float之类的,趁着国庆学习一下 flex 布局 父元素: flex-direction: row row-reverse column column-reve ...
- Shell脚本数据备份