Es计算 总数命令 es的计算公式_字段


在上一节中,我们学习了ES的score打分规则及其公式,对于归一化计算,其公式如下

tf词频归一值的计算公式由freq / (freq + k1 * (1 - b + b * dl / avgdl))

上一节中我们已经讲解过 freq 和 d1 及 avgdl 三个参数的含义,不过参数 b 和 k1并没有去了解。

执行计划中tf解释如下


{
  "value" : 0.65996563,
  "description" : "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
  "details" : [
    {
      "value" : 2.0,
      "description" : "freq, occurrences of term within document",
      "details" : [ ]
    },
    {
      "value" : 1.2,
      "description" : "k1, term saturation parameter",
      "details" : [ ]
    },
    {
      "value" : 0.75,
      "description" : "b, length normalization parameter",
      "details" : [ ]
    },
    {
      "value" : 11.0,
      "description" : "dl, length of field",
      "details" : [ ]
    },
    {
      "value" : 13.553086,
      "description" : "avgdl, average length of field",
      "details" : [ ]
    }
  ]
}


freq:检索关键词组在被检索字段的词组中出现的频率,即出现了多少次,比如上面的执行计划搜索 苏泊尔 在字段中出现了2次,其结果为2

k1:词的饱和度值,默认值为1.2

b:长度归一化参数,默认值为0.75

d1:被检索字段分词后的词组长度,比如上面的执行计划搜索结果第一条搜索的关键字段是 goodsInfoName,其分词后一共产生了11个词组,所以在第一条记录的执行计划中,d1的值为 11;通过上面的公式可以看到,d1出现在分母的位置,即d1的值越大,其计算的评分会越小;

avgdl:分片中当前被检索字段的平均词组数值;即在当前分片中当前索引每个文档中当前字段 goodsInfoName 拆分的词组数量 的平均值;不同的分片中avgdl的值可能是不一样的;因为不同的字段存储的内容不同,每个字段的avgdl也是不一样的,当我们多字段查询时,相比较title之类的字段可以获取的评分相对会更高,因为词组更短;为了均衡这一规律,实现归一值,所以除以avgdl从而获取一个相对比较平和的比较分数,获取的分数更加客观;

上述k1,意为词的饱和度,其默认值为1.2,我们代入到公式中进行查看 tf_score = freq / (freq + k1 * (1 - b + b * dl / avgdl))

忘了介绍,我本地的ES采用的是7.8.0的版本,BM25是7.x之后引入的算法;

参数b为 归一化参数,默认为0.75,最大为1,表示完全归一化,最小值为0,表示禁用归一化;

那么,参数k1和b在TF计算公式中,究竟有什么作用呢;

目前问题:在随着文档中的某个词的出现次数增多,tf评分将会越来越高逐步趋近于1;BM25就针对这点进行来优化,转换TF的逐步增大,该算法的返回值会趋于一个数值。整体而言BM25就是对TF-IDF算法的平滑改进。


Es计算 总数命令 es的计算公式_默认值_02


在评分score计算公式中,k1这个参数控制着词频结果在词频饱和度中的上升速度。默认值为 1.2 。值越小饱和度变化越快,值越大饱和度变化越慢。

b这个参数控制着字段长归一值所起的作用, 0.0 会禁用归一化, 1.0 会启用完全归一化。默认值为 0.75 。

在上图中有2条曲线,下面那条比较平缓的就是使用BM25算法所计算的在词频出现逐步频繁时的一个分数的影响;而上面的那条曲线则表示没有使用BM25算法的情况下的分数的打分情况;

Elasticsearch默认在7.x之前的版本使用的TF-IDF算法,在7.x之后默认采用的BM25算法,其公式就是我们上面看到的 tf_score = freq / (freq + k1 * (1 - b + b * dl / avgdl))

在上一节的索引中,我们新增一个记录,使其出现高频词,DSL语句如下:


POST kstore/_doc/11111
{
  "goodsInfoId" : 11111,
  "goodsInfoName" : "苏泊尔苏泊尔苏泊尔苏泊尔苏泊尔苏泊尔苏泊尔苏泊尔苏泊尔苏泊尔",
  "goodsInfoPreferPrice" : 300.0
}


然后我们再查询一遍,如下图,我们得到的TF最终分数为0.9120356, 可以看到,即使出现高频词,其最终的score分数始终低于1,也就是不完善归一化;


Es计算 总数命令 es的计算公式_默认值_03


BM25官方成为是可拔插的相似度,可以修改k1和b的值进行相似度修改。可以通过对k1和b两个参数的自定义,从而实现对高频词的打分控制,使其分数更加平和;