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

2023-12-07 00:39

本文主要是介绍[Elasticsearch] 控制相关度 (一) - 相关度分值计算背后的理论,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

控制相关度(Controlling Relevance)

对于仅处理结构化数据(比如日期,数值和字符枚举值)的数据库,它们只需要检查一份文档(在关系数据库中是一行)是否匹配查询即可。

尽管布尔类型的YES|NO匹配也是全文搜索的一个必要组成,它们本身是不够的。我们还需要知道每份文档和查询之间的相关程度。全文搜索引擎不仅要找到匹配的文档,还需要根据相关度对它们进行排序。

全文搜索相关度的公式,或者被称为相似度算法,将多个因素综合起来为没份文档产生一个相关度_score。在本章中,我们来讨论一下其中的一些变化的部分以及如何控制它们。

当然相关度并不只和全文查询相关;它也许会将结构化数据考虑在内。我们可能在寻找一个拥有某些卖点(空调,海景,免费的WiFi)的度假旅店。那么当某个度假旅店拥有的卖点越多,那么它也就越相关。或者我们希望除全文搜索本身的相关度外,同时将时间的远近,价格,流行度或者距离这类因素也考虑在内。

以上这些设想都是可以实现的,得益于ES中强大的分值计算功能。

我们首先会从理论角度来看看Lucene是如何计算相关度的,然后从实际的例子出发来讨论一下如何来控制该过程。


相关度分值计算背后的理论

Lucene(也就是ES)使用了布尔模型(Boolean Model)来寻找匹配的文档,以及一个被称为Prarical Scoring Function的公式来计算相关度。该公式借用了词条频度/倒排文档频度以及向量空间模型的概念,同时也增加了一些更现代的特性比如Coordination Factor,字段长度归约,以及词条/查询子句提升。

NOTE

不要害怕!这些概念并不像它们的名字那般复杂。尽管在这一节中提到了算法,公式以及数学模型,它们的作用也只不过是方便人类理解。理解算法本身并不比理解它们对结果的影响更重要。

布尔模型(Boolean Model)

布尔模型简单地应用查询中的AND,OR以及NOT条件来寻找所有匹配的文档。下面的查询:

full AND text AND search AND (elasticsearch OR lucene)

会只包括含有所有full,text,search词条,以及词条elasticsearch或者lucene之一的文档。

这个过程是简单且迅速的。它用来排除那些不会匹配查询的文档。

词条频度/倒排文档频度(TF/IDF)

一旦我们拥有了匹配文档的列表,我们就需要对它们进行相关度排序。并不是所有的文档都会包含所有的词条,而一部分词条也比另一部分的词条更加重要。整个文档的相关度分值取决于(部分)出现在文档中的每个查询词条的权重。

一个词条的权重通过三个因素决定,这在什么是相关度中已经介绍过了。对该公式的介绍是为了兴趣,你不需要记住它们。

词条频度(Term Frequency)

词条在当前文档中出现的有多频繁?越频繁的话,那么权重就越高。在一个字段中出现了5次的词条应该比只出现了1次的文档更加相关。词条频度通过下面的公式进行计算:

tf(t in d) = √frequency

词条t在文档d中的词条频度tf,是该词条在文档中出现次数的平方根。

如果你不在乎一个词条在一个字段中的出现频度,相反你在意的是词条是否出现过,那么你可以在字段映射中禁用词条频度:

PUT /my_index
{"mappings": {"doc": {"properties": {"text": {"type":          "string","index_options": "docs" }}}}
}

将index_options设置为docs会禁用词条频度以及词条位置信息。使用了该设置的字段不会记录词条出现的次数,也不能被用在短语或者邻近度查询中。精确值的not_analyzed字符串字段默认使用该设置。

倒排文档频度(Inverse Document Frequency)

词条在所有的文档中出现的频繁吗?出现的越频繁,权重就越低。像and或者the这样的常见词条对相关度的贡献几乎没有,因为它们在绝大多数的文档中都会出现,而像elastic或者hippopotamus这样的罕见词条则能够帮助找到我们最感兴趣的文档。倒排文档频度的计算方法如下:

idf(t) = 1 + log ( numDocs / (docFreq + 1))

对于词条t的倒排文档频度(idf),通过将索引中的文档数量除以含有该词条的文档数量,再取其对数得到。

字段长度归约(Field-length Norm)

字段的有多长?字段越短,那么其权重就越高。如果一个词条出现在较短的字段,如title字段中,那么该字段的内容相比更长的body字段而言,更有可能是关于该词条的。字段长度归约的计算方法如下:

norm(d) = 1 / √numTerms

尽管字段长度归约对于全文搜索而言是重要的,也有许多其它字段不需要。无论文档是否含有该字段,对于索引中每份文档的每个字符串字段,归约大概需消耗1个字节的空间。对于精确值的not_analyzed字符串字段,归约功能默认是被禁用的,但是你也可以对analyzed类型的字段通过字段映射禁用归约:

PUT /my_index
{"mappings": {"doc": {"properties": {"text": {"type": "string","norms": { "enabled": false } }}}}
}

在以上的例子中,该字段不会将字段长度归约考虑在内。这就意味着字段的长度不再被相关度计算考虑在内。

对于日志记录这种用例,归约是没有多大用处的。你在意的只是某个特定错误代码或者某个浏览器标识码是否出现在了某个字段中。字段的长度不会对结果造成影响。禁用归约功能也可以省下相当的内存空间。

结合起来

以上的三个因素 - 词条频度,倒排文档频度以及字段长度规范 - 都是在索引期间被计算和保存的。它们被用来计算单个词条对于某一份文档的权重。

TIP

我们前面讨论的文档,实际上是在讨论文档中的字段。每个字段都有它自己的倒排索引,因此对于TF/IDF而言,字段的值和文档的值是等效的。

当我们将explain设置为true(参考理解分值(Understanding the Score)),然后再运行简单的term查询时,你会发现参与到分值计算过程中的因素就是我们前面讨论的那些:

PUT /my_index/doc/1
{ "text" : "quick brown fox" }GET /my_index/doc/_search?explain
{"query": {"term": {"text": "fox"}}
}

前面的请求得到的解释(有省略)如下所示:

weight(text:fox in 0) [PerFieldSimilarity]: 0.15342641 result of: fieldWeight in 0 0.15342641 product of: tf(freq=1.0), with freq of 1: 1.0 idf(docFreq=1, maxDocs=1): 0.30685282 fieldNorm(doc=0): 0.5

第一行:对于Lucene内部文档ID为0的文档,词条fox在其text字段中的最终分值。 第五行 - 第七行:词条频度,倒排文档频度以及字段长度归约得到的结果。

当然,查询通常都会由不止一个词条组成,因此我们需要一种将多个词条的权重联系起来的方法。为此我们可以求助向量空间模型(Vector Space Model)。

向量空间模型

向量空间模型提供了一种多词条查询的比较方法。它的输出是一个代表了文档和查询之间匹配程度的分值。为了计算该分值,文档和查询都被表示成向量。

一个向量实际上就是一个包含了数值的一维数组,比如:

[1,2,5,22,3,8]

在向量空间模型中,向量中的每个数值都是由TF/IDF计算得到的一个词条的权重。

TIP

尽管TF/IDF是在向量空间模型中默认被用来计算词条权重的方法,它并不是唯一可用的方法。在ES中,其它诸如Okapi-BM25的计算模型也是可用的。TF/IDF由于其简洁性,高效性,产生的搜索结果的高质量而经受了时间的考验,从而被当做是默认方法。

假设我们查询了"happy hippopotamus"。一个像happy这样的常见单词的权重是较低的,然而像hippopotamus这样的罕见单词则拥有较高的权重。假设happy的权重为2而hippopotamus的权重为5。我们可以使用坐标来表达这个简单的二维向量 - [2, 5] - 一条从坐标(0, 0)到坐标(2, 5)的直线,如下所示:

现在,假设我们有三份文档:

  1. I am happy in summer.
  2. After Christmas I’m a hippopotamus.
  3. The happy hippopotamus helped Harry.

我们可以为每份文档创建一个类似的向量,它由每个查询词条的权重组成 - 也就是出现在文档中的词条happy和hippopotamus,然后将它绘制在坐标中,如下图:

  • 文档1:(happy,____________) — [2,0]
  • 文档2:( ___ ,hippopotamus) — [0,5]
  • 文档3:(happy,hippopotamus) — [2,5]

向量的一个很棒的性质是它们能够被比较。通过测量查询向量和文档向量间的角度,我们可以给每份文档计算一个相关度分值。文档1和查询之间的角度较大,因此它的相关度较低。文档2和查询更靠近,所以它的相关度更高,而文档3和查询之间则是一个完美的匹配。

TIP

实际上,只有二维向量(使用两个词条的查询)才能够被简单地表示在坐标中。幸运的是,线性代数 - 数学的一个分支,能够处理向量 - 提供了用来比较多维向量间角度的工具,这意味着我们能够使用上述原理对包含很多词条的查询进行处理。

你可以获得关于使用余弦相似性来比较两个向量的更多信息:http://en.wikipedia.org/wiki/Cosine_similarity

我们已经讨论了分值计算的理论基础,现在让我们看看Lucene是如何进行分值计算的。

这篇关于[Elasticsearch] 控制相关度 (一) - 相关度分值计算背后的理论的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/463929

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题是由安全生产模拟考试一点通提供,流动式起重机司机证模拟考试题库是根据流动式起重机司机最新版教材,流动式起重机司机大纲整理而成(含2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题参考答案和部分工种参考解析),掌握本资料和学校方法,考试容易。流动式起重机司机考试技

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

XTU 1237 计算几何

题面: Magic Triangle Problem Description: Huangriq is a respectful acmer in ACM team of XTU because he brought the best place in regional contest in history of XTU. Huangriq works in a big compa

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

控制反转 的种类

之前对控制反转的定义和解释都不是很清晰。最近翻书发现在《Pro Spring 5》(免费电子版在文章最后)有一段非常不错的解释。记录一下,有道翻译贴出来方便查看。如有请直接跳过中文,看后面的原文。 控制反转的类型 控制反转的类型您可能想知道为什么有两种类型的IoC,以及为什么这些类型被进一步划分为不同的实现。这个问题似乎没有明确的答案;当然,不同的类型提供了一定程度的灵活性,但