score在ES中有着很重要的做用,有了它才有了rank,是验证文档相关性的关键数据,score越大表明匹配到的文档相关性越大html
查询的时候能够用explain来展现score的计算过程,也能够增长format=yaml来说json转成yaml方便阅读java
相似xxx/_search?explain&format=yamlnode
下图是经过explain看到的一部分json,其实这个解释中就展现出了计算公式,不得不说ES在这点上仍是很人性化的算法
常说的相关性是指计算一个全文(full-text)字段的内容与全文查询字符串的类似程度的算法。apache
这个算法默认是BM25,一个基于TF-IDF(term frequency/inverse document frequency)的算法。json
首先是TF(term frequency),顾名思义,term在field出现的频率越高,则该term与field的相关性越高。socket
公式:elasticsearch
sqrt(TF)ide
而后是IDF(inverse document frequency),term在整个index出现的频率越高,则该term与该document的相关性越低。fetch
公式:
Log(numDocs / docFreq + 1) + 1
BM全称(Best Match),这个名称不得不说有点过度,这个算法也一样有TF和IDF。
TF,BM25把TF的影响范围减少了,不像TF-IDF同样没有边界
公式:
(k+1)* tf /(k + tf),k通常是个常量,[1.2,2],经过k能够改变回归的速度。
IDF几乎同样,只是多加了1(为了提升其总体影响比重)
BM25新加了另外一个特征,Field-length norm,field的长度有多少,若是field的长度越长,则该term与field的相关性越低(分母越大,几率越小)。
公式:
|d|/avgDl(本文档的长度除以平均文档的长度)
下图为不一样文档长度对应相同tf所影响最终tf的曲线。
公式:
(k + 1)* tf / k * ( 1.0 - b + b - L + tf) (其中b为常数)
BM25 Field-length norm之间的对比
在TF角度的对比
Score的计算过程依赖query clause(查询子条件),例如:
1.模糊查询计算匹配到的word和原来的word(匹配前的word)的类似度
2.term查询会包含找到该term所占的百分比
个别查询会结合TF-IDF的socre和其它因素,越多的query clause(查询子条件)匹配到,那么score就越高,具体来讲,是query clause匹配获得的score联合起来计算出最终的score。
须要注意的是,TF-IDF默认是基于shard来计算的,假设1个index有5个shards,则就有5个TF-IDF的结果,也就是5个score,而后score再汇聚到request node,作排序后获得最终结果。因此这有产生了另外一个问题,当index的documents数量较少时,score的结果会不许确,毕竟不是全局的,shard也只是经过hash来区分,有很大的随机性和偶然性。针对这种状况,ES给出了DFS Query Then Fetch(默认是采用Query Then Fetch)这种解决方案,采用全局计算TF-IDF的方式,解决这个问题,在查询的时候能够这么设置
search_type=dfs_query_then_fetch
(不过会影响效率,毕竟是全局计算,多了几回socket传输)。其实还有一种解决方法,直接把index的shard设置成1,这样本身就表明了全局。
稍微解释一下Query Then Fetch,顾名思义,是先查询后获取。
查询流程以下
刚接触score的时候,总有疑惑,为何不是一个百分比,这样可能更加直观的表现出匹配到正确的几率,也就是术语”normalized socre”。
这么想是错误的!
Score的意义仅仅在于对比一次查询的多个结果的对比,起到rank做用,并不能表明匹配到的几率,更不能拿几个匹配到的几率作比较,好比:当一个document自己没有发生变化,可是index发生变化,就会影响匹配到document的sorce。这样的几率是没什么意义的,虽然你能够强行造出一个几率。
在作业务的过程当中领悟到,搜索系统和推荐系统不是一个系统(以前没想过这个问题),重要区别之一就是主动和被动,详细看这篇博客吧,说的很详细了
http://blog.csdn.net/cserchen/article/details/50422553
//官方对相关性的解释,也就是score的计算标准
https://www.elastic.co/guide/en/elasticsearch/guide/master/relevance-intro.html
//当你的数据不多时,请用DFS Query Then Fetch搜索方法
https://www.elastic.co/blog/understanding-query-then-fetch-vs-dfs-query-then-fetch
//ES的两个搜索方法
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-search-type.html
//ES官方解释的BM25和TF-IDF区别
https://www.elastic.co/blog/found-similarity-in-elasticsearch
//外国友人对BM25和TF-IDF的解读
http://opensourceconnections.com/blog/2015/10/16/bm25-the-next-generation-of-lucene-relevation/
//外国友人吐槽 当score变成percentage的后果