ICTCLAS用的字Lucene4.9捆绑

ICTCLAS用的字Lucene4.9捆绑

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

它一直喜欢的搜索方向,虽然无法做到。但仍保持了狂热的份额。记得那个夏天、这间实验室、这一群人,一切都随风而逝。踏上新征程。我以前没有自己。面对七三分技术的商业环境,我选择了沉淀。社会是一个大机器,我们只是一个小螺丝钉。我们不能容忍半点扭扭捏捏。

于一个时代的产物。也终将被时代所抛弃。言归正题,在lucene增加自己定义的分词器,须要继承Analyzer类。实现createComponents方法。同一时候定义Tokenzier类用于记录所需建立索引的词以及其在文章的位置,这里继承SegmentingTokenizerBase类,须要实现setNextSentence与incrementWord两个方法。当中。setNextSentence设置下一个句子,在多域(Filed)分词索引时,setNextSentence就是设置下一个域的内容,能够通过new String(buffer, sentenceStart, sentenceEnd – sentenceStart)获取。而incrementWord方法则是记录每一个单词以及它的位置。须要注意一点就是要在前面加clearAttributes(),否则可能出现first position increment must be > 0…错误。以ICTCLAS分词器为例,以下贴上个人代码,希望能给大家带来帮助,不足之处,多多拍砖。

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.core.LowerCaseFilter;
import org.apache.lucene.analysis.en.PorterStemFilter;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.util.Version;

/**
 * 中科院分词器 继承Analyzer类。实现其 tokenStream方法
 * 
 * @author ckm
 * 
 */
public class ICTCLASAnalyzer extends Analyzer {

	/**
	 * 该方法主要是将文档转变成lucene建立索 引所需的TokenStream对象
	 * 
	 * @param fieldName
	 *            文件名称
	 * @param reader
	 *            文件的输入流
	 */
	@Override
	protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
		try {
			System.out.println(fieldName);
		    final Tokenizer tokenizer = new ICTCLASTokenzier(reader);
		    TokenStream stream = new PorterStemFilter(tokenizer);
		    stream = new LowerCaseFilter(Version.LUCENE_4_9, stream);
		    stream = new PorterStemFilter(stream);
			return new TokenStreamComponents(tokenizer,stream);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
		
	}
	
	
	public static void main(String[] args) throws Exception {  
        Analyzer analyzer = new ICTCLASAnalyzer();  
        String str = "黑客技术";  
        TokenStream ts = analyzer.tokenStream("field", new StringReader(str));  
        CharTermAttribute c = ts.addAttribute(CharTermAttribute.class);  
        ts.reset();  
        while (ts.incrementToken()) {  
            System.out.println(c.toString());  
        }  
  
        ts.end();  
        ts.close();  
    }  

	
}

import java.io.IOException;
import java.io.Reader;
import java.text.BreakIterator;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.util.SegmentingTokenizerBase;
import org.apache.lucene.util.AttributeFactory;


/**
 * 
 * 继承lucene的SegmentingTokenizerBase,重载其setNextSentence与
 * incrementWord方 法,记录所需建立索引的词以及其在文章的位置
 * 
 * @author ckm
 * 
 */
public class ICTCLASTokenzier extends SegmentingTokenizerBase {
	
	private static final BreakIterator sentenceProto = BreakIterator.getSentenceInstance(Locale.ROOT);
	
	private final CharTermAttribute termAttr= addAttribute(CharTermAttribute.class);// 记录所需建立索引的词
	
	private final OffsetAttribute offAttr = addAttribute(OffsetAttribute.class);// 记录所需建立索引的词在文章中的位置
	
	private ICTCLASDelegate ictclas;// 分词系统的托付对象
	
	private Iterator<String> words;// 文章分词后形成的单词
	
	private int offSet= 0;// 记录最后一个词元的结束位置
	
	
	/**
	 * 构造函数
	 * 
	 * @param segmented    分词后的结果
	 * @throws IOException 
	 */
	protected ICTCLASTokenzier(Reader reader) throws IOException {
		this(DEFAULT_TOKEN_ATTRIBUTE_FACTORY, reader);
	}
	
	protected ICTCLASTokenzier(AttributeFactory factory, Reader reader) throws IOException {
		super(factory, reader,sentenceProto);
		ictclas = ICTCLASDelegate.getDelegate();
	  
	}

	@Override
	protected void setNextSentence(int sentenceStart, int sentenceEnd) {
		// TODO Auto-generated method stub
		String sentence = new String(buffer, sentenceStart, sentenceEnd - sentenceStart);
		String result=ictclas.process(sentence);
		String[] array = result.split("\\s");
		if(array!=null){
			List<String> list = Arrays.asList(array);
			words=list.iterator();
		}
		offSet= 0;
	}

	@Override
	protected boolean incrementWord() {
		// TODO Auto-generated method stub
		if (words == null || !words.hasNext()) {
		    return false;
		} else {
			String t = words.next();
			while(t.equals("")||StopWordFilter.filter(t)){ //这里主要是为了过滤空白字符以及停用词
				                                          //StopWordFilter为自己定义停用词过滤类  
				if (t.length() == 0)
					offSet++;
				else
					offSet+= t.length();
				t =words.next();
			}
			if (!t.equals("") && !StopWordFilter.filter(t)) {
				clearAttributes();
				termAttr.copyBuffer(t.toCharArray(), 0, t.length());
				offAttr.setOffset(correctOffset(offSet), correctOffset(offSet=offSet+ t.length()));
				return true;
			} 
			return false;
		}
	}
	
	/**
	 * 重置
	 */
	public void reset() throws IOException {
		super.reset();
		offSet= 0;
	}

	public static void main(String[] args) throws IOException {
		String content = "宝剑锋从磨砺出,梅花香自苦寒来!

"; String seg = ICTCLASDelegate.getDelegate().process(content); //ICTCLASTokenzier test = new ICTCLASTokenzier(seg); //while (test.incrementToken()); } }

import java.io.File;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import ICTCLAS.I3S.AC.ICTCLAS50;

/**
 * 中科院分词系统代理类
 * 
 * @author ckm
 * 
 */
public class ICTCLASDelegate {

	private static final String userDict = "userDict.txt";// 用户词典
	
	private final static Charset charset = Charset.forName("gb2312");// 默认的编码格式
	
	private static String ictclasPath =System.getProperty("user.dir");
	
	private static String dirConfigurate = "ICTCLASConf";// 配置文件所在文件夹名
	
	private static String configurate = ictclasPath + File.separator+ dirConfigurate;// 配置文件所在文件夹的绝对路径
	
	private static int wordLabel = 2;// 词性标注类型(北大二级标注集)
	
	private static ICTCLAS50 ictclas;// 中科院分词系统的jni接口对象
	
	private static ICTCLASDelegate instance = null;
	
	private ICTCLASDelegate(){ }
	

	/**
	 * 初始化ICTCLAS50对象
	 * 
	 * @return ICTCLAS50对象初始化化是否成功
	 */
	public boolean init() {
		ictclas = new ICTCLAS50();
		boolean bool = ictclas.ICTCLAS_Init(configurate
				.getBytes(charset));
		if (bool == false) {
			System.out.println("Init Fail!");
			return false;
		}
		// 设置词性标注集(0 计算所二级标注集。1 计算所一级标注集,2 北大二级标注集,3 北大一级标注集)
		ictclas.ICTCLAS_SetPOSmap(wordLabel);
		importUserDictFile(configurate + File.separator + userDict);// 导入用户词典
		ictclas.ICTCLAS_SaveTheUsrDic();// 保存用户字典
		return true;
	}

	/**
	 * 将编码格式转换为分词系统识别的类型
	 * 
	 * @param charset
	 *            编码格式
	 * @return 编码格式相应的数字
	 **/
	public static int getECode(Charset charset) {
		String name = charset.name();
		if (name.equalsIgnoreCase("ascii"))
			return 1;
		if (name.equalsIgnoreCase("gb2312"))
			return 2;
		if (name.equalsIgnoreCase("gbk"))
			return 2;
		if (name.equalsIgnoreCase("utf8"))
			return 3;
		if (name.equalsIgnoreCase("utf-8"))
			return 3;
		if (name.equalsIgnoreCase("big5"))
			return 4;
		return 0;
	}

	/**
	 * 该方法的作用是导入用户字典
	 * 
	 * @param path
	 *            用户词典的绝对路径
	 * @return 返回导入的词典的单词个数
	 */
	public int importUserDictFile(String path) {
		System.out.println("导入用户词典");
		return ictclas.ICTCLAS_ImportUserDictFile(
				path.getBytes(charset), getECode(charset));
	}

	/**
	 * 该方法的作用是对字符串进行分词
	 * 
	 * @param source
	 *            所要分词的源数据
	 * @return 分词后的结果
	 */
	public String process(String source) {
		return process(source.getBytes(charset));
	}
	
	public String process(char[] chars){
	   CharBuffer cb = CharBuffer.allocate (chars.length);
	   cb.put (chars);
	   cb.flip ();
	   ByteBuffer bb = charset.encode (cb);
	   return process(bb.array());
	   
	}
	
	public String process(byte[] bytes){
		if(bytes==null||bytes.length<1)
			return null;
		byte nativeBytes[] = ictclas.ICTCLAS_ParagraphProcess(bytes, 2, 0);
		String nativeStr = new String(nativeBytes, 0,
				nativeBytes.length-1, charset);
		return nativeStr;
	}

	/**
	 * 获取分词系统代理对象
	 * 
	 * @return 分词系统代理对象
	 */
	public static ICTCLASDelegate getDelegate() {
		if (instance == null) {
			synchronized (ICTCLASDelegate.class) {
				instance = new ICTCLASDelegate();
				instance.init();
			}
		}
		return instance;
	}

	/**
	 * 退出分词系统
	 * 
	 * @return 返回操作是否成功
	 */
	public boolean exit() {
		return ictclas.ICTCLAS_Exit();
	}

	public static void main(String[] args) {
		String str="结婚的和尚未结婚的";
		ICTCLASDelegate id = ICTCLASDelegate.getDelegate();
		String result = id.process(str.toCharArray());
		System.out.println(result.replaceAll(" ", "-"));
	}

}

import java.util.Iterator;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 停用词过滤器
 * 
 * @author ckm
 * 
 */
public class StopWordFilter {

	private static Set<String> chineseStopWords = null;// 中文停用词集
	private static Set<String> englishStopWords = null;// 英文停用词集
	static {
		init();
	}

	/**
	 * 初始化中英文停用词集
	 */
	public static void init() {
		LoadStopWords lsw = new LoadStopWords();
		chineseStopWords = lsw.getChineseStopWords();
		englishStopWords = lsw.getEnglishStopWords();
	}

	/**
	 * 推断keyword的类型以及推断其是否为停用词 注意:临时仅仅考虑中文,英文。中英混合, 中数混合,英数混合这五种类型。当中中英 混合,
	 * 中数混合,英数混合还没特定的停用 词库或语法规则对其进行判别
	 * 
	 * @param word
	 *            keyword
	 * @return true表示是停用词
	 */
	public static boolean filter(String word) {
		Pattern chinese = Pattern.compile("^[\u4e00-\u9fa5]+$");// 中文匹配
		Matcher m1 = chinese.matcher(word);
		if (m1.find())
			return chineseFilter(word);
		Pattern english = Pattern.compile("^[A-Za-z]+$");// 英文匹配
		Matcher m2 = english.matcher(word);
		if (m2.find())
			return englishFilter(word);
		Pattern chineseDigit = Pattern.compile("^[\u4e00-\u9fa50-9]+$");// 中数匹配
		Matcher m3 = chineseDigit.matcher(word);
		if (m3.find())
			return chineseDigitFilter(word);
		Pattern englishDigit = Pattern.compile("^[A-Za-z0-9]+$");// 英数匹配
		Matcher m4 = englishDigit.matcher(word);
		if (m4.find())
			return englishDigitFilter(word);
		Pattern englishChinese = Pattern.compile("^[A-Za-z\u4e00-\u9fa5]+$");// 中英匹配,这个必须在中文匹配与英文匹配之后
		Matcher m5 = englishChinese.matcher(word);
		if (m5.find())
			return englishChineseFilter(word);
		return true;
	}

	/**
	 * 推断keyword是否为中文停用词
	 * 
	 * @param word
	 *            keyword
	 * @return true表示是停用词
	 */
	public static boolean chineseFilter(String word) {
		// System.out.println("中文停用词推断");
		if (chineseStopWords == null || chineseStopWords.size() == 0)
			return false;
		Iterator<String> iterator = chineseStopWords.iterator();
		while (iterator.hasNext()) {
			if (iterator.next().equals(word))
				return true;
		}
		return false;
	}

	/**
	 * 推断keyword是否为英文停用词
	 * 
	 * @param word
	 *            keyword
	 * @return true表示是停用词
	 */
	public static boolean englishFilter(String word) {
		// System.out.println("英文停用词推断");
		if (word.length() <= 2)
			return true;
		if (englishStopWords == null || englishStopWords.size() == 0)
			return false;
		Iterator<String> iterator = englishStopWords.iterator();
		while (iterator.hasNext()) {
			if (iterator.next().equals(word))
				return true;
		}
		return false;
	}

	/**
	 * 推断keyword是否为英数停用词
	 * 
	 * @param word
	 *            keyword
	 * @return true表示是停用词
	 */
	public static boolean englishDigitFilter(String word) {
		return false;

	}

	/**
	 * 推断keyword是否为中数停用词
	 * 
	 * @param word
	 *            keyword
	 * @return true表示是停用词
	 */
	public static boolean chineseDigitFilter(String word) {
		return false;

	}

	/**
	 * 推断keyword是否为英中停用词
	 * 
	 * @param word
	 *            keyword
	 * @return true表示是停用词
	 */
	public static boolean englishChineseFilter(String word) {
		return false;

	}

	public static void main(String[] args) {
		/*
		 * Iterator<String> iterator=
		 * StopWordFilter.chineseStopWords.iterator(); int n=0;
		 * while(iterator.hasNext()){ System.out.println(iterator.next()); n++;
		 * } System.out.println("总单词量:"+n);
		 */
		boolean bool = StopWordFilter.filter("宝剑");
		System.out.println(bool);
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * 载入停用词文件
 * 
 * @author ckm
 * 
 */

public class LoadStopWords {

	private Set<String> chineseStopWords = null;// 中文停用词集

	private Set<String> englishStopWords = null;// 英文停用词集

	/**
	 * 获取中文停用词集
	 * 
	 * @return 中文停用词集Set<String>类型
	 */
	public Set<String> getChineseStopWords() {
		return chineseStopWords;
	}

	/**
	 * 设置中文停用词集
	 * 
	 * @param chineseStopWords
	 *            中文停用词集Set<String>类型
	 */
	public void setChineseStopWords(Set<String> chineseStopWords) {
		this.chineseStopWords = chineseStopWords;
	}

	/**
	 * 获取英文停用词集
	 * 
	 * @return 英文停用词集Set<String>类型
	 */
	public Set<String> getEnglishStopWords() {
		return englishStopWords;
	}

	/**
	 * 设置英文停用词集
	 * 
	 * @param englishStopWords
	 *            英文停用词集Set<String>类型
	 */
	public void setEnglishStopWords(Set<String> englishStopWords) {
		this.englishStopWords = englishStopWords;
	}

	/**
	 * 载入停用词库
	 */
	public LoadStopWords() {
		chineseStopWords = loadStopWords(this.getClass().getResourceAsStream(
				"ChineseStopWords.txt"));
		englishStopWords = loadStopWords(this.getClass().getResourceAsStream(
				"EnglishStopWords.txt"));
	}

	/**
	 * 从停用词文件里载入停用词, 停用词文件是普通GBK编码的文本文件, 每一行 是一个停用词。凝视利用“//”, 停用词中包含中文标点符号,
	 * 中文空格, 以及使用率太高而对索引意义不大的词。
	 * 
	 * @param input
	 *            停用词文件流
	 * @return 停用词组成的HashSet
	 */
	public static Set<String> loadStopWords(InputStream input) {
		String line;
		Set<String> stopWords = new HashSet<String>();
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(input,
					"GBK"));
			while ((line = br.readLine()) != null) {
				if (line.indexOf("//") != -1) {
					line = line.substring(0, line.indexOf("//"));
				}
				line = line.trim();
				if (line.length() != 0)
					stopWords.add(line.toLowerCase());
			}
			br.close();
		} catch (IOException e) {
			System.err.println("不能打开停用词库!。");
		}
		return stopWords;
	}

	public static void main(String[] args) {
		LoadStopWords lsw = new LoadStopWords();
		Iterator<String> iterator = lsw.getEnglishStopWords().iterator();
		int n = 0;
		while (iterator.hasNext()) {
			System.out.println(iterator.next());
			n++;
		}
		System.out.println("总单词量:" + n);
	}

}

这里须要ChineseStopWords.txt 与EnglishStopWords.txt中国和英国都存储停用词,在这里,我们不知道如何上传,有ICTCLAS基本的文件。

下载完整的项目:http://download.csdn.net/detail/km1218/7754907


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/117733.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Mysql函数FIND_IN_SET()的使用方法

    Mysql函数FIND_IN_SET()的使用方法

    2021年10月24日
  • Java后台登录注册管理系统

    Java后台登录注册管理系统转载请注明出处:https://blog.csdn.net/binbinqq86/article/details/81746294项目简介环境搭建ide的选择数据库相关tomcat相关开始JDBC封装DAO封装Junit编写jsp编写servlet编写运行结果写在最后项目简介本文是笔者自己学习后台开发打响的第一枪,也是后台开发最基础的了,记得刚毕业的时候做过一个web项目,一直到今天都没有再了解过这方面,如今重新拾起,感觉还是需要多了解一些后端的东西,如果一直停留在移动端和前

  • mysql+mongodb_统计和汇总的区别

    mysql+mongodb_统计和汇总的区别MySQL和MongoDB的区别的学习与汇总

    2022年10月24日
  • 一次简单的反射型XSS操作及思路

    一次简单的反射型XSS操作及思路xss是类似对html代码的注入,拼接恶意代码获取cookie等分为三种类型,分别是反射型、存储型和dom型反射型是不存入数据库,对自己有影响存储型是存入数据库,对来访者都有影响1.进入靶场看到输入框,进行插入js标签输入框里输入:<script>alert(1)</script>点击搜索语句没有执行,而是被当做文本搜索了,这显然不是我们想看到的,点…

  • 图文详解PID调参

    图文详解PID调参不会PID调参?这篇文章图文结合带你学会PID调参!让你成为PID调参大神!!!

  • Java文件操作(超详细+代码示例)「建议收藏」

    Java文件操作(超详细+代码示例)「建议收藏」Java文件操作一、Java.io包1.1File类1.2Stream流1.2.1使用FileInputStream类1.2.2使用FileOutputStream类二、序列化我们日常使用电脑的时候,基本都会和文件打交道,比如我们做ppt,或者写论文的时候,我们打开的word,ppt等等都是一个文件,这些文件不一样的主要是因为后缀名不一样,所以计算机才可以分辨出来这些文件的区别。文件一…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号