[Elasticsearch] 控制相关度 (四) - 忽略TF/IDF

本章翻译自Elasticsearch官方指南的Controlling Relevance一章。

忽略TF/IDF

有时我们不需要TF/IDF。我们想知道的只是一个特定的单词是否出现在了字段中。比如我们正在搜索度假酒店,希望它拥有的卖点越多越好:

  • WiFi
  • 花园(Garden)
  • 泳池(Pool)

而关于度假酒店的文档类似下面这样:

{ "description": "A delightful four-bedroomed house with ... " }

可以使用一个简单的match查询:

GET /_search
{
  "query": {
    "match": {
      "description": "wifi garden pool"
    }
  }
}

然而,我们需要的并不是真正的全文搜索。此时TF/IDF只会碍手碍脚。我们不在意wifi是否是一个常见的词条,也不在意它在文档中出现的是否频繁。我们在意的只是它是否出现了。实际上,我们只是想通过卖点来对这些度假酒店进行排序 - 越多越好。如果拥有一个卖点,那么它的分值就是1,如果没有它的分值就是0。

constant_score查询

首先介绍constant_score查询。该查询能够包含一个查询或者一个过滤器,所有匹配文档的相关度分值都为1,不考虑TF/IDF:

GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "constant_score": {
          "query": { "match": { "description": "wifi" }}
        }},
        { "constant_score": {
          "query": { "match": { "description": "garden" }}
        }},
        { "constant_score": {
          "query": { "match": { "description": "pool" }}
        }}
      ]
    }
  }
}

大概并不是所有的卖点都同等重要 - 其中的某些更有价值。如果最看中的卖点是泳池,那么我们可以对它进行相应提升:

GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "constant_score": {
          "query": { "match": { "description": "wifi" }}
        }},
        { "constant_score": {
          "query": { "match": { "description": "garden" }}
        }},
        { "constant_score": {
          "boost":   2
          "query": { "match": { "description": "pool" }}
        }}
      ]
    }
  }
}

NOTE

每个结果的最终分值并不是将所有匹配子句的分值累加而得到。Coordination因子查询归约因子(Query Normalization Factor)仍然会被考虑在内。

我们可以在度假酒店的文档中添加一个not_analyzed类型的features字段:

{ "features": [ "wifi", "pool", "garden" ] }

默认情况下,一个not_analyzed字段的字段长度归约(Field-length Norm)是被禁用的,同时其index_options也会被设置为docs,从而禁用词条频度(Term Frequencies),但是问题还是存在:每个词条的倒排文档频度(Inverse Document Frequency)仍然会被考虑。

仍然使用constant_score查询:

GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "constant_score": {
          "query": { "match": { "features": "wifi" }}
        }},
        { "constant_score": {
          "query": { "match": { "features": "garden" }}
        }},
        { "constant_score": {
          "boost":   2
          "query": { "match": { "features": "pool" }}
        }}
      ]
    }
  }
}

实际上,每个卖点都应该被视为一个过滤器。度假酒店要么有该卖点,要么没有 - 使用过滤器似乎是更自然的选择。并且如果我们使用了过滤器,还可以得益于过滤器缓存这一功能。

不使用过滤器的根源在于:过滤器不会计算相关度分值。我们需要的是一座用来连接过滤器和查询的桥梁。而function_score查询就能够做到这一点,并且它也提供了更多的功能。

时间: 2024-12-25 14:29:15

[Elasticsearch] 控制相关度 (四) - 忽略TF/IDF的相关文章

[Elasticsearch] 控制相关度 (二) - Lucene中的PSF(Practical Scoring Function)与查询期间提升

本章翻译自Elasticsearch官方指南的Controlling Relevance一章. Lucene中的Practical Scoring Function 对于多词条查询(Multiterm Queries),Lucene使用的是布尔模型(Boolean Model),TF/IDF以及向量空间模型(Vector Space Model)来将它们结合在一起,用来收集匹配的文档和对它们进行分值计算. 像下面这样的多词条查询: GET /my_index/doc/_search { "que

[Elasticsearch] 控制相关度 (一) - 相关度分值计算背后的理论

本章翻译自Elasticsearch官方指南的Controlling Relevance一章. 控制相关度(Controlling Relevance) 对于仅处理结构化数据(比如日期,数值和字符枚举值)的数据库,它们只需要检查一份文档(在关系数据库中是一行)是否匹配查询即可. 尽管布尔类型的YES|NO匹配也是全文搜索的一个必要组成,它们本身是不够的.我们还需要知道每份文档和查询之间的相关程度.全文搜索引擎不仅要找到匹配的文档,还需要根据相关度对它们进行排序. 全文搜索相关度的公式,或者被称为

[Elasticsearch] 控制相关度 (五) - function_score查询及field_value_factor,boost_mode,max_mode参数

本章翻译自Elasticsearch官方指南的Controlling Relevance一章. function_score查询 function_score查询是处理分值计算过程的终极工具.它让你能够对所有匹配了主查询的每份文档调用一个函数来调整甚至是完全替换原来的_score. 实际上,你可以通过设置过滤器来将查询得到的结果分成若干个子集,然后对每个子集使用不同的函数.这样你就能够同时得益于:高效的分值计算以及可缓存的过滤器. 它拥有几种预先定义好了的函数: weight 对每份文档适用一个

[Elasticsearch] 控制相关度 (三) - 通过查询结构调整相关度以及boosting查询

本章翻译自Elasticsearch官方指南的Controlling Relevance一章. 通过查询结构调整相关度 ES提供的查询DSL是相当灵活的.你可以通过将单独的查询子句在查询层次中上下移动来让它更重要/更不重要.比如,下面的查询: quick OR brown OR red OR fox 我们可以使用一个bool查询,对所有词条一视同仁: GET /_search { "query": { "bool": { "should": [

[Elasticsearch] 控制相关度 (六) - function_score查询中的filter,functions及random_score参数

本章翻译自Elasticsearch官方指南的Looking at Time一章. 时间数据处理(Looking at Time) 如果在ES中,搜索是最常见的行为,那么创建日期柱状图(Date Histogram)肯定是第二常见的.为什么要使用日期柱状图呢? 想象在你的数据中有一个时间戳.数据是什么不重要-Apache日志事件,股票交易日期,棒球比赛时间-任何拥有时间戳的数据都能通过日期柱状图受益.当你有时间戳时,你经常会想创建基于时间的指标信息: 今年的每个月销售了多少辆车? 过去的12小时

Elasticsearch学习之相关度评分TF&IDF

relevance score算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度 Elasticsearch使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法 Term frequency(TF):搜索文本中的各个词条在field文本中出现了多少次,出现次数越多,就越相关 Inverse document frequency(IDF):搜索文本中的各个词条在整个索引的所有文档中出现了多少次,出现的

[Elasticsearch] 全文搜索 (四) - 控制分析及相关度

控制分析(Controlling Analysis) 查询只能摘到真实存在于倒排索引(Inverted Index)中的词条(Term),因此确保相同的分析过程会被适用于文档的索引阶段和搜索阶段的查询字符串是很重要的,这样才能够让查询中的词条能够和倒排索引中的词条匹配. 尽管我们说的是文档(Document),解析器(Analyzer)是因字段而异的(Determined per Field).每个字段都能够拥有一个不同的解析器,通过为该字段配置一个特定的解析器或者通过依赖类型(Type),索引

55.TF/IDF算法

主要知识点: TF/IDF算法介绍 查看es计算_source的过程及各词条的分数 查看一个document是如何被匹配到的 一.算法介绍 relevance score算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度.Elasticsearch使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法 1.Term frequency 搜索文本中的各个词条在field文本中出现了多少次,出现次数越多,

tf–idf算法解释及其python代码实现(下)

tf–idf算法python代码实现 这是我写的一个tf-idf的核心部分的代码,没有完整实现,当然剩下的事情就非常简单了,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四句话,每句表示一个文档 copus=['我正在学习计算机','它正在吃饭','我的书还在你那儿','今天不上班'] 由于中文需要分词,jieba分词是python里面比较好用的分词工具,所以选用jieba分词,文末是jieba的链接.首先对文档进行分词: i