二十四、ElasticSearch的评分知识讲解

2019-12-02  本文已影响0人  书写只为分享

1、TF/IDF相关评分算法公式

score(q,d) =
queryNorm(q)
· coord(q,d)
· ∑ (
tf(t in d)
· idf(t)2
· t.getBoost()
· norm(t,d)
) (t in q)
score(q,d)
这个公式的最终结果,就是说是一个query(叫做q),对一个doc(叫做d)的最终的总评分
queryNorm(q)
是用来让一个doc的分数处于一个合理的区间内,不要太离谱,举个例子,一个doc分数是10000,一个doc分数是0.1,你们说好不好,肯定不好
coord(q,d)
简单来说,就是对更加匹配的doc,进行一些分数上的成倍的奖励
∑:求和的符号
∑ (t in q):
query中每个term对doc的分数,进行求和,多个term对一个doc的分数
2、对相关度评分进行调节和优化的常见的4种方法
(1)query-time boost(对查询的评分增加评分)

GET /forum/article/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": {
              "query": "java spark",
              "boost": 2
            }
          }
        },
        {
          "match": {
            "content": "java spark"
          }
        }
      ]
    }
  }
}

(2)、重构查询结构

GET /forum/article/_search 
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "content": "java"
          }
        },
        {
          "match": {
            "content": "spark"
          }
        },
        {
          "bool": {
            "should": [
              {
                "match": {
                  "content": "solution"
                }
              },
              {
                "match": {
                  "content": "beginner"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

(3)、negative boost(降低不相关的值分数)

搜索包含java,不包含spark的doc,但是这样子很死板
搜索包含java,尽量不包含spark的doc,如果包含了spark,不会说排除掉这个doc,而是说将这个doc的分数降低
包含了negative term的doc,分数乘以negative boost,分数降低
以前写法:

GET /forum/article/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {
          "content": "java"
        }}
      ],
      "must_not": [
        {"match": {
          "content": "solution"
        }}
      ]
    }
  }
}

negative boost写法:

GET /forum/article/_search
{
  "query": {
    "boosting": {
      "positive": {
        "match": {
          "content": "java"
        }
      },
      "negative": {
        "match": {
          "content": "solution"
        }
      },
      "negative_boost": 0.2
    }
  }
}

(4)、constant_score(不需要相关评分)

GET /forum/article/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "constant_score": {
            "query": {
              "match": {
                "content": "java"
              }
            }
          }
        }
      ]
    }
  }
}

3、用function_score自定义相关度分数算法

GET /forum/article/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query": "java spark",
          "fields": ["title","content"]
        }
      },
      "field_value_factor": {
        "field": "view_cnt",
        "modifier": "log1p",
        "factor": 1.2
      },
      "boost_mode": "sum",
      "max_boost": 2
    }
  }
}

如果只有field,那么会将每个doc的分数都乘以view_cnt,如果有的doc follower是0,那么分数就会变为0,效果很不好。因此一般会加个log1p函数,公式会变为,new_score = old_score * log(1 + number_of_votes),这样出来的分数会比较合理
再加个factor,可以进一步影响分数,new_score = old_score * log(1 + factor * number_of_votes)
boost_mode,可以决定分数与指定字段的值如何计算,multiply,sum,min,max,replace
max_boost,限制计算出来的分数不要超过max_boost指定的值

上一篇下一篇

猜你喜欢

热点阅读