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

相关推荐
Majoy26 分钟前
HBase
大数据·数据库·hbase
夜光小兔纸1 小时前
oracle查询出表中某几个字段值不唯一的数据
数据库·sql·oracle
好悬给我拽开线1 小时前
【】AI八股-神经网络相关
人工智能·深度学习·神经网络
deadknight93 小时前
Oracle密码过期处理方式
数据库·oracle
Ljubim.te3 小时前
数据库第01讲章节测验(选项顺序可能不同)
数据库
吱吱喔喔3 小时前
数据分表和分库原理
数据库·分表·分库
快乐非自愿3 小时前
KES数据库实践指南:探索KES数据库的事务隔离级别
数据库·oracle
一只fish3 小时前
Oracle的RECYCLEBIN回收站:轻松恢复误删对象
数据库·oracle
weixin_440401693 小时前
分布式锁——基于Redis分布式锁
java·数据库·spring boot·redis·分布式
TOR-NADO3 小时前
数据库概念题总结
数据库·oracle