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

于一个时代的产物。也终将被时代所抛弃。言归正题,在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



ICTCLAS用的字Lucene4.9捆绑的更多相关文章

  1. LINUX - 获取本地ip

    Linux编程获取本机IP地址的几种方法 参考: https://blog.csdn.net/zhongmushu/article/details/89944990 https://www.cnblo ...

  2. ICTCLAS 汉语词性标注集

    以前使用jieba分词时,并没有注意到词性标注集到底包含哪些,刚好最近学习自然语言处理,涉及到分词以及词性标注,将ICTCLAS 词性标注集记录如下: ICTCLAS 汉语词性标注集 代码 名称 帮助 ...

  3. 【课程分享】基于Lucene4.6+Solr4.6+Heritrix1.14+S2SH实战开发从无到有垂直搜索引擎

    对这个课程有兴趣的朋友,能够加我的QQ2059055336和我联系,能够和您分享.  课程介绍:最有前途的软件开发技术--搜索引擎技术  搜索引擎作为互联网发展中至关重要的一种应用,已经成为互联网各个 ...

  4. 【UNIX网络编程(二)】基本TCP套接字编程函数

    基于TCP客户/server程序的套接字函数图例如以下: 运行网络I/O.一个进程必须做的第一件事就是调用socket函数.指定期望的通信协议类型. #include <sys/socket.h ...

  5. 《UNIX网络编程 卷1:套接字联网API》读书笔记(一):网络编程简介

    概述 要编写通过计算机网络通信的程序,首先要确定这些程序相互通信所用的协议.大多数网络是按照划分成客户和服务器来组织的.本章及后续章节的焦点是TCP/IP协议族,也可称为网际协议族.下图为客户与服务器 ...

  6. UNIX网络编程——通用套接字选项

    1. SO_BROADCAST 套接字选项 本选项开启或禁止进程发送广播消息的能力.只有数据报套接字支持广播,并且还必须是在支持广播消息的网络上(例如以太网,令牌环网等).我们不可能在点对点链路上进行 ...

  7. UNIX网络编程——套接字选项(SO_REUSEADDR)

    1.一般来说,一个端口释放后会等待两分钟之后才能再被使用,SO_REUSEADDR是让端口释放后立即就可以被再次使用. SO_REUSEADDR用于对TCP套接字处于TIME_WAIT状态下的sock ...

  8. UNIX网络编程——基本TCP套接字编程

    一.基于TCP协议的网络程序 下图是基于TCP协议的客户端/服务器程序的一般流程: 服务器调用socket().bind().listen()完成初始化后,调用accept()阻塞等待,处于监听端口的 ...

  9. 套接字编程相关函数(2:TCP套接字编程相关函数)

    本文摘录自<UNIX网络编程 卷1>. 基本套接字函数 socket函数 为了执行网络I/O,一个进程必须做的第一件事就是调用socket函数,指定期望的通信协议类型.其定义如下: #in ...

随机推荐

  1. hdu2647 逆拓扑,链式前向星。

    pid=2647">原文地址 题目分析 题意 老板发工资,可是要保证发的工资数满足每一个人的期望,比方A期望工资大于B,仅仅需比B多1元钱就可以.老板发的最低工资为888元.输出老板最 ...

  2. LeetCode——Populating Next Right Pointers in Each Node II

    Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...

  3. maven使用.02.一些概念

    在上一篇POST中,简要的介绍了一下maven的特点,优势,安装.并建立了一个简单地Hello world工程.这一篇POST中,将主要会介绍一下Maven的一些约定. pom.xml文件 Maven ...

  4. 利用Perf4j 对java项目进行性能监控

    Perf4j 可以对自定义监控范围的java代码进行日志记录,再经统计分析生成所需性能数据.Perf4j 提供了对常用日志工具log4j的扩展以方便与产品集成,它产生的性能数据可被用于生成可视化的性能 ...

  5. SQL Server Database 维护计划创建一个完整的备份策略

     SQL Server维护计划Maintenance Plan这是一个非常有用的维护工具,能够完成大部分的数据库维护任务,通过这些功能包.您可以省略大量的编码时间. 介绍的不是非常多,特此补上一篇 ...

  6. nginx.conf 文中描述的配置文件

    ###############################nginx.conf 件里文说明 #user nobody; # user 主模块指令,指令nginx worker 执行用户和用户组(u ...

  7. python实用小代码

    栈的实现 #!/usr/bin/env python #coding=utf-8 #python version 2.7.4 class stack: def __init__(self,list=N ...

  8. unity中的MonoBehaviour.OnMouseDown()

    在官网的api文档中仅说明了 Description OnMouseDown is called when the user has pressed the mouse button while ov ...

  9. 《软件project》课程报告 —国土资源执法监察管理信息系统建模

    ***********************************************声明*************************************************** ...

  10. A Game of Thrones(4) - Eddard

    The visitors poured(倾泻:流出) through the castle gates in a river of gold and silver and polished steel ...