`
JimmyWen
  • 浏览: 13506 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

ik源码分析之我见

阅读更多

 最近对lucene的分词有比较浓厚的兴趣,对ik的源码研究了一段时间
 
 ik对分词的处理参照DictSegment类的match方法

  DictSegment类会先构建一个类似tree的结构,tree的根节点是以字典里的所有词的首字符为入口,后续的每个字符都是一个节点,如果该子节点已经是字典里的某个词的结束符将DictSegment(每个节点的bean类型)的nodeState的属性置为1(表示要匹配的词是一个分词),否则为0。

在match方法中

else if (length == 1){//到达分析的词最后一个
    Hit searchHit= new Hit();
    //搜索最后一个char
    if(ds.nodeState == 1){
     //添加HIT状态为完全匹配
     searchHit.setMatch();
    }
    if(ds.hasNextNode()){
     //添加HIT状态为前缀匹配
     searchHit.setPrefix();
    }
    return searchHit;
   }

 
假设我们要分析的词是中华人民共和国,那将达到searchHit.setMatch();这行,如果我们要分析的词是中华人民共和国都,那该词将不会被匹配,这跟ik的处理有关系。下面我解释ik这么处理的原因。

ik处理分词有最大正向匹配和最细粒度区分,如果要分析的词是中华人民共和国,最大正向匹配只会得到 中华人民共和国 一个结果 ,
但最细粒度将得到 中华人民,中华,华人,人民共和国,人民,共和国,共和 这样的结果
在ik中都是最细粒度的处理方法,只是在最后如果是最大正向匹配的话会做一个归并操作(参照IKSegmentation中的next方法,最后结果调用了context中的excludeOverlap方法将所有的分词结果做归并操作)

ik对要处理的文档是先读取缓存,然后对缓存的数据做处理,如果缓存的数据满了,再清空缓存读取后续缓存,避免了大数据引起的内存溢出。

IKSegmentation的next得到下个分词的结果,但它会先处理一个缓存的所有数据得到该缓存数据的所有分词结果集。

分析缓存数据时是顺序读取字符数据

 int available = fillBuffer(input);
int buffIndex = 0;
for( ; buffIndex < available ;  buffIndex++){
           //移动缓冲区指针
           context.setCursor(buffIndex);
           //进行字符规格化(全角转半角,大写转小写处理)
           segmentBuff[buffIndex] = CharacterHelper.regularize(segmentBuff[buffIndex]);
           //遍历子分词器
           for(ISegmenter segmenter : segmenters){
            segmenter.nextLexeme(segmentBuff , context);
           }
           /*
            * 满足一下条件时,
            * 1.available == BUFF_SIZE 表示buffer满载
            * 2.buffIndex < available - 1 && buffIndex > available - BUFF_EXHAUST_CRITICAL表示当前指针处于临界区内
            * 3.!context.isBufferLocked()表示没有segmenter在占用buffer
            * 要中断当前循环(buffer要进行移位,并再读取数据的操作)
            */           
           if(available == BUFF_SIZE
             && buffIndex < available - 1   
             && buffIndex > available - BUFF_EXHAUST_CRITICAL
             && !context.isBufferLocked()){

            break;
           }
          }

 在for(ISegmenter segmenter : segmenters){
      segmenter.nextLexeme(segmentBuff , context);}
这个过程中各个子segmenter(包括 中文处理ChineseSegmenter ,英文处理LetterSegmenter,QuantifierSegmenter)都会对字符进行分析,这里我们主要讨论ChineseSegmenter。在ChineseSegmenter 中nextLexeme方法中接收IKSegmentation.next方法传入的字符和context,context的cursor属性每次传入都会加一,表示要分析的字符在缓存数据中的偏移量。
  1 如果从该缓存数据的开始位置到该字符串为止组成的一个字符串(A)是字典里的一个词那将会添加到context的Lexeme中,表示这是一个分析后的词,
  2 如果A是某个词的前缀,比如(中华人就是中华人民的前缀)将不会做特殊处理,等待下个字符进入(例子中的 民 )组成一个 中华人民 再添加到lexeme中。
  3  如果该字符是前缀那将添加到 ChineseSegmenter 中的_CSegList变量,该变量保存了所有已经分析了的并且是前缀的字符和它在缓存中的偏移量(被移除_CSegList的条件是不是A不是字典里的词 或 A是字典的一个词但A不是某个词的前缀,移除避免了_CSegList持续增长和重复的检查)
 4 如果该字符不是前缀做其他的处理,这里暂不讨论


说到现在读者应该明白了为什么上面提出的问题了吧。


不过ik的处理方式还有个问题,那就是一个文档足够大,如果一个词刚好在两个缓存中间那该词将不会得到

 

分享到:
评论

相关推荐

    多个版本ik分词器源码

    此外,分析源码还可以帮助我们掌握如何利用IK Analyzer进行自定义配置,例如添加新词,调整分词策略,或者集成到其他系统中。这对于那些需要在特定领域(如医疗、法律)进行精细化分词的项目来说尤其重要。 总之,...

    IKAnalyzer3.2.8 源码

    源码分析: 1. **分词原理**:IKAnalyzer采用动态构建的词典树(Trie树)和Aho-Corasick算法,快速匹配和查找词汇。同时,它支持用户自定义扩展词典,以适应特定领域的分词需求。 2. **字典构建**:源码中会包含...

    IKAnalyzer源码解析

    通过对IKAnalyzer源码的分析,我们可以看到其设计精妙之处在于利用了Trie树这一高效的数据结构来加速词典的加载和词汇的匹配。此外,自定义词典的功能也极大地增强了其灵活性和适应性。在实际应用中,理解IKAnalyzer...

    IK3.2.8原理及源码分析(原创)

    ### IK3.2.8原理及源码分析 #### 一、IKAnalyzer3.2.8系统架构 IKAnalyzer3.2.8是一款基于Java语言编写的开源分词组件,广泛应用于搜索引擎、文本处理等领域。它能够高效地对中文文本进行分词处理,并支持自定义...

    IK分词器源码

    源码分析有助于理解其内部工作原理,从而更好地优化和定制分词效果。 IK分词器的主要特点是支持动态词典加载,能够根据实际需求添加或更新词库,提高了对新词汇的识别能力。此外,IK还提供了精准模式和全模式两种...

    IKAnalyzer 分词源码

    源码分析 - `org.ansj.domain`: 定义了分词过程中涉及的实体类,如Term(词语)、Nature(词性)等。 - `org.ansj.splitWord`: 包含了分词的主要实现,如`Analysis`接口和`Analyzer`类。 - `org.ansj.util`: 提供...

    IKAnalyzer2012源码

    **IKAnalyzer 2012源码分析** IKAnalyzer 是一个开源的、基于Java实现的中文分词器,主要用于提高中文信息处理的效率。这款工具广泛应用于搜索引擎、文本挖掘、信息检索等领域,其核心功能是对中文文本进行有效的...

    elasticsearch-analysis-ik-5.3.2 源码

    **Elasticsearch Analysis IK 5.3.2 源码分析** Elasticsearch是一款流行的开源全文搜索引擎,它提供了一种分布式、实时的搜索和分析引擎。在处理中文文本时,由于中文的特殊性(词语边界不明显),需要借助特定的...

    IKAnalyzer源码

    **IKAnalyzer源码详解** **一、IKAnalyzer简介** IKAnalyzer是基于Java语言开发的一款开源的中文分词组件,主要用于解决在信息检索、文本挖掘等领域中的中文处理问题。它的全称为"Intelligent Chinese Analyzer ...

    IKAnalyzer源码+配置+智能分词类

    3. **自定义字典**:解压`IK Analyzer 2012FF_hf1_source.rar`,获取源码并根据需要修改字典,然后重新编译生成新的jar包。 **应用场景** - **全文检索**:IKAnalyzer常用于构建搜索引擎,如Solr和Elasticsearch,...

    快速上手数据挖掘之solr搜索引擎高级教程(Solr集群、KI分词)第22讲 IK分词源码分析 共7页.pptx

    solr之MoreLikeThis第20讲 solr之dataimport第21讲 IK分词简介第22讲 IK分词源码分析第23讲 IK与Solr集成第24讲 IK动态词库加载第25讲 项目实战之比比看架构设计第26讲 项目实战之比比看索引设计第27讲 项目实战之...

    solr5的ik中文分词器源码

    在处理中文文本时,一个关键的组件就是中文分词器,而IK(Intelligent Chinese)分词器是Solr中常用的中文分词工具之一。本文将深入探讨"solr5的ik中文分词器源码"的相关知识点。 1. **IK分词器概述**: IK分词器...

    solr ik源码详细解析

    《Solr IK源码深度解析:词典、分词与歧义处理》 中文分词是自然语言处理中的关键步骤,它涉及到对文本的精细化处理,以实现诸如搜索引擎、信息检索等应用。本文将深入探讨IKAnalyzer的源码,剖析其核心的词典处理...

    Ik中文分词jar包+指导手册+源码src

    对于有意向进行二次开发或优化的用户来说,源码分析是必不可少的。 Ik中文分词器的特点包括: - 动态词典加载:允许用户在运行时添加或修改词典,适应不同领域或场景的需求。 - 词性标注:除了分词外,Ik还提供了...

    使用IK Analyzer实现中文分词之Java实现

    最初,它是以开源项目Luence 为应用主体的,结合词典分词和文法分析算法的中文分词组件。 从 3.0 版本开始,IK 发展为面向 Java 的公用分词组件,独立于 Lucene 项目,同时提供了对 Lucene 的默认优化实现。 在 2012...

    IK算法源码

    IK算法,全称为“Intelligent Keyword”算法,是中国开源的分词组件,主要应用于Java环境,广泛用于搜索引擎、文本分析等领域。它旨在提供一个高效、灵活的中文分词解决方案。IKAnalyzer是IK算法的一种实现,它基于...

    ikanalyzer2.0.2源码

    1. **分词核心算法**:ikanalyzer采用了基于词典的分词方法,主要运用了HMM( Hidden Markov Model)隐马尔可夫模型,通过对已知词汇的统计分析,预测当前字最可能属于哪个词。同时,它还支持自定义词典,以满足特定...

    6.8.5版本ES和6.8.5IK分词及源码文件.7z

    对于想要定制分词规则或优化搜索性能的开发者而言,源码分析是不可或缺的步骤。源码中的注释和模块划分可以帮助我们快速定位问题,进行调试和优化。 **安装与运行** 获取资源包后,只需将ES和IK的解压文件放置在...

    IKAnalyzer分词器源码+可直接使用jar包

    源码分析可以帮助我们了解分词器如何进行词语切分、如何处理未登录词(unknown words)以及如何优化性能。 - 分词器:这是IKAnalyzer的核心,负责将输入的文本分解为一系列的词语。它可能会使用正向最大匹配法...

Global site tag (gtag.js) - Google Analytics