文章目录

  • 导语
  • 线性扫描
  • KDTree
    • 构造
    • 检索
    • 特点
  • BallTree
    • 构造
    • 检索
    • 特点
  • Annoy
    • 构造
    • 检索
    • 特点
  • NSW
    • 构造
    • 检索
  • HNSW
    • 构造
    • 查找

导语

为什么要用向量快速检索呢?因为实际上现在各家公司主召回都会使用向量化召回,但是工业界数据规模太大,精确的近邻搜索太过困难,研究随之转向了在精确性和搜索时间做取舍,即Approximate Nearest Neighbor Search (ANNS)
本文会介绍常用的一些快速检索方法原理,即其效果

线性扫描

将待预测样本和候选样本逐一比对,最终挑选出距离最接近的k个样本即可,时间复杂度O(n)。对于样本数量较少的情况,这种方法简单稳定,已经能有不错的效果。但是数据规模较大时,时间开销严重无法接受

KDTree

构造

kd树是二叉树,核心思想是对 k 维特征空间不断切分(假设特征维度是768,对于(0,1,2,…,767)中的每一个维度,以中值递归切分)构造的树,每一个节点是一个超矩形,小于结点的样本划分到左子树,大于结点的样本划分到右子树。

检索

检索时(1)从根结点出发,递归地向下访问kd树。若目标点 [公式] 当前维的坐标小于切分点的坐标,移动到左子树,否则移动到右子树,直至到达叶结点;(2)以此叶结点为“最近点”,递归地向上回退,查找该结点的兄弟结点中是否存在更近的点,若存在则更新“最近点”,否则回退;未到达根结点时继续执行(2);(3)回退到根结点时,搜索结束。

特点

kd树在维数小于20时效率最高,一般适用于训练实例数远大于空间维数时的k近邻搜索;当空间维数接近训练实例数时,它的效率会迅速下降,几乎接近线形扫描。

BallTree

构造

KD 树沿坐标轴分割数据,BallTree将在一系列嵌套的超球面上分割数据,即使用超球面而不是超矩形划分区域。

具体而言,BallTree 将数据递归地划分到由质心 C 和 半径 r 定义的节点上,以使得节点内的每个点都位于由质心C和半径 r 定义的超球面内。通过使用三角不等式 减少近邻搜索的候选点数。

检索

  1. 从根节点开始从上至下递归遍历每个可能包含最终近邻的子空间
  2. 如果子空间的半径 R(pi)与 r之和大于中心点 pi 到目标点 q 的距离,则圆必相交。接着在满足这样条件的子空间样本点内递归搜索满足条件的点就是我们想要的最近邻点了。

特点

虽然在构建数据结构的花费上大过于KDtree,但是在高维甚至很高维的数据上都表现的很高效

Annoy

annoy全称“Approximate Nearest Neighbors Oh Yeah”,是一种适合实际应用的快速相似查找算法。Annoy 同样通过建立一个二叉树来使得每个点查找时间复杂度是O(log n),和kd树不同的是,annoy没有对k维特征进行切分。

annoy的每一次空间划分,可以看作聚类数为2的KMeans过程。收敛后在产生的两个聚类中心连线之间建立一条垂线(图中的黑线),把数据空间划分为两部分。

构造



最终生成的二叉树具有如下类似结构,二叉树底层是叶子节点记录原始数据节点,其他中间节点记录的是分割超平面的信息

检索

查询过程和kd树类似,先从根向叶子结点递归查找,再向上回溯即可

特点

annoy接口中一般需要调整的参数有两个:查找返回的topk近邻和树的个数。一般树越多,精准率越高但是对内存的开销也越大,需要权衡取舍

NSW

NSW(Navigable Small World graphs)是基于图存储的数据结构

朴素查找法:不少人脑子里都冒出过这样的朴素想法,把某些点和点之间连上线,构成一个查找图,存下来备用;当我想查找与粉色点最近的一点时,我从任意一个黑色点出发,计算它和粉色点的距离,与这个任意黑色点有连接关系的点我们称之为“友点”(直译),然后我要计算这个黑色点的所有“友点”与粉色点的距离,从所有“友点”中选出与粉色点最近的一个点,把这个点作为下一个进入点,继续按照上面的步骤查找下去。如果当前黑色点对粉色点的距离比所有“友点”都近,终止查找,这个黑色点就是我们要找的离粉色点最近的点

朴素想法之所以叫朴素想法就是因为它的缺点非常多。首先,我们发现图中的K点是无法被查询到的,因为K点没有友点,怎么办?。其次,如果我们要查找距离粉色点最近的两个点,而这两个近点之间如果没有连线,那么将大大影响效率(比如L和E点,如果L和E有连线,那么我们可以轻易用上述方法查出距离粉色点最近的两个点),怎么办?。最后一个大问题,D点真的需要这么多“友点”吗?谁是谁的友点应该怎么确定呢?

三条规定:关于K点的问题,我们规定在构图时所有数据向量节点都必须有友点。关于L和E的问题,我们规定在构图时所有距离相近(相似)到一定程度的向量必须互为友点。关于D点问题,权衡构造这张图的时间复杂度,我们规定尽量减少每个节点的“友点”数量。

构造

在图论中有一个很好的剖分法则专门解决上一节中提到的朴素想法的缺陷问题------德劳内(Delaunay)三角剖分算法,这个算法可以达成如下要求:1,图中每个点都有“友点”。2,相近的点都互为“友点”。3,图中所有连接(线段)的数量最少。效果如下图。

但NSW没有采用德劳内三角剖分法来构成德劳内三角网图,原因之一是德劳内三角剖分构图算法时间复杂度太高,换句话说,构图太耗时。原因之二是德劳内三角形的查找效率并不一定最高,如果初始点和查找点距离很远的话我们需要进行多次跳转才能查到其临近点,需要“高速公路”机制(Expressway mechanism, 这里指部分远点之间拥有线段连接,以便于快速查找)。在理想状态下,我们的算法不仅要满足上面三条需求,还要算法复杂度低,同时配有高速公路机制的构图法。

NSW朴素构图算法在这里:向图中逐个插入点,插图一个全新点时,通过朴素想法中的朴素查找法(通过计算“友点”和待插入点的距离来判断下一个进入点是哪个点)查找到与这个全新点最近的m个点(m由用户设置),连接全新点到m个点的连线。完了。

首先,我们的构图算法是逐点随机插入的,这就意味着在图构建的早期,很有可能构建出“高速公路”。

检索

  1. 算法计算从查询 q q q 到当前顶点的朋友列表的每个顶点的距离,然后选择具有最小距离的顶点。
  2. 如果查询与所选顶点之间的距离小于查询与当前元素之间的距离,则算法移动到所选顶点,并且它变为新的当前顶点。
  3. 算法在达到局部最小值时停止:一个顶点,其朋友列表不包含比顶点本身更接近查询的顶点

HNSW

HNSW加入了跳表结构做了进一步优化。最底层是所有数据点,每一个点都有50%概率进入上一层的有序链表。这样可以保证表层是“高速通道”,底层是精细查找。通过层状结构,将边按特征半径进行分层,使每个顶点在所有层中平均度数变为常数,从而将NSW的计算复杂度由多重对数复杂度降到了对数复杂度。

构造

第0层中,是数据集中的所有点,你需要设置一个常数ml,通过公式floor(-ln(uniform(0,1)) x ml)来计算这个点可以深入到第几层。公式中x是乘号,floor()的含义是向下取整,uniform(0,1)的含义是在均匀分布中随机取出一个值,ln()表示取对数。

查找

  1. 该算法贪婪地遍历来自上层的元素,直到达到局部最小值。
  2. 之后,搜索切换到较低层(具有较短 link),从元素重新开始,该元素是前一层中的局部最小值,并且该过程重复。
  3. 通过采用层状结构,将边按特征半径进行分层,从而将 NSW 的计算复杂度由多重对数复杂度降到了对数复杂度。

向量快速检索方法总结——KDtree/Balltree/Annoy/NSW/HNSW相关推荐

  1. java实现k 近邻算法_K近邻算法哪家强?KDTree、Annoy、HNSW原理和使用方法介绍

    1.什么是K近邻算法 K近邻算法(KNN)是一种常用的分类和回归方法,它的基本思想是从训练集中寻找和输入样本最相似的k个样本,如果这k个样本中的大多数属于某一个类别,则输入的样本也属于这个类别. 关于 ...

  2. NLP学习—18.Annoy、HNSW、KD tree以及多轮对话

    文章目录 引言 一.Annoy 1.Annoy实战 二.HNSW 三.KD tree 1.Annoy与KD Tree比较 四.Dialog Management(任务型多轮对话) 引言   Annoy ...

  3. 国赛latex方法快速检索(入门级)

    latex方法快速检索 本文主要为国赛论文书写服务,利用的是Github上cumcmthesis论文模板 本文部分节选自:https://zhuanlan.zhihu.com/p/456055339? ...

  4. 快速检索2021年EI会议论文的方法

    1. EI检索条件设置 1.1选择数据库 在SELECT DATABASE的下拉菜单中选择Compendex,系统默认数据库为Compendex, 其他数据库为: INSPEC(科学文摘).Paten ...

  5. 虹软人脸识别SDK接入Milvus实现海量人脸快速检索

    虹软人脸识别SDK接入Milvus实现海量人脸快速检索 背景 虹软SDK及Milvus简介 开发环境 虹软人脸识别SDK使用简介 Milvus环境搭建 快速检索实现 人脸识别流程简介 快速检索 虹软S ...

  6. 快速检索并引用你在CSDN上所有的博文笔记

    简 介: 利用CSDN提供的博文的列表,编写了一个快速检索自己博文,并自动插入索引连接的程序.这样就可以大大提高博文写作的效率,将之前记录学习.工作的内容更好的进行连接.最后,感谢CSDN技术人员的大 ...

  7. ACL 2020 | 多跳问答的基于对齐的无监督迭代解释检索方法

    ©PaperWeekly 原创 · 作者|舒意恒 学校|南京大学硕士生 研究方向|知识图谱 论文标题:Unsupervised Alignment-based Iterative Evidence R ...

  8. python批量检索文献pubmed_PubMed快速检索文献,学学这些技巧!

    原标题:PubMed快速检索文献,学学这些技巧! PubMed为科研路上必不可少的数据库,今天传授PubMed高手常用的7个技巧,让你快速找到自己想要的文献. 1,获取全文技巧 Pubmed提供的文献 ...

  9. 基于 FCCA 的多特征融合的检索方法

    论文杂记 上一篇 主目录 下一篇 文章结构 1 知识基础 1.1 卷积神经网络 1.2 灰度共生矩阵 1.3 LBP 特征 1.4 特征融合 1.5 典型相关分析算法(CCA) 1.6 Faster- ...

最新文章

  1. 零基础java自学就业_java零基础到就业需要多长时间呢?
  2. expdp oracle 并行_关于Expdp/Impdp 并行导入导出详细测试结果和并行参数的正确理解!!...
  3. JSONObject 和 GSON 解析 JSON 数据详解(转)
  4. docx4j学习笔记
  5. 高通平台 LCD 的 LK部分代码解析
  6. 细化迭代三文档-2.1,2.2,2.3
  7. 在win10中加载ISO文件到虚拟光驱
  8. 企业邮箱如何免费申请注册?
  9. 国内高校大数据教研机构调研报告
  10. mysql 分表-横向,纵向
  11. 职场遭遇“小人”,你如何应对?
  12. 笔记:STM32——PWM波形生成以及控制电机
  13. 在Linux中设置共享目录
  14. Meld Diff for windows 安装配置
  15. Python-Flask开发微电影网站(一)
  16. Android投屏到Windows电脑
  17. 电竞英雄联盟数据API接口 - 【联赛列表】API调用示例代码
  18. TCP Flood攻击实验
  19. 高通Android随身WIFI屏蔽商家远程控制断网
  20. 分页的php处理,分页处理的PHP类

热门文章

  1. html5 dramweaver 版本,Dreamweaver CS5 HTML 5 扩展包
  2. c语言ftest函数,阅读以下说明、c函数和问题,将解答写入答题纸的对应栏内。【说明1】函数testf - 信管网...
  3. Access2003开发者扩展工具集概述(转)
  4. VB程序学习代码记录20160731
  5. C++图片保存,加载(LoadImage()),编辑,资源句柄(HBITMAP )的使用总结
  6. java计算机毕业设计ssm“阳光”养老院管理系统
  7. Unity使用滚动条Slider控制声音音量
  8. 科技巨头纷纷角逐奥运会,参赛的正确姿势是什么?
  9. spring boot 启用定时任务调取精伦IDR210阅读软件获取身份证信息 jna dll
  10. 23-职位分类展示平台响应式网页模板{HTML JS CSS)