检索--ANN

专题1:ANN和KNN的对比

K-Nearest Neighbor (KNN):

  1. 定义: KNN是一种通用的分类与回归分析的算法,它在向量检索中的作用是,通过计算样本之间的欧氏距离来找出k个最近的样本。

  2. 算法特性:

    1. 精度:由于它是基于实际距离计算的,所以结果是精确的。

    2. 时间复杂度:高,寻找最近邻需要对所有样本进行距离计算,时间复杂度为O(n)。

    3. 空间复杂度:低,通常只存储样本数据。

  3. 适用场景:

    1. 数据量较小。

    2. 精度要求非常高的场景。

Approximate Nearest Neighbor (ANN):

  1. 定义: ANN是一种近似算法,用于加速高维空间近邻查询。它通过一些近似方法来避免对所有数据点进行精确距离计算,因此显著提高了检索速度。

  2. 算法特性:

    1. 精度:由于是近似方法,可能结果不是绝对精确的,但一般精度可以保证在可接受范围内。

    2. 时间复杂度:低,通过近似计算和加速结构(如IVF、LSH、VP-Tree、HNSW等)可以大大减少计算量。

    3. 空间复杂度:通常较高,因为需要额外的信息来加快索引和查询过程。

  3. 适用场景:

    1. 数据量大(大规模向量数据集)。

    2. 对实时性能要求高的场景(如实时推荐、搜索等)。

    3. 可以接受近似答案的场景。

专题2:IVF原理

Step1:分割区域

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

有时Voronoi(沃罗诺伊, 中文发音)区域(region)也被称为单元(cell)或者分区/划分(partitions)

Step2:选择TOPk

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

最终, 通过计算query到所有候选向量的距离并选择其中最接近的前$k$个, 作为结果返回.

Step3:边缘问题

随着搜索速度的提升, 倒排文件也会有一个缺点: 无法保证找到的对象始终是最近邻.

在下图中, 我们可以看到, 实际的最近邻在红色区域, 但是我们仅仅从绿色区域中选择候选者, 这种情况就是边缘问题

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

专题3:HNSW原理

HNSW全称Hierarchical NSW,NSW是Navigable Small World,即“可导航小世界网络”算法。

何为小世界网络?现实世界中,处处都是小世界网络。比如A跟B是微信好友,B跟C是微信好友,但A跟C不是,但是A跟C可以通过B建立起连接。也就是说,世界上任何事物都可以通过间接的途径建立起连接。

https://zhuanlan.zhihu.com/p/379372268

专题3:评价指标

3.1 Hit Rate

计算公式:

假设有5个查询,每个查询的相关文档按如下方式分布(假设相关文档标记为1,非相关文档标记为0):

  • 查询1: [0, 1, 0, 0, 0]

  • 查询2: [1, 0, 0, 0, 0]

  • 查询3: [0, 0, 0, 0, 0]

  • 查询4: [0, 0, 0, 1, 0]

  • 查询5: [0, 0, 1, 0, 0]

计算Hit Rate@3,表示在前3个检索结果中是否有相关文档:

  • 查询1: 前3个结果 [0, 1, 0],包含1(相关文档),所以命中。

  • 查询2: 前3个结果 [1, 0, 0],包含1(相关文档),所以命中。

  • 查询3: 前3个结果 [0, 0, 0],不包含相关文档,所以未命中。

  • 查询4: 前3个结果 [0, 0, 0],不包含相关文档,所以未命中。

  • 查询5: 前3个结果 [0, 0, 1],包含1(相关文档),所以命中。

Hit Rate@3 = (3/5) = 0.6 或 60%。

3.2 召回率

3.3 精确率

3.4 F1-score

### ANN检索算法实现库 对于近似最近邻(ANN检索,存在多种高效的开源实现库。这些库提供了针对不同场景和需求的解决方案,以下是几个常用的ANN检索算法实现库: #### 1. **Faiss** Facebook开发的Faiss是一个专门用于大规模相似性搜索和聚类的高效库[^1]。它支持密集向量的索引构建,并提供了一系列优化过的ANN算法,如IVF(Inverted File System)、PQ(Product Quantization)等。Faiss以其高性能著称,在GPU加速方面表现尤为突出。 ```python import faiss index = faiss.IndexFlatL2(d) # 构建 L2 距离计算的索引 index.add(xb) # 添加训练数据到索引 D, I = index.search(xq, k) # 查询 top-k 结果 ``` #### 2. **Annoy (Approximate Nearest Neighbors Oh Yeah)** 由Spotify开发并维护的Annoy是一种基于随机投影森林的方法来实现ANN搜索的工具[^3]。它的核心思想是将高维空间中的点映射至一棵或多棵二叉树上,从而快速定位可能接近查询点的位置。Annoy适合处理中小规模的数据集,并且可以轻松存储于磁盘文件中以便持久化使用。 ```python from annoy import AnnoyIndex t = AnnoyIndex(f, 'angular') # 初始化 f 维度的空间 for i in range(n): t.add_item(i, v[i]) # 插入第i个样本v[i] t.build(10) # 创建10棵树 result = t.get_nns_by_vector(q, n_results) ``` #### 3. **Hnswlib** Hnswlib实现了Hierarchical Navigable Small World Graphs这一先进算法。此方法利用图结构连接各个节点形成网络路径,使得即使是在超高维度下也能保持较快的速度完成搜索操作。相比其他方案而言,hnswlib更加灵活可控,允许调整参数平衡精度与效率之间的关系。 ```cpp #include <hnswlib/hnswlib.h> using namespace hnswlib; // 定义距离度量方式以及初始化空间对象... Space* space_ptr = new Space(); size_t dim = ... ; std::vector<float> data_point(dim); LabelType label_id; AlgorithmFactory factory(space_ptr,dim,"lsh"); ALSH * alsh_index = dynamic_cast<ALSH*>(factory.create_index()); alsh_index->addPoint(data_point,label_id); // 加载数据进入索引 std::priority_queue<std::pair<double, LabelType>> res_list; alsh_index->searchKnn(query,k,res_list); // 执行kNN查询 ``` #### 4. **LSHForest** 局部敏感哈希(Locality-Sensitive Hashing)[^2] 是一种特别适用于稀疏特征表示情况下的有效策略之一。Scikit-Learn 提供了一个名为 `sklearn.neighbors.LSHForest` 的模块可以直接应用于机器学习项目当中。尽管官方文档提到该功能已被弃用,但它仍然作为理解原理的一个良好起点。 ```python from sklearn.neighbors import LSHForest model = LSHForest() model.fit(X_train) distances, indices = model.kneighbors(X_test, n_neighbors=5) ``` --- ### 总结 上述列举了几种主流的ANN检索算法及其对应的软件包实现形式。每种都有各自的特点及适用范围,实际应用时需根据具体业务背景选取合适的选项。例如,如果追求极致性能并且拥有强大的硬件资源,则可以选择 Faiss 或 Hnswlib;而对于轻量化部署环境来说,Annoy 可能更为合适。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值