IKAnalyzer3.2.8中文分词器介绍
2012年3月2日
1.
IKAnalyzer简介
IKAnalyzer简介
IKAnalyzer是一个开源基于JAVA语言的轻量级的中文分词第三方工具包,从2006年推出已经经历了三个较为完整的版本,目前最新版本为3.2.8,它基于lucene为应用主体,但是,它也支持脱离lucene,成为一个独立的面向JAVA的分词工具。
2. IKAnalyzer结构图
3. IKAnalyzer特性
a. 算法采用“正向迭代最细粒度切分算法”,支持细粒度和最大词长两种分词方式,速度最大支持80W字/秒(1600KB/秒)。
b. 支持多子处理器分析模式:中文、数字、字母,并兼容日文、韩文。
c. 较小的内存占用,优化词库占有空间,用户可自定义扩展词库。
d. 扩展lucene的扩展实现,采用歧义分析算法优化查询关键字的搜索排列组合,提高lucene检索命中率。
4. 关键类介绍
org.wltea.analyzer.lucene.IKAnalyzer
IK分词主类,基于Lucene的Analyzer接口实现。
org.wltea.analyzer.lucene.IKQueryParser
IK分词器提供的Query解析、构造工具类,其中parseMultiField
函数(所有的重载函数)为关键函数。
org.wltea.analyzer.IKSegmentation
IK分词器的核心类,真正分词的实现类。
5. IK分词算法理解
根据作者官方说法IK分词器采用“正向迭代最细粒度切分算法”,分析它的源代码,可以看到分词工具类IKQueryParser起至关重要的作用,它对搜索关键词采用从最大词到最小词层层迭代检索方式切分,比如搜索词:“中华人民共和国成立了”,首先到词库中检索该搜索词中最大分割词,即分割为:“中华人民共和国”和“成立了”,然后对“中华人民共和国”切分为“中华人民”和“人民共和国”,以此类推。最后,“中华人民共和国成立了”切分为:“中华人民 | 中华 | 华人 | 人民 | 人民共和国 | 共和国 | 共和 | 成立 | 立了”,当然,该切分方式为默认的细粒度切分,若按最大词长切分,结果为:“中华人民共和国 | 成立 | 立了”。核心算法代码如下:
boolean accept(Lexeme _lexeme){
/*
* 检查新的lexeme 对当前的branch 的可接受类型
* acceptType : REFUSED 不能接受
* acceptType : ACCEPTED 接受
* acceptType : TONEXT 由相邻分支接受
*/
int acceptType = checkAccept(_lexeme);
switch(acceptType){
case REFUSED:
// REFUSE 情况
return false;
case ACCEPTED :
if(acceptedBranchs == null){
//当前branch没有子branch,则添加到当前branch下
acceptedBranchs = new ArrayList<TokenBranch>(2);
acceptedBranchs.add(new TokenBranch(_lexeme));
}else{
boolean acceptedByChild = false;
//当前branch拥有子branch,则优先由子branch接纳
for(TokenBranch childBranch : acceptedBranchs){
acceptedByChild = childBranch.accept(_lexeme) || acceptedByChild;
}
//如果所有的子branch不能接纳,则由当前branch接纳
if(!acceptedByChild){
acceptedBranchs.add(new TokenBranch(_lexeme));
}
}
//设置branch的最大右边界
if(_EndPosition() > this.rightBorder){
this.rightBorder = _EndPosition();
}
break;
case TONEXT :
//把lexeme放入当前branch的相邻分支
if(this.nextBranch == null){
//如果还没有相邻分支,则建立一个不交叠的分支
this.nextBranch = new TokenBranch(null);
}
this.nextBranch.accept(_lexeme);
break;
}
return true;
}
从代码中可以了解到,作者采用了递归算法(代码中加粗的部分)切分搜索词。若词存在子词则递归该函数,继续切分。
6. 词库的扩展
IK本身带有27W的词库,对于词库的扩展目前支持两种方式,分别是配置文件和API扩展,同时提供了对用户自定义停止词的扩展支持。针对数据库存储字库,采用这种方式比较好。
基于API词库扩展:
类名:org.wltea.analyzer.dic.Dictionary
函数:public static void loadExtendWords(List<String> extWords)
加载用户扩展的词汇列表到IK的主词典中。
函数:public static void loadExtendStopWords(List<String> extStopWords)
加载用户扩展的停止词列表。
基于配置的词库扩展:
l文件可以扩展专有词库及停止词库。配置如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "java.sun/dtd/properties.dtd"> <properties> <comment>IK Analyzer 扩展配置</comment> <!--用户可以在这里配置自己的扩展字典 --> <entry key="ext_dict">/mydict.dic; /com/mycompany/dic/mydict2.dic;</entry> <!--用户可以在这里配置自己的扩展停止词字典--> <entry key="ext_stopwords">/ext_stopword.dic</entry> </properties> |
7. 与solr的结合
可以说IK与solr的结合非常简单,只要把 solr中的l添加如下代码即可:
<schema name="example" version="1.1"> …… <fieldType name="text" class="solr.TextField"> <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/> </fieldType> …… </schema> |
或者是: |
<fieldType name="text" class="solr.TextField" > <analyzer type="index"> <tokenizer class="org.wltea.analyzer.solr.IKTokenizerFactory" isMaxWordLength="false"/> …… </analyzer> <analyzer type="query"> <tokenizer class="org.wltea.analyzer.solr.IKTokenizerFactory" isMaxWordLength="true"/> …… |
</analyzer> </fieldType> |
其中org.wltea.analyzer.solr.IKTokenizerFactory 继承了solr1.4的BaseTokenizerFactory类,而org.wltea.analyzer.lucene.IKAnalyzer继承了lucene的Analyzer类。
8. 在solr1.4中使用IKQueryParser
由于 Solr 默认的 Query Parser 生成的 Query 一般是 “短语查询”,导致只有很精确的结果才被搜索出来。比如默认情况下,库里有”北京爱皮科技有限公司”,用户搜索词为”爱皮公司”,solr是不会把结果显示出来的。所以,必须分别扩展:QParserPlugin、QParser,代码如下:
IKQParserPlugin:
import org.apache.solrmon.params.SolrParams;
import org.apache.solrmon.util.NamedList;
import org.quest.SolrQueryRequest;
import org.apache.solr.search.QParser;
import org.apache.solr.search.QParserPlugin;
public class IKQParserPlugin extends QParserPlugin {
public void init(NamedList args) {
}
publicaccepted什么意思中文 QParser createParser(String qstr, SolrParams localParams,
SolrParams params, SolrQueryRequest req) {
return new IKQParser(qstr, localParams, params, req);
}
}
IKQParser:
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.Query;
import org.apache.solrmon.params.CommonParams;
import org.apache.solrmon.params.SolrParams;
import org.quest.SolrQueryRequest;
import org.apache.solr.search.QParser;
import org.wltea.analyzer.lucene.IKQueryParser;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论