ES相关性计算原理

了解es搜索过程中的相关性计算原理,对判断当前应用场景是否适合使用es来召回相关结果至关重要。本篇博文尝试对es在每一个节点执行搜索时如何计算query和经由倒排索引查询到的对应字段文本之间的相关性做简要说明。

ES搜索过程(节点层面)

ES的搜索过程具体到每一个节点可以简单地描述为三个步骤:

分词
计算相关性
查询解析
按分词结果执行term查询
按相关性排序,返回优先队列顺序长度的结果

当我们在ES中使用关键字搜索文档时,会得到由from+size指定的窗口大小多个文档,这些文档按照max_score的大小从高到低排列。毫无疑问,max_score衡量了查询结果和关键字之间的相似度或者说相关度大小,那么你是否好奇过它是如何计算出来的,本篇博文就来谈谈max_score的计算过程。

max_score如何计算

tf-idf公式

自然语言处理有一个计算文档权重的tf-idf公式(tf*idf),max_score的计算,也主要使用该公式。其中TF词频(Term Frequency)指的是词条t在文档中出现的频率IDF逆向文件频率(Inverse Document Frequency)指的是包含词条t的文档总数/全部文档总数的倒数取对数(逆向的意思就是取倒数,即全部文档总数/包含词条t的文档总数)。

tf不难理解,同一个文档中出现频率越高的词重要程度越高,idf是为了排除同时在多个文档出现的高频词,比如定冠词the、a的在同一个文档中词频很高,且在多个文档中出现,但是并没有什么实际意义,因而取倒数作为一种重要性上的惩罚

tf-idf公式的核心思想是:如果某个词条在一篇文章中出现的频率TF很高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

max_score计算公式

max_score计算公式如下,max_score = b o o s t ∗ t f ∗ i d f =boost * tf * idf =boosttfidf,其中tfidf的计算稍有不同,下文有详细说明,boost可以手动指定,用来控制查询词条的权重。

参数含义取值示例
boost词条权重2.2(基础值)* 当前字段查询权重(默认为1,可以手动指定)
tf词频0.66753393
idf逆文档频率6.2964954
max_score得分 9.246874 = 2.2 × 1 × 0.66753393 × 6.2964954 9.246874 = 2.2\times1 \times 0.66753393\times6.2964954 9.246874=2.2×1×0.66753393×6.2964954

在search时,通过指定参数explain=true,即可在返回的_explanation字段内看到max_score的计算过程和中间结果:

GET /test_index/_search?explain=true
{"query": {"match": {"test_field": "测试用query"}        }
}

上述示例查询结果如下:

{... # 省略其他字段"_explanation" : {"value" : 9.246874,"description" : "sum of:","details" : [{"value" : 9.246874,"description" : "weight(test_field:升级 in 398) [PerFieldSimilarity], result of:","details" : [{"value" : 9.246874,"description" : "score(freq=1.0), product of:","details" : [{"value" : 2.2,"description" : "boost","details" : [ ]},{"value" : 6.2964954,"description" : "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:","details" : [{"value" : 1,"description" : "n, number of documents containing term","details" : [ ]},{"value" : 813,"description" : "N, total number of documents with field","details" : [ ]}]},{"value" : 0.66753393,"description" : "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:","details" : [{"value" : 1.0,"description" : "freq, occurrences of term within document","details" : [ ]},{"value" : 1.2,"description" : "k1, term saturation parameter","details" : [ ]},{"value" : 0.75,"description" : "b, length normalization parameter","details" : [ ]},{"value" : 2.0,"description" : "dl, length of field","details" : [ ]},{"value" : 9.088561,"description" : "avgdl, average length of field","details" : [ ]}]}]}]}]}
}

下面我们来仔细研究一下这里面的每一项。

计算tf

tf(Term Frequency,词频):搜索文本分词后各个词条(term)在被查询文档的相应字段中出现的频率,频率越大,相关性越高,得分就越高。

{"value" : 0.66753393,"description" : "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:","details" : [{"value" : 1.0,"description" : "freq, occurrences of term within document","details" : [ ]},{"value" : 1.2,"description" : "k1, term saturation parameter","details" : [ ]},{"value" : 0.75,"description" : "b, length normalization parameter","details" : [ ]},{"value" : 2.0,"description" : "dl, length of field","details" : [ ]},{"value" : 9.088561,"description" : "avgdl, average length of field","details" : [ ]}]
}

t f = f r e q f r e q + k 1 × ( 1 − b ) + b × d l a v g d l tf=\frac{freq}{freq+k1\times(1-b)+b\times \frac{dl}{avgdl}} tf=freq+k1×(1b)+b×avgdldlfreq

参数含义示例取值
freq文档中词条出现的次数1.0
k1词条饱和参数1.2(默认值)
b长度规格化参数(平衡词条长度对于整个文档的影响程度)0.75(默认值)
dl搜索的关键词在当前文档中的分解字段长度2.0
avgdl查询出来的所有文档被字段分解长度总和/查询文档总数9.088561

可以理解为自然语言处理中的tf做了一定程度的正则化

计算idf

idf(Inverse Document Frequency,逆文档频率):搜索文本中分词后各个词条(term)在整个索引的所有文档中出现的频率倒数,频率越大,频率倒数越小,相关性越低,得分就越低。

{"value" : 6.2964954,"description" : "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:","details" : [{"value" : 1,"description" : "n, number of documents containing term","details" : [ ]},{"value" : 813,"description" : "N, total number of documents with field","details" : [ ]}]
}

i d f = l o g ( 1 + ( N − n + 0.5 ) n + 0.5 ) idf=log(\frac{1+(N-n+0.5)}{n+0.5}) idf=log(n+0.51+(Nn+0.5))

参数含义示例取值
n包含查询词条的文档总数1
N包含查询字段的文档总数813

同样也可以理解为自然语言处理中的idf做了一定程度的正则化

boost查询权重

boost在同一个字段匹配多个词条时才有实际意义,它用来控制每个词条的计算相关度的权重。

示例查询:

GET /test_index/_search?explain=true{"query": {"bool": {"should": [{"match": {"test_field": {"query": "xxx","boost": 1}}},{"match": {"test_field": {"query": "yyy","boost": 2}}},{"match": {"test_field": {"query": "zzz","boost": 3}}}]}}
}

在上面的搜索计算相关度时,文档命中词条xxx时指定boost=1计算max_score,命中命中词条yyy时指定boost=2计算max_score,命中词条zzz时指定boost=3计算max_score

参考文献

  1. ES系列–打分机制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/6759.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024.4.27 —— LeetCode 高频题复盘

目录 102. 二叉树的层序遍历33. 搜索旋转排序数组121. 买卖股票的最佳时机200. 岛屿数量20. 有效的括号88. 合并两个有序数组141. 环形链表46. 全排列236. 二叉树的最近公共祖先 102. 二叉树的层序遍历 题目链接 Python 方法一 # Definition for a binary tree node. # clas…

深入浅出区块链技术:原理、应用与挑战

区块链技术是一种分布式数据库技术,其核心在于提供一个去中心化、不可篡改的数据记录系统。以下是区块链技术的原理、应用和面临的挑战的详细解析: ### 原理 1. **去中心化**:区块链技术不依赖于中央控制点,而是通过网络上的多个…

菜鸡学习netty源码(五)—— EventLoop

1.EventLoop的类关系图 2. EventExecutor /*** 返回自身的对象* Returns a reference to itself.*/OverrideEventExecutor next();/*** 获取所属的EventExecutorGroup* Return the {link EventExecutorGroup} which is the parent of this {link EventExecutor},*/EventExecuto…

利用大语言模型(KIMI)构建智能产品的信息模型

数字化的核心是数字化建模,为一个事物构建数字模型是一件非常繁杂和耗费人工的事情。利用大语言模型,能够轻松地生成设备的信息模型,我们的初步实验表明,只要提供足够的模板,就能够准确地生成设备的数字化模型。 我们尝…

Pytorch 实现 GAN 对抗网络

GAN 对抗网络 GAN(Generative Adversarial Network)对抗网络指的是神经网络中包括两个子网络,一个用于生成信息,一个用于验证信息。下面的例子是生成图片的对抗网络,一个网络用于生成图片,另一个网络用于验…

debootstrap构建基于Debian的嵌入式系统的rootfs

嵌入式芯片:iMX6ULL 准备环境: 确保您的开发机器已安装debootstrap和qemu-user-static(如果您在非ARM机器上构建ARM rootfs)。 sudo apt-get updatesudo apt-get install debootstrap qemu-user-static使用debootstrap创建rootf…

[C++基础学习-06]----C++指针详解

前言 指针是一个存储变量地址的变量,可以用来访问内存中的数据。在C中,指针是一种非常有用的数据类型,可以帮助我们在程序中对内存进行操作和管理。 正文 01-指针简介 指针的基本概念如下: 声明指针:使用“*”符…

Python零基础快速入门学习笔记

文章目录 1. 安装python2. 安装vscode3. python语法3.1 流程控制3.1.1 条件语句3.1.2 循环语句 3.2 模块与包3.2.1 模块3.2.2 包 3.3 数据类型3.3.1 数字(Number)3.3.2 字符串(string)3.3.3 列表(list)3.3.…

[单片机课设]十字路口交通灯的设计

题目要求: 模拟交通灯运行情况。南北绿灯亮30秒,南北黄灯亮3秒,东西红灯亮33秒;南北红灯亮33秒,东西绿灯亮30秒,东西黄灯亮3秒;要求数码管同步显示时间的倒计时,用定时器实现延时。…

(HAL)STM32F103C8T6——内部flash模拟EEPROM

内部Flash大部分空间是用来存储烧录进单片机的程序代码,因此可以将非代码等无关区域用来存储数据。项目工程的代码量可以通过Keil uVision5软件底下框查看,如下图所示。一般只需参考代码量(Code)以及只读数据(RO-data&…

某盾BLACKBOX逆向关键点

需要准备的东西: 1、原JS码 2、AST解混淆码 3、token(来源于JSON) 一、原JS码很好获取,每次页面刷新,混淆的代码都会变,这是正常,以下为部分代码 while (Qooo0) {switch (Qooo0) {case 110 14 - 55: {function O0…

C++入门第二节--关键字、命名空间、输入输出

点赞关注不迷路!本节涉及c入门关键字、命名空间、输入输出... 1. C关键字 C总计63个关键字,C语言32个关键字 asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseen…

1.预备知识

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 预备知识 一、C语言和C的发展历史和基本原理二、过程性编程和面向对象编程三、编程语言的标准 提示:以下是本篇文章正文内容,下面案例可供参考 一、C…

A Dexterous Hand-Arm Teleoperation System

A Dexterous Hand-Arm Teleoperation System Based on Hand Pose Estimation and Active Vision解读 摘要1. 简介2.相关工作2.1 机器人遥操作2.2 主动视觉(Active Vision) 3. 硬件设置4. 基于视觉的机器人手部姿态估计4.1 Transteleop4.2 Dataset 5. 主动…

升级OpenSSH版本(安装telnet远程管理主机)

一 OpenSSH是什么 OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。SSH协议族可以用来进行远程控制, 或在计算机之间传送文件。而实现此功能的传统方式,如telnet(终端仿真协议)、 rcp ftp、 rlogin、 rsh都是极为不安全的&…

C++奇迹之旅:string类接口详解(上)

文章目录 📝为什么学习string类?🌉 C语言中的字符串🌉string考察 🌠标准库中的string类🌉string类的常用接口说明🌠string类对象的常见构造 🚩总结 📝为什么学习string类…

二维泊松方程(Neumann+Direchliet边界条件)有限元Matlab编程求解|程序源码+说明文本

专栏导读 作者简介:工学博士,高级工程师,专注于工业软件算法研究本文已收录于专栏:《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现,并提供所有案例完整源码;2.单元…

stm32开发之netxduo网口通讯,网线热插拔处理

前言 在使用netxduo组件时,如果在上电过程中,未插入网线,eth驱动使能过程中未正常初始化本次使用以下几种方式进行设置 问题原因 使用定时器事件回调方式 网络组件中进行调整 /** Copyright (c) 2024-2024,shchl** SPDX-Licen…

Initialize failed: invalid dom.

项目场景: 在vue中使用Echarts出现的错误 问题描述 提示:这里描述项目中遇到的问题: 例如:在vue中使用Echarts出现的错误 ERROR Initialize failed: invalid dom.at Module.init (webpack-internal:///./node_modules/echarts…

Delta lake with Java--入门

最近在研究数据湖,虽然不知道研究成果是否可以用于工作,但我相信机会总是留给有准备的人。 数据湖尤其是最近提出的湖仓一体化概念,很少有相关的资料,目前开源的项目就三个,分别是hudi, delta lake, iceberg。最终选择…