• Elasticsearch调优篇 07


    背景

      这里介绍的优化是基于 ik 分词源码的优化。首先,我们知道,ik 分词默认有两种分词模式,分别为:ik_max_word 和 ik_smart

      这里针对这两种分词方式分别存在的问题有:

      ik_max_word :最细粒度分词方式

        分的太细了,召回率确实很高,但是会导致召回的内容存在语义问题。例如,北京的一天,召回了 南京的游玩,或者任何地方的一天等等。

      ik_smart:最粗颗粒度分词方式

        1. 分的太粗,保证了召回的精准性,但是召回率却很低。

        2. 存在歧义,导致召回了不是想要的结果集,例如:广西北海 --> 广西 | 西北 | 北海,找回去了西北相关的数据。

    ik_smart 消歧逻辑

       

       当前 ik_smart 采用的是:贪心算法,分别为:

        有效文本长度->词元个数->路径跨越->词元位置->词长平均→词元位置权重

      可以在该算法的基础上进行改进

    优化三部曲

      不管做什么优化,前提保证不影响原分词效果,故在原有基础之上增加一种新的分词方式,暂定为:ik

     去除语义覆盖的单字

      例:玻璃栈道 

      ik:玻璃栈道 | 玻璃 | 栈道 

      ik_max_word:玻璃栈道 | 玻璃 | 玻 | 璃 | 栈道 |   

      这里需要注意:在去除单字的时候需要考虑当前 token 所在位置与单字所在位置是否可覆盖,不可覆盖的情况下该单字是不能去除的,例如:

       月坨岛华清月府温泉酒店 --> 月坨岛 不能覆盖 华清月府 中的月,故不能因为月坨岛有月,在华清月府中就将单字 月 去掉,这是不对的。

     专有名词优化

      这个优化一般都是基于行业垂直领域来做的优化。先举例来说吧:

      普吉岛、印度尼西亚、香格里拉一日游,分出来的:普吉岛-->吉岛、印度尼西亚-->印度 以及 香格里拉-->里拉,这些都是另外的一个国家地名,都不是这个原词所表达的含义,也就是说想这类专有词就不应该再拆分了,拆分开就会导致语义失真。

      优化的方式就是将这些专有名词,这里指的是对应的 mdd、poi 等词用文件固话到 ik 分词器中,启动的时候通过 Dictionary 类去加载到内存,在分词链条中做对应的过滤处理即可。

      香格里拉一日游  :原始 ik 分词结果 →  香格里拉|香格|格里拉|格里|里拉|一日游|一日| 

                                    新版 ik 分词结果 →  香格里拉|一日游|一日|

     去歧处理

      借鉴 jieba 分词方式,修改词库文件格式。因为 ik 分词器词典格式为一行一词,需要进行改进,在词典中加入对应挖掘的词频,以及词性。

      词典结构为: 单词  词频  词性  ,例如: 西安  2000  n

      需要对ik源码中词典结构进行修改。

      这里可以提供点改动思路,详情想了解的可以私信我吧,毕竟属于公司内部的:

      利用 es 提供的接口,将词库中所有的词分别获取一遍对应的词频,这个是可以取到的。

      而且使用 es 获取业务内部的词频更加准确有效,比起从人民日报资源中挖掘出的,直接应用在项目中要好太多了。

      其次可以利用第三方接口来得到对应词的词性,这个也很容易拿到,这样词典格式改造就可以轻松的完成了。剩下的就是 ik 源码的改造:

      一是首先修改 Dictionary 加载词典的方式;

      二是改造去歧逻辑,优化的地方采用的是:

        在ik进行前三步判断后: 有效文本长度->词元个数→路径跨越 ,如果还剩多个候选集,后三步骤结合jieba分词中的动态规划计算组合的成词概率来进行去歧处理。

  • 相关阅读:
    线程进程之间的关系
    socket网络编程
    Docker在github上的站点
    大型网站架构体系的演变
    centos7 安装SSH
    如何在CentOS 7中禁用IPv6
    在 Docker 上运行一个 RESTful 风格的微服务
    docker 操作命令详解
    玩转Docker镜像
    搭建自己的 Docker 私有仓库服务
  • 原文地址:https://www.cnblogs.com/liang1101/p/13189005.html
Copyright © 2020-2023  润新知