本页面介绍了如何在 Google Cloud 中执行相似性向量搜索, Spanner(使用余弦距离、欧几里得距离和点) 产品向量函数来查找 K 最近邻。在阅读本页内容之前, 请务必了解以下概念:
- 欧几里得距离: 测量两个向量之间的最短距离。
- 余弦距离: 测量两个向量之间角度的余弦。
- 点积:计算
角度的余弦与对应向量的乘积
震级。如果您知道数据集中的所有向量嵌入
那么可以使用
DOT_PRODUCT()
作为距离函数。 - K 最近邻 (KNN): 一种用于解决分类问题的监督式机器学习算法, 回归问题。
您可以使用矢量距离函数执行 K 最近邻 (KNN)。
向量搜索,用于相似性搜索或检索增强
。Spanner 支持 COSINE_DISTANCE()
,
EUCLIDEAN_DISTANCE()
和 DOT_PRODUCT()
函数,它们作用于矢量
用于找出输入嵌入的 KNN。
例如,在生成并保存可操作的 Spanner 之后 将数据作为向量嵌入进行转换,然后 在查询中提供这些向量嵌入作为输入参数, N 维空间中最接近的向量,以搜索 相关项。
所有三个距离函数都采用 vector1
和 vector2
参数,
类型为array<>
,必须由相同的尺寸组成,且具有
相同长度的如需详细了解这些函数,请参阅:
- GoogleSQL 中的
COSINE_DISTANCE()
- GoogleSQL 中的
EUCLIDEAN_DISTANCE()
- GoogleSQL 中的
DOT_PRODUCT()
- PostgreSQL 中的数学函数
(
spanner.cosine_distance()
、spanner.euclidean_distance()
和spanner.dot_product()
) - 选择向量距离函数以测量向量嵌入的相似性。
示例
以下示例展示了 KNN 搜索、KNN 对分区数据的搜索,以及 将二级索引与 KNN 结合起来使用。
示例均使用 EUCLIDEAN_DISTANCE()
。您还可以使用
COSINE_DISTANCE()
.此外,如果数据集中的所有向量嵌入
标准化,因此可以使用 DOT_PRODUCT()
作为距离函数。
示例 1:KNN 搜索
假设有一个 Documents
表,其中包含预先计算的列 (DocEmbedding
)
文本嵌入。DocContents
GoogleSQL
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES,
DocEmbedding ARRAY<FLOAT32>
) PRIMARY KEY (UserId, DocId);
PostgreSQL
CREATE TABLE Documents (
UserId bigint primary key,
DocId bigint primary key,
Author varchar(1024),
DocContents bytea,
DocEmbedding float4[]
);
假设“棒球,但不是职业棒球”的输入嵌入
是数组 [0.3, 0.3, 0.7, 0.7]
,您可以找到前五个最接近的文档
结果替换为以下查询:
GoogleSQL
SELECT DocId, DocEmbedding FROM Documents
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
ARRAY<FLOAT32>[0.3, 0.3, 0.7, 0.8])
LIMIT 5;
PostgreSQL
SELECT DocId, DocEmbedding FROM Documents
ORDER BY spanner.euclidean_distance(DocEmbedding,
'{0.3, 0.3, 0.7, 0.8}'::float4[])
LIMIT 5;
本示例的预期结果:
Documents
+---------------------------+-----------------+
| DocId | DocEmbedding |
+---------------------------+-----------------+
| 24 | [8, ...] |
+---------------------------+-----------------+
| 25 | [6, ...] |
+---------------------------+-----------------+
| 26 | [3.2, ...] |
+---------------------------+-----------------+
| 27 | [38, ...] |
+---------------------------+-----------------+
| 14229 | [1.6, ...] |
+---------------------------+-----------------+
示例 2:KNN 对分区数据进行搜索
上述示例中的查询可通过向
WHERE
子句将矢量搜索限制为数据的子集。常见
搜索分区数据,
特定的 UserId
。
GoogleSQL
SELECT UserId, DocId, DocEmbedding FROM Documents
WHERE UserId=18
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
ARRAY<FLOAT32>[0.3, 0.3, 0.7, 0.8])
LIMIT 5;
PostgreSQL
SELECT UserId, DocId, DocEmbedding FROM Documents
WHERE UserId=18
ORDER BY spanner.euclidean_distance(DocEmbedding,
'{0.3, 0.3, 0.7, 0.8}'::float4[])
LIMIT 5;
本示例的预期结果:
Documents
+-----------+-----------------+-----------------+
| UserId | DocId | DocEmbedding |
+-----------+-----------------+-----------------+
| 18 | 234 | [12, ...] |
+-----------+-----------------+-----------------+
| 18 | 12 | [1.6, ...] |
+-----------+-----------------+-----------------+
| 18 | 321 | [22, ...] |
+-----------+-----------------+-----------------+
| 18 | 432 | [3, ...] |
+-----------+-----------------+-----------------+
示例 3:在二级索引范围上执行 KNN 搜索
如果您使用的 WHERE
子句过滤条件不是表主键的一部分,
那么您可以创建二级索引来加速操作
仅索引扫描。
GoogleSQL
CREATE INDEX DocsByAuthor
ON Documents(Author)
STORING (DocEmbedding);
SELECT Author, DocId, DocEmbedding FROM Documents
WHERE Author="Mark Twain"
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
<embeddings for "book about the time traveling American">)
LIMIT 5;
PostgreSQL
CREATE INDEX DocsByAuthor
ON Documents(Author)
INCLUDE (DocEmbedding);
SELECT Author, DocId, DocEmbedding FROM Documents
WHERE Author="Mark Twain"
ORDER BY spanner.euclidean_distance(DocEmbedding,
<embeddings for "that book about the time traveling American">)
LIMIT 5;
本示例的预期结果:
Documents
+------------+-----------------+-----------------+
| Author | DocId | DocEmbedding |
+------------+-----------------+-----------------+
| Mark Twain | 234 | [12, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 12 | [1.6, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 321 | [22, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 432 | [3, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 375 | [9, ...] |
+------------+-----------------+-----------------+
后续步骤
详细了解 GoogleSQL
COSINE_DISTANCE()
、EUCLIDEAN_DISTANCE()
、DOT_PRODUCT()
函数。详细了解 PostgreSQL
spanner.cosine_distance()
、spanner.euclidean_distance()
、spanner.dot_product()
函数。详细了解如何在向量距离函数中进行选择以衡量向量嵌入的相似性。