相关性算分 | Relevance
- 搜索的相关性算分,描述了一个文档和查询语句的匹配程度,ES 会对每一个匹配查询条件的文档进行算分 _score;
- 相关性算分是一篇文档针对某个关键词来说的相关度高低的一个分数;
- 打分的本质算排序,需要把最符合用户需求的文档排在前面,ES 5 之前,默认的相关性算分采用 TF-IDF,现在采用 BM 25;
词频 | TF | Term Frequency
Term Frequency
- 词在一篇文档中出现的频率;
- 词出现的次数 / 文档的总词数
文档和关键词相关性的简单度量方式
- 度量一条查询和结果文档相关性的简单方法:简单的将文档中每一个关键词的 TF 相加,比如搜索的关键词为:"区块链 的 应用",那么一篇文档和关键词的相关性 = TF(区块链)+ TF(的)+ TF(应用);
Stop Word
- “的”在文档中出现了很多次,但是对贡献相关度几乎没有用处,不应该考虑这样的 TF;
逆文档频率 | IDF
DF | Document Frequency
- 检索词在文档中出现的频率;
- “区块链”在相对少的在文档中出现;
- “应用”在相对比较多的文档中出现;
- “Stop Word”在大量的文档中出现;
IDF | Inverse Document Frequency
- 简单说 = log(全部文档数 / 检索词出现过的文档数);
- IDF 可以衡量出关键词的重要程度,IDF 值越大的关键词越重要;
TF - IDF
- TF-IDF 本质上就是将 TF 求和变成了加权求和:TF(区块链) * IDF(区块链) + TF(应用) * IDF(应用) + TF(的) * IDF(的)
TF-IDF | 概念
- TF-IDF 被公认为信息检索领域最重要的发明;
- 除了在信息检索,在文献分类和其他相关领域有着非常广泛的应用;
BM 25
- 从 ES 5 开始,默认算法改为了 BM 25;
- 和经典的 TF-IDF 相比,当 TF 无限增加时,BM 25 算分会趋于一个数值;
- 在创建索引的时候,可以对相关性的算分做定制;
BM 25 | 实例分析一下
Boost 是啥
- 放大因子,默认是 2.2;
- 文档中一个字段的得分:
TF * IDF * Boost
; - 不同的字段的重要性是不同的,比如 movie 的 title 和 overview 字段,通常认为 title
字段在搜索的算分中的地位更重要,那么就可以放大 title 的 Boost,title 一旦命中后,更大的 Boost 使得 title 字段的算分更高,可以这样用:
GET /movie/_search
{
"query":{
"multi_match":{
"query":"basketball with cartoom aliens",
"fields:"["title^10","overview"]
}
}
}
IDF 的计算公式
IDF = log(1 + (N - n + 0.5) / (n + 0.5) )
- N:有指定字段的文档的数量;
- n:包含关键词的文档数;
TF 的计算公式
tf = freq / (freq + k1 * (1 - b + b * dl / avgdl ) )
- freq:关键词在字段中出现的次数;
- k1
- b
- dl:字段的长度;
- avgdl:字段的平均长度;
TF - IDF | 举几个例子
数据准备
PUT testscore
{
"settings": {
"number_of_shards": 1
},
"mappings": {
"properties": {
"content": {
"type": "text"
}
}
}
}
PUT testscore/_bulk
{ "index": { "_id": 1 }}
{ "content":"we use Elasticsearch to power the search" }
{ "index": { "_id": 2 }}
{ "content":"we like elasticsearch" }
{ "index": { "_id": 3 }}
{ "content":"The scoring of documents is caculated by the scoring formula" }
{ "index": { "_id": 4 }}
{ "content":"you know, for search" }
id 为 2 的文档出现在 1 的前面
- 两个文档的 IDF 都是 log(4/2);
- id 为 1 的文档的 TF 是 1/7;id 为 2 的文档的 TF 是 1/3;所以 id 为 2 的文档的 TF-IDF 比 1 的高,所以排在了前面;
POST /testscore/_search
{
"query": {
"match": {
"content": "elasticsearch"
}
}
}
通过 explain 查看 ES 对相关性算分中每个参数的计算结果
POST /testscore/_search
{
"explain": true,
"query": {
"match": {
"content": "elasticsearch"
}
}
}
Boosting Relevance
- Boosting 是控制相关度的一种手段,在索引、字段或子查询中都可以设置 Boosting 的值;
参数 boost 的含义
- 当 boost > 1 时,打分的相关度相对提升;
- 当 0 < boost < 1 时,打分的权重相对性降低;
- 当 boost > 0 时,贡献负分;
举个栗子
POST testscore/_search
{
"query": {
"boosting" : {
"positive" : {
"term" : {
"content" : "elasticsearch"
}
},
"negative" : {
"term" : {
"content" : "like"
}
},
"negative_boost" : 0.2
}
}
}