Lucene自带的中文分词器SmartChineseAnalyzer不太好扩展,于是我用了IKAnalyzer来进行敏感词和停用词的过滤。

首先,下载IKAnalyzer,我下载了

然后,由于IKAnalyzer已经很久不更新了,不兼容现在的Lucene6版本,所以我参考网上的资料,重写了IKTokenizer和IKAnalyzer两个类。

 package kidsearch;
import java.io.IOException;
import java.io.Reader; import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme; public class MyIKTokenizer extends Tokenizer {
// IK分词器实现
private IKSegmenter _IKImplement; // 词元文本属性
private final CharTermAttribute termAtt;
// 词元位移属性
private final OffsetAttribute offsetAtt;
// 词元分类属性(该属性分类参考org.wltea.analyzer.core.Lexeme中的分类常量)
private final TypeAttribute typeAtt;
// 记录最后一个词元的结束位置
private int endPosition; public MyIKTokenizer(Reader in) {
this(in, true);
} public MyIKTokenizer(Reader in, boolean useSmart) {
offsetAtt = addAttribute(OffsetAttribute.class);
termAtt = addAttribute(CharTermAttribute.class);
typeAtt = addAttribute(TypeAttribute.class);
_IKImplement = new IKSegmenter(input, useSmart);
} @Override
public boolean incrementToken() throws IOException {
// 清除所有的词元属性
clearAttributes();
Lexeme nextLexeme = _IKImplement.next();
if (nextLexeme != null) {
// 将Lexeme转成Attributes
// 设置词元文本
termAtt.append(nextLexeme.getLexemeText());
// 设置词元长度
termAtt.setLength(nextLexeme.getLength());
// 设置词元位移
offsetAtt.setOffset(nextLexeme.getBeginPosition(),
nextLexeme.getEndPosition());
// 记录分词的最后位置
endPosition = nextLexeme.getEndPosition();
// 记录词元分类
typeAtt.setType(String.valueOf(nextLexeme.getLexemeType()));
// 返会true告知还有下个词元
return true;
}
// 返会false告知词元输出完毕
return false;
} public void reset() throws IOException {
super.reset();
_IKImplement.reset(input);
} @Override
public final void end() {
// set final offset
int finalOffset = correctOffset(this.endPosition);
offsetAtt.setOffset(finalOffset, finalOffset);
} }

MyIKTokenizer

 package kidsearch;
import java.io.Reader;
import java.io.StringReader; import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.util.IOUtils;
import kidsearch.MyIKTokenizer;
public class MyIkAnalyzer extends Analyzer { @Override
protected TokenStreamComponents createComponents(String arg0) {
Reader reader=null;
try{
reader=new StringReader(arg0);
MyIKTokenizer it = new MyIKTokenizer(reader);
return new Analyzer.TokenStreamComponents(it);
}finally {
IOUtils.closeWhileHandlingException(reader);
}
} }

MyIKAnalyzer

参考的博客里有一部分是错误的

于是我又下载了IKAnalyzer的源码,仔细看了一下Lexeme.java,发现没有这个方法,只有getLexemeType,而且返回值是int,于是自己做了点小改动,终于编译通过了!

值得注意的是,MyIKTokenizer里

 public MyIKTokenizer(Reader in) {
this(in, true);
}

true为选择智能划分(北京师范大学),而false为最细粒度划分(北京师范大学,北京,京师,师范大学,师范,大学)。

最后,要配置自己的停用词和敏感词。

自定义词典一定要使用UTF-8无BOM编码,否则不能实现过滤功能。

然后,在配置文件IKAnalyzer.cfg.xml里配置自定义词典

最后,分别把所有的自定义词典和IKAnalyzer.cfg.xml加到工程里的src(为了保险起见,我又把他们加到了bin里,IK的jar包里也加了)。

为了测试停用词的效果,可以自己写几个小程序。

 import java.io.IOException;
import java.io.StringReader; import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.wltea.analyzer.cfg.Configuration;
import org.wltea.analyzer.cfg.DefaultConfig;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
import org.wltea.analyzer.lucene.IKAnalyzer; public class OwnIKAnalyzer {
public static void main(String[] args) throws IOException {
String text="我有一个红红的苹果";
StringReader sr=new StringReader(text);
// IKSegmenter ik=new IKSegmenter(sr, true);
IKSegmenter ik=new IKSegmenter(sr,true);
Lexeme lex=null;
while((lex=ik.next())!=null){
System.out.print(lex.getLexemeText()+",");
}
// String text = "这是一个红红的苹果";
// Configuration configuration = DefaultConfig.getInstance();
// configuration.setUseSmart(true);
// IKSegmenter ik = new IKSegmenter(new StringReader(text), configuration);
// Lexeme lexeme = null;
// while ((lexeme = ik.next()) != null) {
// System.out.println(lexeme.getLexemeText());
}
}

测试结果为:(词典里并没有过滤“我”)

另外,IKAnalyzer可以配置自己的扩展词典,比如“你的名字”本来会被分词为“你,的,名字”,但是在ext.dic里加入“你的名字”后就是一个完整的整体,不会被切分了!

关于IKAnalyzer词语过滤的功能今天就做了多,以后还会继续补充~

【lucene系列学习四】使用IKAnalyzer分词器实现敏感词和停用词过滤的更多相关文章

  1. lucene全文搜索之二:创建索引器(创建IKAnalyzer分词器和索引目录管理)基于lucene5.5.3

    前言: lucene全文搜索之一中讲解了lucene开发搜索服务的基本结构,本章将会讲解如何创建索引器.管理索引目录和中文分词器的使用. 包括标准分词器,IKAnalyzer分词器以及两种索引目录的创 ...

  2. lucene内存索引库、分词器

    内存索引库 特点 在内存中开辟一块空间,专门为索引库存放.这样有以下几个特征: 1)    因为索引库在内存中,所以访问速度更快. 2)    在程序退出时,索引库中的文件也相应的消失了. 3)    ...

  3. Solr配置Ikanalyzer分词器

    上一篇文章讲解在win系统中如何安装solr并创建一个名为test_core的Core,接下为text_core配置Ikanalyzer 分词器 1.打开text_core的instanceDir目录 ...

  4. lucene全文搜索之四:创建索引搜索器、6种文档搜索器实现以及搜索结果分析(结合IKAnalyzer分词器的搜索器)基于lucene5.5.3

    前言: 前面几章已经很详细的讲解了如何创建索引器对索引进行增删查(没有更新操作).如何管理索引目录以及如何使用分词器,上一章讲解了如何生成索引字段和创建索引文档,并把创建的索引文档保存到索引目录,到这 ...

  5. Lucene.Net3.0.3+盘古分词器学习使用

    一.Lucene.Net介绍 Lucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索 ...

  6. python调用jieba(结巴)分词 加入自定义词典和去停用词功能

    把语料从数据库提取出来以后就要进行分词啦,我是在linux环境下做的,先把jieba安装好,然后找到内容是build jieba PKG-INFO setup.py test的那个文件夹(我这边是ji ...

  7. IKanalyzer分词器分词并且统计词频

    <dependency> <groupId>com.janeluo</groupId> <artifactId>ikanalyzer</artif ...

  8. 【lucene系列学习四】log4j日志文件实现多线程的测试

    参考资料:http://nudtgk2000.iteye.com/blog/1716379 首先,在http://www.apache.org/dyn/closer.cgi/logging/log4j ...

  9. Lucene系列四:Lucene提供的分词器、IKAnalyze中文分词器集成、扩展 IKAnalyzer的停用词和新词

    一.Lucene提供的分词器StandardAnalyzer和SmartChineseAnalyzer 1.新建一个测试Lucene提供的分词器的maven项目LuceneAnalyzer 2. 在p ...

随机推荐

  1. okhttp +fastJson 在UI层的回调封装

    一直使用OkHttp 经常烦人的地方是回调方法  数据解析后必须通过handler 在主线程做操作 网上找了很多资料 发现有些都是基于Gson做的解析 fastJson 在封装时 泛型传入会有很多不方 ...

  2. SpringMVC中@RequestBody引起的400异常处理,返回校验失败具体信息

    问题 使用@RequestBody接收一个json数据的时候,如果传入的参数不符合条件,就会直接返回400的error page. 但究竟是为什么会400并没有抛出来.这对大量参数字段的我们来说,排错 ...

  3. Storm(2015.08.12笔记)

    2015.08.12Storm   一.Storm简介 Storm是Twitter开源的一个类似于Hadoop的实时数据处理框架.   Storm能实现高频数据和大规模数据的实时处理. 官网资料显示s ...

  4. iOS开发之通知机制

    1.通知中心 每一个应用程序都有一个通知中心(NSNotificationCenter)实例,专门负责协助不同对象之间的消息通信 任何一个对象都可以向通知中心发布通知(NSNotification), ...

  5. django出现__init__() got an unexpected keyword argument 'mimetype‘ 问题解决

    这种问题好多新手按照djangobook学习的时候应该都遇到过,是因为这是老的django的写法,新的django已经升级改变了很多东西. 处理方法如下: I think you are not us ...

  6. 小程序新能力-个人开发者尝鲜微信小程序

    个人开发者的福利 微信小程序,刚听到这个新名词的时候,我就兴冲冲的去找入口,看看自己能不能搞个微信小程序的HelloWorld,毕竟能在微信上把自己写的一些小工具跑起来还是满炫酷的. 没想,网上一查, ...

  7. 机器学习:Python中如何使用最小二乘法

    之所以说"使用"而不是"实现",是因为python的相关类库已经帮我们实现了具体算法,而我们只要学会使用就可以了.随着对技术的逐渐掌握及积累,当类库中的算法已经 ...

  8. dede织梦数据表字段解释

    提示:常用字段,可以在dede后台->系统->SQL命令行工具,执行sql语句来批量修改 dede_addonarticle   附加文章表   aid  int(11)  文章编号    ...

  9. Object-C定时器,封装GCD定时器的必要性!!! (一)

    实际项目开发中经常会遇到延迟某件任务的执行,或者让某件任务周期性的执行.然后也会在某些时候需要取消掉之前延迟执行的任务. iOS中延迟操作有三种解决方案: 1.NSObject的方法:(对象方法) p ...

  10. nginx 配置禁用ip地址访问

    做过面向公网WEB运维的苦逼们肯定见识过各种恶意扫描.拉取.注入等图谋不轨行为吧?对于直接对外的WEB服务器,我们可以直接通过 iptables . Nginx 的deny指令或者是程序来ban掉这些 ...