Neste tutorial, mostramos como realizar uma
pesquisa de similaridade em
embeddings armazenados em tabelas do BigQuery usando a
função VECTOR_SEARCH
e um índice vetorial.
A busca vetorial é uma técnica para comparar objetos semelhantes usando embeddings, e é usada para potencializar produtos do Google, incluindo a Pesquisa Google, o YouTube e o Google Play. É possível usar a busca vetorial para realizar pesquisas semânticas em grande escala ou uma pesquisa híbrida que combina uma pesquisa semântica com uma pesquisa lexical (por palavra-chave). Ao usar índices vetoriais com a busca vetorial, é possível aproveitar tecnologias fundamentais, como a indexação de arquivo invertido (IVF) e o algoritmo ScaNN.
A pesquisa vetorial é baseada 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
- Realize uma pesquisa de similaridade em embeddings armazenados em tabelas do BigQuery
usando a função
VECTOR_SEARCH. - Use um índice vetorial para melhorar o desempenho da pesquisa vetorial.
- Realize uma pesquisa que use um índice vetorial e outra que não use um índice.
- Avalie 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.
A pesquisa de similaridade é cobrada de acordo com os preços on demand ou das edições.
- Sob demanda: você recebe uma cobrança pela quantidade de bytes verificados na tabela base, no índice e na consulta de pesquisa.
Preços das 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 console do Google Cloud , na página do seletor de projetos, selecione ou crie um projeto do Google Cloud .
Papéis necessários para selecionar ou criar um projeto
- Selecionar um projeto: para selecionar um projeto, não é necessário ter um papel do IAM específico. É possível selecionar qualquer projeto em que você tenha um papel.
-
Criar um projeto: para criar um projeto, é preciso ter o papel de criador de projetos
(
roles/resourcemanager.projectCreator), que contém a permissãoresourcemanager.projects.create. Saiba como conceder papéis.
-
Verifique se o faturamento está ativado para o projeto do Google Cloud .
-
Ative a API BigQuery, se ainda não estiver ativada.
Funções necessárias para ativar APIs
Para ativar APIs, você precisa da 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, é possível conseguir essa permissão pelo papel de administrador do Service Usage (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 usando 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 console do Google Cloud , acesse a página BigQuery.
No painel à esquerda, clique em Explorer:

Se o painel esquerdo não aparecer, clique em Expandir painel esquerdo para abrir.
No 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.Em Local dos dados, selecione EUA.
Não altere as outras configurações padrão.
Clique em Criar conjunto de dados.
bq
Para criar um novo conjunto de dados, use o
comando bq mk --dataset.
Crie um conjunto de dados chamado
bqml_tutorialcom o local de 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 método datasets.insert com um recurso de conjunto de dados definido:
{ "datasetReference": { "datasetId": "bqml_tutorial" } }
Criar tabelas para armazenar dados e embeddings
Nesta seção, você vai criar 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 vai criar 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ê vai receber 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ê vai receber 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 vetorial, mas reduzindo o
recall
e, portanto, retornando resultados mais aproximados. Sem um índice de vetor, o VECTOR_SEARCH usa a pesquisa de força bruta para medir a distância de cada registro.
Nesta seção, você vai criar 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_v1da tabelapatents, 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ê vai receber 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
index_statuséACTIVEe se o valor decoverage_percentageé100. Pode levar vários minutos para quecoverage_percentagealcance100.
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, VECTOR_SEARCH ela 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ê vai usar 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 vetorial com um índice, ela retorna resultados aproximados,
mas reduz o recall. É possível calcular o recall comparando os resultados retornados pela pesquisa vetorial com um índice e pela pesquisa vetorial com força bruta. O valor publication_number identifica exclusivamente uma patente. Por isso, é 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á latência e uso de recursos potencialmente maiores. Para ajustar a busca vetorial, 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 no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.
- No console Google Cloud , 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 Encerrar para excluí-lo.
Como alternativa, para manter o projeto e excluir os recursos usados neste tutorial, siga estas etapas:
Acessar a página do BigQuery.
No painel à esquerda, expanda o projeto e clique em Conjuntos de dados.
No 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.