ik分词器 分词原理_IK分词器输出多类型词源

背景:

IK分词器分为两种,粗粒度分词和细粒度分词,粗粒度会分为长词,细粒度分出的词比较多,会分出与词库中所有可匹配的词,现在我们想要这样的分词效果如:

关键词:“北京青年路”

粗粒度会分出:

aeb89c0d3aa0ef8ded2a4b6168f9199f.png

细粒度会分出:

5be4fbe737b093e2e616649b690c9892.png

那么我们需要只分出整词、去掉包含词、相同词不去重 如下:

eca61063dae8f5c2165459b26f58824f.png

1、歧义词处理

这个功能实际上是用到了IK的歧义词处理,为什么粗粒度不展示包含词和重复词了?是因为做了歧义词过滤,过程如下:

在IKAegmennter.java的next方法中进行歧义词处理

da829c490bcba412be9b37ffad8e3cfb.png

歧义词处理分了两块,功能是一样的,只是处理循环中和循环结束最后一个词组的处理。

d0fef53c24767bded492d08ec9cda44f.png

上面的代码是我修改后的了,增加了judge2的方法,用于处理不处理重复歧义词,第99行判读是否执行歧义处理过程,如果不执行歧义词处理则所有的词都添加到context的词队列中,接下来看看judge歧义词处理过程:

d20cc236ae7dfa9ef78ad56a12aba84d.png

首先输入的参数lexemeCell是成词的一个链表,这个链表存储了当前词、同位置词、包含词,代码156行过滤歧义词保存到lexemeStack中,以提供后续处理,159行pathOptions存储了处理歧义后的结果,163行循环歧义列表开始处理歧义词,166行move掉了包含歧义词,168行生成拷贝C创建一个optionn,169行添加到结果列表中,这个添加的重复词是添加不进去的,因为LexemePath重写了compareTo方法,173行只取结果列表的第一个,实际上这第一个词是按权重的分词器排在上面的分词器分出的词。

eeae9f6e05662ee6638767b32f4d0961.png

2、保留重复词

增加一个处理歧义词的方法judeg2,用来保留歧义重复词,200行遍历词源队列,并判断是否小于队列中的第一个词,如果小于说明是包含词则进行过滤,大于等于队列第一个词则保留,并调用optionn.addCrossLexeme方法加入到结果集队列中,返回为分词队列,而原方法返回的是一个词源。

ae74c8dd967ca3b165dbb6980c6bde7b.png

addCrossLexeme方法向LexemePath追加相交的Lexeme。

5850e55d1c863af9ed184ffa77c447f9.png

3、分词字符

题外话,IK会对不认识的特征字符做分割处理,如果词典中有特殊字符想被分出时,可以修改 CharacterUtil类中的identifyCharType方法实现。

bd6bb0e15414f827d4de97b8b93fe341.png

如果喜欢搜索技术请来我的公众号吧 ‘Lucene Elasticsearch 工作积累’

每天会持续更新搜索相关技术

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值