Esta página descreve como realizar uma pesquisa de similaridade vetorial no Spanner usando as funções vetoriais de distância de cossenos, distância euclidiana e produto escalar para encontrar os K vizinhos mais próximos. Estas informações aplicam-se a bases de dados com dialeto GoogleSQL e bases de dados com dialeto PostgreSQL. Antes de ler esta página, é importante que compreenda os seguintes conceitos:
- Distância euclidiana: mede a distância mais curta 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 souber que todas as incorporações vetoriais no seu conjunto de dados estão normalizadas, pode usar
DOT_PRODUCT()
como função de distância. - K-nearest neighbors (KNN): um algoritmo de aprendizagem automática supervisionada usado para resolver problemas de classificação ou regressão.
Pode usar funções de distância vetorial para realizar uma pesquisa vetorial de K-vizinhos mais próximos (KNN) para exemplos de utilização como a pesquisa de semelhanças ou a geração aumentada de recuperação. O Spanner suporta as funções COSINE_DISTANCE()
,
EUCLIDEAN_DISTANCE()
e DOT_PRODUCT()
, que operam em incorporações de vetores, o que lhe permite encontrar o KNN da incorporação de entrada.
Por exemplo, depois de gerar e guardar os seus dados operacionais do Spanner como incorporações de vetores, pode fornecer estas incorporações de vetores como um parâmetro de entrada na sua 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 recebem os argumentos vector1
e vector2
, que são do tipo array<>
e têm de consistir nas mesmas dimensões e ter o mesmo comprimento. Para mais detalhes sobre estas 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 as funções de distância vetorial para medir a semelhança das incorporações de vetores.
Exemplos
Os exemplos seguintes mostram a pesquisa KNN, a pesquisa KNN sobre dados particionados e a utilização de um índice secundário com KNN.
Todos os exemplos usam EUCLIDEAN_DISTANCE()
. Também pode usar
COSINE_DISTANCE()
. Além disso, se todas as incorporações vetoriais no seu conjunto de dados
forem normalizadas, pode usar DOT_PRODUCT()
como uma função de distância.
Exemplo 1: pesquisa KNN
Considere uma tabela Documents
que tenha uma coluna (DocEmbedding
) de incorporações de texto pré-calculadas a partir 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)
);
Partindo do princípio de que uma incorporação de entrada para "basebol, mas não basebol profissional"
é a matriz [0.3, 0.3, 0.7, 0.7]
, 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 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 desta funcionalidade é 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 KNN em intervalos de índice secundário
Se a cláusula WHERE
filter que está a usar não fizer parte da chave principal da tabela,
pode criar um índice secundário para acelerar a operação com uma
análise apenas 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, ...] |
+------------+-----------------+-----------------+
O que se segue?
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()
espanner.dot_product()
.Saiba como escolher entre funções de distância vetorial para medir a semelhança de incorporações vetoriais.