IKAnalyzer 源码分析-概览
Posted 代码与美食
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IKAnalyzer 源码分析-概览相关的知识,希望对你有一定的参考价值。
一、背景
持续研究ES中,搭建中文搜索引擎时必然涉及到中文分词,使用合适的分词可提高召回率、准确率,解决搜索中各种相关性问题。ik分词作为ElasticSearch常用分词插件,项目中经常使用,所以对其进行深度研究,以便解决项目中碰到的各种搜索问题,比如:
1、功能:比如搜索“潼南”,含有“潼南县”的文档却检索不出来
2、性能:控制query和index分词个数、歧义问题,可减少磁盘占用、query分词后的分词个数,减少query dsl中query的数量,更高效的利用ES
二、
IKAnalyzer是什么IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开始,IK发展为面向Java的的公用分词组件,独立于Lucene的项目,同时提供了对Lucene的的默认优化实现。在2012版本中, IK实现了简单的分词歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化。IK即可作为ElasticSearch 分词插件使用,也可作为面向Java的公用分词组件。
IK Analyzer 2012特性:
1、采用了特有的“正向迭代最细粒度切分算法“,支持细粒度和智能分词两种切分模式;
2、在系统环境:Core2 i7 3.4G双核,4G内存,window 7 64位, Sun JDK 1.6_29 64位 普通pc环境测试,IK2012具有160万字/秒(3000KB/S)的高速处理能力。
3、2012版本的智能分词模式支持简单的分词排歧义处理和数量词合并输出。
4、采用了多子处理器分析模式,支持:英文字母、数字、中文词汇等分词处理,兼容韩文、日文字符
5、优化的词典存储,更小的内存占用。支持用户词典扩展定义。特别的,在2012版本,词典支持中文,英文,数字混合词语。
三、
代码目录结构1、总目录结构,如下图
1.1、elasticsearch es相关的代码
1.2、wltea.analyzer ik和lucene使用ik的代码,我们主要分析这块
2、ik相关代码,如下图
2.1、Configuration.java
读取配置相关代码,包括是否启用智能分词(默认是);是否忽略大小写(默认是,统一小写处理);是否启用远程字典(默认否);初始化词典
2.2、Dictionary.java
词典管理类,包括如何加载词典,动态变更词典树,词典匹配等方法;总共有6类词典,主词典(main.dic、ext_dict指定的扩展词词典、remote_ext_dict指定的远程扩展词词典)、姓氏词典(surname.dic)、量词词典(quantifier.dic)、后缀词词典(suffix.dic)、介词词典(preposition.dic)、停止词词典(stopword.dic、ext_stopwords制定的扩展停止词词典、remote_ext_stopwords指定的远程停止词词典)。背后使用的是字典树数据结构,所以加载和匹配逻辑和字典树加载、匹配类似
2.3、DictSegment.java
字典树中节点的数据结构,包括当前节点字符串、字符串状态(是否为一个结束节点),通用的字典树匹配方法等。charMap结构在建树时使用,便于判断子节点是否存在,提高建树性能
2.4、Monitor.java
监控远程词典是否发生改变,动态支持词典变更
2.5、Hit.java
词典匹配结果的存储结构,匹配状态(不匹配、前缀匹配、完全匹配),匹配的节点、词段开始、结束位置等
2.6、CharacterHelper.java、Sleep.java
已废弃
2.7、CharacterUtil.java
字符集识别工具类,字符串类型识别,规范化等
2.8、Lexeme.java
词元结构,包括词元类型,词元字符串,词元所在待匹配字符串中的相对起始位置、词元长度等
2.9、QuickSortSet.java
一个双向链表,是个有序的递增链表
2.10、LexemePath.java
词元链,QuickSortSet的子类,用来存放匹配的词元结果,包括起始、结束位置,有效长度
2.11、ISegmenter.java
分词器公共抽象接口定义
2.12、LetterSegmenter.java
ISegmenter接口的实现,英文字符及阿拉伯数字子分词器,包含词元开始、结束位置,字母开始、结束位置,数字开始、结束位置。数字链接符、字母连接符
2.13、CN_QuantifierSegmenter.java
ISegmenter接口的实现,中文数量词子分词器
2.14、CJKSegmenter.java
ISegmenter接口的实现,中文-日韩文子分词器
2.15、AnalyzeContext.java
分词器上下文状态,匹配过程的结果记录,包括字符串缓冲区segmentBuff,当前缓冲区位置指针,分词过程结果orgLexemes,最终分词结果results。available,最近一次读入的,可处理的字串长度 由于缓冲区只有4096,如果输入字符过长需要分多长载入,available主要用于解决这个问题
2.16、IKSegmenter.java
IK分词器主类,包含基础配置、分词器list,输入字符串,分词歧义裁决器等
2.17、IKArbitrator.java
IK分词歧义裁决器,如果选择智能分词,对分词结果进行裁剪、选择
2.18、IKAnalyzer.java
IK分词器,Lucene Analyzer接口实现
2.19、IKTokenizer.java
IK分词器 Lucene Tokenizer适配器类
四、
代码阅读顺序按照第三步介绍顺序看就可以,具体可以分四块
1、初始化相关:Configuration.java、Dictionary.java、DictSegment.java、Monitor.java、CharacterUtil.java
2、基础类库相关:Lexeme.java、QuickSortSet.java、LexemePath.java、ISegmenter.java、Hit.java
3、核心逻辑相关:LetterSegmenter.java、CN_QuantifierSegmenter.java、CJKSegmenter.java、AnalyzeContext.java、IKArbitrator.java、IKSegmenter.java
4、lucene接口相关:IKAnalyzer.java、IKTokenizer.java
五、项目代码
1、https://github.com/medcl/elasticsearch-analysis-ik
2、https://github.com/wks/ik-analyzer
3、https://code.google.com/archive/p/ik-analyzer/
注:分析的代码主要是链接1中的代码,分析时代码版本6.3.0
如需转载,请注明来源
以上是关于IKAnalyzer 源码分析-概览的主要内容,如果未能解决你的问题,请参考以下文章