向量数据库Annoy和Milvus

news2025/1/22 1:20:44

Annoy 和 Milvus 都是用于向量索引和相似度搜索的开源库,它们可以高效地处理大规模的向量数据。

Annoy(Approximate Nearest Neighbors Oh Yeah):

  • Annoy 是一种近似最近邻搜索算法,它通过构建一个树状结构来加速最近邻搜索。
  • Annoy 支持支持欧氏距离,曼哈顿距离,余弦距离,汉明距离或点(内)乘积距离等多种度量方式。
  • Annoy 是一个轻量级的库,易于使用和集成,如果向量维度不是太多(例如<100维),效果会比较好。
  • 目前 Annoy 主要支持 Python 和 C++ 接口。

Milvus:

  • Milvus 是一个基于向量相似度搜索的开源引擎,它可以将大规模向量数据快速存储和检索。
  • Milvus 使用了各种索引和算法优化技术,提供了高效的向量搜索能力。
  • Milvus 支持欧式距离、内积相似度等多种度量方式,且具有扩展性和可定制性。
  • Milvus 提供了 Python、Java 和 Go 等多种编程语言的接口。
  • Milvus 还提供了图形用户界面 (GUI) 和可视化工具来辅助管理和查询向量数据库。

选择 Annoy 还是 Milvus 取决于您的具体需求和应用场景:

  • 如果对于近似最近邻搜索的速度轻量级集成更为关注,可以选择 Annoy。(demo入门)
  • 如果需要管理和查询大规模的向量数据库,并希望具备更多的功能和可扩展性,可以选择 Milvus。(工业级应用)

1. Annoy

Annoy (Approximate Nearest Neighbors Oh Yeah)是一个带有Python bindings的C ++库,用于搜索空间中给定查询点的近邻点。它还会创建大型的基于文件的只读数据结构,并将其映射到内存中,以便许多进程可以共享相同的数据。annoy的学习成本非常低,能较快的掌握,非常适合项目的快速开发,于此对比的是,faiss和Milvus的学习成本较高,用起来较为复杂。

用于空间检索近邻的数据。检索过程分成三步:

  • 建立索引过程;
  • 近邻查询过程;
  • 返回最终近邻节点;

首先先来一张2D数据分布图:
在这里插入图片描述

接下来按照步骤1,2和3进行分析。

1.1 建立索引过程

Annoy的目标是建立一个数据结构,使得查询一个点的最近邻点的时间复杂度是次线性。Annoy 通过建立一个二叉树来使得每个点查找时间复杂度是O(log n)。以下图为例,随机选择两个点,以这两个节点为初始中心节点,执行聚类数为2的kmeans过程,最终产生收敛后两个聚类中心点。这两个聚类中心点之间连一条线段(灰色短线),建立一条垂直于这条灰线,并且通过灰线中心点的线(黑色粗线)。这条黑色粗线把数据空间分成两部分。在多维空间的话,这条黑色粗线可以看成等距垂直超平面。
在这里插入图片描述

在划分的子空间内进行不停的递归迭代继续划分,直到每个子空间最多只剩下K个数据节点。

在这里插入图片描述

通过多次递归迭代划分的话,最终原始数据会形成类似下图的二叉树结构。二叉树底层是叶子节点记录原始数据节点其他中间节点记录的是分割超平面的信息。Annoy建立这样的二叉树结构是希望满足这样的一个假设: 相似的数据节点应该在二叉树上位置更接近,一个分割超平面不应该把相似的数据节点分割二叉树的不同分支上。

在这里插入图片描述
根据上述步骤,建立多棵二叉树树,构成一个森林。

1.2 近邻查询过程

上面已完成节点索引建立过程。如何进行对一个数据点进行查找相似节点集合呢?比如下图的红色节点,查找的过程就是不断看他在分割超平面的哪一边。从二叉树索引结构来看,就是从根节点不停的往叶子节点遍历的过程。通过对二叉树每个中间节点(分割超平面相关信息)和查询数据节点进行相关计算来确定二叉树遍历过程是往这个中间节点左孩子节点走还是右孩子节点走。通过以上方式完成查询过程。

在这里插入图片描述

查询过程采用优先队列机制:采用一个优先队列来遍历二叉树,从根节点往下的路径,根据查询节点与当前分割超平面距离进行排序。

在这里插入图片描述

1.3 返回最终近邻节点

步骤1会构建多棵二叉树树,每棵树都返回一堆近邻点后,如何得到最终的Top N相似集合呢?首先所有树返回近邻点都插入到优先队列中,求并集去重, 然后计算和查询点距离,最终根据距离值从近距离到远距离排序,返回Top-N近邻节点集合。

1.4 完整的Python API

  • AnnoyIndex(f, metric)返回可读写的新索引,用于存储f维度向量。metric 可以"angular""euclidean""manhattan""hamming""dot"
  • a.add_item(i, v)用于给索引添加向量v,i(任何非负整数)是给向量v的表示。
  • a.build(n_trees)用于构建 n_trees 的森林。查询时,树越多,精度越高。在调用build后,无法再添加任何向量。
  • a.save(fn, prefault=False)将索引保存到磁盘。保存后,不能再添加任何向量。
  • a.load(fn, prefault=False)从磁盘加载索引。如果prefault设置为True,它将把整个文件预读到内存中。默认值为False。
  • a.unload() 释放索引。
  • a.get_nns_by_item(i, n, search_k=-1, include_distances=False)返回第i 个item的n个最近邻的item。在查询期间,它将检索多达search_k(默认n_trees * n)个点。search_k为您提供了更好的准确性和速度之间权衡。如果设置include_distances为True,它将返回一个包含两个列表的2元素元组:第二个包含所有对应的距离。
  • a.get_nns_by_vector(v, n, search_k=-1, include_distances=False)与上面的相同,但按向量v查询。
  • a.get_item_vector(i)返回第i个向量前添加的向量。
  • a.get_distance(i, j)返回向量i和向量j之间的距离。注意:此函数用于返回平方距离。
  • a.get_n_items() 返回索引中的向量数。
  • a.get_n_trees() 返回索引中的树的数量。
  • a.on_disk_build(fn) 用以在指定文件而不是RAM中建立索引(在添加向量之前执行,在建立之后无需保存)。

Notes:
Annoy使用归一化向量的欧式距离作为其角距离,对于两个向量u,v,其等于 sqrt(2(1-cos(u,v)))
C ++ API非常相似:调用annoy只需使用#include "annoylib.h"

权衡
调整Annoy仅需要两个主要参数:树的数量 n_trees 和搜索期间要检查的节点的数量search_k

  • n_trees在构建索引期间提供该值,并且会影响构建时间和索引大小。较大的值将给出更准确的结果,但索引较大。
  • search_k是在运行时提供的,并且会影响搜索性能。较大的值将给出更准确的结果,但返回时间将更长。

如果search_k未提供,它将默认为n * n_trees * Dn是近似最近邻居的数目,并且D是一个常数,取决于向量维度。否则,search_kn_trees是大致独立的,即如果search_k保持不变,n_trees不会影响搜索时间,反之亦然。基本上,在您可以负担的内存使用量的情况下建议在n_trees可能大的值,并且在给定查询时间的限制的情况下建议设置search_k尽可能大。

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

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

相关文章

CSS中如何实现文字描边效果(Text Stroke)?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 文字描边效果&#xff08;Text Stroke&#xff09;⭐ 示例⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个…

zookeeper 集群

zookeeper 集群 1、zookeeper 集群说明 initLimit 是Zookeeper用它来限定集群中的Zookeeper服务器连接到Leader的时限 syncLimit 限制了follower服务器与leader服务器之间请求和应答之间的时限 服务器名称与地址&#xff1a;集群信息&#xff08;服务器编号&#xff0c;服务器…

【Java 基础篇】Java 面向对象详解:面向对象编程的艺术

如果你正在学习Java编程&#xff0c;面向对象编程&#xff08;Object-Oriented Programming&#xff0c;OOP&#xff09;是一个不可或缺的概念。Java是一种面向对象的编程语言&#xff0c;这意味着它的编程范式基于对象、类和继承。在本篇博客中&#xff0c;我们将深入探讨Java…

IIR滤波器算法

IIR&#xff08;Infinite Impulse Response&#xff09;滤波器是一类递归型数字滤波器&#xff0c;其输出信号不仅与当前的输入信号有关&#xff0c;还与之前的输入和输出信号有关。因此&#xff0c;IIR滤波器的阶数相对较低&#xff0c;可以实现更为复杂的频率响应。 IIR滤波…

C++包含整数各位重组

void 包含整数各位重组() {//缘由https://bbs.csdn.net/topics/395402016int shu 100000, bs 4, bi shu * bs, a 0, p 0, d 0;while (shu < 500000)if (a<6 && (p to_string(shu).find(to_string(bi)[a], p)) ! string::npos && (d to_string(bi…

2PCNet:昼夜无监督域自适应目标检测(附原代码)

点击蓝字 关注我们 关注并星标 从此不迷路 计算机视觉研究院 公众号ID&#xff5c;计算机视觉研究院 学习群&#xff5c;扫码在主页获取加入方式 计算机视觉研究院专栏 Column of Computer Vision Institute 由于缺乏夜间图像注释&#xff0c;夜间目标检测是一个具有挑战性的问…

反转了,中国发售5G手机,ASML就出售先进光刻机,跪地求饶

日前据《中国日报》等多家知名媒体确认&#xff0c;ASML已获得荷兰许可出售先进的2000i光刻机&#xff0c;这款光刻机可用于生产7纳米工艺&#xff0c;而就在数天前一家中国手机企业发布了国产化的5G手机&#xff0c;采用国产的5G芯片和5G射频芯片&#xff0c;这实在太巧合了。…

Linux持续学习者的必备工具:文本处理神器awk

引言 作为一名Linux持续学习者&#xff0c;我们经常需要处理各种各样的文本文件&#xff0c;例如日志文件、配置文件等。而对于大规模的文本数据&#xff0c;手动处理往往效率低下且容易出错。那么&#xff0c;有没有一种快速而强大的工具可以帮助我们进行文本处理呢&#xff1…

废品回收功能文档

废品回收 基础版 后台功能 功能字段描述二级分类表字段&#xff1a;图标、名称、描述、图片、注意事项、上一级、状态功能&#xff1a;前端展示和筛选&#xff1b;增删改查今日指导价表字段&#xff1a;关联分类、名称、价格、单位、状态功能&#xff1a;前端展示和预估价格&…

基于java+springboot+vue的考研资讯平台-lw

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; ssm mybatis Maven mysql5.7或8.0等等组成&#xff0c;B…

Windows Network File System Remote Code Execution Vulnerability

文章目录 NFS(Network File System)漏洞描述攻击者如何利用此漏洞&#xff1f;该漏洞的危险程度机密性-high真实性-high可用性-high 如何降低漏洞风险推荐阅读 NFS(Network File System)漏洞描述 Name Microsoft Windows Network File System Remote Code Execution Vulnerabi…

IM即时聊天项目

目录 IM即时聊天项目WebSocket 原理搭建环境设置代理创建环境配置驱动&#xff08;搭建环境需要的驱动&#xff09;conf&#xff08;配置信息&#xff09;cache&#xff08;redis&#xff09;model&#xff08;数据库连接&#xff09; 用户注册serializermodelserviceapirouter…

CSS中如何实现元素的旋转和缩放效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 元素的旋转和缩放效果⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏…

打卡智能中国(六):村里出了“飞行员”

提起返乡青年&#xff0c;你的第一印象是什么&#xff1f;失败、躺平、卷不动了&#xff1f; 我们在浙江、福建、青海等地&#xff0c;参观一些农业智能化项目时&#xff0c;陪同参观的“飞手”&#xff0c;高兴地跟我们分享自己的心路历程&#xff1a; 在家门口做农业无人机操…

每日一题 98验证二叉搜索树(中序遍历)

题目 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#xff1a…

Java-API简析_java.net.Inet4Address类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/132643590 出自【进步*于辰的博客】 因为我发现目前&#xff0c;我对Java-API的学习意识比较薄弱…

2023开学礼新疆财经大学图书馆藏八一新书《乡村振兴战略下传统村落文化旅游设计》许少辉新财经理工

2023开学礼新疆财经大学图书馆藏八一新书《乡村振兴战略下传统村落文化旅游设计》许少辉新财经理工

【经济研究】论文《经济ZC不确定性与创新》数据复现

数据简介&#xff1a;当前宏观经济面临较大下行压力&#xff0c;需要“稳中求进”兼顾经济高质量发展与经济增速等多种目标&#xff0c;这就不可避免地导致各种经济ZC的频繁调整&#xff0c;产生不确定性风险。在此背景下&#xff0c;经济政策不确定性上升如何影响企业决策&…

无涯教程-JavaScript - RANK函数

RANK函数取代了Excel 2010中的RANK.EQ函数。 描述 该函数返回数字列表中数字的等级。数字的等级是其相对于列表中其他值的大小。 如果对列表进行排序,则数字的排名将是其位置。 语法 RANK (number,ref,[order])争论 Argument描述Required/OptionalNumberThe number whose…

c++11 标准模板(STL)(std::basic_stringstream)(四)

定义于头文件 <sstream> template< class CharT, class Traits std::char_traits<CharT> > class basic_stringstream;(C11 前)template< class CharT, class Traits std::char_traits<CharT>, class Allocator std::alloc…