探索 HNSW:分层导航小世界算法的深度解析

近年来,随着大规模数据和高维数据的广泛应用,高效的近似最近邻(Approximate Nearest Neighbor, ANN)搜索变得越来越重要。HNSW(Hierarchical Navigable Small World)算法因其出色的性能和高效的查询速度,逐渐成为ANN搜索领域的重要工具。在这篇博客中,我们将深入解析HNSW算法的原理、实现细节及其应用,帮助读者全面理解这一强大的算法。

什么是HNSW?

HNSW,全称为Hierarchical Navigable Small World,是一种用于高维空间中进行近似最近邻搜索的图结构算法。它基于小世界网络(Small World Networks)的概念,通过构建多层次的图结构,实现快速高效的搜索。

小世界网络简介

小世界网络是一种特殊的图结构,其特点是具有较短的平均路径长度和较高的聚集系数。这意味着在这种网络中,任意两个节点之间的路径长度相对较短,同时节点之间的连接具有很高的局部聚集性。小世界网络的这些特性使其非常适合于高效的搜索和导航。

HNSW的基本概念

HNSW通过构建多层次的小世界网络,实现高效的近似最近邻搜索。它的核心思想是:

  1. 层次化图结构:HNSW构建了一个由多层次图组成的结构,每一层次的图都是一个小世界网络,顶层的节点数最少,底层的节点数最多。
  2. 导航小世界:通过从顶层向底层逐层导航,实现高效的最近邻搜索。每一层次的图都可以被视为一个小世界网络,能够提供快速的局部搜索能力。

HNSW的算法详解

接下来,我们将详细探讨HNSW算法的构建过程、搜索过程及其关键技术细节。

构建过程

HNSW的构建过程包括两个主要步骤:插入节点和构建层次图。

插入节点

插入节点是HNSW算法的基础操作之一。在插入一个新节点时,算法会依次决定它在每一层次图中的位置。具体步骤如下:

  1. 随机层次选择:首先,为新节点随机选择一个最大层次。这个层次决定了新节点在构建图时的起始层次。
  2. 逐层插入:从最高层次开始,逐层向下插入新节点。在每一层次,算法会选择该层次中的一个节点作为起始点,并通过贪心策略找到新节点的近邻节点,将其插入图中。
构建层次图

在插入节点的过程中,HNSW会逐层构建小世界网络。具体来说:

  1. 初始层次:构建初始层次图时,节点之间的连接主要通过贪心策略确定,确保较短路径和高效搜索。
  2. 多层次扩展:随着节点的插入,逐层扩展图结构,每一层次图都作为下一层次图的基础,不断增强网络的连接性和搜索效率。

搜索过程

HNSW的搜索过程也可以分为两个主要步骤:初始导航和逐层优化。

初始导航

在搜索过程中,算法首先从最高层次的图开始,选择一个起始节点作为搜索的起点。通过贪心策略,算法会不断选择当前节点的最优近邻节点,逐步靠近目标节点。

逐层优化

当算法到达最低层次时,将进行逐层优化搜索。在每一层次中,算法会通过局部搜索不断优化当前解,确保找到最优的近似最近邻节点。

关键技术细节

贪心策略

HNSW中的贪心策略是指在每一步选择当前节点的最优近邻节点,从而快速接近目标节点。这一策略的关键在于如何定义和计算最优近邻。

多层次结构

HNSW的多层次结构是其高效搜索的核心。通过逐层导航,算法能够快速缩小搜索范围,提高搜索效率。

HNSW的优势与局限

优势

  1. 高效的搜索性能:HNSW的多层次结构和贪心策略使其在高维数据中具有出色的搜索性能。
  2. 动态更新能力:HNSW支持动态插入节点,能够适应不断变化的数据集。
  3. 内存友好:相比其他图结构,HNSW的内存使用效率较高,适合大规模数据集。

局限

  1. 构建复杂度:HNSW的构建过程较为复杂,特别是在大规模数据集上,构建时间可能较长。
  2. 参数调优:HNSW的性能依赖于多个参数的设置,需要进行一定的调优工作。

HNSW的应用场景

HNSW在多个领域有广泛应用,尤其是在需要高效ANN搜索的场景中,如推荐系统、图像检索、自然语言处理等。

推荐系统

在推荐系统中,HNSW可以用于高效的用户和商品匹配,提高推荐精度和响应速度。

图像检索

HNSW在图像检索中可以用于快速匹配相似图像,提高检索效率。

自然语言处理

在自然语言处理领域,HNSW可以用于快速匹配相似文本,提高文本检索和分类的性能。

HNSW的实现

接下来,我们将通过具体代码示例,展示如何实现HNSW算法。

插入节点

import random
import heapqclass HNSW:def __init__(self, max_elements, M=16, ef_construction=200):self.max_elements = max_elementsself.M = Mself.ef_construction = ef_constructionself.layers = []self.enter_point = Nonedef insert(self, element):layer = self._random_level()self._insert_at_layer(element, layer)def _random_level(self):level = 0while random.random() < 0.5 and level < self.max_elements:level += 1return leveldef _insert_at_layer(self, element, layer):if not self.layers:self.layers.append([])while len(self.layers) <= layer:self.layers.append([])if self.enter_point is None:self.enter_point = elementself.layers[layer].append(element)else:current = self.enter_pointfor l in reversed(range(layer, len(self.layers))):current = self._search_layer(element, current, l)self.layers[layer].append(element)self._connect_new_element(element, layer)def _search_layer(self, element, current, layer):neighbors = self.layers[layer]while True:closest = min(neighbors, key=lambda x: self._distance(element, x))if closest == current:breakcurrent = closestreturn currentdef _connect_new_element(self, element, layer):neighbors = self.layers[layer]candidates = self._select_neighbors(element, neighbors)for neighbor in candidates:self._add_connection(element, neighbor, layer)def _select_neighbors(self, element, neighbors):candidates = heapq.nsmallest(self.M, neighbors, key=lambda x: self._distance(element, x))return candidatesdef _add_connection(self, element, neighbor, layer):pass  # 连接逻辑def _distance(self, a, b):return sum((ai - bi) ** 2 for ai, bi in zip(a, b)) ** 0.5

搜索节点

class HNSW:# previous codedef search(self, query, k=1):current = self.enter_pointfor layer in reversed(range(len(self.layers))):current = self._search_layer(query, current, layer)candidates = [current]visited = set(candidates)results = []while candidates:current = candidates.pop(0)results.append(current)neighbors = self.layers[0]  # 只在最低层次进行邻居搜索for neighbor in neighbors:if neighbor not in visited:visited.add(neighbor)candidates.append(neighbor)candidates.sort(key=lambda x: self._distance(query, x))results = sorted(results, key=lambda x: self._distance(query, x))[:k]return resultsdef _search_layer(self, element, current, layer):neighbors = self.layers[layer]while True:closest = min(neighbors, key=lambda x: self._distance(element, x))if closest == current:breakcurrent = closestreturn current

总结

HNSW算法通过构建多层次的小世界网络,实现了高效的近似最近邻搜索。其出色的搜索性能和动态更新能力使其在

多个领域得到了广泛应用。虽然HNSW的构建过程和参数调优较为复杂,但其优越的性能使得这些投入是值得的。

希望通过这篇博客,读者能够对HNSW算法有一个全面的了解,并能够在实际应用中灵活运用这一强大的工具。如果你对HNSW算法有更多的兴趣,建议进一步阅读相关文献和源码,深入理解其原理和实现细节。

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

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

相关文章

JAVAEE认证题库

1、&#xff08;2分&#xff09;下列哪个命令用于在Tomcat服务器上启动一个特定的Web应用程序&#xff1f; A、catalina.bat start B、catalina.bat deploy C、catalina.bat stop D、catalina.bat run 你的答案&#xff1a;D正确答案&#xff1a;A 2、&#xff08;2分&am…

毕业了!给学计算机朋友的 10 条血泪建议

大家好&#xff0c;我是程序员鱼皮。最近高考结束了&#xff0c;也有很多同学毕业了&#xff0c;首先祝福这些朋友在人生的新阶段一帆风顺。 刚参加完高考的朋友&#xff0c;面临的最大问题就是选专业&#xff0c;这段时间也有一些家长向我咨询&#xff1a;还能不能选计算机啦…

人脸匹配——OpenCV

人脸匹配 导入所需的库加载dlib的人脸识别模型和面部检测器读取图片并转换为灰度图比较两张人脸选择图片并显示结果比较图片创建GUI界面运行GUI主循环运行显示全部代码 导入所需的库 cv2&#xff1a;OpenCV库&#xff0c;用于图像处理。 dlib&#xff1a;一个机器学习库&#x…

爬山算法(Hill Climbing Algorithm)详细介绍

爬山算法&#xff08;Hill Climbing Algorithm&#xff09;详细介绍 1. 概述 爬山算法&#xff08;Hill Climbing Algorithm&#xff09;是一种基于启发式的搜索算法&#xff0c;广泛应用于人工智能、运筹学和优化问题。该算法以当前状态为起点&#xff0c;不断选择邻域中能够…

基于深度学习视觉算法的多模型文件融合检测系统设计与实现及优化(工人姿态检测+安全帽佩戴检测系统)

1&#xff0c;融合pose.pt(姿态检测)(安全帽佩戴检测)效果图 实时检测优化后FPS可达20 2,原理介绍 YOLOv5是目前应用广泛的目标检测算法之一&#xff0c;其主要结构分为两个部分&#xff1a;骨干网络和检测头。 输入&#xff08;Input&#xff09;: YOLOv5的输入是一张RGB图像…

定档6.20,创邻科技图数据库先锋版发布会来了!

6月20日 14:00 &#xff0c;创邻科技将重磅召开 2024 Galaxybase银河图数据库先锋版发布会&#xff0c;戳此预约&#xff01; 书于竹帛&#xff0c;镂于金石&#xff0c;琢于盘盂。历史长河中&#xff0c;数据通过不同形态承载着人类文明&#xff0c;人们在数千年中始终保持着…

微信小程序:实现音乐播放器的功能

在编写微信小程序时&#xff0c;也许会用到播放背景音乐的功能&#xff0c;那么如果是自动播放背景音乐&#xff0c;可以在加载页面时就运行播放音乐的函数&#xff0c;若是希望简单实现音乐播放器的功能&#xff0c;那么设计几个按钮&#xff0c;并且设计按钮点击的事件。 接…

使用Python和Matplotlib绘制复杂数学函数图像

本文介绍了如何使用Python编程语言和Matplotlib库来绘制复杂的数学函数图像。通过引入NumPy库的数学函数,我们可以处理包括指数函数在内的各种复杂表达式。本文详细讲解了如何设置中文字体以确保在图像中正确显示中文标题和标签,并提供了一个完整的代码示例,用户可以通过输入…

找不到xinput1_3.dll文件要怎么修复?有哪些有效修复xinput1_3.dll文件的方法

要解决xinput1_3.dll文件缺失的问题&#xff0c;首先我们需要对这个文件有所了解。理解了这个文件的性质和作用后&#xff0c;才能更科学、有效地解决因其丢失而导致的问题。那么接下来&#xff0c;让我们不浪费时间&#xff0c;直接深入研究如何修复xinput1_3.dll文件的最佳方…

震坤行亮相2024成都工博会,赋能产业新发

为期3天的成都工博会于2024年4月23日在成都国际会展中心完美落幕。震坤行再次紧跟西部智能制造产业发展步伐&#xff0c;亮相现场&#xff0c;实力“圈粉”&#xff0c;为西部地区的制造企业带来打造了一场工业互联网盛宴。 本届成都工博会成功举办&#xff0c;展会聚集了各个国…

在ubuntu中恢复误删除的文件

1、安装 TestDisk 在 Ubuntu 上&#xff0c;可以使用以下命令安装 TestDisk&#xff1a; sudo apt-get install testdisk2、查询你删除的文件所在那个分区 #查询分区 df -h #我这里是/dev/sda2 #也可以使用下面命令查看具体哪个分区 lsblk3、查询该分区是什么系统类型 sudo …

java:【@ComponentScan】和【@SpringBootApplication】扫包范围的冲突

# 代码结构如下&#xff1a; 注意【com.chz.myBean.branch】和【com.chz.myBean.main】这两个包是没有生重叠的。 主程序【MyBeanTest1、MyBeanTest2、MyBeanTest3】这两个类是在包【com.chz.myBean.main】下 # 示例代码 【pom.xml】 org.springframework.boot spring-boot-…

spark mllib 特征学习笔记 (二)

当然&#xff0c;请继续介绍其他特征处理方法的公式、适用场景和案例&#xff1a; 10. StringIndexer 公式&#xff1a; 将字符串类型的标签转换为数值索引&#xff1a; StringIndexer ( x ) { 0 , 1 , 2 , … , N − 1 } \text{StringIndexer}(x) \{0, 1, 2, \ldots, N-1…

java采集微信公众号数据

需求背景: 最新需要调用微信公众号api 去微信公众号采集 发布文章数据。 &#xff08;本片文章的意义&#xff1a;根据自己开发的方案来提供思路&#xff0c;当然那不会提供代码。代码是最没有 含金量的东西。&#xff09; 1:遇到的坑:首先 想到的是调用 https://api.weixin…

科技项目验收测试必须进行吗?软件测试公司推荐

科技项目验收测试是指在科技项目开发周期中&#xff0c;对项目完成后进行的一种测试和评估工作。它的目的是验证项目是否达到预期的要求&#xff0c;并确保项目交付给客户前达到预期的质量标准。 一、科技项目验收测试的必要性   科技项目验收测试是项目管理中不可或缺的一个…

Maven认识与学习

1. Maven介绍 1.2 初识Maven 1.2.1 什么是Maven Maven是Apache旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具。 官网&#xff1a;Maven – Welcome to Apache Maven Apache 软件基金会&#xff0c;成立于1999年7月&#xff0c;是目前世界上最大的最受…

Linux C语言:变量的作用域和生命周期(auto、register、static和extern)

一、变量存储类型-auto 1、auto变量的说明 变量在程序中使用时,必须预先说明它们的存储类型和数据类型。 变量说明的一般形式是&#xff1a; <存储类型> <数据类型 > <变量名> &#xff1b; <存储类型>是关键词auto、register、static和extern<…

湘江早报专访惟客数据李柯辰:湖南伢子返湘玩转“AI+金融”

来源 |《湘江早报》 记者 | 黄荣佳 ​ 随着数字化浪潮的到来&#xff0c;AI的风吹遍了各行各业&#xff0c;金融作为对新兴技术最敏感的行业&#xff0c;前沿技术的赋能&#xff0c;让金融科技成为行业发展的“新赛点”。作为一家以大数据和AI人工智能技术驱动的新一代数字化…

多源最短路径算法 -- 弗洛伊德(Floyd)算法

1. 简介 Floyd算法&#xff0c;全名为Floyd-Warshall算法&#xff0c;亦称弗洛伊德算法或佛洛依德算法&#xff0c;是一种用于寻找给定加权图中所有顶点对之间的最短路径的算法。这种算法以1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特弗洛伊德的名字命名。 2. 核心思…

加码多肤色影像技术 这是传音找到的“出海利器“?

全球化时代&#xff0c;市场竞争愈演愈烈&#xff0c;产品差异化已然成为了企业脱颖而出的关键。在黄、白肤色长期占据人像摄影主赛道的背景下&#xff0c;传音就凭借独一无二的多肤色影像技术走出非洲&#xff0c;走向了更广阔的新兴市场。 聚焦深肤色人群拍照痛点&#xff0c…