Esta página descreve como realizar uma pesquisa de similaridade de vetor no Spanner usando as funções de vetor de distância de cosseno, distância euclidiana e produto escalar para encontrar os K vizinhos mais próximos. Essas informações se aplicam a bancos de dados do dialeto GoogleSQL e do dialeto PostgreSQL. Antes de ler esta página, é importante entender 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 dos vetores correspondentes. Se você souber que todos os embeddings de vetor no seu conjunto de dados estão normalizados, poderá usar
DOT_PRODUCT()
como uma função de distância. - Vizinhos k-mais próximos (KNN): um algoritmo de aprendizado de máquina supervisionado usado para resolver problemas de classificação ou regressão.
Você pode usar funções de distância vetorial para realizar uma pesquisa de vetor de vizinhos mais próximos (KNN) em 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 vetor, permitindo encontrar o KNN do embedding de entrada.
Por exemplo, depois de gerar e salvar seus dados operacionais do Spanner como embeddings de vetor, você pode fornecer esses embeddings como um parâmetro de entrada na sua consulta para encontrar os vetores mais próximos no espaço N-dimensional e 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 de vetor para medir a similaridade de embeddings de vetor.
Exemplos
Os exemplos a seguir mostram a pesquisa de KNN, a pesquisa de KNN em dados particionados e o uso de um índice secundário com KNN.
Todos os exemplos usam EUCLIDEAN_DISTANCE()
. Também é possível usar
COSINE_DISTANCE()
. Além disso, se todos os embeddings de vetor no seu conjunto de dados estiverem normalizados, você poderá usar DOT_PRODUCT()
como uma função de distância.
Exemplo 1: pesquisa de vizinho k-mais perto
Considere uma tabela Documents
que tem uma coluna (DocEmbedding
) de incorporações de texto pré-computadas da coluna de bytes DocContents
.
GoogleSQL
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES(MAX),
DocEmbedding ARRAY<FLOAT32>
) PRIMARY KEY (UserId, DocId);
PostgreSQL
CREATE TABLE Documents (
UserId bigint NOT NULL,
DocId bigint NOT NULL,
Author varchar(1024),
DocContents bytea,
DocEmbedding float4[],
PRIMARY KEY (UserId, DocId)
);
Supondo que um embedding de entrada para "beisebol, mas não beisebol profissional" seja a matriz [0.3, 0.3, 0.7, 0.7]
, você pode encontrar os cinco documentos mais próximos que correspondem 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 índice secundário
Se o filtro de 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()
,DOT_PRODUCT()
.Saiba mais sobre as funções PostgreSQL
spanner.cosine_distance()
,spanner.euclidean_distance()
,spanner.dot_product()
.Saiba como escolher entre funções de distância de vetor para medir a similaridade de embeddings de vetor.