AI 应用开发:pgvector 在文本搜索中的革命(上篇)

文章略长,分成两部分。

PostgreSQL已经成为顶级的关系型数据库有一段时间了。现在,在人工智能时代,我们还需要存储向量数据以实现快速且相似的搜索。这就是pgvector的用武之地------它就像PostgreSQL的一个插件,帮助它很好地处理向量数据。

什么是向量数据?

想象你有一张地图,但上面不是城市和街道,而是你最喜欢的东西:电影、音乐和有趣的猫视频。每样东西都像地图上的一个点,如果这些点很接近,就意味着它们很相似。例如,一部喜剧电影的点可能靠近另一部喜剧,但与科幻电影的点就不那么接近。在数字世界中,向量就像地图上的点,代表信息,如文本或图像。通过比较这些点的接近程度,我们可以判断事物的相似性,即使它们使用不同的词汇或看起来有点不同。这就像一种计算机能理解的超越文字或像素含义的秘密语言------有点像魔法,但用的是数学!我们将向量数据表示为浮点数列表。

例如:[0.5, 1.2, -0.3, 4.7] 代表一个四维向量。

pgvector - 文本搜索的革命

想象一下普通的文本搜索就像一个侦探仔细地逐字检查文件,以找到匹配的内容。现在,pgvector更像是一个AI代理。它将文本、图像或声音存储为高维向量,就像捕捉数据核心含义的数字指纹。如上所述,如果两个向量在这个空间中很接近,就意味着它们在意义上非常相似。这就是余弦距离的用武之地。这种余弦度量查看两个向量之间的角度,如果角度小,就意味着它们非常相似。

本地安装pgvector

为了便于使用,我们将pgvector打包成了一个docker镜像,里面还包含了其他一些常用的功能,比如时序数据库timescaledb、空间数据库插件postgis等。

下载方法:

bash 复制代码
docker pull nimblex/memfiredb

使用方法:

css 复制代码
docker run --name memfiredb -p 5432:5432 -e POSTGRES_PASSWORD=memfiredb -d nimblex/memfiredb

创建pgvector:

arduino 复制代码
create extension vector;

我们也提供了在线直接使用的方式,可以在文末找到链接。

pgvector解决了什么问题?

pgvector旨在解决PostgreSQL在搜索和数据表示方面的几个关键问题:

  • 有限的文本和数据表示:传统的PostgreSQL以简单的格式存储数据,如文本、数字和日期。这种缺乏灵活表示的方式使得捕捉复杂数据点(如文本文档、图像或科学数据)之间的真实含义和关系变得困难。pgvector引入了多维向量作为一种数据类型,允许基于其固有质量和关系对数据进行更丰富的表示。此外,pgvector的基于向量的方法,结合HNSW和IVFFlat等索引技术,使得在大型数据集上进行更快速、更高效的搜索成为可能,为实时应用程序和大数据环境提供可扩展性。
  • 低效的相似性搜索:传统的PostgreSQL文本搜索依赖于关键字匹配或模式识别,这在寻找相似文档或内容时可能会很慢,也不能用于执行基于数据含义的搜索。pgvector基于余弦距离等高级距离度量实现高效的相似性搜索,允许您找到即使不共享相同单词或模式也具有相似含义的项目。
  • 缺乏与机器学习的集成:pgvector通过使PostgreSQL与机器学习模型生成的向量嵌入无缝集成,弥合了PostgreSQL和机器学习之间的差距。这使您能够直接在PostgreSQL数据库中利用机器学习的强大功能,用于文档检索、图像搜索和推荐系统等任务。

pgvector支持两种主要类型的搜索------精确近邻搜索(ENN)和近似近邻搜索(ANN)。ENN和ANN都专注于在高维空间中寻找相似的向量,但它们的方法不同,也有不同的优缺点

精确近邻搜索(ENN)定义:

  • 在数据集中找到与查询向量完全相同的向量。
  • 算法:采用暴力方法,将查询向量与数据库中的每个向量进行比较。
  • 准确性:保证找到真正的最近邻,确保最高可能的精度。
  • 性能:需要将查询向量与所有可用向量进行比较,导致可能的慢速计算和高资源消耗,特别是对于大型数据集。
  • 常见用例:当绝对精度至关重要时,例如在关键的财务计算或科学分析中。

近似近邻搜索(ANN):

  • 在一定容差内找到与查询向量大致相似的向量。
  • 利用索引技术识别候选向量,而无需将它们全部比较,显著减少搜索空间。
  • 提供近似答案,可能错过真正的最近邻,但通常返回接近的替代品。
  • 与ENN相比,提供更快的搜索时间和更低的资源消耗,适合大型数据集和实时应用程序。
  • 当实时响应和可扩展性优先于绝对精度时,例如在推荐系统、图像/视频检索和自然语言处理应用程序中。

选择ENN还是ANN取决于您的具体需求

  • 准确性:如果您需要以最高精度找到绝对最接近的匹配,ENN是您的选择。
  • 性能:对于实时应用程序和大型数据集,ANN提供了更快的速度和资源效率。
  • 数据大小:数据集越大,人工神经网络的性能优势就越显著。
  • 对不准确的容忍度:想想在你的应用程序中有一个势均力敌的匹配是多么好。

额外因素:

  • 距离度量:ENN和ANN都可以使用各种距离度量,如L2、内积和余弦距离。
  • 索引技术:不同的ANN算法,如HNSW和IVF,提供不同的性能和准确性权衡。

L2距离、内积和余弦距离的简单示例解释:

想象两个苹果在一个水果篮子里:

  • L2距离:这告诉你篮子里苹果之间的距离,就像测量它们之间的直线距离。距离越大,它们越不相似。当你需要知道事物之间的确切差异时,比如地图上的距离或价格差异,就会使用它。
  • 内积:这就像比较苹果的味道和质地。高内积意味着它们都是甜的和脆的,而低内积意味着它们不同(也许一个是酸的,另一个是软的)。当你想要比较事物在特定品质上的相似性时,比如比较具有相似主题的文档或具有相似节奏的音乐时,就会使用它。
  • 余弦距离:假设每个苹果顶部都有一个小箭头,指向某个方向。现在,如果你想要知道这些苹果有多相似,你可以检查它们箭头之间的角度。当你想要知道事物在一般意义上的对齐程度时,比如找到相似的图片或根据你过去的购买推荐相关产品时,就会使用它。

注意:pgvector本身并不直接提供基于内积或余弦距离的内置搜索。然而,它以不同的方式利用L2距离来实现类似的结果。

pgvector中的索引:

pgvector提供两种类型的索引,都是近似最近邻(ANN)索引,用于加速搜索相似向量。选择正确的索引取决于几个因素。以下是它们的关键差异:

  • 特征:将向量空间划分为分区,构建类似图结构的相似向量。
  • 构建时间:显著更快,显著更慢。
  • 内存使用:较少内存,更多内存。
  • 准确性:通常对高维向量不太准确,尤其是对于高维向量,通常具有更好的准确性。
  • 适应性:可能不适用于所有向量分布,很好地处理各种向量分布。

理解IVFFlat和HNSW的真实世界示例:

想象你住在一个城市,需要找到一个与你喜欢的餐厅相似的餐厅(一个"最近邻")。

  • IVFFlat就像有一张带有标签的社区地图。
  • 根据一般特征将城市划分为不同的区域。
  • 可以快速告诉你哪些社区可能有类似的餐厅。
  • 引导你到那些社区内的餐厅,可能接近,但不一定是每个方面都最相似的。
  • 快速开始使用地图(更快的索引构建)。
  • 需要较少的内存来存储地图。
  • HNSW就像有一个了解城市的当地向导。
  • 了解城市如何连接餐厅(相似的口味、氛围等)。
  • 可以快速引导你到在整体体验上接近你最喜欢的餐厅的餐厅,即使它们不完全相同。
  • 需要向导花更多时间了解城市(构建索引)。
  • 需要向导记住更多信息(更高的内存使用)。

选择正确的方法取决于你的优先级:HNSW就像向导,优先找到最相似的餐厅,即使需要更长的时间。速度:IVFFlat就像地图,专注于快速找到类似的餐厅,即使它不是完美的。HNSW适用于复杂的城市布局(高维数据),而IVFFlat适用于大城市(大型数据集)。

数据嵌入过程

要创建向量数据,我们首先需要生成它。创建向量数据的过程称为嵌入,它就像一种秘密语言,弥合了计算机数字形式的单词、图像或声音世界之间的差距。

  • 收集数据:想象一个满是书籍的书架,一个充满艺术作品的艺术画廊,或者一起播放的一堆旋律。当我们开始嵌入时,意味着我们正在收集我们想要以向量形式展示的基本元素。

  • 选择嵌入模型:有不同类型的嵌入模型可用于特定类型的信息。一些常见的模型包括:

    • HuggingFace或OpenAI的text-embedding-ada-002用于文本
    • VGG16或ResNet50用于图像
    • Audio2Vec用于声音
  • 训练模型:这就是魔法发生的地方!模型分析数据,识别模式、关系和隐藏的含义。它将单词、图像或声音映射到它们对应的向量,为每一个创建独特的数值表示。

  • 生成向量:一旦模型学会了数据的语言,它就可以根据需求将新输入转换为向量。

HuggingFace或OpenAI嵌入模型 - 如何选择?

选择Hugging Face和OpenAI来满足您的嵌入需求取决于几个因素:

  • Hugging Face:侧重于广度和灵活性,提供广泛的自然语言处理模型,用于各种任务。大多数模型都是免费的,某些特定模型或API可能需要付费。易于使用,有工具和社区支持。开源工具提供更多控制,但对模型定制的控制较少。
  • OpenAI:专注于高性能嵌入模型,提供专门化的嵌入模型。通过计划访问,需要付费。API或Hugging Face模型中心访问,对模型定制的控制较少。

最终,最佳选择取决于您的具体需求、预算和技术专长。在做出决定之前,仔细考虑您的优先事项,并比较可用的选项。

利用pgvector:实际示例

想象一个场景,我们在数据库中以向量形式存储各种单词。然后我们提供不同的单词给数据库,以找到最相似的单词。

我们将存储在数据库中的单词是Apple、Banana、Cat和Dog。我们要搜索的单词是Mango和Horse。

创建扩展:

一旦您在计算机上安装了pgvector,首先需要创建所需的扩展。

arduino 复制代码
CREATE EXTENSION vector;

创建表:

为了存储向量数据:

sql 复制代码
CREATE TABLE items (id bigserial PRIMARY KEY, name varchar(100), embedding vector);

生成嵌入:

我们将使用HuggingFace来生成我们的嵌入。

安装所需的Python包:

复制代码
pip3 install sentence-transformers
 pip3 install langchain 

Python代码以从langchain生成嵌入:

python 复制代码
from langchain.embeddings import HuggingFaceEmbeddings

 embeddings = HuggingFaceEmbeddings(model_name='all-MiniLM-L6-v2')
 print(embeddings.embed_query("Apple"))

这里使用的模型是all-MiniLM-L6-v2。

下面的图表显示了单词Apple的嵌入。

将数据插入数据库:

sql 复制代码
INSERT INTO items (name, embedding) VALUES ('Apple', '<Your_Apple_Embedding>');

将Your_Apple_Embedding替换为上面图表中显示的原始嵌入。

类似地,我们将插入其他向量,即Banana、Cat和Dog。

插入所有关键词后,我们可以检查items表中的行数。

sql 复制代码
SELECT COUNT(*) FROM items;

向量搜索:

为了找到一个单词,我们将再次为该单词创建嵌入,并利用生成的嵌入在数据库中搜索该单词。

将生成的Mango嵌入插入到下面的查询中以获取结果:

sql 复制代码
SELECT name, 1 - (embedding <-> '<Mango_embedding>') AS cosine_similarity FROM items ORDER BY cosine_similarity DESC LIMIT 2;

SELECT查询结构解析:

  • SELECT name:这从items表中选择项目的名称。
  • 1 - (embedding <-> '<Horse_embedding>') AS cosine_similarity:这个表达式计算每个项目的嵌入与指定的"Horse"嵌入之间的余弦相似度,并将结果别名为cosine_similarity列。
  • embedding <-> '<Horse_embedding>':这个操作符计算两个向量之间的余弦相似度。它将每个项目的嵌入(存储在embedding列中)与"Horse"嵌入的占位符进行比较。
  • 1 -- ...:相似度计算的结果从1中减去,以反转比例,使更高的值代表更大的相似性。
  • ORDER BY cosine_similarity DESC:这根据计算出的余弦相似度以降序排序结果。这将最相似于"Horse"的项目放在顶部。
  • LIMIT 2:这限制输出仅为基于计算出的余弦相似度的前两个最相似的项目。

结果分析:

Mango和horse并不直接出现在表中:如果它们在表中列出,那么将返回完美的匹配(余弦相似度为1)。Banana和Apple对Mango有适度的语义相似性。Banana(0.5249995745718354)是最相似的,但不是完全匹配。Apple(0.4006202280151715)的相似度较低,表明关系较弱。Dog和Cat对Horse有适度的语义相似性。Dog(0.5349170288394121)是最相似的,但不是完全匹配。Cat(0.41092748143620783)的相似度较低,表明关系较弱。值得注意的是,余弦相似度的范围是从0到1,1表示完全匹配,意味着项目在用于比较的表示方面是相同的。0表示完全不相似,意味着项目在它们的表示中没有任何重叠。介于0和1之间的值代表不同程度的相似性。

在线使用pgvector:cloud.memfiredb.com/auth/login?...

原文:AI Meets PostgreSQL - The pgvector Revolution in Text Search - Stormatics

相关推荐
一屉大大大花卷15 分钟前
初识Neo4j之入门介绍(一)
数据库·neo4j
周胡杰1 小时前
鸿蒙arkts使用关系型数据库,使用DB Browser for SQLite连接和查看数据库数据?使用TaskPool进行频繁数据库操作
前端·数据库·华为·harmonyos·鸿蒙·鸿蒙系统
wkj0011 小时前
navicate如何设置数据库引擎
数据库·mysql
赵渝强老师1 小时前
【赵渝强老师】Oracle RMAN的目录数据库
数据库·oracle
暖暖木头1 小时前
Oracle注释详解
数据库·oracle
AI街潜水的八角1 小时前
深度学习图像分类数据集—濒危动物识别分类
人工智能·深度学习
御控工业物联网1 小时前
御控网关如何实现MQTT、MODBUS、OPCUA、SQL、HTTP之间协议转换
数据库·sql·http
程序员陆通1 小时前
独立开发A/B测试实用教程
人工智能·ai编程
knowfoot1 小时前
硬核拆解!跟着公式“走”一遍,你也能彻底看懂神经网络
人工智能·神经网络
FF-Studio1 小时前
大语言模型(LLM)课程学习(Curriculum Learning)、数据课程(data curriculum)指南:从原理到实践
人工智能·python·深度学习·神经网络·机器学习·语言模型·自然语言处理