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. 推荐三款日期选择插件(My97DatePicker+jquery.datepicker+Mobiscroll)

    1.My97DatePicker 纯原生JS,专注于PC端,支持IE6+:页面上只需要引入WdatePicker.js文件,但是My97DatePicker整个目录是一个整体,最好不要破坏里面的目录结 ...

  2. 启动tomcat直接报错:org.apache.tomcat.util.digester.Digester startElement

    今天很奇怪,自己手动搭建了一个ssm(spring+springmvc+mybatis)的项目,然后添加到tomcat下,启动直接报错: 2017-3-19 9:24:47 org.apache.to ...

  3. yii2.0使用之缓存

    1.片段缓存(针对于视图中的某部分进行缓存): <?php 设置有效时间 $time=15; 缓存依赖,存入文件.当文件内容发生改变是才会刷新新内容 $dependecy=[ 'class'=& ...

  4. Power BI Embedded 与 Bot Framework 结合的AI解决方案

    最近最热门的话题莫过于AI了,之前我做过一片讲 BOTFRAMEWORK和微信 相结合的帖子 如何将 Microsoft Bot Framework 链接至微信公共号 我想今天基于这个题目扩展一下,P ...

  5. C#实现不影响当前线程情况下间隔一定的时间执行一段代码

    大家知道C#间隔一定时间去执行一段代码,常用的有 1. Thread.Sleep(多少毫秒); 2. 使用Timer控件间隔一定的时间,设置执行一次 以上两种方法,实现起来不难,弊端在于会阻塞当前线程 ...

  6. jQuery选择器对应的DOM API ——选择元素

    英文原文:http://blog.garstasio.com/you-dont-need-jquery/selectors/愚人码头注: 原作者的写这文章的意图是让我们抛弃jQuery,You Don ...

  7. 学习Jammendo代码的心路历程(一)简单的淡出效果实现

    最近在看 Jammendo代码,打算将学习过程简单的记录下来,下面开始第一篇: 打开Jammendo运行之后,出弹出一个对话框,跳过对话框之后,会有一个淡出界面跳转到首页效果的实现.那么这个效果是怎么 ...

  8. HTML的语义化,你需要深入了解

    有关HTML的一些基础课程,很多网站都有讲,于我而言,真正实践起来,我只要求我能够让它表现出我所想要的结果即可.然而,这种要求,对于后期的维护与测试,真的是......想起日前我们所做的这个项目,那里 ...

  9. Legendary Items-微软实习生笔试第一题

    题目如下: 这道题难点不仅在于正确理解题意,判断递归条件,更在于用数学方法推出解决公式.因为N最大为1百万,而内存只有256MB, 所以暴力递归肯定会超时,超空间. 不过,我才疏学浅,又没有大量时间去 ...

  10. 更换gitlab公网IP,引发的故障。

    gitlab更换公网IP地址,导致gitlab非常的很卡,并且ssh方式添加的远程仓库是无法git pull 或者git push,只有是添加http方式的可以正常git pull和git push ...