热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ElasticSearch学习笔记(五)相关性

2019独角兽企业重金招聘Python工程师标准Elasticsearch的相似度算法被定义为检索词频率反向文档频率,TFIDF,包括以下内容&#

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

Elasticsearch 的相似度算法 被定义为检索词频率/反向文档频率, TF/IDF ,包括以下内容:

  • 检索词频率

    检索词在该字段出现的频率?出现频率越高,相关性也越高。 字段中出现过 5 次要比只出现过 1 次的相关性高。

  • 反向文档频率

    每个检索词在索引中出现的频率?频率越高,相关性越低。检索词出现在多数文档中会比出现在少数文档中的权重更低。

  • 字段长度准则

    字段的长度是多少?长度越长,相关性越低。 检索词出现在一个短的 title 要比同样的词出现在一个长的 content 字段权重更大。

++词频率和 文档频率是在每个分片中计算出来的,而不是每个索引中++。 可以在查询中将explain设为true,可以得到详细的评分过程。此操作是十分昂贵的,它只能用作调试工具 。千万不要用于生产环境。

GET /employee/doc/_search?format=yaml
{"explain": true,...
}

Elasticsearch 中的 ==Doc Values== 常被应用到以下场景:

  • 对一个字段进行排序
  • 对一个字段进行聚合
  • 某些过滤,比如地理位置过滤
  • 某些与字段相关的脚本计算

排序发生在索引时建立的平行数据结构中。

组合查询对相关性影响

在一个查询中使用组合查询(如bool),它除了决定一个文档是否应该被包括在结果中,还会计算文档的相关程度。

GET /my_index/my_type/_search
{"query": {"bool": {"must": { "match": { "title": "quick" }},"must_not": { "match": { "title": "lazy" }},"should": [{ "match": { "title": "brown" }},{ "match": { "title": "dog" }}]}}
}

两个should语句,一个文档不必包含 brown 或 dog这两个词项,但如果一旦包含,我们就认为它们更相关。

bool 查询会为每个文档计算相关度评分 _score , 再将所有匹配的 must 和 should 语句的分数 _score 求和,最后除以 must 和 should 语句的总数。

must_not 语句不会影响评分; 它的作用只是将不相关的文档排除。

所有 must 语句必须匹配,所有 must_not 语句都必须不匹配,但有多少 should 语句应该匹配呢? 默认情况下,没有 should 语句是必须匹配的,只有一个例外:那就是当没有 must 语句的时候,至少有一个 should 语句必须匹配。

通过指定 boost 来控制任何查询语句的相对的权重, boost 的默认值为 1 ,大于 1 会提升一个语句的相对权重。

可以通过指定 boost 来控制任何查询语句的相对的权重, boost 的默认值为 1 ,大于 1 会提升一个语句的相对权重。但是这种提升或降低并不是线性的,换句话说,如果一个 boost 值为 2 ,并不能获得两倍的评分 _score 。

boost 值比较合理的区间处于 1 到 10 之间,当然也有可能是 15 。如果为 boost 指定比这更高的值,将不会对最终的评分结果产生更大影响,因为评分是被 归一化的(normalized) 。

GET /_search
{"query": {"bool": {"must": {"match": { "content": {"query": "full text search","operator": "and"}}},"should": [{ "match": {"content": {"query": "Elasticsearch","boost": 3 }}},{ "match": {"content": {"query": "Lucene","boost": 2 }}}]}}
}

不同层级对评分的影响

GET /_search
{"query": {"bool": {"should": [{ "match": { "title": "War and Peace" }},{ "match": { "author": "Leo Tolstoy" }},{ "bool": {"should": [{ "match": { "translator": "Constance Garnett" }},{ "match": { "translator": "Louise Maude" }}]}}]}}
}

bool 查询运行每个 match 查询,再把评分加在一起,然后将结果与所有匹配的语句数量相乘,最后除以所有的语句数量。处于同一层的每条语句具有相同的权重。在前面这个例子中,包含 translator 语句的 bool 查询,只占总评分的三分之一。如果将 translator 语句与 title 和 author 两条语句放入同一层,那么 title 和 author 语句只贡献四分之一评分。

dis_max查询

分离最大化查询(Disjunction Max Query)指的是: 将任何与任一查询匹配的文档作为结果返回,但只将最佳匹配的评分作为查询的评分结果返回。

tie_breaker参数

{"query": {"dis_max": {"queries": [{ "match": { "title": "Quick pets" }},{ "match": { "body": "Quick pets" }}],"tie_breaker": 0.3}}
}

tie_breaker 参数提供了一种 dis_max 和 bool 之间的折中选择,它的评分方式如下:

  1. 获得最佳匹配语句的评分 _score 。
  2. 将其他匹配语句的评分结果与 tie_breaker 相乘。
  3. 对以上评分求和并规范化。

tie_breaker 可以是 0 到 1 之间的浮点数,其中 0 代表使用 dis_max 最佳匹配语句的普通逻辑, 1 表示所有匹配语句同等重要。最佳的精确值需要根据数据与查询调试得出,但是合理值应该与零接近(处于 0.1 - 0.4 之间),这样就不会颠覆 dis_max 最佳匹配性质的根本。

提升单个字段的权重

可以使用 ^ 字符语法为单个字段提升权重,在字段名称的末尾添加 ^boost , 其中 boost 是一个浮点数

{"multi_match": {"query": "Quick brown fox","fields": [ "*_title", "chapter_title^2" ] }
}

chapter_title 这个字段的 boost 值为 2 ,而其他两个字段 book_title 和 section_title 字段的默认 boost 值为 1 。


转:https://my.oschina.net/xiaominmin/blog/1666072



推荐阅读
author-avatar
KNN
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有