• Elasticsearch实战(二十一)---ES相关度分数评分优化及FunctionScore 自定义相关度分数算法


    Elasticsearch实战—FunctionScore 自定义相关度分数算法

    ES相关度评分算法调优

    1. boost 增加权重
    2. negative boost削弱权重
    3. funciton_score自定义相关度分数算法

    场景:
    现在我想把 相关度分数和 文章的浏览量关联起来, 浏览量越大,分数越高,怎么实现, 就要用自定义分数算法

    1.ES 自定义相关分数算法 Function Score

    1.1 Function Score 原理

    自定义分数计算方式, 定义function score 指定字段直接参与到相关度分数计算中,甚至可以替换掉ES的相关度算分,自定义分数算法有几个关键点

    1. query内部使用 function_score 表明我要使用自定义相关度分数
    2. function_score内部 使用 field_value_factor 表明参与到分数计算的字段 设置,及按照什么来计算等
    3. function_score 的 field表示 对哪个字段进行积分
    4. modifier表示 对哪个字段进行积分 比如 ln, log1p, log2p log 等等算式
    5. factor 表示 对 你要计算的字段 field 的值 与 factor 相乘 处理
    6. boost_mode表示 分数 旧分数和新分数 如何处理 累加/减/乘/除/max/min 等等
    7. max_boost表示 限制计算出来的分数不要超过max_boost指定的值 , 不是最终得分不超过多少

    上面讲了基本原理及参数,下面开始实战

    1.2 准备数据

    POST /saytest/_bulk
    {"index" : { "_id" : "1" }}
    {"countnum" : 10, "say" : "hello world"}
    {"index" : { "_id" : "2" }}
    {"countnum" : 20, "say" : "hello java"}
    {"index" : { "_id" : "3" }}
    {"countnum" : 5, "say" : "hello spark learning"}
    {"index" : { "_id" : "4" }}
    {"countnum" : 15, "say" : "hello bye bye"}
    {"index" : { "_id" : "5" }}
    {"countnum" : 13, "say" : "hi world"}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    查一下 如果不用 function_score 查询条件获取的基本分数 是多少

    #不使用 function_score基本分数查询
    GET /saytest/_search
    {
      "query": {
          "match": {
            "say": "java spark"
          }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    查询结果

    文档分数分数
    id:2hello java1.4877305
    id:3java spark1.2576691

    1.3 自定义计算方式实现 function_score boost_mode 相乘

    查询公式及参数如下:

    • field 参与计算字段式 是文章的浏览量 countnum
    • boost_mode 是 multiply 相乘的方式 计算方式 old_score x 新分数
    • modifier 计算方式 式 log1p , 就是 log(1+xxx) 的计算方式 new_score = old_score * log(1+countnum)
    • factor 是 1 且 boost_mode 是 multiply 相乘的方式 计算方式 new_score = old_score * log(1+ factor x countnum)
    GET /saytest/_search
    {
      "query": {
        "function_score": {
          "query": {
            "match": {
              "say": "java spark"
            }
          },
          "field_value_factor": {
            "field": "countnum",
            "modifier": "log1p", 
            "factor": 1
          },
          "boost_mode": "multiply",
          "max_boost": 2
        }
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    自定义公式查询结果 :
    在这里插入图片描述

    这个分 如何算出来的 ? 我们来看一下原理

    文档分数原分数自定义分数
    id:2hello java1.48773051.967106
    id:3java spark1.25766910.978656

    对于 id-2 文档doc,countnum=20, 计算方式 new_score = old_score * log(1+ factor*countnum)
    也就是 1.4877305 * log ( 1+ 1 x 20) = 1.967105 ~ 就是 算出来的 1.967106
    对于 id-3 文档doc, countnum = 5
    也就是 1.2576691 * log (1+ 1 x 5) = 0.97865678273 ~ 同样也是 算出来的 0.978656
    在这里插入图片描述

    1.4 自定义 function_score 修改 modifier及 factor及boost_mode 相加

    查询公式及参数如下:

    • field 参与计算字段式 是文章的浏览量 countnum
    • boost_mode 是 sum 累加的方式 计算方式
    • modifier 计算方式 式 ln , 就是 ln(xxx) 的计算方式 new_score = old_score + ln(countnum)
    • factor 是 0.8 且 boost_mode 是 sum 累加的方式 计算方式 new_score = old_score + ln( factor x countnum)
      !!! 注意 改了 boost_mode的方式,变为累加
      !!! 注意 改了 boost_mode的方式,变为累加
      !!! 注意 改了 boost_mode的方式,变为累加
    GET /saytest/_search
    {
      "query": {
        "function_score": {
          "query": {
            "match": {
              "say": "java spark"
            }
          },
          "field_value_factor": {
            "field": "countnum",
            "modifier": "ln", 
            "factor": 0.8
          },
          "boost_mode": "sum",
          "max_boost": 10
        }
      }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    自定义公式查询结果 :
    在这里插入图片描述

    这个分 如何算出来的 ? 我们来看一下原理

    文档分数原分数自定义分数
    id:2hello java1.48773053.4877305
    id:3java spark1.25766912.6439636

    对于 id-2 文档doc,countnum=20, 计算方式new_score = old_score + ln( factor x countnum)
    也就是 1.4877305 + ln ( 0.8 x 20) = 4.26031922224 ~ 就是 算出来的 4.260319,
    对于 id-3 文档doc, countnum = 5
    也就是 1.2576691 + ln(0.8 x 5) = 2.64396346112 ~ 同样也是 算出来的 2.6439636
    在这里插入图片描述

    1.5 自定义 function_score max_boost 限制算出来的最大分

    上一步 我们看了一下 算分 原理, max_boost 其实是限制的 ln( factor x countnum) 分数, 我们修改下 max_boost 试试 效果,看看 是否能够限制 计算出来的分数

    # max_boost 限制最大算出来的分=2
    GET /saytest/_search
    {
      "query": {
        "function_score": {
          "query": {
            "match": {
              "say": "java spark"
            }
          },
          "field_value_factor": {
            "field": "countnum",
            "modifier": "ln", 
            "factor": 0.8
          },
          "boost_mode": "sum",
          "max_boost": 2
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    文档分数原分数自定义分数
    id:2hello java1.48773053.4877305
    id:3java spark1.25766912.6439636

    对于 id-2 文档doc,countnum=20, 计算方式new_score = old_score + ln( factor x countnum)
    也就是 ln ( 0.8 x 20) = 2.77258872224 ,累加旧的分数 1.4877305 + 2.77258872224 = 4.26031922224 ~
    为啥 id-2的分数是 3.4877305 呢?

    • 原因就是 max_boost=2 限制了 计算出来的分的最大值是2, 即使 ln ( 0.8 x 20) = 2.77258872224 > 2 , 累加旧分的时候,用设置的 max_boost=2 去累加 , 因此 实际计算的过程就是 1.4877305 + 2 = 3.4877305
    • 对于 id-3 文档doc, countnum = 5 计算出来的分 ln(0.8 x 5)=1.38629436112 < 2 , 小于2 累加旧分用算出来的值 1.2576691 + 1.38629436112 = 2.64396346112 ~ 即 2.6439636

    再试一下,把max_boost调整为1 看下结果, 也是符合正确的
    在这里插入图片描述


    至此 我们已经学习了 ES Function score 自定义相关度分数算法的 实现逻辑, 并且可以根据自己的业务场景去定制算法了

  • 相关阅读:
    【LeetCode热题100】--283.移动零
    操作系统概念 系统调用与 API
    外贸员的日常工作分享
    PyTorch学习笔记(二)
    利用DMA的触发循环实现eTMR的PWM周期计数
    mysql 指定库对所有表加tenant_id
    Flink SQL自定义表值函数(Table Function)
    C# 11 的这个新特性,我愿称之最强!
    力扣(LeetCode)259. 较小的三数之和(2022.09.16)
    同构和异构经典图神经网络汇总+pytorch代码
  • 原文地址:https://blog.csdn.net/u010134642/article/details/126321714