下载链接http://ictclas.org/Down_OpenSrc.asp
简单介绍:
imdict-chinese-analyzer是 imdict智能词典的智能中文分词模块,作者高小平,算法基于隐马
尔科夫模型(Hidden Markov Model, HMM),是中国科学院计算技术研究所的ictclas中文分词程序
的重新实现(基于Java),可以直接为lucene搜索引擎提供中文分词支持。
应用:
下到的压缩包解压后就是一个java工程,eclipse直接导入即可,但由于其开发的环境是UTF8所以
要将eclipse的工作空间的编码也设置为utf8,test包里面的AnalyzerTest就是其用法,看了以后
就可以直接用了
功能:中文分词、停止词过滤
优点:开源,分词速度快,效率高
缺点:不支持自己添加词库,不支持词性标注(开发人员自己说是为了提高速度),data文件夹仅
自带了两个字典coredict核心字典、bigramdict词关系字典,这是两个最重要的词典,没有地名和
人名的词典,所以要识别人名地名比较麻烦,据说要用层次hmm,先粗分在细分。
深入学习:主类是net.imdict.analysis.chinese中的ChineseAnalyzer.java它继承了lucene的
Analyzer类,有两个构造方法:public ChineseAnalyzer()、public ChineseAnalyzer
(Set<String> stopWords)第二个构造方法支持停用词,最重要的是tokenStream函数,它用了
SentenceTokenizer和new WordTokenizer,前一个是将文章分成句子,后一个是将句子分成单词,
单词和句子都是用Lucene的Token(词)的类存储的,(Token是一个抽象类,TokenStream是Token
类的子类,但也是一个抽象类,Tokenizer和TokenFilter则是TokenStream的具体实现,他们实现
了TokenStream的next()方法,Tokenizer的next方法返回的是原始的、切分出来的词,而
TokenFilter方法返回的是一个经过过滤的词条,他们结合起来形成Lucene分析器的核心结构)如
Token token = new Token(),然后通过token.reinit(buffer.toString(), tokenStart,
tokenEnd, "sentence");中间两个参数是Token存储的字符串的起止位置,以0开始计数,引用
token中字符串的函数是token.term(),真正调用分词核心算法的WordSegmenter的
segmentSentence方法对句子进行分词,在WordTokenizer类中调用它得到分词结果。在往下层的代
码我就没看了。
两个改动:
(1)ChineseAnalyzer只能对文件进行分词,如何对一个字符串进行分词,改动如下
/* TokenStream ts = ca.tokenStream("sentence", new InputStreamReader(
new FileInputStream("test.txt"), "UTF-8"));*/
将注释部分改为
TokenStream ts = ca.tokenStream("sentence",new StringReader("姚明在火
箭队"));
就行了
(2)鉴于 imdict-chinese-analyzer对人名和流行词汇的处理不好,我将其核心算法改为用JE分
词软件来做,效果好一些,当然这样就等于抛弃了 imdict-chinese-analyzer的所有优势,另起炉
灶。缺点是JE分词不开源,也没有词性标注。
将WordTokenizer中的processNextSentence函数中的注释部分:
// tokenBuffer = wordSegmenter.segmentSentence(sentenceToken, 1);//原程序
改为
String str = analyzer.segment(sentenceToken.term(), " ");
String []strs = str.split(" ");
List<Token> result = new ArrayList<Token>();
for(int i=0;i<strs.length;i++)
{
Token token = new Token();
// System.out.println(strs.length);
token.reinit(strs[i],0,strs[i].length()-1,"word");
// System.out.println(token.term());
result.add(token);
}
就行了