Nesta página, descrevemos como realizar a pesquisa de vetores de similaridade no Spanner usando as funções de distância do cosseno, distância euclidiana e vetor de produto escalar para encontrar vizinhos mais próximos. Antes de ler esta página, é importante que você entenda os seguintes conceitos:
- Distância euclidiana: mede a menor distância entre dois vetores.
- Distância do cosseno: mede o cosseno do ângulo entre dois vetores.
- Produto escalar: calcula o cosseno do ângulo multiplicado pelo produto das magnitudes vetoriais correspondentes. Se você sabe que todos os embeddings de vetores no conjunto de dados são normalizados, pode usar
DOT_PRODUCT()
como uma função de distância. - Vizinhos K-mais próximos (KNN, na sigla em inglês): um algoritmo de machine learning supervisionado usado para resolver problemas de classificação ou regressão.
É possível usar funções de distância vetorial para realizar a pesquisa de vetores de vizinhos mais próximos (KNN, na sigla em inglês)
para casos de uso como pesquisa por similaridade ou geração aumentada de
recuperação. O Spanner é compatível com as funções COSINE_DISTANCE()
, EUCLIDEAN_DISTANCE()
e DOT_PRODUCT()
, que operam em embeddings de vetores, permitindo que você encontre o KNN do embedding de entrada.
Por exemplo, depois de gerar e salvar os dados operacionais do Spanner como embeddings de vetores, é possível fornecer esses embeddings de vetores como um parâmetro de entrada na consulta para encontrar os vetores mais próximos no espaço N-dimensional para pesquisar itens semanticamente semelhantes ou relacionados.
Todas as três funções de distância usam os argumentos vector1
e vector2
, que
são do tipo array<>
e precisam consistir nas mesmas dimensões e ter o
mesmo comprimento. Para mais detalhes sobre essas funções, consulte:
COSINE_DISTANCE()
no GoogleSQLEUCLIDEAN_DISTANCE()
no GoogleSQLDOT_PRODUCT()
no GoogleSQL- Funções matemáticas no PostgreSQL
(
spanner.cosine_distance()
,spanner.euclidean_distance()
espanner.dot_product()
) - Escolha entre funções de distância vetorial para medir a semelhança de embeddings vetoriais.
Examples
Os exemplos a seguir mostram a pesquisa KNN, a pesquisa KNN em dados particionados e o uso de um índice secundário com KNN.
Todos os exemplos usam EUCLIDEAN_DISTANCE()
. Você também pode usar
COSINE_DISTANCE()
. Além disso, se todos os embeddings de vetores no conjunto de dados
forem normalizados, será possível usar DOT_PRODUCT()
como uma função de distância.
Exemplo 1: pesquisa KNN
Considere uma tabela Documents
que tenha uma coluna (DocEmbedding
) de embeddings de texto pré-computados da coluna de bytes 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[]
);
Supondo que um embedding de entrada para "baseball, mas não beisebol profissional" seja a matriz [0.3, 0.3, 0.7, 0.7]
, será possível encontrar os cinco principais documentos mais próximos correspondentes com a seguinte consulta:
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;
Os resultados esperados deste exemplo:
Documents
+---------------------------+-----------------+
| DocId | DocEmbedding |
+---------------------------+-----------------+
| 24 | [8, ...] |
+---------------------------+-----------------+
| 25 | [6, ...] |
+---------------------------+-----------------+
| 26 | [3.2, ...] |
+---------------------------+-----------------+
| 27 | [38, ...] |
+---------------------------+-----------------+
| 14229 | [1.6, ...] |
+---------------------------+-----------------+
Exemplo 2: pesquisa de KNN em dados particionados
A consulta no exemplo anterior pode ser modificada adicionando condições à cláusula WHERE
para limitar a pesquisa vetorial a um subconjunto dos seus dados. Uma aplicação
comum disso é pesquisar dados particionados, como linhas que pertencem
a um UserId
específico.
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;
Os resultados esperados deste exemplo:
Documents
+-----------+-----------------+-----------------+
| UserId | DocId | DocEmbedding |
+-----------+-----------------+-----------------+
| 18 | 234 | [12, ...] |
+-----------+-----------------+-----------------+
| 18 | 12 | [1.6, ...] |
+-----------+-----------------+-----------------+
| 18 | 321 | [22, ...] |
+-----------+-----------------+-----------------+
| 18 | 432 | [3, ...] |
+-----------+-----------------+-----------------+
Exemplo 3: pesquisa de KNN em intervalos de índices secundários
Se o filtro da cláusula WHERE
que você está usando não fizer parte da chave primária da tabela,
crie um índice secundário para acelerar a operação com uma
verificação somente de índice.
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;
Os resultados esperados deste exemplo:
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, ...] |
+------------+-----------------+-----------------+
A seguir
Saiba mais sobre as funções GoogleSQL
COSINE_DISTANCE()
,EUCLIDEAN_DISTANCE()
eDOT_PRODUCT()
.Saiba mais sobre as funções PostgreSQL
spanner.cosine_distance()
,spanner.euclidean_distance()
,spanner.dot_product()
.Saiba mais sobre como Escolher entre funções de distância vetorial para medir a semelhança de embeddings de vetores.