相似性搜索:第 1 部分- kNN 和倒置文件索引

图片来源:维亚切斯拉夫·叶菲莫夫

一、说明

        SImilarity 搜索是一个问题,给定一个查询的目标是在所有数据库文档中找到与其最相似的文档。

        在数据科学中,相似性搜索经常出现在NLP领域,搜索引擎或推荐系统中,其中需要检索最相关的文档或项目以进行查询。通常,文档或项目以文本或图像的形式表示。但是,机器学习算法不能直接处理原始文本或图像,这就是为什么文档和项目通常被预处理并存储为数字向量的原因。

        有时,向量的每个组件都可以存储语义含义。在这种情况下,这些表示也称为嵌入。这样的嵌入可以有数百个维度,它们的数量可以达到数百万个!由于数量如此之大,任何信息检索系统都必须能够快速检测相关文档。

在机器学习中,向量也称为对象

二、索引指数

        为了提高搜索性能,在数据集嵌入之上构建了一个特殊的数据结构。这种数据结构称为索引。该领域已经有很多研究,并且已经发展了许多类型的索引。在选择要申请某项任务的索引之前,有必要了解它在引擎盖下的运作方式,因为每个索引都有不同的用途,并且各有优缺点。

        在本文中,我们将看看最幼稚的方法 — kNN。基于 kNN,我们将切换到倒排文件 — 用于更具可扩展性的搜索的索引,可以将搜索过程加速数倍。

2.1 kNN

        kNN是最简单、最幼稚的相似性搜索算法。考虑一个向量数据集和一个新的查询向量 Q。我们想找到与 Q 最相似的前 k 个数据集向量。要考虑的第一个方面是如何测量两个向量之间的相似性(距离)。事实上,有几个相似性指标可以做到这一点。其中一些如下图所示。

相似性指标

2.2 knn相似性训练和使用

2.2.1 训练

        kNN是机器学习中为数不多的不需要训练阶段的算法之一。选择合适的指标后,我们可以直接进行预测。

2.2.2 推理

        对于新对象,该算法会详尽地计算到所有其他对象的距离。之后,它找到距离最小的 k 个对象并将它们作为响应返回。

kNN 工作流程

        显然,通过检查到所有数据集向量的距离,kNN 保证 100% 准确的结果。但是,就时间性能而言,这种蛮力方法效率非常低。如果数据集由 n 个具有 m 维的向量组成,则对于 n 个向量中的每一个,都需要 O(m) 时间来计算从查询 Q 到它的距离,这会导致 O(mn) 的总时间复杂度。正如我们稍后将看到的,存在更有效的方法。

        此外,原始矢量没有压缩机制。想象一个包含数十亿个对象的数据集。将它们全部存储在RAM中可能是不可能的!

        kNN 性能。具有 100% 的准确性且没有训练阶段会导致在向量推理和无内存压缩期间进行详尽搜索。注意:这种类型的图表显示了不同算法的相对比较。根据情况和所选的超参数,性能可能会有所不同。

2.3 如何应用

        kNN 的应用范围有限,应仅在以下场景之一中使用:

  • 数据集大小或嵌入维度相对较小。这方面确保算法仍然快速执行。
  • 算法所需的精度必须为 100%。在准确性方面,没有其他最近邻算法可以超越kNN的性能。

        根据一个人的指纹检测一个人是需要100%准确性的问题的一个例子。如果该人犯罪并留下了指纹,则仅检索正确的结果至关重要。否则,如果系统不是100%可靠的,那么另一个人可能会被判犯有罪行,这是一个非常严重的错误。

        基本上,有两种主要方法可以改善 kNN(我们将在后面讨论):

  • 缩小搜索范围。
  • 降低矢量的维数。

使用这两种方法之一时,我们不会再次执行详尽搜索。这种算法被称为近似最近邻(ANN),因为它们不能保证100%准确的结果。

三、倒排文件索引

“倒排索引(也称为帖子列表帖子文件或倒排文件)是一种数据库索引,存储从内容(如单词或数字)到其在表格、文档或一组文档中的位置的映射” — 维基百科

        执行查询时,将计算查询的哈希函数,并从哈希表中获取映射值。这些映射值中的每一个都包含其自己的一组潜在候选项,然后根据条件完全检查这些候选项,使其成为查询的最近邻域。这样,所有数据库向量的搜索范围都会缩小。

        倒排文件索引工作流

        此索引有不同的实现,具体取决于哈希函数的计算方式。我们将要研究的实现是使用Voronoi图(或狄利克雷镶嵌)的实现。

3.1 训练

该算法的思想是创建每个数据集点所属的几个非相交区域。每个区域都有自己的质心,指向该区域的中心。

有时沃罗诺伊地区被称为单元分区

沃罗诺伊图的示例。白点是包含一组候选项的相应分区的中心。

Voronoi 图的主要性质是,从一个质心到其区域的任何一点的距离小于从该点到另一个质心的距离。

3.2 推理

        当给定一个新对象时,将计算到Voronoi分区的所有质心的距离。然后选择距离最小的质心,然后将该分区中包含的向量作为候选。

通过给定的查询,我们搜索最近的质心(位于绿色区域)

最终,通过计算到候选人的距离并选择离候选人最近的前 k 个,返回最终答案。

查找所选区域中最近的邻居

如您所见,这种方法比前一种方法快得多,因为我们不必查看所有数据集向量。

3.3 边缘问题

        随着搜索速度的提高,反转文件有一个缺点:它不能保证找到的对象始终是最近的。

        在下图中,我们可以看到这样的场景:实际的最近邻位于红色区域,但我们仅从绿色区域中选择候选人。这种情况称为边缘问题

边缘问题

        当查询的对象位于与另一个区域的边界附近时,通常会发生这种情况。为了减少这种情况中的错误数量,我们可以增加搜索范围,并根据最接近对象的前 m 个质心选择几个区域来搜索候选者。

在多个区域内搜索最近的邻居 (m = 3)

探索的区域越多,结果就越准确,计算它们所需的时间就越多。

3.4 应用

        尽管存在边缘问题,但反转文件在实践中显示出不错的结果。在我们想要权衡精度略有下降以实现多次速度增长的情况下,它是完美的选择。

        其中一个用例示例是基于内容的推荐系统。想象一下,它根据用户过去看过的其他电影向用户推荐一部电影。该数据库包含一百万部电影可供选择。

  • 通过使用kNN,系统确实为用户选择了最相关的电影并推荐它。但是,执行查询所需的时间很长。
  • 让我们假设使用倒排文件索引,系统会推荐第 5 部最相关的电影,这在现实生活中可能就是这种情况。搜索时间比 kNN 快 20 倍。

        从用户体验来看,很难区分这两个推荐的质量结果:第 1 和第 5 个最相关的结果都是来自一百万个可能的电影的好推荐。用户可能会对这些建议中的任何一个感到满意。从时间的角度来看,倒置文件显然是赢家。这就是为什么在这种情况下最好使用后一种方法。

        倒排文件索引性能。在这里,我们略微降低了在推理过程中实现更高速度的精度。

四、Faiss库实施

Faiss(Facebook AI Search Similarity)是一个用C++编写的Python库,用于优化的相似性搜索。该库提供了不同类型的索引,这些索引是用于有效存储数据和执行查询的数据结构。

根据 Faiss 文档中的信息,我们将了解如何创建和参数化索引。

4.1 实现kNN

        实现 kNN 方法的索引在 Faiss 中被称为平面索引,因为它们不压缩任何信息。它们是保证正确搜索结果的唯一索引。实际上,Faiss中存在两种类型的平面索引:

  • 索引平L2.相似性计算为欧几里得距离。
  • 索引平面IP。相似性计算为内积。

        这两个索引都需要在其构造函数中包含一个参数 d:数据维度。这些索引没有任何可调参数。

IndexFlatL2 和 IndexFlatIP 的 Faiss 实现

存储矢量的单个分量需要 4 个字节。因此,要存储维度为 d 的单个向量,需要 4 * d 字节。

4.2 倒排文件索引

        对于描述的倒置文件,Faiss 实现了类 IndexIVFFlat。与 kNN 的情况一样,单词“Flat”表示原始向量没有解压缩并且它们已完全存储。

        要创建此索引,我们首先需要传递一个量化器 — 一个确定如何存储和比较数据库向量的对象。

        IndexIVFFlat 有 2 个重要参数:

  • nlist:定义训练期间要创建的多个区域(Voronoi 单元)。
  • nprobe:确定搜索候选项的区域数。更改 nprobe 参数不需要重新训练。

Faiss 实现 IndexIVFFlat

与前面的情况一样,我们需要 4 * d 字节来存储单个向量。但是现在我们还必须存储有关数据集向量所属的Voronoi区域的信息。在 Faiss 实现中,此信息每个向量占用 8 个字节。因此,存储单个向量所需的内存为:

五、结论

        我们已经在相似性搜索中经历了两种基本算法。实际上,朴素的kNN几乎不应该用于机器学习应用程序,因为它的可扩展性很差,除非在特定情况下。另一方面,反转文件为加速搜索提供了良好的启发式方法,可以通过调整其超参数来提高其质量。仍然可以从不同的角度增强搜索性能。在本系列文章的下一部分中,我们将介绍一种旨在压缩数据集向量的方法。

系列下篇:相似性搜索:第 2 部分:产品量化_无水先生的博客-CSDN博客

参考资源

  • 倒排索引 |维基百科
  • 费斯文档
  • 费斯存储库
  • 费斯指数摘要
  • 选择索引的准则

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

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

相关文章

目标文件格式

目标文件里有什么 目标文件格式 目标文件就是源代码编译后但未进行链接的中间文件(linux下的.o)。 ELF文件:从广义上看,目标文件与可执行文件的格式其实几乎是一样的,可以将目标文件与可执行文件看成是一种类型的文…

忘记开机密码啦!我教你用ventoy找回密码

文章目录 一、前言二、实战过程三、动态演示四、原理解析五、总结 一、前言 当你有一天突然忘记了开机密码怎么办?又要上电脑店花个几十块让人弄?在上一章《你该自己学学安装操作系统了,小白一学就会(ventoy装系统超详细&#xff…

Unity设计模式——建造者模式

Product类——产品类&#xff0c;由多个部件组成。 class Product {IList<string> parts new List<string>();//添加产品部件public void Add(string part){parts.Add(part);}public void Show(){foreach (string part in parts){Debug.Log("产品:"pa…

python+深度学习+opencv实现植物识别算法系统 计算机竞赛

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习的植物识别算法研究与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;4分 &#x1f9ff; 更多…

Android+Appium自动化测试环境搭建及实操

1、Appium简介1.1 Appium概念1.2 Appium工作原理 2、Appium Server环境搭建2.1 Java JDK2.1.1 下载JDK2.1.2 运行exe安装JDK&#xff0c;设置安装路径2.1.3 设置环境变量2.1.4 验证安装结果 2.2 Android SDK2.2.1 下载安装Android SDK安装包2.2.2 下载platform-tools&#xff0…

Linux下将驱动编译进内核

在开发的过程中&#xff0c;一般都是将驱动编译成模块&#xff0c;然后将其发送到开发板加载驱动进行功能验证&#xff0c;驱动的功能验证没有问题后就可以将其编译进内核了。本文将介绍如何把上一篇文章Linux下设备树、pinctrl和gpio子系统、LED灯驱动实验中的LED驱动编译到内…

【LeetCode】9. 回文数

1 问题 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff0c;121 是回文&…

【计算机网络】IP协议详解

文章目录 一、引入 二、简单认识IP协议 2、1 IP协议基本概念 2、2 IP协议报文格式 2、3 分片与组装 2、3、1 MTU 与 MSS 2、4 网段划分 2、4、1 简单理解路由 2、4、2 IP地址 2、4、3 IP地址的划分 2、4、4 CIDR&#xff08;无类别域间路由&#xff09; 2、4、5 特殊的IP地址 …

Redis微服务架构

Redis微服务架构 缓存设计 缓存穿透 缓存穿透是指查询一个根本不存在的数据&#xff0c;缓存层和存储层都不会命中&#xff0c;通常出于容错的考虑&#xff0c;如果从存储层查不到数据则不写入缓层。 缓存穿透将导致不存在的数据每次请求都要到存储层去查询&#xff0c;失去…

【Nginx32】Nginx学习:随机索引、真实IP处理与来源处理模块

Nginx学习&#xff1a;随机索引、真实IP处理与来源处理模块 完成了代理这个大模块的学习&#xff0c;我们继续其它 Nginx 中 HTTP 相关的模块学习。今天的内容都比较简单&#xff0c;不过最后的来源处理非常有用&#xff0c;可以帮我们解决外链问题。另外两个其实大家了解一下就…

Java IO流

IO 即 Input / Output &#xff0c;输入输出流。IO流在Java中分为输入流和输出流&#xff0c;而根据数据的处理方式又分为字节流和字符流。 Java IO 流的 40 多个类都是从如下 4 个 抽象类基类中派生出来的。 InputStream /Reader : 所有的输入流的基类&#xff0c;前者是字节…

大数据flink篇之三-flink运行环境安装(一)单机Standalone安装

一、安装包下载地址 https://archive.apache.org/dist/flink/flink-1.15.0/ 二、安装配置流程 前提基础&#xff1a;Centos环境&#xff08;建议7以上&#xff09; 安装命令&#xff1a; 解压&#xff1a;tar -zxvf flink-xxxx.tar.gz 修改配置conf/flink-conf.yaml&#xff1…

IDEA通过Docker插件部署SpringBoot项目

1、配置Docker远程连接端口 找到并编辑服务器上的docker.service文件。 vim /usr/lib/systemd/system/docker.service在下面ExecStart替换成下面的 ExecStart/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock2.重启docker systemctl daemon-reload s…

交叉熵Loss多分类问题实战(手写数字)

1、import所需要的torch库和包 2、加载mnist手写数字数据集&#xff0c;划分训练集和测试集&#xff0c;转化数据格式&#xff0c;batch_size设置为200 3、定义三层线性网络参数w&#xff0c;b&#xff0c;设置求导信息 4、初始化参数&#xff0c;这一步比较关键&#xff0c;…

强化学习(Reinforcement Learning)与策略梯度(Policy Gradient)

写在前面&#xff1a;本篇博文的内容来自李宏毅机器学习课程与自己的理解&#xff0c;同时还参考了一些其他博客(懒得放链接)。博文的内容主要用于自己学习与记录。 1 强化学习的基本框架 强化学习(Reinforcement Learning, RL)主要由智能体(Agent/Actor)、环境(Environment)、…

【学习笔记】项目进行过程中遇到有关composer的问题

composer.json内容详解 以项目中的composer.json为例&#xff0c;参考文档。 name&#xff1a;composer包名type&#xff1a;包的类型&#xff0c;project和library两种keywords&#xff1a;关键词&#xff0c;方便别人在安装时通过关键词检索&#xff08;没试过&#xff0c;好…

《C++ Primer》练习9.52:使用栈实现四则运算

栈可以用来使用四则运算&#xff0c;是一个稍微有点复杂的题目&#xff0c;去学习了一下用栈实现四则运算的原理&#xff0c;用C实现了一下。首先要把常见的中缀表达式改成后缀表达式&#xff0c;然后通过后缀表达式计算&#xff0c;具体的原理可以参考这位博主的文章&#xff…

抖音直播招聘小程序可以增加职位展示,提升转化率,增加曝光度

抖音直播招聘报白是指进入抖音的白名单&#xff0c;允许在直播间或小视频中发布招聘或找工作等关键词。否则会断播、不推流、限流。抖音已成为短视频流量最大的平台&#xff0c;但招聘企业数量较少。抖音招聘的优势在于职位以视频、直播方式展示&#xff0c;留存联系方式更加精…

到底什么是5G-R?

近日&#xff0c;工信部向中国国家铁路集团有限公司&#xff08;以下简称“国铁集团”&#xff09;批复5G-R试验频率的消息&#xff0c;引起了行业内的广泛关注。 究竟什么是5G-R&#xff1f;为什么工信部会在此时批复5G-R的试验频率&#xff1f; 今天&#xff0c;小枣君就通过…

公司文件防泄密软件——「天锐绿盾」@德人合科技

天锐绿盾是一款企业级数据安全解决方案&#xff0c;主要用于保护企业的知识产权、客户资料、财务数据、技术图纸、应用系统等机密信息化数据不外泄。 PC访问地址&#xff1a; &#x1f517;isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 该软件解决方案…