tf 是要查询的词在一个文档中出现的次数。
是逆向文档频率的得分,等于文档频率 的倒数取log。
文档频率 就是要出现查询的词文档数与文档总数加一的比,代表了查询的词在全部文档中占的大小。
numDocs 即为文档总数; docFreq 即为出现要查询词出现在文档(这个概念对应关系型数据库的“记录”,见上文)中出现的次数;
IDF score 的意义在于考虑查询的词在文档总数出现的频率,对总分产生影响。查询的词在文档中出现的频率越高,对结果产生的影响越小。比如想 “的”,“你” 等常见的词几乎出现在每一个文档中,对结果会有很小的影响。
是字段长度归一值。它的计算方式为:
length 表示文档的长度。
fieldNorms 的意义在于考虑文档长度对于查询得分的影响。例如在一条短信中匹配到搜索的词与在一本书中匹配到,肯定是这个短信更有可能属于结果集。
将所有的分项带入,得到 TF/IDF 的公式:
ES 中的数据:
搜索”zhang“ 后,得到的前一条结果及其得分的详情:
我们可以看到框选的部分: tf、idf、fieldNorm 分别对应前文公式的三个部分。感兴趣的同学可以自己具体计算一下得分。
上面介绍的TF/IDF 模型是针对一个词来进行查询的,如果我们搜索多个词,改怎么处理呢?
向量空间模型(Vector Space Model) 提供一种比较多词查询的方式,模型将文档和查询都以 向量(vectors)的形式表示。
举例来说:[1]
假设我们有三个文档:
I am happy in summer 。
After Christmas I’m a hippopotamus 。
The happy hippopotamus helped Harry 。
我们要在这三个文档中搜索 “happy hippopotamus” (快乐的河马)
可以为每个文档都创建包括每个查询词 ( happy 和 hippopotamus )权重的向量(事实上使用的是得分,这里为了便于理解,人工指定了权重),然后将这些向量置入同一个坐标系中:
通过比较各个文档的向量与查询词的向量的夹角(计算时使用夹角的余弦值),来判断哪个文档与查询更为接近。
具体计算时,使用**余弦相似度**公式计算:
Lucene 实用评分函数是有余弦相似度公式演变而来。图中相同颜色的框代表的含义是一样的。
我们可以看到,Lucene 实用评分函数改变的是 增加了 和。
上文提到过 ,考虑了文档的长度,而余弦相似度公式中对应的部分为,为 的单位长度,未考虑文档长度。
和 分别代表查询的权重提升和文档的权重提升,可以更为灵活的手工指定,影响搜索结果。
BM25 全称 Okapi BM25 是 Okapi Best Match 25 的缩写。
ES 版本 5.0 将 TF/IDF 模型更换为了 BM25 模型。BM25可以看做是 TF/IDF 的改良。
BM25 与 TF/IDF 相比,主要体现在 TF 和 fieldNorms 的计算上。
对于IDF,我们看到两者的趋势基本是一致的
对于 TF 我们看到,传统的 TF 曲线随着 tf(词频) 的升高,其值无限的增加,而 BM 25的
TF 值收敛到一个值()。在一定程度上,词频越高,固然得分也应该越高。但是不能没有限度。否则像是网页搜索,站长可以通过作弊,使得词频达到极高的值,就达到了垄断这个词的效果 了。
BM25 将 fieldNorms 与词频进行合并,一起对得分产生影响,称为 tfNorm
:表示文档的长度是平均文档长度的多少倍。计算方式:
参数的作用:调节 L 的影响程度,当b=0时,文档的长度对于结果没有影响
下图展示了文档长度对于得分的影响:
将以上部分组合起来,我们得到了 BM25 的公式:
分享的第二部分,请查看 深入理解 ES 查询机制[二](即将推出)
来自 ElasticSearch 权威指南:https://www.elastic.co/guide/cn/elasticsearch/guide/current/scoring-theory.html ↩︎