如何在 Elasticsearch 中选择精确 kNN 搜索和近似 kNN 搜索

作者:来自 Elastic Carlos Delgado

kNN 是什么?

语义搜索(semantic search)是相关性排名的强大工具。 它使你不仅可以使用关键字,还可以考虑文档和查询的实际含义。

语义搜索基于向量搜索(vector search)。 在向量搜索中,我们要搜索的文档具有为其计算的向量嵌入。 这些嵌入是使用机器学习模型计算的,并作为向量返回,与我们的文档数据一起存储。

执行查询时,将使用相同的机器学习模型来计算查询文本的嵌入。 语义搜索包括通过将查询嵌入与文档嵌入进行比较来查找最接近查询的结果。

kNN(或 k nearest neighbors - k 最近邻)是一种用于获取与特定嵌入最接近的前 k 个结果的技术。

使用嵌入计算查询的 kNN 有两种主要方法:精确和近似。 这篇文章将帮助你:

  • 了解什么是精确和近似 kNN 搜索
  • 如何为这些方法准备索引
  • 如何确定哪种方法最适合你的用例

精确 kNN:搜索所有内容

计算更接近结果的一种方法是将所有现有文档嵌入与查询的文档嵌入进行比较。 这将确保我们获得尽可能最接近的匹配,因为我们将比较所有匹配。 我们的搜索结果将尽可能准确,因为我们正在考虑整个文档语料库并将所有文档嵌入与查询嵌入进行比较。

当然,与所有文档进行比较有一个缺点:需要时间。 我们将使用相似度函数对所有文档逐一计算嵌入相似度。 这也意味着我们将线性扩展 —— 文档数量增加一倍可能需要两倍的时间。

可以使用 script_score 和用于计算向量之间相似度的向量函数在向量场上进行精确搜索。

近似 kNN:一个很好的估计

另一种方法是使用近似值而不是考虑所有文档。 为了提供 kNN 的有效近似,Elasticsearch 和 Lucene 使用分层导航小世界 HNSW (Hierachical Navigation Small Worlds)。

HNSW 是一种图数据结构,它维护不同层中靠近的元素之间的链接。 每层都包含相互连接的元素,并且还与其下方层的元素相连接。 每层包含更多元素,底层包含所有元素。

图 1 - HNSW 图示例。 顶层包含开始搜索的初始节点。 这些初始节点充当较低层的入口点,每个层包含更多节点。 下层包含所有节点。

可以把它想象成开车:有高速公路、道路和街道。在高速公路上行驶时,你会看到一些描述高层次区域(如城镇或社区)的出口标志。然后你会到达一条有具体街道指示的道路。一旦你到达某条街道,你就可以找到具体的地址,以及同一社区内的其他地址。

HNSW(Hierarchical Navigable Small World)结构类似于此,它创建了不同层次的向量嵌入。它计算离初始查询较近的 “高速公路”,选择看起来更有希望的出口,继续寻找更接近目标地址的地方。这在性能方面非常优秀,因为它不必考虑所有文档,而是使用这种多层次的方法快速找到接近目标的近似结果。

但是,这只是一个近似值。并不是所有节点都是互联的,这意味着可能会忽略某些更接近特定节点的结果,因为它们可能没有连接。节点的互联程度取决于 HNSW 结构的创建方式。

HNSW 的效果取决于多个因素:

  • 它是如何构建的。HNSW 的构建过程会考虑一定数量的候选节点,作为某一特定节点的近邻。增加考虑的候选节点数量会使结构更精确,但会在索引时花费更多时间。dense vector index_options 中的 ef_construction 参数用于此目的。

  • 搜索时考虑的候选节点数量。在寻找更近结果时,过程会跟踪一定数量的候选节点。这个数量越大,结果越精确,但搜索速度会变慢。kNN 参数中的 num_candidates 控制这种行为。

  • 我们搜索的分段数量。每个分段都有一个需要搜索的 HNSW 图,其结果需要与其他分段图的结果结合。分段越少,搜索的图就越少(因此速度更快),但结果集的多样性会减少(因此精度较低)。

总的来说,HNSW 在性能和召回率之间提供了良好的权衡,并允许在索引和查询两方面进行微调。

使用 HNSW 进行搜索可以在大多数情况下通过 kNN 搜索部分完成。对于更高级的用例,也可以使用 kNN 查询,例如:

  • 将 kNN 与其他查询结合(作为布尔查询或固定查询的一部分)
  • 使用 function_score 微调评分
  • 提高聚合和字段折叠(field collapse)的多样性

你可以在这篇文章中查看关于 kNN 查询及其与 kNN 搜索部分的区别。我们将在下面深入讨论何时使用这种方法与其他方法。

为精确和近似搜索建立索引

dense_vector 字段类型

对于存储嵌入,dense_vector 字段有两种主要的索引类型可供选择:

  1. flat 类型(包括 flat 和 int8_flat):存储原始向量,不添加 HNSW 数据结构。使用 flat 索引类型的 dense_vector 将始终使用精确的 kNN,kNN 查询将执行精确查询而不是近似查询。

  2. HNSW 类型(包括 hnsw 和 int8_hnsw):创建 HNSW 数据结构,允许使用近似 kNN 搜索。

这是否意味着你不能对 HNSW 字段类型使用精确的 kNN?并非如此!你可以通过 script_score 查询使用精确 kNN,也可以通过 kNN 部分和 kNN 查询使用近似 kNN。这样可以根据你的搜索用例提供更多的灵活性。

使用 HNSW 字段类型意味着需要构建 HNSW 图结构,这需要时间、内存和磁盘空间。如果你只会使用精确搜索,可以使用 flat 向量字段类型。这确保了你的嵌入索引是最佳的,并且占用更少的空间。

请记住,在任何情况下都应避免将嵌入存储在 _source 中,以减少存储需求。

量化

使用量化技术,无论是 flat(int8_flat)还是 HNSW(int8_hnsw)类型的索引,都可以帮助你减少嵌入的大小,从而使用更少的内存和磁盘存储来保存嵌入信息。

由于搜索性能依赖于尽可能多地将嵌入存储在内存中,因此你应该始终寻找减少数据的方法。使用量化是在内存和召回率之间进行权衡。

如何在精确搜索和近似搜索之间做出选择?

没有一种适用于所有情况的答案。你需要考虑多个因素,并进行实验,以找到性能和准确性之间的最佳平衡:

数据规模

不应该不惜一切代价避免搜索所有内容。根据你的数据规模(文档数量和嵌入维度),进行精确的 kNN 搜索可能是合理的。

作为一个经验法则,如果需要搜索的文档少于一万,可能表明应该使用精确搜索。请记住,可以提前过滤需要搜索的文档数量,因此通过应用过滤条件可以限制实际需要搜索的文档数量。

近似搜索在文档数量方面具有更好的扩展性,因此如果你有大量文档需要搜索,或者预计文档数量会显著增加,应该选择近似搜索。

图 2 - 使用 so_vector rally track 中 768 维向量进行精确和近似 kNN 的示例运行。该示例展示了精确 kNN 的线性运行时间与 HNSW 搜索的对数运行时间。

过滤 - filtering

过滤非常重要,因为它减少了需要考虑搜索的文档数量。在决定使用精确搜索还是近似搜索时,需要考虑这一点。可以使用 query filters 来减少需要考虑的文档数量,无论是精确搜索还是近似搜索。

然而,近似搜索在过滤时采用了不同的方法。在使用 HNSW 进行近似搜索时,查询过滤器将在检索到前 k 个结果后应用。这就是为什么与 kNN 查询一起使用查询过滤器被称为 kNN 的后过滤。

图 3 - kNN 搜索中的后过滤。

这种特定的 kNN 查询过滤器被称为 kNN 预过滤器,因为它在检索结果之前应用,而不是之后。因此,在使用 kNN 查询的上下文中,常规查询过滤器被称为后过滤器。

幸运的是,还有另一种与 kNN 一起使用的方法,即在 kNN 查询本身中指定过滤器。 当遍历 HNSW 图收集结果时,此过滤器适用于图元素,而不是事后应用。 这确保返回前 k 个元素,因为将遍历图 - 跳过未通过过滤器的元素 - 直到我们获得前 k 个元素。

即将推出的功能

即将推出的一些改进将有助于精确和近似 kNN。

Elasticsearch 将增加将 dense_vector 类型从 flat 升级到 HNSW 的功能。这意味着你可以先使用 flat 向量类型进行精确 kNN,当需要扩展时可以开始使用 HNSW。使用近似 kNN 时,你的段将透明地被搜索,并在合并时自动转换为 HNSW。

一个新的精确 kNN 查询将被添加,以便使用简单的查询来对 flat 和 HNSW 字段进行精确 kNN,而不是依赖于 script score 查询。这将使精确 kNN 更加简便。

结论

那么,你应该在文档上使用近似 kNN 还是精确 kNN 呢?请检查以下几点:

  • 文档数量:如果少于一万(应用过滤器后),可能适合使用精确搜索。
  • 你的搜索是否使用了过滤器:这会影响要搜索的文档数量。如果需要使用近似 kNN,请记住使用 kNN 预过滤器以获取更多结果,代价是性能下降。

你可以通过使用 HNSW dense_vector 进行索引,并将 kNN 搜索与 script_score 进行精确 kNN 的对比,来比较两种方法的性能。这允许在使用相同字段类型的情况下比较两种方法(如果决定使用精确搜索,请记住将 dense_vector 字段类型更改为 flat)。

祝你搜索愉快!

准备将 RAG 集成到你的应用中吗?想尝试在向量数据库中使用不同的 LLMs 吗? 查看我们在 Github 上的 LangChain、Cohere 等示例笔记本,并参加即将开始的 Elasticsearch 工程师培训吧!

原文:kNN in Elasticsearch: How to choose between exact and approximate kNN search — Elastic Search Labs

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

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

相关文章

大数据工具之HIVE-参数调优,调度乱码(二)

一、调度乱码 在利用HUE工具,搭建WORKFLOW流程的过程中,如果直接执行hivesql数据正常,不会出现乱码现象,如果利用WORKFLOW搭建的流程,进行数据的拉取,会出现数据中文乱码现象,这些乱码主要是由于select 中的硬编码中文导致出现的现象 具体现象如下: select case when …

TG5032CGN TCXO 超高稳定10pin端子型适用于汽车动力转向控制器

TG5032CGN TCXO / VC-TCXO是一款应用广泛的晶振,具有超高稳定性,CMOS输出和使用晶体基振的削波正弦波输出形式。且有低相位噪声优势,是温补晶体振荡器(TCXO)和压控晶体振荡器(VCXO)结合的产物,具有TCXO和VCXO的共同优点&#xff0…

微信小程序上线必备:SSL证书申请以及安装

一、认识ssl证书 1、ssl证书是什么? SSL证书,全称Secure Socket Layer Certificate,是一种数字证书,它遵循SSL(现在通常指TLS,Transport Layer Security)协议标准,用于在客户端&…

SpringCloud系列(26)--OpenFeign超时控制

前言:在上一章节中我们简单的介绍了如何使用OprnFeign去调用微服务,因为消费侧和服务侧是两个不同的微服务,这样可能会出现超时的现象,例如服务侧需要3秒处理任何才能返回结果,但消费侧可能2秒就断开连接了&#xff0c…

【深度学习】2.单层感知机

目标: 实现一个简单的二分类模型的训练过程,通过模拟数据集进行训练和优化,训练目标是使模型能够根据输入特征正确分类数据。 演示: 1.通过PyTorch生成了一个模拟的二分类数据集,包括特征矩阵data_x和对应的标签数据data_y。标签…

加密与安全_AES RSA 密钥对生成及PEM格式的代码实现

文章目录 RSA(非对称)和AES(对称)加密算法一、RSA(Rivest-Shamir-Adleman)二、AES(Advanced Encryption Standard) RSA加密三种填充模式一、RSA填充模式二、常见的RSA填充模式组合三…

新业务 新市场 | 灵途科技新品亮相马来西亚亚洲防务展

5月6日,灵途科技携新品模组与武汉长盈通光电(股票代码:688143)携手参加第18届马来西亚亚洲防务展。首次亮相海外,灵途科技便收获全球客户的广泛关注,为公司海外市场开拓打下坚实基础。 灵途科技与长盈通共同…

Dbs封装_连接池

1.Dbs封装 每一个数据库都对应着一个dao 每个dao势必存在公共部分 我们需要将公共部分抽取出来 封装成一个工具类 保留个性化代码即可 我们的工具类一般命名为xxxs 比如Strings 就是字符串相关的工具类 而工具类 我们将其放置于util包中我们以是否有<T>区分泛型方法和非泛…

Python并发编程学习记录

1、初识并发编程 1.1、串行&#xff0c;并行&#xff0c;并发 串行(serial)&#xff1a;一个cpu上按顺序完成多个任务&#xff1b; 并行(parallelism)&#xff1a;任务数小于或等于cup核数&#xff0c;多个任务是同时执行的&#xff1b; 并发(concurrency)&#xff1a;一个…

计算机SCI期刊,IF=8+,专业性强,潜力新刊!

一、期刊名称 Journal of Big data 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;计算机科学 影响因子&#xff1a;8.1 中科院分区&#xff1a;2区 出版方式&#xff1a;开放出版 版面费&#xff1a;$1990 三、期刊征稿范围 《大数据杂志》发表了关于…

2024年【T电梯修理】考试内容及T电梯修理新版试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【T电梯修理】考试内容及T电梯修理新版试题&#xff0c;包含T电梯修理考试内容答案和解析及T电梯修理新版试题练习。安全生产模拟考试一点通结合国家T电梯修理考试最新大纲及T电梯修理考试真题汇总&#xff0c;…

(2024,SDE,对抗薛定谔桥匹配,离散时间迭代马尔可夫拟合,去噪扩散 GAN)

Adversarial Schrdinger Bridge Matching 公众号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 1. 简介 4. 实验 0. 摘要 薛定谔桥&#xff08;Schrdinger Bridge&#xff0c;SB&…

浮点型比较大小

浮点数的存储形式 浮点数按照在内存中所占字节数和数值范围&#xff0c;可以分为浮点型&#xff0c;双精度浮点型和长双浮点型数。 代码&#xff1a; printf("lgn:%e \n", pow(exp(1), 100));printf("lgn:%f ", pow(exp(1), 100));输出结果&#xff1a; …

CLIP 论文的关键内容

CLIP 论文整体架构 该论文总共有 48 页&#xff0c;除去最后的补充材料十页去掉&#xff0c;正文也还有三十多页&#xff0c;其中大部分篇幅都留给了实验和响应的一些分析。 从头开始的话&#xff0c;第一页就是摘要&#xff0c;接下来一页多是引言&#xff0c;接下来的两页就…

python文件IO基础知识

目录 1.open函数打开文件 2.文件对象读写数据和关闭 3.文本文件和二进制文件的区别 4.编码和解码 读写文本文件时 读写二进制文件时 5.文件指针位置 6.文件缓存区与flush()方法 1.open函数打开文件 使用 open 函数创建一个文件对象&#xff0c;read 方法来读取数据&…

电子技术学习路线

在小破站上看到大佬李皆宁的技术路线分析&#xff0c;再结合自己这几年的工作。发现的确是这样&#xff0c;跟着大佬的技术路线去学习是会轻松很多&#xff0c;现在想想&#xff0c;这路线其实跟大学四年的学习顺序是很像的。 本期记录学习路线&#xff0c;方便日后查看。 传统…

京东Java社招面试题真题,最新面试题

Java中接口与抽象类的区别是什么&#xff1f; 1、定义方式&#xff1a; 接口是完全抽象的&#xff0c;只能定义抽象方法和常量&#xff0c;不能有实现&#xff1b;而抽象类可以有抽象方法和具体实现的方法&#xff0c;也可以定义成员变量。 2、实现与继承&#xff1a; 一个类…

FPGA之tcp/udp

在调试以太网的过程中&#xff0c;考虑了vivado IP配置(管脚、reset等)&#xff0c;SDK中PHY芯片的配置(芯片地址、自适应速率配置等)&#xff0c;但是&#xff0c;唯独忽略了tcp/udp协议&#xff0c;所以在ping通之后仍无法连接。 所以现在来学习一下tcp与udp的区别 ---- 为什…

浪潮信息IPF24:AI+时代,创新驱动未来,携手共创智慧新纪元

如今&#xff0c;数字化时代的浪潮席卷全球&#xff0c;人工智能已经成为推动社会进步的重要引擎。浪潮信息IPF24作为行业领先的AI技术盛会&#xff0c;不仅为业界提供了交流合作的平台&#xff0c;更在激发创新活力、拓展发展路径、加速AI技术落地等方面发挥了重要作用。 升级…

OS复习笔记ch6-2

死锁的解决 死锁的预防&#xff08;打疫苗&#xff09;死锁的避免&#xff08;戴口罩&#xff09;死锁的检测&#xff08;做核酸&#xff09; 死锁的预防 前面我们提到了死锁的四个必要条件 防止前三个必要条件&#xff0c;就是间接预防防止最后一个必要条件–循环等待&…