中科院分词工具imdict-chinese-analyzer学习-java分词

关浩壤
2023-12-01

下载链接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); 
  }
就行了

 类似资料: