Neste tutorial, mostramos como realizar uma
pesquisa de similaridade em
embeddings armazenados em tabelas do BigQuery usando a
VECTOR_SEARCH função
e um índice vetorial.
A pesquisa de vetor é uma técnica para comparar objetos semelhantes usando embeddings, e é usada para impulsionar produtos do Google, incluindo a Pesquisa Google, o YouTube e o Google Play. É possível usar a pesquisa de vetor para realizar pesquisas semânticas em grande escala ou uma pesquisa híbrida que combina uma pesquisa semântica com uma pesquisa lexical (palavra-chave). Ao usar índices vetoriais com a pesquisa de vetor, você pode aproveitar tecnologias fundamentais, como a indexação de arquivo invertido (IVF) e o algoritmo ScaNN.
A pesquisa de vetor é criada com base em embeddings. Os embeddings são vetores numéricos de alta dimensão que representam uma determinada entidade, como um texto ou um arquivo de áudio. Os modelos de machine learning (ML) usam embeddings para codificar semântica sobre essas entidades, facilitando o entendimento delas e sua comparação. Por exemplo, uma operação comum em modelos de clustering, classificação e recomendação é medir a distância entre vetores em um espaço de embedding para encontrar os itens semanticamente mais parecidos.
Objetivos
- Realizar uma pesquisa de similaridade em embeddings armazenados em tabelas do BigQuery usando a função
VECTOR_SEARCH. - Usar um índice vetorial para melhorar o desempenho da pesquisa de vetor.
- Realizar uma pesquisa que usa um índice vetorial e uma pesquisa que não usa um índice.
- Avaliar o recall comparando os resultados de pesquisas com um índice e pesquisas sem um índice.
Custos
A função VECTOR_SEARCH usa
os preços de computação do BigQuery.
Você recebe cobranças pela pesquisa de similaridade, usando preços sob demanda ou de edições.
- Sob demanda: você recebe cobranças pela quantidade de bytes verificados na tabela de base, no índice e na consulta de pesquisa.
Preços de edições: você recebe cobranças pelos slots necessários para concluir o job na edição da reserva. Cálculos de similaridade maiores e mais complexos geram mais cobranças.
Para mais informações, consulte preços do BigQuery.
Antes de começar
-
No Google Cloud console do, na página do seletor de projetos, escolha ou crie um Google Cloud projeto do.
Funções necessárias para selecionar ou criar um projeto
- Selecionar um projeto: a seleção de um projeto não exige um papel específico do IAM. Você pode selecionar qualquer projeto em que tenha recebido um papel.
-
Criar um projeto: para criar um projeto, você precisa do papel de criador de projetos
(
roles/resourcemanager.projectCreator), que contém aresourcemanager.projects.createpermissão. Saiba como conceder papéis.
-
Verifique se o faturamento está ativado para o Google Cloud projeto.
-
Ative a API BigQuery.
Funções necessárias para ativar APIs
Para ativar as APIs, é necessário ter a permissão
serviceusage.services.enable. Se você criou o projeto, provavelmente já tem essa permissão pelo papel de proprietário (roles/owner). Caso contrário, você pode receber essa permissão pelo papel de administrador de uso do serviço (roles/serviceusage.serviceUsageAdmin). Saiba como conceder papéis.
Funções exigidas
Para conseguir as permissões necessárias para concluir o tutorial, peça ao administrador para conceder a você os seguintes papéis do IAM no projeto:
-
Criar conjuntos de dados, tabelas e índices vetoriais:
editor de dados do BigQuery (
roles/bigquery.dataEditor) -
Executar jobs do BigQuery:
usuário de jobs do BigQuery (
roles/bigquery.jobUser)
Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.
Também é possível conseguir as permissões necessárias com papéis personalizados ou outros papéis predefinidos.
Criar um conjunto de dados
Para criar um conjunto de dados do BigQuery, selecione uma das seguintes opções:
Console
No Google Cloud console, acesse a página BigQuery.
No painel esquerdo, clique em Explorar:

Se o painel esquerdo não aparecer, clique em Expandir painel esquerdo para abrir o painel.
Em Explorer, expanda o projeto e clique em Conjuntos de dados.
Na página Conjuntos de dados, clique em Criar conjunto de dados.
No painel Criar conjunto de dados, faça o seguinte:
Para o código do conjunto de dados, insira
bqml_tutorial.Para Local dos dados, selecione EUA.
Deixe as configurações padrão restantes como estão.
Clique em Criar conjunto de dados.
bq
Para criar um novo conjunto de dados, use o
bq mk --dataset comando.
Crie um conjunto de dados chamado
bqml_tutorialcom o local dos dados definido comoUS:bq mk --dataset \ --location=US \ --description "BigQuery ML tutorial dataset." \ bqml_tutorial
Confirme se o conjunto de dados foi criado:
bq ls
API
Chame o datasets.insert
método com um recurso de conjunto de dados definido:
{ "datasetReference": { "datasetId": "bqml_tutorial" } }
Criar tabelas para armazenar dados e embeddings
Nesta seção, você cria a tabela patents, que contém embeddings de patentes. Os embeddings são baseados em um subconjunto do conjunto de dados público do Google Patentes. Você também cria a tabela patents2, que contém um embedding de patente para encontrar vizinhos mais próximos.
Para criar as tabelas, siga estas etapas:
Para criar a tabela
patents, cole o seguinte no editor de consultas e clique em Executar:CREATE TABLE bqml_tutorial.patents AS SELECT * FROM `patents-public-data.google_patents_research.publications` WHERE ARRAY_LENGTH(embedding_v1) > 0 AND publication_number NOT IN ('KR-20180122872-A') LIMIT 1000000;
Você recebe uma mensagem de confirmação como esta:
This statement created a new table named patents.Para criar a tabela
patents2que contém um embedding de patente para encontrar vizinhos mais próximos, cole o seguinte no editor de consultas e clique em Executar:CREATE TABLE bqml_tutorial.patents2 AS SELECT * FROM `patents-public-data.google_patents_research.publications` WHERE publication_number = 'KR-20180122872-A';
Você recebe uma mensagem de confirmação como esta:
This statement created a new table named patents2.
Criar um índice vetorial
Quando você usa VECTOR_SEARCH com um índice vetorial, VECTOR_SEARCH usa o
método do Vizinho aproximado mais perto
para melhorar o desempenho da pesquisa de vetor, mas reduzindo o
recall
e, portanto, retornando resultados mais aproximados. Sem um índice vetorial,
VECTOR_SEARCH usa
a pesquisa de força bruta
para medir a distância de cada registro.
Nesta seção, você cria o índice vetorial my_index na coluna embedding_v1 da tabela patents. Em seguida, verifique se o índice está disponível.
Para criar o índice vetorial, siga estas etapas:
Para criar o índice vetorial
my_indexna colunaembedding_v1dapatentstabela, cole o seguinte no editor de consultas e clique em Executar:CREATE OR REPLACE VECTOR INDEX my_index ON bqml_tutorial.patents(embedding_v1) STORING(publication_number, title) OPTIONS(distance_type='COSINE', index_type='IVF');
Você recebe uma mensagem de confirmação como esta:
The vector index creation on table bqml_tutorial.patents was initiated. Please query bqml_tutorial.INFORMATION_SCHEMA.VECTOR_INDEXES to check the progress of the index.Para confirmar se o índice vetorial está pronto, cole o seguinte no editor de consultas e clique em Executar:
SELECT * FROM bqml_tutorial.INFORMATION_SCHEMA.VECTOR_INDEXES;
Nos resultados da consulta, verifique se o
index_statuséACTIVEe se o valorcoverage_percentageé100. Pode levar vários minutos para quecoverage_percentagechegue a100.
Usar a função VECTOR_SEARCH com um índice
Depois que o índice vetorial for criado e preenchido, use a função VECTOR_SEARCH para encontrar o vizinho mais próximo do embedding na coluna embedding_v1 da tabela patents2. Como essa consulta usa o índice vetorial na pesquisa,
então VECTOR_SEARCH usa um
método do Vizinho aproximado mais perto
para encontrar o vizinho mais próximo do embedding.
Para usar a função VECTOR_SEARCH com um índice, cole o seguinte no
editor de consultas e clique em
Executar:
SELECT query.publication_number AS query_publication_number, query.title AS query_title, base.publication_number AS base_publication_number, base.title AS base_title, distance FROM VECTOR_SEARCH( TABLE bqml_tutorial.patents, 'embedding_v1', TABLE bqml_tutorial.patents2, top_k => 5, distance_type => 'COSINE', options => '{"fraction_lists_to_search": 0.005}');
Os resultados são semelhantes aos seguintes:
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+ | query_publication_number | query_title | base_publication_number | base_title | distance | +--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+ | KR-20180122872-A | Rainwater management system based on rainwater keeping unit | CN-106599080-B | A kind of rapid generation for keeping away big vast transfer figure based on GIS | 0.14471956347590609 | | KR-20180122872-A | Rainwater management system based on rainwater keeping unit | CN-114118544-A | Urban waterlogging detection method and device | 0.17472108931171348 | | KR-20180122872-A | Rainwater management system based on rainwater keeping unit | KR-20200048143-A | Method and system for mornitoring dry stream using unmanned aerial vehicle | 0.17561990745619782 | | KR-20180122872-A | Rainwater management system based on rainwater keeping unit | KR-101721695-B1 | Urban Climate Impact Assessment method of Reflecting Urban Planning Scenarios and Analysis System using the same | 0.17696129365559843 | | KR-20180122872-A | Rainwater management system based on rainwater keeping unit | CN-109000731-B | The experimental rig and method that research inlet for stom water chocking-up degree influences water discharged amount | 0.17902723269642917 | +--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
Usar a função VECTOR_SEARCH com força bruta
Nesta seção, você usa a função VECTOR_SEARCH para encontrar o vizinho mais próximo do embedding na coluna embedding_v1 da tabela patents2.
Essa consulta não usa o índice vetorial na pesquisa. Portanto, VECTOR_SEARCH encontra o vizinho exato mais próximo do embedding.
Para usar VECTOR_SEARCH com força bruta, cole o seguinte no editor de consultas
e clique em
Executar:
SELECT query.publication_number AS query_publication_number, query.title AS query_title, base.publication_number AS base_publication_number, base.title AS base_title, distance FROM VECTOR_SEARCH( TABLE bqml_tutorial.patents, 'embedding_v1', TABLE bqml_tutorial.patents2, top_k => 5, distance_type => 'COSINE', options => '{"use_brute_force":true}');
Os resultados são semelhantes aos seguintes:
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+ | query_publication_number | query_title | base_publication_number | base_title | distance | +--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+ | KR-20180122872-A | Rainwater management system based on rainwater keeping unit | CN-106599080-B | A kind of rapid generation for keeping away big vast transfer figure based on GIS | 0.1447195634759062 | | KR-20180122872-A | Rainwater management system based on rainwater keeping unit | CN-114118544-A | Urban waterlogging detection method and device | 0.1747210893117136 | | KR-20180122872-A | Rainwater management system based on rainwater keeping unit | KR-20200048143-A | Method and system for mornitoring dry stream using unmanned aerial vehicle | 0.17561990745619782 | | KR-20180122872-A | Rainwater management system based on rainwater keeping unit | KR-101721695-B1 | Urban Climate Impact Assessment method of Reflecting Urban Planning Scenarios and Analysis System using the same | 0.17696129365559843 | | KR-20180122872-A | Rainwater management system based on rainwater keeping unit | CN-109000731-B | The experimental rig and method that research inlet for stom water chocking-up degree influences water discharged amount | 0.17902723269642928 | +--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
Avaliar o recall
Quando você realiza uma pesquisa de vetor com um índice, ela retorna resultados aproximados,
mas reduz o recall. É possível calcular o recall comparando os resultados retornados pela pesquisa de vetor com um índice e os resultados retornados pela pesquisa de vetor com força bruta. O valor publication_number identifica exclusivamente uma patente. Portanto, ele é usado para comparação na consulta a seguir.
Para avaliar o recall, cole o seguinte no editor de consultas e clique em Executar:
WITH approx_results AS ( SELECT query.publication_number AS query_publication_number, base.publication_number AS base_publication_number FROM VECTOR_SEARCH( TABLE bqml_tutorial.patents, 'embedding_v1', TABLE bqml_tutorial.patents2, top_k => 5, distance_type => 'COSINE', options => '{"fraction_lists_to_search": 0.005}') ), exact_results AS ( SELECT query.publication_number AS query_publication_number, base.publication_number AS base_publication_number FROM VECTOR_SEARCH( TABLE bqml_tutorial.patents, 'embedding_v1', TABLE bqml_tutorial.patents2, top_k => 5, distance_type => 'COSINE', options => '{"use_brute_force":true}') ) SELECT a.query_publication_number, SUM(CASE WHEN a.base_publication_number = e.base_publication_number THEN 1 ELSE 0 END) / 5 AS recall FROM exact_results e LEFT JOIN approx_results a ON e.query_publication_number = a.query_publication_number GROUP BY a.query_publication_number;
Os resultados têm a seguinte aparência:
+--------------------------+--------+ | query_publication_number | recall | +--------------------------+--------+ | KR-20180122872-A | 1.0 | +--------------------------+--------+
Se o recall for menor do que o desejado, será possível aumentar o valor de fraction_lists_to_search, mas você terá uma latência e um uso de recursos potencialmente maiores. Para ajustar a pesquisa de vetor, tente várias execuções de VECTOR_SEARCH com diferentes valores de argumento, salve os resultados em tabelas e depois os compare.
Limpar
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados neste tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.
- No Google Cloud console, acesse a página Gerenciar recursos.
- Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir.
- Na caixa de diálogo, digite o ID do projeto e clique em Desativar para excluir o projeto.
Como alternativa, para manter o projeto e excluir os recursos usados neste tutorial, siga estas etapas:
Acesse a página BigQuery.
No painel esquerdo, expanda o projeto e clique em Conjuntos de dados.
Para o conjunto de dados
bqml_tutorial, clique em Abrir ações > Excluir.Na caixa de diálogo Excluir conjunto de dados, clique em Excluir para confirmar.