IKAnalyzer3.2.8中文分词器介绍
201232
1.
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的结合
可以说IKsolr的结合非常简单,只要把 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.4BaseTokenizerFactory类,而org.wltea.analyzer.lucene.IKAnalyzer继承了luceneAnalyzer类。
8. solr1.4中使用IKQueryParser
由于 Solr 默认的 Query Parser 生成的 Query 一般是短语查询,导致只有很精确的结果才被搜索出来。比如默认情况下,库里有北京爱皮科技有限公司,用户搜索词为爱皮公司solr是不会把结果显示出来的。所以,必须分别扩展QParserPluginQParser,代码如下:
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小时内删除。