Usar a pesquisa vetorial com o Spanner Graph

Esta página descreve como usar a pesquisa de vetor no Spanner Graph para encontrar vizinhos mais próximos (KNN, na sigla em inglês) e vizinhos aproximados mais próximos (ANN, na sigla em inglês). É possível usar funções de distância de vetor para realizar pesquisas de vetor KNN e ANN em casos de uso como pesquisa de similaridade ou geração de recuperação aumentada para aplicativos de IA generativa.

O Spanner Graph oferece suporte às seguintes funções de distância para realizar a pesquisa de similaridade de vetores KNN:

  • COSINE_DISTANCE(): mede a distância mais curta entre dois vetores.
  • EUCLIDEAN_DISTANCE(): mede o cosseno do ângulo entre dois vetores.
  • DOT_PRODUCT(): calcula o cosseno do ângulo multiplicado pelo produto das magnitudes vetoriais correspondentes. Se você souber que todos os embeddings de vetor no seu conjunto de dados estão normalizados, use DOT_PRODUCT() como uma função de distância.

Para mais informações, consulte Executar uma pesquisa de similaridade de vetor no Spanner encontrando os vizinhos mais próximos K.

O Spanner Graph também oferece suporte às seguintes funções de distância aproximada para realizar a pesquisa de similaridade de vetores ANN:

  • APPROX_COSINE_DISTANCE: mede a distância aproximada mais curta entre dois vetores.
  • APPROX_EUCLIDEAN_DISTANCE: mede o cosseno aproximado do ângulo entre dois vetores.
  • APPROX_DOT_PRODUCT: calcula o cosseno aproximado do ângulo multiplicado pelo produto das magnitudes de vetor correspondentes. Se você souber que todos os embeddings de vetor no seu conjunto de dados estão normalizados, use DOT_PRODUCT() como uma função de distância.

Para mais informações, consulte Encontrar vizinhos mais próximos aproximados, criar índice vetorial e consultar embeddings vetoriais.

Antes de começar

Para executar os exemplos neste documento, primeiro siga as etapas em Configurar e consultar o Spanner Graph para fazer o seguinte:

  1. Crie uma instância.
  2. Crie um banco de dados com um esquema do Spanner Graph.
  3. Inserir dados essenciais do gráfico.

Depois de inserir os dados essenciais do gráfico, faça as seguintes atualizações no seu banco de dados.

Inserir outros dados de vetor no banco de dados de gráfico

Para fazer as atualizações necessárias no banco de dados de gráficos, faça o seguinte:

  1. Adicione uma nova coluna, nick_name_embeddings, à tabela de entrada Account.

    ALTER TABLE Account
    ADD COLUMN nick_name_embeddings ARRAY<FLOAT32>(vector_length=>4);
    
  2. Adicione dados à coluna nick_name.

    UPDATE Account SET nick_name = "Fund for a refreshing tropical vacation" WHERE id = 7;
    UPDATE Account SET nick_name = "Fund for a rainy day!" WHERE id = 16;
    UPDATE Account SET nick_name = "Saving up for travel" WHERE id = 20;
    
  3. Crie representações para o texto na coluna nick_name e preencha-as na nova coluna nick_name_embeddings.

    Para gerar embeddings da Vertex AI para seus dados operacionais no Spanner Graph, consulte Usar embeddings de texto da Vertex AI.

    Para fins ilustrativos, nossos exemplos usam valores de vetor artificial de baixa dimensão.

    UPDATE Account SET nick_name_embeddings = ARRAY<FLOAT32>[0.3, 0.5, 0.8, 0.7] WHERE id = 7;
    UPDATE Account SET nick_name_embeddings = ARRAY<FLOAT32>[0.4, 0.9, 0.7, 0.1] WHERE id = 16;
    UPDATE Account SET nick_name_embeddings = ARRAY<FLOAT32>[0.2, 0.5, 0.6, 0.6] WHERE id = 20;
    
  4. Adicione duas novas colunas à tabela de entrada AccountTransferAccount: notes e notes_embeddings.

    ALTER TABLE AccountTransferAccount
    ADD COLUMN notes STRING(MAX);
    ALTER TABLE AccountTransferAccount
    ADD COLUMN notes_embeddings ARRAY<FLOAT32>(vector_length=>4);
    
  5. Crie embeddings para o texto na coluna notes e preencha-os na coluna notes_embeddings.

    Para gerar embeddings da Vertex AI para seus dados operacionais no Spanner Graph, consulte Usar embeddings de texto da Vertex AI.

    Para fins ilustrativos, nossos exemplos usam valores de vetor artificial de baixa dimensão.

    UPDATE AccountTransferAccount
    SET notes = "for shared cost of dinner",
      notes_embeddings = ARRAY<FLOAT32>[0.3, 0.5, 0.8, 0.7]
    WHERE id = 16 AND to_id = 20;
    UPDATE AccountTransferAccount
    SET notes = "fees for tuition",
      notes_embeddings = ARRAY<FLOAT32>[0.1, 0.9, 0.1, 0.7]
    WHERE id = 20 AND to_id = 7;
    UPDATE AccountTransferAccount
    SET notes = 'loved the lunch',
      notes_embeddings = ARRAY<FLOAT32>[0.4, 0.5, 0.7, 0.9]
    WHERE id = 20 AND to_id = 16;
    
  6. Depois de adicionar novas colunas às tabelas de entrada Account e AccountTransferAccount, atualize a definição do gráfico de propriedades usando as instruções a seguir. Para mais informações, consulte Atualizar definições de nó ou aresta atuais.

    CREATE OR REPLACE PROPERTY GRAPH FinGraph
    NODE TABLES (Account, Person)
    EDGE TABLES (
      PersonOwnAccount
        SOURCE KEY (id) REFERENCES Person (id)
        DESTINATION KEY (account_id) REFERENCES Account (id)
        LABEL Owns,
      AccountTransferAccount
        SOURCE KEY (id) REFERENCES Account (id)
        DESTINATION KEY (to_id) REFERENCES Account (id)
        LABEL Transfers
    );
    

Encontrar vizinhos k-mais próximos

No exemplo a seguir, use a função EUCLIDEAN_DISTANCE() para realizar a pesquisa de vetor KNN nos nós e arestas do banco de dados de gráfico.

Realizar pesquisa vetorial KNN em nós de gráfico

É possível realizar uma pesquisa de vetor KNN na propriedade nick_name_embeddings do nó Account. Essa pesquisa de vetor KNN retorna o name do proprietário da conta e o nick_name da conta. No exemplo a seguir, o resultado mostra os dois vizinhos mais próximos de K para contas de viagens de lazer e férias, que é representado pelo embedding de vetor [0.2, 0.4, 0.9, 0.6].

GRAPH FinGraph
MATCH (p:Person)-[:Owns]->(a:Account)
RETURN p.name, a.nick_name
ORDER BY EUCLIDEAN_DISTANCE(a.nick_name_embeddings,
  -- An illustrative embedding for 'accounts for leisure travel and vacation'
  ARRAY<FLOAT32>[0.2, 0.4, 0.9, 0.6])
LIMIT 2;

Resultados

name nick_name
Alex Fundo para férias tropicais
Dana Economizar para viajar

Realizar a pesquisa vetorial KNN nas arestas do gráfico

É possível realizar uma pesquisa vetorial KNN na propriedade notes_embeddings da borda Owns. Essa pesquisa de vetor KNN retorna o name do proprietário da conta e o notes da transferência. No exemplo abaixo, o resultado mostra os dois K vizinhos mais próximos de despesas com alimentação, representado pela incorporação de vetor [0.2, 0.4, 0.9, 0.6].

GRAPH FinGraph
MATCH (p:Person)-[:Owns]->(:Account)-[t:Transfers]->(:Account)
WHERE t.notes_embeddings IS NOT NULL
RETURN p.name, t.notes
ORDER BY EUCLIDEAN_DISTANCE(t.notes_embeddings,
  -- An illustrative vector embedding for 'food expenses'
  ARRAY<FLOAT32>[0.2, 0.4, 0.9, 0.6])
LIMIT 2;

Resultados

name observações
Lee para dividir o custo do jantar
Dana adorei o almoço

Criar um índice vetorial e encontrar vizinhos mais próximos aproximados

Para realizar uma pesquisa de ANN, é necessário criar um índice vetorial especializado que o Spanner Graph usa para acelerar a pesquisa de vetor. O índice de vetor precisa usar uma métrica de distância específica. Para escolher a métrica de distância mais adequada para seu caso de uso, defina o parâmetro distance_type como COSINE, DOT_PRODUCT ou EUCLIDEAN. Para mais informações, consulte Instruções VECTOR INDEX.

No exemplo abaixo, você cria um índice vetorial usando o tipo de distância euclidiana na coluna nick_name_embedding da tabela de entrada Account:

CREATE VECTOR INDEX NickNameEmbeddingIndex
ON Account(nick_name_embeddings)
WHERE nick_name_embeddings IS NOT NULL
OPTIONS (distance_type = 'EUCLIDEAN', tree_depth = 2, num_leaves = 1000);

Realizar pesquisa vetorial de ANN em nós de gráfico

Depois de criar um índice de vetor, é possível realizar uma pesquisa de vetor ANN na propriedade nick_name do nó Account. A pesquisa de vetor ANN retorna o name do proprietário da conta e o nick_name da conta. No exemplo abaixo, o resultado mostra os dois vizinhos mais próximos aproximados de contas para viagens de lazer e férias, que é representado pela incorporação de vetor [0.2, 0.4, 0.9, 0.6].

A dica de gráfico força o otimizador de consultas a usar o índice de vetor especificado no plano de execução da consulta.

GRAPH FinGraph
MATCH (@{FORCE_INDEX=NickNameEmbeddingIndex} a:Account)
WHERE a.nick_name_embeddings IS NOT NULL
RETURN a, APPROX_EUCLIDEAN_DISTANCE(a.nick_name_embeddings,
  -- An illustrative embedding for 'accounts for leisure travel and vacation'
  ARRAY<FLOAT32>[0.2, 0.4, 0.9, 0.6],
  options => JSON '{"num_leaves_to_search": 10}') AS distance
ORDER BY distance
LIMIT 2

NEXT

MATCH (p:Person)-[:Owns]->(a)
RETURN p.name, a.nick_name;

Resultados

name nick_name
Alex Fundo para férias tropicais
Dana Economizar para viajar

A seguir