想象一下你正在用零散的信息来解决一个复杂的难题。

传统的数据库搜索就像翻阅 Rolodex 一样——您寻找精确匹配或简单属性:“谁有红头发?”或“谁有一辆蓝色汽车?” ——有用,但有限。向量相似性搜索(Vector Similarity Search)改变了游戏规则,让您可以问:“还有哪些作品看起来像这个?”它擅长寻找语义相似性,揭示可能隐藏的模式。

但复杂的谜题不仅仅关乎单个碎片 — 它们关乎万物如何连接。这正是图数据库的闪光点。它们映射关系:“谁与谁有联系?”或“两点之间的最短路径是什么?”图可以帮助您看到更大的图景。

现在想象一下将这两种功能结合起来。你不仅可以找到看起来相似的部分,还可以立即看到它们如何融入更广泛的背景中。例如,识别与另一名嫌疑人相似的嫌疑人是不够的——重要的是揭示他们的网络:他们的同伙、行动和互动。

这种向量相似性搜索和图遍历的融合为通过含义和关系理解数据创造了一个强大的新范式。

矢量数据库擅长揭示语义相似性:“这个文档感觉像那个文档”或“这个图像类似于那个图像”。

同时,图数据库解开了关系和层次结构:“谁与谁有联系?”或“两个节点之间的最短路径是什么?”

理解向量嵌入

看看嵌入算法如何将相似的单词“分组”在一起,以及搜索查询如何找到具有相似含义的单词/短语!

向量嵌入将复杂数据(如文本、图像或图中的节点)转换为固定长度的数值向量。虽然上图是在三维平面上,但 OpenAI 的 API(例如text-embedding-3-small)会生成1536 维向量。这些高维表示可以实现详细的上下文理解,这对于语义搜索、推荐系统等任务至关重要。

我们可以使用余弦相似度搜索等算法来找到相似度分数,以确定两个词的相似程度。

将向量嵌入视为将单词、短语或图像转换成计算机可以理解的语言的一种方式——封装其含义和关系的紧凑数字表示。

速度和性能

  • 查询延迟:即使在具有数百万嵌入的数据集中,PineconeDB 等工具也可以优化低于 50 毫秒的查询时间。

  • 批处理:嵌入 OpenAI 等 API 每秒可以处理数百个文本,使其适用于实时应用程序。

  • 维度与速度的权衡:虽然更高的维度(例如 1536)提供了更丰富的上下文,但它们需要更多的计算能力,特别是对于相似性搜索。

from openai import OpenAI
import numpy as np
from numpy.linalg import norm

client = OpenAI(api_key='YOUR_API_KEY')
# You can change any of the texts here!
texts = ["apple", "banana", "computer"]
# Get embeddings for all texts
responses = client.embeddings.create(
input=texts,
model="text-embedding-3-small"
)
embeddings = [r.embedding for r in responses.data]
# Calculate similarity scores with cosine similarity algorithm
sim1 = np.dot(embeddings[0], embeddings[1]) / (norm(embeddings[0]) * norm(embeddings[1]))
sim2 = np.dot(embeddings[0], embeddings[2]) / (norm(embeddings[0]) * norm(embeddings[2]))
sim3 = np.dot(embeddings[0], embeddings[3]) / (norm(embeddings[0]) * norm(embeddings[3]))
print(f"Similarity (apple-banana): {sim1:.3f}")
print(f"Similarity (apple-computer): {sim2:.3f}")
print(f"Similarity (apple-{user_text}): {sim3:.3f}")


考虑一下:PostgreSQL 查询可能会找到上个月购买了某种产品的所有客户,而 Pinecone 矢量搜索可以找到行为类似于经常购买类似商品的客户。

一般来说,维度越多,存储的“上下文”就越多,因此相似性搜索就越准确!

这是上述代码片段的二维简化图 — — 注意“apple”和“banana”是如何与“computer”这样的单词分开的。

以下是一些矢量数据库提供商的示例:

  • PineconeDB:针对低延迟的大规模相似性搜索进行了优化。它支持实时查询并与机器学习工作流程集成。

  • Weaviate:提供模块化、基于模式的存储,内置向量索引。它支持结合向量和符号过滤器的混合搜索。

  • pgvector:PostgreSQL 的扩展,用于将向量搜索嵌入到关系数据库中,从而能够与传统 SQL 查询一起进行向量操作。

知识图谱基础知识

为了充分理解向量相似性搜索和图数据库的融合,我们首先分解它们的核心组件。

一个简单的图数据库。请注意,这里有不同类型的节点/向量。

图表通过将数据建模为相互连接的实体来提供独特的视角。关键概念包括:

  • 节点:代表实体(例如,用户或产品)。

  • 边:定义关系(例如“购买”、“与……成为朋友”)。

  • 属性:存储节点和边的元数据(例如时间戳或权重)。

速度和性能

  • 查询效率:Neo4j 等图数据库针对复杂的遍历查询进行了优化,通常可以在几毫秒内提供结果,即使对于深度连接的数据也是如此。

  • 可扩展性:这些数据库旨在有效处理数十亿个节点和边缘,并在规模上保持高性能。

  • 遍历与连接:通过直接遍历连接的节点,图数据库实现了关系查询的 O(n) 效率,这与具有多个连接的 SQL 查询的 O(n^k) 复杂度形成鲜明对比。这使得它们特别适合分析互联数据,例如社交网络或推荐系统。

图数据库提供商的一些示例:

  • Neo4j:最流行的图数据库之一,为分析和机器学习工作流程提供高级图算法和集成。

  • ArangoDB:支持图、文档和键值数据的多模型数据库,旨在实现灵活性和可扩展性。

  • Amazon Neptune:完全托管的图数据库服务,支持属性图和RDF(资源描述框架)图。

有趣的事实:资源描述框架 (RDF) 图是一种将数据表示为三元组的方式:主语、谓语、宾语。例如,“Alice(主语)知道(谓语)Bob(宾语)”是一个三元组。这种结构使 RDF 图特别适用于语义网应用程序和知识图,因为它们以机器可以理解的方式标准化数据,并使用 SPARQL(一种为 RDF 数据量身定制的强大查询语言)进行查询。

结合图和向量:两种方法

记住:矢量数据库会告诉您感觉相似,而图数据库会告诉您它们是如何连接的。

方法 1:将向量嵌入存储在图数据库中

如上所述,图数据库本质上将数据存储为节点、边和属性,但此结构针对检索、查询执行和图遍历(例如,查找用户的所有好友及其帖子)进行了优化。

节点、边以及...子图?

然而,大多数机器学习模型、相似度计算和下游任务(例如推荐系统、欺诈检测、聚类)都需要以固定长度的数值向量形式的输入(例如之前来自 OpenAI 的 1536 维向量)!

  • 节点嵌入:捕获单个节点的特征,例如用户个人资料数据或连接性(例如,用户的年龄、兴趣和社交图中的朋友数量)。

  • 边缘嵌入:量化关系或交互,例如电子商务图表中的购买频率或评级。

  • 子图嵌入:总结模式或聚类,例如检测社区或欺诈团伙(例如,一群购买类似产品的客户)。

例如,在社交网络中:

  • 节点嵌入可能代表用户的个人资料和连接性。

  • 边缘嵌入可以模拟用户与他人互动的强度。

  • 子图嵌入可能概括出具有相似兴趣的用户社区。

from openai import OpenAI
import networkx as nx
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
import numpy as np

client = OpenAI(api_key='YOUR_API_KEY')

# Create a simple graph
G = nx.Graph()
G.add_edges_from([("User1", "Movie1"), ("User1", "Movie2"),
("User2", "Movie1"), ("User2", "Movie3"),
("User3", "Movie3"), ("User3", "Movie4")])
nx.draw(G, with_labels=True, node_color="lightblue", font_size=10)
plt.title("Graph: Users and Movies")
plt.show()

# Generate embeddings using OpenAI API
def get_embedding(node):
return client.embeddings.create(input=node, model="text-embedding-3-small")["data"][0]["embedding"]
embeddings = np.array([get_embedding(node) for node in G.nodes()])

# Reduce dimensions and visualize
embeddings_2d = PCA(n_components=2).fit_transform(embeddings)
plt.scatter(embeddings_2d[:, 0], embeddings_2d[:, 1], c="lightblue")
for i, node in enumerate(G.nodes()):
plt.text(embeddings_2d[i, 0], embeddings_2d[i, 1], node, fontsize=9)
plt.title("Node Embeddings Visualization")
plt.show()


节点、边和子图如何变成向量?

为了将图元素转换为向量,我们应用了Node2Vec、TransE 和 GraphSAGE等技术。它们的作用如下:

  • 节点嵌入:Node2Vec 等技术在节点周围执行随机游走,并将图中的上下文编码为向量。例如,“Netflix”节点可以通过捕获与“电影”、“节目”和“订阅者”等相关节点的连接来嵌入其上下文。

  • 边嵌入:TransE 等技术将节点之间的关系建模为向量平移。例如,在知识图谱中,“巴黎是法国首都”的关系变成了向量运算:Paris + is_capital_of ≈ France。

  • 子图嵌入:GraphSAGE 等聚合方法将子图中的特征和关系汇总为单个向量。例如,包含房屋、学校、杂货店节点的邻里地图可以嵌入为其连通性、交通模式和建筑类型的摘要。

方法 2:结合独立的图和矢量数据库

当结合图遍历和向量相似性搜索时,目标是高效处理这两种类型的查询。为此,我们需要一种称为混合索引结构的东西。可以将其视为一个智能系统,它以一种可以无缝协作的方式组织关系分数(图数据)和相似性分数(向量数据)。

关系分数量化了图中连接的强度或性质。例如,两个经常互动的用户的关系分数可能是 5。

相似度得分根据向量嵌入来告诉您两个实体的相似程度。例如,在本文前面,“苹果”和“香蕉”的相似度得分接近 1。

工作原理:

  • 图索引:想象一张地图,其中每个城市(节点)都通过道路(边)连接。此索引存储这些连接,以帮助回答诸如“如何从城市 A 到达城市 B?”(最短路径查询)之类的问题。

  • 矢量索引:此部分将城市的“概况”(如人口、气候或氛围等信息)组织成一个系统,将相似的城市分组在一起。可以将其想象成“哪个城市最像 A 市?”

  • 集成层:此层充当转换器,可让您将这些系统组合在一起。例如:“哪些与城市 A 相似的城市也与城市 B 直接相连?”

想象一下电子商务的推荐系统。Pinecone 中的矢量索引根据描述或评论识别与用户之前购买的产品相似的产品。同时,ArangoDB 中的图索引显示经常一起购买的产品。通过结合这些,您可以推荐不仅相似而且上下文相关的商品。

有效地规划查询

为了充分利用混合系统,我们需要一种策略来结合两种搜索,而不会使系统过载。以下是一些方法:

逐步(顺序执行):

  • 首先,使用向量相似度缩小结果范围。例如,找到前 10 个最相似的产品。

  • 接下来,使用图遍历按关系过滤这些结果,例如与前 10 种类似产品一起购买的其他产品。

同时(并行执行):

  • 同时运行两个搜索,然后合并结果。例如,找到与产品 A 最相似的产品以及与产品 A 一起购买的其他产品,然后比较相似度和关系分数以对商品进行排名。

预过滤(优化过滤):

  • 在应用计算量更大的图算法之前,使用向量相似度来快速减少搜索空间。

让速度更快:性能优化

  • 高级:处理大型图和矢量可能很困难,但有一些方法可以提高效率:

  • 预计算:保存频繁查询的结果,这样就无需重新运行。例如,缓存经常搜索的关系或集群。

  • 索引调整:针对最常见的查询模式对图和向量索引进行微调。对于图索引,这可能意味着优化边缘存储或对频繁访问的节点进行聚类。对于向量索引,这可能涉及选择正确的维度或修剪不太相关的嵌入。

  • 分布式处理:使用多台机器来划分工作负载。与依赖单台强大的机器不同,分配任务允许跨数据集并行执行查询,从而减少瓶颈并实现水平扩展以有效处理更大的工作负载。

哪个更好?

方法 1:在图数据库中嵌入向量

许多现代图数据库(例如Neo4j、ArangoDB和Amazon Neptune)现在都支持直接在图中嵌入向量,从而实现将关系遍历与语义相似性相结合的混合查询。

优点:

  • 统一数据管理:将嵌入直接存储在图中可降低管理多个系统的复杂性。

  • 混合查询:在单个查询中实现向量相似性和图遍历的无缝组合,例如在探索社区时识别与目标相似的用户。

  • 减少延迟:消除系统之间的数据传输,这对于实时应用至关重要。

挑战:

  • 可扩展性:图数据库可以努力处理超过数千万个节点或超过 1,500 个维度的数据集的嵌入,而不会降低性能。

  • 搜索精度:专用矢量数据库通常对极高维数据提供更快、更准确的相似性搜索。

更高的维度可以让你表示更多的数据。在需要捕捉数据的许多细微特征(例如几乎相同的图像、长段复杂文本等)的任务中,你会使用极高维度的向量。

方法 2:合并独立系统

直到去年,图数据库还不支持直接在图内进行向量嵌入。这仍然是一项相对较新的技术,而专用的向量数据库仍然在速度上胜出——尤其是在高维相似性搜索方面。

优点:

  • 领域专业化:像 Pinecone 这样的矢量数据库擅长高维相似性搜索,而图数据库则针对复杂关系进行了优化。

  • 可扩展性:每个系统都可以独立扩展,从而可以管理具有数十亿个节点或嵌入的数据集。

  • 定制优化:两个系统都可以针对其特定的工作负载进行微调,例如优化图遍历算法或相似性索引。

挑战:

  • 集成开销:维持系统之间的同步需要额外的基础设施,例如 ETL 管道或中间件。

  • 查询延迟:结合两个系统的结果可能会引起延迟,特别是对于低延迟要求而言。

组合独立的数据库可以提供特定领域的优势,例如更快的相似性搜索,但系统间通信增加的延迟可能不值得。

下一步:利用专业网络构建电影推荐引擎

考虑使用TMDB 5000 电影数据集构建电影推荐引擎。这将集成向量嵌入和图遍历,根据内容和专业联系推荐电影,并巩固您对这些概念的理解。

注意:这只是一个高级项目概述。乐趣/学习在于细节和弄清楚!

  1. 数据收集:下载TMDB 5000 电影元数据数据集。

  2. 数据预处理:清理数据,重点关注描述、类型和演员阵容。将电影描述矢量化为嵌入。

  3. 向量嵌入:使用 OpenAI 的嵌入 API 将描述转换为高维向量,以进行基于相似性的推荐。

  4. 图数据库:建立图数据库(例如,ArangoDB)来模拟专业网络(例如,演员、导演、制片人)及其与电影的关系。

  5. 相似性搜索:实现余弦相似性,基于向量嵌入查找内容相似的电影。

  6. 图遍历:使用图遍历根据专业联系(例如相同的导演、演员)推荐电影。

  7. 混合系统:将基于内容的建议(向量相似度)与基于网络的建议(图遍历)相结合。

  8. 优化:预先计算常见查询并优化图/向量索引以提高性能。

该项目将帮助您在实际环境中应用向量相似性和图遍历。

挑战:以上说明针对方法 2。如何使用该数据集直接使用向量嵌入来设置图数据库?

最后

这次融合不仅仅是一次迭代 — — 它可能是一种范式转变。我们终于可以大规模地将含义与上下文结合起来,随着更多图数据库添加原生向量支持,相信即将看到图数据库成为主流。

微信群

内容中包含的图片若涉及版权问题,请及时与我们联系删除