近似最近邻查找的几种方法

近似最近邻查找

  • 定义
  • 主要方法
    • 1. 局部敏感哈希(LSH)
    • 2. KD树(k-d tree)
    • 3. 球树(Ball Tree)
    • 4. 随机投影树(Random Projection Trees)
    • 5. 图结构方法(Graph-Based Methods)
    • 6. 产品量化(Product Quantization, PQ)
    • 结论

定义

近似最近邻查找(Approximate Nearest Neighbor Search, ANNS)是一种在高维空间中查找与查询点距离最近的若干个点的技术。与精确最近邻查找不同,近似最近邻查找允许一定程度的误差,以换取更高的查询效率和更低的计算成本。

主要方法

近似最近邻查找的常用方法包括以下几种:

  1. 局部敏感哈希(Locality-Sensitive Hashing, LSH)
  2. KD树(k-d tree)
  3. 球树(Ball Tree)
  4. 随机投影树(Random Projection Trees)
  5. 图结构方法(Graph-Based Methods)
  6. 产品量化(Product Quantization, PQ)

1. 局部敏感哈希(LSH)

方法描述
LSH通过将相似的数据点映射到相同的哈希桶中,从而快速找到近似最近邻。LSH使用多个哈希函数来降低误差。

  • 优点
  1. 高效:在高维空间中查询速度快。
  2. 简单:实现相对简单。
  • 缺点
  1. 精度:精度可能不如其他方法高。
  2. 空间复杂度:需要较多的内存来存储哈希表。

代码示例

import numpy as np
from sklearn.neighbors import LSHForest# 创建数据集
data = np.random.rand(100, 5)  # 100个点,每个点5维
query = np.random.rand(1, 5)   # 查询点# 使用LSHForest进行近似最近邻查找
lshf = LSHForest(n_estimators=10, n_candidates=50)
lshf.fit(data)
distances, indices = lshf.kneighbors(query, n_neighbors=3)print(indices)  # 最近邻点的索引
print(distances)  # 最近邻点的距离

2. KD树(k-d tree)

方法描述
KD树是一种二叉树结构,用于组织k维空间中的点。适用于低维空间的精确最近邻查找,但在高维空间中性能下降。

  • 优点
  1. 精确:提供精确的最近邻结果。
  2. 适用性:适用于低维空间。
  • 缺点
  1. 高维空间:在高维空间中性能较差。
  2. 构建时间:构建KD树的时间复杂度较高。
    代码示例
from sklearn.neighbors import KDTree# 创建数据集
data = np.random.rand(100, 5)  # 100个点,每个点5维
query = np.random.rand(1, 5)   # 查询点# 使用KDTree进行近似最近邻查找
tree = KDTree(data)
distances, indices = tree.query(query, k=3)print(indices)  # 最近邻点的索引
print(distances)  # 最近邻点的距离

3. 球树(Ball Tree)

方法描述
球树是一种分层数据结构,用于组织高维空间中的点。通过递归地将数据集划分为球体,可以高效地进行最近邻查找。

  • 优点
  1. 高效:在高维空间中查询速度较快。
  2. 适用性:适用于高维空间。
  • 缺点
  1. 构建时间:构建球树的时间复杂度较高。
  2. 精度:在极高维空间中精度可能下降。

代码示例

from sklearn.neighbors import BallTree# 创建数据集
data = np.random.rand(100, 5)  # 100个点,每个点5维
query = np.random.rand(1, 5)   # 查询点# 使用BallTree进行近似最近邻查找
tree = BallTree(data)
distances, indices = tree.query(query, k=3)print(indices)  # 最近邻点的索引
print(distances)  # 最近邻点的距离

4. 随机投影树(Random Projection Trees)

方法描述
随机投影树通过随机选择投影方向将高维数据投影到低维空间,从而构建树结构进行近似最近邻查找。

  • 优点
  1. 高效:在高维空间中查询速度较快。
  2. 简单:实现相对简单。
  • 缺点
  1. 精度:精度可能不如其他方法高。
  2. 随机性:结果可能受随机投影方向影响。
    代码示例
import numpy as np
from sklearn.random_projection import SparseRandomProjection# 创建数据集
data = np.random.rand(100, 5)  # 100个点,每个点5维
query = np.random.rand(1, 5)   # 查询点# 使用随机投影降维
transformer = SparseRandomProjection(n_components=3)
data_transformed = transformer.fit_transform(data)
query_transformed = transformer.transform(query)# 使用BallTree进行近似最近邻查找
tree = BallTree(data_transformed)
distances, indices = tree.query(query_transformed, k=3)print(indices)  # 最近邻点的索引
print(distances)  # 最近邻点的距离

5. 图结构方法(Graph-Based Methods)

方法描述
基于图的近似最近邻查找方法通过构建一个图结构,其中节点表示数据点,边表示相似度关系。查询时通过图的遍历找到近似最近邻。

  • 优点
  1. 高效:在高维空间中查询速度较快。
  2. 扩展性:适用于大规模数据集。
  • 缺点
  1. 构建时间:构建图的时间复杂度较高。
  2. 实现复杂:实现相对复杂。
    代码示例
import hnswlib# 创建数据集
data = np.random.rand(100, 5).astype(np.float32)  # 100个点,每个点5维
query = np.random.rand(1, 5).astype(np.float32)   # 查询点# 使用HNSW进行近似最近邻查找
dim = data.shape[1]
num_elements = data.shape[0]# Declaring index
p = hnswlib.Index(space='l2', dim=dim)# Initializing index
p.init_index(max_elements=num_elements, ef_construction=100, M=16)# Adding data
p.add_items(data)# Controlling the recall by setting ef
p.set_ef(50)# Querying the elements
labels, distances = p.knn_query(query, k=3)print(labels)  # 最近邻点的索引
print(distances)  # 最近邻点的距离

6. 产品量化(Product Quantization, PQ)

方法描述
产品量化通过将数据向量分成多个子向量,对每个子向量进行量化,从而减少存储和计算成本。

  • 优点
  1. 存储效率:显著减少存储空间。
  2. 查询效率:在高维空间中查询速度较快。
  • 缺点
  1. 精度:精度可能不如其他方法高。
  2. 实现复杂:实现相对复杂。

代码示例

import faiss
import numpy as np# 创建数据集
data = np.random.rand(100, 128).astype(np.float32)  # 100个点,每个点128维
query = np.random.rand(1, 128).astype(np.float32)   # 查询点# 使用产品量化进行近似最近邻查找
d = data.shape[1]
nlist = 10  # 聚类中心的数量
m = 8       # 子向量的数量
k = 3       # 需要查找的最近邻数量quantizer = faiss.IndexFlatL2(d)  # 使用L2距离
index = faiss.IndexIVFPQ(quantizer, d, nlist, m, 8)
index.train(data)
index.add(data)index.nprobe = 5  # 设置查询时使用的聚类中心的数量
distances, indices = index.search(query, k)print(indices)  # 最近邻点的索引
print(distances)  # 最近邻点的距离

结论

近似最近邻查找在高维空间中查找与查询点距离最近的点时具有重要意义。常用的方法包括局部敏感哈希(LSH)、KD树、球树、随机投影树、

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

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

相关文章

自制全网最便宜的雷达感应灯光画,成本只需5元

自制全网最便宜的雷达感应灯光画,成本5元 ​ 成本组成:带热释电的人体感应灯(0.5元)雷达感应模块(3.5元)首饰盒(0.45元)微喷油画布(1元)5.45元 ​ 说一下做灯…

Flutter学习:从搭建环境到运行

一、开发环境的搭建 本文所示内容都是在Windows系统下进行的。 1、下载 Flutter SDK Flutter 官网(https://docs.flutter.cn/release/archive?tabwindows) 或者通过 git clone -b master https://github.com/flutter/flutter.git 下载 2、配置环境…

[数据集][目标检测]井盖未盖好检测数据集VOC+YOLO格式20123张2类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):20123 标注数量(xml文件个数):20123 标注数量(txt文件个数):20123 标…

Gamepad API 控制游戏的 JavaScript 指南

在现代网页游戏中,通过游戏手柄来控制游戏是一种常见的需求。HTML5 提供了一个名为 Gamepad API 的接口,使得从浏览器中读取游戏手柄输入变得相对简单。 什么是 Gamepad API? Gamepad API 是 HTML5 的一部分,允许开发者通过 Jav…

.net 奇葩问题调试经历之2——内存暴涨,来自非托管的内存泄露

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不仅仅是技术还有人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔序言 这是一个序列文章,请看以往文…

AI推介-信息抽取(information extraction,NER)论文速览(arXiv方向):2023.11.15-2023.12.31

文章目录~ 1.Large Language Models for Generative Information Extraction: A Survey2.Commonsense for Zero-Shot Natural Language Video Localization3.Unified Lattice Graph Fusion for Chinese Named Entity Recognition4.Solving Label Variation in Scien…

代码统计工具V1.0.0(支持各种文件类型)

点击下载《代码统计工具(支持各种文件类型)》 1. 前言 本文介绍了一款使用C#开发的代码行数统计软件。该软件允许用户通过选择文件目录和设置统计项目类型,来统计指定目录下的代码行数。软件提供了三种统计方式:按文件名统计、按…

线性图标绘制指南:从基础到精通

图标在生活中随处可见。相比文字来说,图标可以让人在更短的时间内认知并了解信息,并且大大提升信息的视觉美观性,增加设计的艺术感染力。在用户界面中使用图标,是一种用户熟知的设计模式。而线性图标是通过提炼图形轮廓&#xff0…

jquery动态插件之gsap和TextPlugin

<!DOCTYPE html> <html> <head><title>数字化人才认证数动画</title><script src"https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script><script src"https://cdnjs.cloudflare.com/ajax…

【强化学习】第02期:动态规划方法

笔者近期上了国科大周晓飞老师《强化学习及其应用》课程&#xff0c;计划整理一个强化学习系列笔记。笔记中所引用的内容部分出自周老师的课程PPT。笔记中如有不到之处&#xff0c;敬请批评指正。 文章目录 2.1 动态规划&#xff1a;策略收敛法/策略迭代法2.2 动态规划&#xf…

GD32F4时钟配置

1.前言 硬件&#xff1a;GD32F450 最高时钟频率200MHZ(外部晶振8MHZ) 软件&#xff1a;KEIL(V5.35) 固件包&#xff1a;GD32F4xx_Firmware_Library_V3.2.0 2.时钟树 时钟配置大概流程如下图红线指示&#xff0c;GD32F470的最高频率可以到240MHZ&#xff0c;GD32F450最高…

【frp】cron定时检查zfrpc.service是否启动成功

zfrpc 经常自动启动失败cron定时检查zfrpc.service是否启动成功 ChatGPT 要使用 cron 定期检查 zfrpc.service 是否启动成功,并在服务未运行时尝试启动它,你可以按照以下步骤进行操作: 创建脚本 首先,你需要创建一个脚本,这个脚本将检查 zfrpc.service 的状态,并在服务未…

字符串反转字符串单词(1)

大家好&#xff0c;今天我们来探讨一道经典的编程问题——翻转字符串里的单词。这个问题要求我们编写一个函数&#xff0c;将输入字符串中的所有单词进行翻转&#xff0c;但单词内部的字符顺序保持不变。 问题分析&#xff1a; 1. 首先&#xff0c;我们需要理解翻转字符串里的…

Codeforces Round 143 (Div. 2) C. To Add or Not to Add 题解 前缀和 二分

To Add or Not to Add 题目描述 A piece of paper contains an array of n n n integers a 1 , a 2 , . . . , a n a_{1},a_{2},...,a_{n} a1​,a2​,...,an​. Your task is to find a number that occurs the maximum number of times in this array. However, before l…

点云压缩配置开发环境遇到一些bug

1、配置基于cuda的计算库&#xff0c;Chamfer3D和pointops 编译chamfer3D时候会遇到一个cub版本的校验错误。 解决方法&#xff1a;根据错误提示&#xff0c;进入cuda的config配置文件中&#xff0c;使用#define将校验功能关闭 编译pointops&#xff0c;会遇到报错&#xff1a;…

C++Primer Plus 第十四章代码重用:14.4.4 数组模板示例和非类型参数2

14.4.4 数组模板示例和非类型参数 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右…

《分析模式》漫谈08-单继承不是“唯一继承”

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 《分析模式》第2章这一段&#xff1a; 划线处的single inheritance&#xff0c;2004中译本的翻译&#xff1a; 翻译为“单继承”&#xff0c;是正确的。 2020中译本的翻译&#xff1a…

Java NIO(一) 概述

NIO主要用于以少量线程来管理多个网络连接&#xff0c;处理其上的读写等事件。在大量连接情况下&#xff0c;不管是效率还是空间占用都要优于传统的BIO。 Java NIO 由以下几个核心部分组成&#xff1a; Channel Buffer Selector Selector 如果你的应用打开了多个连接&#x…

分页插件 count有数据,代码不往下执行

如下:如果打印了sql那么当row>0时会有图2下面sql详情的输出 问题出在了分页参数上,pageNum为1,并且pageSize>2才能打印出图二的结果,图一为pageNum值是0,注意,查询第一页,分页应该传入的是1而不是0

大数据批处理系统和业务系统是两种不同类型的系统,它们在目的、设计、功能和使用场景上有所区别

大数据批处理系统和业务系统是两种不同类型的系统&#xff0c;它们在目的、设计、功能和使用场景上有所区别。以下是大数据批处理系统和业务系统之间的一些主要差异&#xff1a; 1. **目的**&#xff1a; - **大数据批处理系统**&#xff1a;主要用于处理和分析大量数据&am…