推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > 代码与美食 > IKAnalyzer 源码分析-概览

IKAnalyzer 源码分析-概览

代码与美食 2018-10-28

一、背景

持续研究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.javaIKSegmenter.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 源码分析-概览》的版权归原作者「代码与美食」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注代码与美食微信公众号

代码与美食微信公众号:gh_5612855b2c45

代码与美食

手机扫描上方二维码即可关注代码与美食微信公众号

代码与美食最新文章

精品公众号随机推荐