【Elasticsearch】打分策略详解与explain手把手计算

1、目的

一个搜索引擎使用的时候一定须要排序这个模块,通常状况下在不选择按照某一字段排序的状况下,都是按照打分的高低进行一个默认排序的,因此若是正式使用的话,必须对默认排序的打分策略有一个详细的了解才能够,不然被问起来为何这个在前面,那个在后面很差办,所以对Elasticsearch的打分策略详细的看了下,虽说还不是了解的很所有,可是大部分都看的差很少了,结合理论以及搜索的结果,作一个简单的介绍html

2、Elasticsearch的打分公式

Elasticsearch的默认打分公式是lucene的打分公式,主要分为两部分的计算,一部分是计算query部分的得分,另外一部分是计算field部分的得分,下面给出ES官网给出的打分公式:java

 

[java] view plain copyapp

 

  1. score(q,d)  =    
  2.             queryNorm(q)    
  3.           · coord(q,d)      
  4.           · ∑ (             
  5.                 tf(t in d)     
  6.               · idf(t)²        
  7.               · t.getBoost()   
  8.               · norm(t,d)      
  9.             ) (t in q)      

在此给每个部分作一个解释elasticsearch

 

queryNorm(q):

对查询进行一个归一化,不影响排序,由于对于同一个查询这个值是相同的,可是对term于ES来讲,必须在分片是1的时候才不影响排序,不然的话,仍是会有一些细小的区别,有几个分片就会有几个不一样的queryNorm值ide

queryNorm(q)=1 / √sumOfSquaredWeights ui

上述公式是ES官网的公式,这是在默认query boost为1,而且在默认term boost为1 的状况下的打分,其中搜索引擎

sumOfSquaredWeights =idf(t1)*idf(t1)+idf(t2)*idf(t2)+...+idf(tn)*idf(tn)spa

其中n为在query里面切成term的个数,可是上面所有是在默认为1的状况下的计算,实际上的计算公式以下所示:.net

coord(q,d):

coord(q,d)是一个协调因子它的值以下:3d

 

[java] view plain copy

 

  1. coord(q,d)=overlap/maxoverlap  

其中overlap是检索命中query中term的个数,maxoverlap是query中总共的term个数,例如查询词为“无线通讯”,使用默认分词器,若是文档为“通知他们开会”,只会有一个“通”命中,这个时候它的值就是1/4=0.25

 

tf(t in d):

即term t在文档中出现的个数,它的计算公式官网给出的是:

 

[java] view plain copy

 

  1. tf(t in d) = √frequency  

即出现的个数进行开方,这个没什么能够讲述的,实际打分也是如此

 

idf(t):

这个的意思是出现的逆词频数,即召回的文档在总文档中出现过多少次,这个的计算在ES中与lucene中有些区别,只有在分片数为1的状况下,与lucene的计算是一致的,若是不惟一,那么每个分片都有一个不一样的idf的值,它的计算方式以下所示:

 

[java] view plain copy

 

  1. idf(t) = 1 + log ( numDocs / (docFreq + 1))  

其中,log是以e为底的,不是以10或者以2为底,这点须要注意,numDocs是指全部的文档个数,若是有分片的话,就是指的是在当前分片下总的文档个数,docFreq是指召回文档的个数,若是有分片对应的也是在当前分片下召回的个数,这点是计算的时候与lucene不一样之处,若是想验证是否正确,只需将分片shard的个数设置为1便可。

 

t.getboost():

对于每个term的权值,没仔细研究这个项,我的理解的是,若是对一个field设置boost,那么若是在这个boost召回的话,每个term的boost都是该field的boost

norm(t,d):

对于field的标准化因子,在官方给的解释是field越短,若是召回的话权重越大,例如搜索无线通讯,一个是很长的内容,但都是包含这几个字,可是并非咱们想要的,另一个内容很短,可是完整包含了无线通讯,咱们不能由于后面的只出现了一次就认为权重是低的,相反,权重应当是更高的,其计算公式以下所示:



其中d.getboost代表若是该文档权重越大那么久越重要

f.getboost代表该field的权值越大,越重要

lengthnorm表示该field越长,越不重要,越短,越重要,在官方文档给出的公式中,默认boost所有为1,在此给出官方文档的打分公式:

 

[java] view plain copy

 

  1. norm(d) = 1 / √numTerms   

该值在计算的时候老是没法对上,查询网上的资料说是在打分的时候将结果先进行压缩,而后解压缩,因此结果跟原始值对不上,我的理解有点像量化的过程,由于在实际explain的时候发现该值有必定的规律性

 

3、实际的打分explain

在实际的时候,例如搜索“无线通讯”,以下图所示,由于一些私人缘由,将一些字段打码,查询的时候设置explain为true,以下图所示:


 

由于使用的是默认的分词器,因此最后的结果是将“无线通讯”分红了四个字,而且认为是四个term来进行计算,最后将计算的结果进行相加获得最后的得分0.7605926,这个分数是“无”的得分+“线”的得分+“通”的得分+“信”的得分,四个term的得分以下图所示:

最后的得分是0.7605926=0.118954286+0.1808154+0.14515185+0.31567,与上述符合,由于四个词都出现了因此在这里面的coord=1,总分数的计算知道后,咱们单看每一部分的得分的计算,以“无”为例进行介绍:

其中每个term内部分为两部分的分数,一部分是queryweight,一部分是fieldweight,其中总分数=queryweight*fieldweight

例如此处queryweight=0.51195854,fieldWeight=0.2323514,因此总的分数就是0.118954286

queryweigth计算:

对于queryweight部分的计算分为两个部分idf和querynorm,其中idf的值是2.8618271,这个值是如何计算的呢

idf=1+ln(1995/(309+1))=2.8618271,说明在分片四里面共有1995个文档,召回了包含“无”的309个文档,所以为这个值

querynorm部分的计算:根据上面“无”“线”“通”“信”四个的分数计算,能够看到,idf的值分别为

无:2.8618271

线:3.1053379

通:2.235371

信:2.901306

因此按照计算公式

 

[java] view plain copy

 

  1. querynorm=1 / √2.8618271*2.8618271+3.1053379*3.1053379+2.235371*2.235371+2.901306*2.901306=0.1788922  

 

因此queryweight部分的值是0.1788922*2.8618271=0.51195854

再次总结下此处的公式:queryweight=idf*queryNorm(d)

fieldweight部分计算:

idf的计算上边已经算过,在此不详细叙述

tf的值是在此处出现3次,因此为√3=1.7320508

fieldnorm的值不知道如何计算,按照公式计算不出来explain的值,网上资料说是编解码致使的,哪位朋友知道如何计算麻烦回复下,多谢

总结下fieldweight部分的计算公式:fieldweight=idf*tf*fieldnorm=1.7320508*2.8618271*0.046875=0.2323514

因此整体的计算就是

[java] view plain copy

 

  1. score=queryweight*fieldweight=idf*queryNorm(d)*idf*tf*fieldnorm=coord*queryNorm(d)*tf*idf^2*fieldnorm  

4、参考文档

http://www.cnblogs.com/forfuture1978/archive/2010/03/07/1680007.html

https://www.elastic.co/guide/en/elasticsearch/guide/current/scoring-theory.html#field-norm

版权声明:本文为博主原创文章,转载请注明出处:http://blog.csdn.net/molong1208 https://blog.csdn.net/molong1208/article/details/50623948

文章标签: Elasticsearch score explain TFIDF 打分

我的分类: elasticsearch

所属专栏: Elasticsearch专栏

相关文章
相关标签/搜索