文档章节

IKAnalyzer实现扩展词库+动态更新词库的方法

傲娇字符
 傲娇字符
发布于 2017/10/11 10:50
字数 1107
阅读 31
收藏 0
点赞 0
评论 0

当前IKAnalyzer从发布最后一个版本后就一直没有再更新,使用过程中,经常遇到需要扩展词库以及动态更新字典表的问题,此处给出一种解决办法(注意:本方法中的IKAnalyzer代码我已经将源码移植到了自己的工程中,目录结构也进行了修改):

 

1、将扩展字典表做成可动态生成:

 1)、在IKAnalyzer.cfg.xml中添加扩展字典路径

    blob.png

 2)、在分词的时候,先采取动态生成上面两个字典表的方式进行更新,例如事先将字典词库放在数据表中,需要分词之前先更新字典。当然此方法只支持第一次调用的时候动态加载词库,如果服务没有重启之前,数据库中添加的词是不会进行重新加载的。下面是动态生成字典表的实现类:

package com.chz.apps.sm.IKAnalyzer;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

import com.chz.apps.sm.model.IkanalyzerExtendModel;
import com.chz.base.util.FileUtil;
import com.chz.plugin.IKAnalyzer.core.IKSegmenter;
import com.chz.plugin.IKAnalyzer.core.Lexeme;

/**
 * @Description 分词工具类
 * @author gongstring<1@gongstring.com>
 * @createTime 2016年11月28日 下午2:46:06
 */
public class IKAnalyzerTool {

	/**
	 * 是否已经初始化过词库,如果没有,则会自动先调用词库
	 */
	private static boolean init_words = false;
	
	/**
	 * 扩展关键字
	 */
	private static List<String> extendWords = new ArrayList<String>();

	/**
	 * 停用关键字
	 */
	private static List<String> stopWords = new ArrayList<String>();
	
	
	/**
	 * @Description 初始化词库以及停用词
	 * @author gongstring<1@gongstring.com>
	 * @createTime 2016年11月28日 下午2:29:59
	 */
	public static void initWords(){
		//从关键字表中查询扩展关键字,并生成到指定文件中
		IKAnalyzerTool.extendWords = new ArrayList<String>();
		List<IkanalyzerExtendModel> extendWords = IkanalyzerExtendModel.dao.findByProperty("status", 1);
		String fileDirPath = IKAnalyzerTool.class.getResource("/com/chz/apps/sm/IKAnalyzer/").getPath();
		String filePath = fileDirPath+"extend.dic";
		FileUtil.removeFile(filePath);//先删除文件,此处重新生成
		for (int i = 0; i < extendWords.size(); i++) {
			String txt = extendWords.get(i).getStr("extend_word");
			FileUtil.appendToFile(filePath, txt,true);
			IKAnalyzerTool.extendWords.add(txt);
		}
		//从关键字表中查询停用关键字,并生成到指定文件中
		IKAnalyzerTool.stopWords = new ArrayList<String>();
		List<IkanalyzerExtendModel> stopWords = IkanalyzerExtendModel.dao.findByProperty("status", 0);
		String stopFilePath = fileDirPath+"stopword.dic";
		FileUtil.removeFile(stopFilePath);//先删除文件,此处重新生成
		for (int i = 0; i < stopWords.size(); i++) {
			String txt = stopWords.get(i).getStr("extend_word");
			FileUtil.appendToFile(stopFilePath, txt,true);
			IKAnalyzerTool.stopWords.add(txt);
		}
		init_words = true;
	}

	/**
	 * @Description 分词操作
	 * @author gongstring<1@gongstring.com>
	 * @createTime 2016年11月28日 下午3:30:10
	 * @param str
	 * @param justExist 是否只显示已经在词库中维护了的关键词
	 * @return
	 */
	public static List<String> IKAnalysis(String str,boolean justExist) {
		List<String> tmp = IKAnalysis(str);
		List<String> result = new ArrayList<String>();
		if(justExist){
			for (int i = 0; i < tmp.size(); i++) {
				if(IKAnalyzerTool.extendWords.contains(tmp.get(i))){
					result.add(tmp.get(i));
				}
			}
		}else{
			result = tmp;
		}
		return result;
	}
	
	/**
	 * @Description 根据字符串自动拆分成关键字集合
	 * @author gongstring<1@gongstring.com>
	 * @createTime 2016年11月28日 下午2:55:24
	 * @param str
	 * @return
	 */
	public static List<String> IKAnalysis(String str) {
		if(!init_words){
			initWords();
		}
		
		List<String> result = new ArrayList<String>();
		try {
			// InputStream in = new FileInputStream(str);//
			byte[] bt = str.getBytes();// str
			InputStream ip = new ByteArrayInputStream(bt);
			Reader read = new InputStreamReader(ip);
			IKSegmenter iks = new IKSegmenter(read, true);
			Lexeme t;
			while ((t = iks.next()) != null) {
				result.add(t.getLexemeText());
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;

	}
	
}

 

2、修改源码,实现动态更新字典表。通过查看源码IKAnalyzer.dic.Dictionary.java文件得出,字典对象是采取单例模式,也就是第一次加载后,后续不在重新加载,这样即使字典表内容变化,缓存中的字典库是不会变更的,所以需要修改源码,可以手动更新静态对象的内容,此处我采取添加clear方法,在需要更新时候调用,将instance对象设置为null,下次调用字典的时候,程序就会自动加载了

/**
	 * @Description 清空字典缓存,用于动态更新字典表
	 * @author gongstring<1@gongstring.com>
	 * @createTime 2016年11月29日 上午9:56:15
	 */
	public static void clear(){
		singleton = null;
	}

 

blob.png

 

源码修改完后,可以选择编译重新打包,或者将jar包中的class文件删除,java类在工程中按照源目录存放。

3、手动调用,我这里是做的一个页面,点击更新字典库时,调用更新代码:

/**
	 * @Description 刷新关键词缓存
	 * @author gongstring<1@gongstring.com>
	 * @createTime 2016年11月29日 上午9:33:49
	 */
	public void refreshCache(){
		IKAnalyzerTool.initWords();//重新加载词汇
		Dictionary.clear();//将字典表缓存清空
		this.renderSuccessJson(EnvConfig.APP_PATH+"/sm/ikanalyzerExtend");
	}

 

4、可能存在的性能问题:由于词库一般会比较大,所以每次大批量更新可能会出现性能损耗。。。

注:本文转载自gongstring.com,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除。

© 著作权归作者所有

共有 人打赏支持
傲娇字符
粉丝 5
博文 37
码字总数 14089
作品 0
武汉
架构师
在Solr4.9中使用IKAnalyzer,实现同义词,扩展词库,停顿词的添加

在使用solr4.9的过程中,使用了IKAnalyzer分词器,其中遇到了不少问题,现在做个记录,以备后续只用。 首先使用IKAnalyzer是看到群里有人介绍,但是貌似现在IKAnalyzer已经没人更新了。。。不...

翊骷
2014/09/11
0
1
ElasticSearch的ik分词插件开发

ik插件,说白了,就是通过封装ik分词器,与ElasticSearch对接,让ElasticSearch能够驱动该分词器。那么,具体怎么与ElasticSearch对接呢?从下往上走,总共3步: 一、封装IK分析器 与Elastic...

萧十一郎君
2014/05/26
0
1
solr配置停止词,同义词和扩展词库

停止词:lucene的停止词是无功能意义的词,比如is 、a 、are 、”的”,“得”,“我” 等,这些词会在句子中多次出现却无意义,所以在分词的时候需要把这些词过滤掉。 扩展词库:就是不想让...

zachary124
2013/07/05
0
2
Lucene使用IKAnalyzer中文分词笔记

本文主要讲解IKAnalyzer(以下简称‘IK’)在Lucene中的具体使用,关于Lucene和IK分词器的背景及其作用在这里就不再熬述。不得不感叹下Lucene版本变更的快速,如今最新已经到了4.9.0,相信任...

Jialy
2014/09/02
0
0
Lucene的中文分词器IKAnalyzer

分词器对英文的支持是非常好的。 一般分词经过的流程: 1)切分关键词 2)去除停用词 3)把英文单词转为小写 但是老外写的分词器对中文分词一般都是单字分词,分词的效果不好。 国人林良益写...

王国龙_成长
2013/02/05
0
3
Apache Lucene 几种分词系统

1、 StopAnalyzer StopAnalyzer能过滤词汇中的特定字符串和词汇,并且完成大写转小写的功能。 2、 StandardAnalyzer StandardAnalyzer根据空格和符号来完成分词,还可以完成数字、字母、E-m...

6pker
2015/02/26
0
0
IKAnalyzer中文分词器

IKAnalyzer3.0介绍 IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出了3个大版本。最初,它是以开源项目Luence为应用主体...

期待变强的菜鸟
2014/09/10
0
0
lucene4.0与IKAnalyzer2012_u6的冲突

在网上下载了lucene当前最新版本4.0,以及IKAnalyzer中文分词器的完整发布包。 一起运行之后发现异常: java.lang.VerifyError: class org.wltea.analyzer.lucene.IKAnalyzer overrides fina...

黄敦仁
2013/01/15
0
4
lucene4.0与IKAnalyzer的冲突

在网上下载了lucene当前最新版本4.0,以及IKAnalyzer中文分词器的完整发布包。 运行之后发现异常:Exception in thread "main" java.lang.VerifyError: class org.wltea.analyzer.lucene.IKA...

翊骷
2014/08/26
0
0
关于OSC项目演示平台maven的一点疑问

osc的项目演示平台,由于必须是maven项目,一些jar没有maven坐标,如IKAnalyzer2012FF_u1.jar,所以使用了scope为system,放在项目的lib目录,但是在演示平台启动后,涉及这些jar的类会编译错...

Realfighter
2015/04/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

【面试题】盲人坐飞机

有100位乘客乘坐飞机,其中有一位是盲人,每位乘客都按自己的座位号就坐。由于盲人看不见自己的座位号,所以他可能会坐错位置,而自己的座位被占的乘客会随便找个座位就坐。问所有乘客都坐对...

garkey
8分钟前
0
0
谈谈神秘的ES6——(二)ES6的变量

谈谈神秘的ES6——(二)ES6的变量 我们在《零基础入门JavaScript》的时候就说过,在ES5里,变量是有弊端的,我们先来回顾一下。 首先,在ES5中,我们所有的变量都是通过关键字var来定义的。...

JandenMa
今天
1
0
arts-week1

Algorithm 594. Longest Harmonious Subsequence - LeetCode 274. H-Index - LeetCode 219. Contains Duplicate II - LeetCode 217. Contains Duplicate - LeetCode 438. Find All Anagrams ......

yysue
今天
0
0
NNS拍卖合约

前言 关于NNS的介绍,这里就不多做描述,相关的信息可以查看NNS的白皮书http://doc.neons.name/zh_CN/latest/nns_background.html。 首先nns中使用的竞价货币是sgas,关于sgas介绍可以戳htt...

红烧飞鱼
今天
1
0
Java IO类库之管道流PipeInputStream与PipeOutputStream

一、java管道流介绍 在java多线程通信中管道通信是一种重要的通信方式,在java中我们通过配套使用管道输出流PipedOutputStream和管道输入流PipedInputStream完成线程间通信。多线程管道通信的...

老韭菜
今天
0
0
用Python绘制红楼梦词云图,竟然发现了这个!

Python在数据分析中越来越受欢迎,已经达到了统计学家对R的喜爱程度,Python的拥护者们当然不会落后于R,开发了一个个好玩的数据分析工具,下面我们来看看如何使用Python,来读红楼梦,绘制小...

猫咪编程
今天
1
0
Java中 发出请求获取别人的数据(阿里云 查询IP归属地)

1.效果 调用阿里云的接口 去定位IP地址 2. 代码 /** * 1. Java中远程调用方法 * http://localhost:8080/mavenssm20180519/invokingUrl.action * @Title: invokingUrl * @Description: * @ret......

Lucky_Me
今天
1
0
protobuf学习笔记

相关文档 Protocol buffers(protobuf)入门简介及性能分析 Protobuf学习 - 入门

OSC_fly
昨天
0
0
Mybaties入门介绍

Mybaties和Hibernate是我们在Java开发中应用的比较多的两个ORM框架。当然,目前Mybaties正在慢慢取代Hibernate,这是因为相比较Hibernate而言Mybaties性能更好,响应更快,更加灵活。我们在开...

王子城
昨天
2
0
编程学习笔记之python深入之装饰器案例及说明文档[图]

编程学习笔记之python深入之装饰器案例及说明文档[图] 装饰器即在不对一个函数体进行任何修改,以及不改变整体的原本意思的情况下,增加函数功能的新函数,因为这个新函数对旧函数进行了装饰...

原创小博客
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部