ElasticSearch向量检索技术方案介绍

1、背景

      在人工智能快速发展的今天,推荐技术、以文搜图、以文搜视频、以图搜图等技术已经得到了广泛的应用,在百度、小红书、抖音、快手等app上随便输入一段文本,搜索结果已不像早些年那么单一:只有一些文字信息,现在的搜索结果里不仅有文字,还能够搜索出与检索词高度相关的图片、视频、或者商品(电商app),甚至都不用检索,feed流推荐的内容或者商品都是自身感兴趣的,大家一定会有疑问,整个系统背后是如何实现的呢,为什么输入一段文字,就能检索到相关的视频、音频或者图像呢?不同的内容形式,中间是怎么实现的匹配呢?

      答案就是向量匹配,不同形式的内容需要转化成一个统一的结构化数据。

      AI的出现,实现了这个过程,他可以以一定的算法提取文字、图像、音频、视频等各种形式内容的特征向量,实现了将所有内容形式转化为特征向量的过程。

      内容结构化为特征向量后,那么如何进行检索呢?这就涉及到了本文的主题:向量检索了。

2、es向量检索

2.1 检索算法

1、KNN算法

KNN (K-Nearest Neighbor Search)指的是最近邻搜索。它的原理是:计算待查询向量与数据库中所有向量之间的距离,然后按照距离从小到大排序,选择距离最近的 K 个向量作为查询结果。KNN 算法的优点是可以保证精确的结果,但是效率较低。

2、ANN算法

ANN(Approximate Nearest Neighbor Search) 表示近似最近邻搜索,是一种用于高维数据空间中快速查找最近邻点的方法。与KNN(最近邻搜索)相比,ANN 牺牲了一定的精度以换取更高的搜索速度,因此在处理大规模数据集时具有较高的效率。

ANN 会对数据进行预处理,从而在查询时减少计算距离的次数。其优点是速度快、效率高,但精度有所下降。

3、HNSW

HNSW(Hierarchical Navigable Small World) 是一种基于图的高维向量相似性搜索算法。通过构建一张图来表示向量之间的相似度关系,并使用一些优化策略来加速搜索过程。

2.2 向量距离

向量检索的本质就是计算向量之间的距离,向量距离的大小直接反映两个向量的相似程度,距离越小,两个向量越相似,反之,相似度越低。

常用的距离度量有:

  • 欧式距离:l2
  • 余弦距离:cosine
  • 内积:innerproduct

2.3 elasticsearch环境

es使用的是厂内的:百度Elasticsearch,最新版本7.10,支持向量检索。

2.4 创建索引

以下面创建索引的语句为例说明,这个索引即为工作中开发使用到的,只是对字段做了精简。

{
    "settings": {
        "index": {
            "knn": true,
            "number_of_shards": 9,
            "number_of_replicas": 1
        }
    },
    "mappings": {
        "_source": {
            "excludes": [
                "IFV",
                "TFV"
            ]
        },
        "properties": {
            "car_id": {
                "type": "keyword",
                "ignore_above": 256
            },
            "camera_type": {
                "type": "keyword",
                "ignore_above": 256
            },
            "image_id": {
                "type": "keyword",
                "ignore_above": 256,
                "index": false
            },
            "bbox": {
                "properties": {
                    "left": {
                        "type": "integer",
                        "index": false
                    },
                    "top": {
                        "type": "integer",
                        "index": false
                    },
                    "width": {
                        "type": "integer",
                        "index": false
                    },
                    "height": {
                        "type": "integer",
                        "index": false
                    }
                }
            },
            "IFV": {
                "type": "bpack_vector",
                "index_type": "hnsw_sq8",
                "dims": 768,
                "space_type": "l2",
                "parameters": {
                    "m": 32,
                    "ef_construction": 256
                }
            },
            "TFV": {
                "type": "bpack_vector",
                "index_type": "hnsw_sq8",
                "dims": 768,
                "space_type": "innerproduct",
                "parameters": {
                    "m": 32,
                    "ef_construction": 256
                }
            }
        }
    }
}

各重要字段的含义如下: 

字段示例说明
setting{
        "index": {
            "knn": true,
            "number_of_shards": 9,
            "number_of_replicas": 1
        }
    }

knn:设置为ture,开启向量检索功能。

number_of_shards:分片数量,与集群节点数量一致。

number_of_replicas:副本数量,一般设置为1.

excludes
: {
            "excludes": [
                "IMAGE",
                "TEXT"
            ]
        },
这个字段主要是为了减少数据的存储,这样可以大大降低对存储的消耗(IFV、TFV为向量字段)
IMAGE
            "IMAGE": {
                "type": "bpack_vector",
                "index_type": "hnsw_sq8",
                "dims": 768,
                "space_type": "l2",
                "parameters": {
                    "m": 32,
                    "ef_construction": 256
                }
            }

type:向量字段类型固定为 bpack_vector

index_type: 向量检索算法,hnsw算法+sq8量化

dims:向量维度,768维

space_type:距离计算方式,l2,欧式距离

m:hnsw算法参数。此参数表示构造期间为每个新元素创建的双向链接数,主要影响内存、存储消耗以及召回率。m值越高,意味着更高消耗的内存和存储,更慢的索引构建时间,以及更好的召回率。建议根据min(向量维度 * 1.5, 32)取值,以保证性能,12-48可以满足大多数场景的需求。

ef_construction:hnsw算法参数。此参数表示在索引构建过程中,最近邻居的动态扫描区域大小。该值越大,越不容易陷入局部最优解,召回率更高,但是索引构建越慢,取值范围为[2,+∞]。需要注意,如果用户业务需求要求检索top k,那设置的ef_construction值需要大于k。

注意,向量检索算法、维数、距离计算方式千万不能出错,否则会出现检索结果相关性降低,甚至是不相关。

索引创建完成后,就可以正是写入数据了。

2.5 检索

检索dsl:

{
    "size": 2,
    "query": {
        "knn": {
            "image-vector": {
                "vector": [
                    3,
                    4,
                    5,
                    6
                ],
                "k": 2,
                "ef": 100,
                "filter": {
                    "term": {
                        "car_id": "A88888"
                    }
                }
            }
        }
    }
}

百度elasticsearch的向量检索与官方8.x版本es的检索语句稍有不同,支持向量检索和标量的组合检索。

3、代码实现(golang)

向量检索与普通检索在代码的实现上区别不大,重点是dsl的构建与普通检索略有不同,目前在自研的dsl包(elasticsearch查询语言DSL构建包使用及实现原理(golang)_golang es包-CSDN博客)也实现了向量检索dsl的构建,可以直接使用,非常方便,使用示例:

package main

import (
	"fmt"

	"github.com/liupengh3c/esbuilder"
)

func main() {
	vector := []float64{0.045727044343948364, 0.029040496796369553,
		0.02996855601668358, 0.0001537138596177101,
		-0.011850773356854916, 0.016586067155003548,
		0.029250113293528557}
	dslQuery := esbuilder.NewDsl()
	knnQuery := esbuilder.NewKnnQuery("IFV")
	knnQuery.SetK(10).SetEf(256).SetVector(vector)
	filter := esbuilder.NewTermQuery("car_id.keyword", "京AJB139")
	knnQuery.Filter(filter)
	dslQuery.SetQuery(knnQuery)
	fmt.Println(dslQuery.BuildJson())
}

构建的dsl如下:

{
    "query": {
        "knn": {
            "IFV": {
                "ef": 256,
                "filter": {
                    "term": {
                        "car_id.keyword": "京AJB139"
                    }
                },
                "k": 10,
                "vector": [
                    0.045727044343948364,
                    0.029040496796369553,
                    0.02996855601668358,
                    0.0001537138596177101,
                    -0.011850773356854916,
                    0.016586067155003548,
                    0.029250113293528557
                ]
            }
        }
    }
}

含义为,检索car_id为京AJB139且与检索条件中向量近似的数据。

4、展望

      向量检索在信息技术和数据处理领域具有广泛的应用前景和重要性。随着技术的不断发展,向量检索的性能和准确性将不断提高,为各个领域带来更多的创新和价值。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySql中索引为什么用B+树,他有什么特点?时间复杂度是多少?能存多少数据?是不是只能三层?他与B-树有什么不同?还有其它的树你是是否知道?

平衡二叉树 平衡二叉树又被称为AVL树平衡二叉树是一颗空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右子树也是平衡树非叶子节点值大于左子节点值而小于右子节点值非叶子节点最多拥有两个子节点 平衡二叉树的不足之处及时间复杂度 如果每次插入的数据都…

3DMAX城镇建筑区块生成插件TownBlocks使用方法详解

3DMAX城镇建筑区块生成插件TownBlocks使用教程 3DMAX城镇建筑区块生成插件TownBlocks,是一款专为城镇建筑区块生成设计的实用工具,它能够实现从2D轮廓到低多边形城镇建筑群的一键批量转换。该插件不仅操作简便,而且提供了丰富的参数设置选项&…

手机内卷下一站,AI Agent

作者 | 辰纹 来源 | 洞见新研社 2024年除夕夜,OPPO在央视春晚即将开始前举办了一场“史上最短发布会”,OPPO首席产品官刘作虎宣布,“OPPO正式进入AI手机时代”。 春节假期刚过,魅族又公开表示,将停止“传统智能手机…

A021基于Spring Boot的自习室管理和预约系统设计与实现

🙊作者简介:在校研究生,拥有计算机专业的研究生开发团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹 赠送计算机毕业设计600…

浮点数二进制在线转换器

具体请前往:浮点数在线转二进制工具--在线将10进制浮点数(float)转化为4字节32位的二进制序列

探索 Python 的新边疆:sh 库的革命性功能

文章目录 **探索 Python 的新边疆:sh 库的革命性功能**第一部分:背景介绍第二部分:sh 库是什么?第三部分:如何安装 sh 库?第四部分:简单库函数使用方法1. 执行 ls 命令2. 使用 grep 搜索文件内容…

【GeoJSON在线编辑平台】(2)吸附+删除+挖孔+扩展

前言 在上一篇的基础上继续开发,补充上吸附功能、删除矢量、挖孔功能。 实现 1. 吸附 参考官方案例:Snap Interaction 2. 删除 通过 removeFeature 直接移除选中的要素。 3. 挖孔 首先是引入 Turf.js ,然后通过 mask 方法来实现挖孔的…

吾店云介绍 – 中国人的WordPress独立站和商城系统平台

经过多年在WordPress建站领域的摸索和探索,能轻松创建和管理各种类型网站的平台 – 吾店云建站平台诞生了。 应该说这是一个艰苦卓绝的过程,在中国创建一个能轻松创建和使用WordPress网站的平台并不容易,最主要是网络环境和托管软件的限制。…

【动手学电机驱动】STM32-FOC(6)基于 IHM03 的无感方波控制

STM32-FOC(1)STM32 电机控制的软件开发环境 STM32-FOC(2)STM32 导入和创建项目 STM32-FOC(3)STM32 三路互补 PWM 输出 STM32-FOC(4)IHM03 电机控制套件介绍 STM32-FOC(5&…

94.【C语言】数据结构之双向链表的初始化,尾插,打印和尾删

目录 1.双向链表 2.结构体的定义 3.示意图 3.代码示例 1.双向链表的尾插 示意图 代码 main.c List.h List.c 详细分析代码的执行过程 双向链表的初始化 2.双向链表的打印 代码 3.双向链表的尾删 1.双向链表 以一种典型的双向链表为例:带头双向循环链表(带头:带…

「QT」几何数据类 之 QPoint 整型点类

✨博客主页何曾参静谧的博客📌文章专栏「QT」QT5程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid…

黑马点评1 session实现短信验证码登录

1 什么是session cookie的session的应用场景:cookie可以用来保存用户的登陆信息,如果删除cookie则下一次用户仍需要重新登录 session就类似于我们拿到钥匙去开锁,拿到的就是我们个人的信息,一般我们可以在session中存放个人的信息…

[Docker#3] LXC | 详解安装docker | docker的架构与生态

目录 1.LXC容器操作 安装LXC LXC容器操作步骤 2.理论 LXC 是什么? Docker 是什么 Docker 和虚拟机的区别 Docker 和 JVM 虚拟化的区别 Docker 版本 ⭕Docker 官方网站(建议收藏) Docker 架构 生活案例 Docker 生态 Docker 解决…

MySQL数据库专栏(五)连接MySQL数据库C API篇

摘要 本篇文章主要介绍通过C语言API接口链接MySQL数据库,各接口功能及使用方式,辅助类的封装及调用实例,可以直接移植到项目里面使用。 目录 1、环境配置 1.1、添加头文件 1.2、添加库目录 2、接口介绍 2.1、MySql初始化及数据清理 2.1.…

从0开始深度学习(27)——卷积神经网络(LeNet)

1 LeNet神经网络 LeNet是最早的卷积神经网络之一,由Yann LeCun等人在1990年代提出,并以其名字命名。最初,LeNet被设计用于手写数字识别,最著名的应用是在美国的邮政系统中识别手写邮政编码。LeNet架构的成功证明了卷积神经网络在…

如何用C#和Aspose.PDF实现PDF转Word工具

在本篇博文中,我将详细讲解如何用C#实现一个PDF转Word工具。这款工具基于Aspose.PDF库,实现PDF文件转为Word(DOC/DOCX)格式的功能,并通过用户友好的界面和状态提示提升用户体验。希望通过这篇文章帮助大家理解软件的实…

运维技术之文件系统(File System for 0peration and Maintenance Technology)

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

IoTDB 与 HBase 对比详解:架构、功能与性能

五大方向,洞悉 IoTDB 与 HBase 的详尽对比! 在物联网(IoT)领域,数据的采集、存储和分析是确保系统高效运行和决策准确的重要环节。随着物联网设备数量的增加和数据量的爆炸式增长,开发者和决策者们需要选择…

【Vue】Vue2和Vue3响应式原理

前言 Vue 3 的核心部分可以分为三个主要模块:Compiler、Reactivity 和 Runtime。响应式的处理逻辑在 Reactivity 部分。 Compiler(编译器):Template > 渲染函数 将 Vue 的模板(Template)转换成 JavaS…

哪些人群适合考取 PostgreSQL 数据库 PGCM 证书?

#postgresql#,作为开源数据库领域的佼佼者,凭借其强大的功能和广泛的应用场景,吸引了大量数据库从业者的关注。它代表着持有者在PostgreSQL数据库管理、优化、安全和高可用性设计等方面的专家级技能。 PGCM证书适合那些具备扎实理论基础和一…