Buscar incrustaciones con la búsqueda vectorial

En este tutorial se muestra cómo realizar una búsqueda por similitud en las inserciones almacenadas en tablas de BigQuery mediante la función VECTOR_SEARCH y, opcionalmente, un índice vectorial.

Cuando usas VECTOR_SEARCH con un índice vectorial, VECTOR_SEARCH utiliza el método Vecino más cercano aproximado para mejorar el rendimiento de la búsqueda vectorial, pero a cambio se reduce la recuperación y, por lo tanto, se devuelven resultados más aproximados. Sin un índice vectorial, VECTOR_SEARCH usa la búsqueda por fuerza bruta para medir la distancia de cada registro.

Permisos obligatorios

Para completar este tutorial, necesitas los siguientes permisos de gestión de identidades y accesos (IAM):

  • Para crear un conjunto de datos, necesitas el permiso bigquery.datasets.create.
  • Para crear una tabla, necesitas los siguientes permisos:

    • bigquery.tables.create
    • bigquery.tables.updateData
    • bigquery.jobs.create
  • Para crear un índice vectorial, necesitas el permiso bigquery.tables.createIndex en la tabla en la que vas a crear el índice.

  • Para eliminar un índice vectorial, necesitas el permiso bigquery.tables.deleteIndex en la tabla en la que vas a eliminar el índice.

Cada uno de los siguientes roles de gestión de identidades y accesos predefinidos incluye los permisos que necesitas para trabajar con índices vectoriales:

  • Propietario de datos de BigQuery (roles/bigquery.dataOwner)
  • Editor de datos de BigQuery (roles/bigquery.dataEditor)

Costes

La función VECTOR_SEARCH usa los precios de computación de BigQuery. Se te cobra por la búsqueda de similitud, ya sea con el modelo de precios bajo demanda o con el de ediciones.

  • Bajo demanda: se te cobra por la cantidad de bytes analizados en la tabla base, el índice y la consulta de búsqueda.
  • Precios de las ediciones: se te cobrará por los espacios necesarios para completar el trabajo en la edición de reserva. Cuanto más grandes y complejas sean las comparaciones de similitud, más se te cobrará.

Para obtener más información, consulta los precios de BigQuery.

Antes de empezar

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. Verify that billing is enabled for your Google Cloud project.

  3. Enable the BigQuery API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

Crear conjunto de datos

Crea un conjunto de datos de BigQuery:

  1. En la Google Cloud consola, ve a la página BigQuery.

    Ir a la página de BigQuery

  2. En el panel Explorador, haz clic en el nombre de tu proyecto.

  3. Haz clic en Ver acciones > Crear conjunto de datos.

    Crea un conjunto de datos que contenga los objetos que se usan en el tutorial.

  4. En la página Crear conjunto de datos, haz lo siguiente:

    • En ID del conjunto de datos, introduce vector_search.

    • En Tipo de ubicación, selecciona Multirregión y, a continuación, EE. UU. (varias regiones de Estados Unidos).

      Los conjuntos de datos públicos se almacenan en la US multirregión. Para simplificar el proceso, guarda el conjunto de datos en la misma ubicación.

    • Deje el resto de los ajustes predeterminados como están y haga clic en Crear conjunto de datos.

Crear tablas de prueba

  1. Crea la tabla patents que contiene las inserciones de patentes, a partir de un subconjunto del conjunto de datos público Patentes de Google:

    CREATE TABLE vector_search.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;
  2. Crea la tabla patents2 que contiene una inserción de patente para buscar los vecinos más cercanos:

    CREATE TABLE vector_search.patents2 AS
    SELECT * FROM `patents-public-data.google_patents_research.publications`
    WHERE publication_number = 'KR-20180122872-A';

Crear un índice vectorial

  1. Crea el índice vectorial my_index en la columna embeddings_v1 de la tabla patents:

    CREATE OR REPLACE VECTOR INDEX my_index ON vector_search.patents(embedding_v1)
    STORING(publication_number, title)
    OPTIONS(distance_type='COSINE', index_type='IVF');
  2. Espera varios minutos a que se cree el índice vectorial y, a continuación, ejecuta la siguiente consulta y confirma que el valor de coverage_percentage es 100:

    SELECT * FROM vector_search.INFORMATION_SCHEMA.VECTOR_INDEXES;

Usar la función VECTOR_SEARCH con un índice

Una vez que se haya creado y rellenado el índice vectorial, usa la función VECTOR_SEARCH para encontrar el vecino más cercano de la inserción de la columna embedding_v1 de la tabla patents2. Esta consulta usa el índice vectorial en la búsqueda, por lo que VECTOR_SEARCH usa un método Approximate Nearest Neighbor para encontrar el vecino más cercano de la inserción.

Usa la función VECTOR_SEARCH con un índice:

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 vector_search.patents,
    'embedding_v1',
    TABLE vector_search.patents2,
    top_k => 5,
    distance_type => 'COSINE',
    options => '{"fraction_lists_to_search": 0.005}');

Los resultados deberían ser similares a los siguientes:

+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| 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 la función VECTOR_SEARCH con fuerza bruta

Usa la función VECTOR_SEARCH para encontrar el vecino más cercano de la inserción en la columna embedding_v1 de la tabla patents2. Esta consulta no usa el índice vectorial en la búsqueda, por lo que VECTOR_SEARCH encuentra el vecino más cercano exacto de la inserción.

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 vector_search.patents,
    'embedding_v1',
    TABLE vector_search.patents2,
    top_k => 5,
    distance_type => 'COSINE',
    options => '{"use_brute_force":true}');

Los resultados deberían ser similares a los siguientes:

+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| 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 |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+

Evaluar la recuperación

Cuando realizas una búsqueda vectorial con un índice, se devuelven resultados aproximados, lo que conlleva una reducción de la cobertura. Puedes calcular la recuperación comparando los resultados devueltos por la búsqueda vectorial con un índice y por la búsqueda vectorial con fuerza bruta. En este conjunto de datos, el valor publication_number identifica de forma única una patente, por lo que se usa para la comparación.

WITH approx_results AS (
  SELECT query.publication_number AS query_publication_number,
    base.publication_number AS base_publication_number
  FROM
    VECTOR_SEARCH(
      TABLE vector_search.patents,
      'embedding_v1',
      TABLE vector_search.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 vector_search.patents,
      'embedding_v1',
      TABLE vector_search.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

Si el recall es inferior al que te gustaría, puedes aumentar el valor de fraction_lists_to_search, pero esto puede provocar una latencia y un uso de recursos mayores. Para ajustar la búsqueda vectorial, puedes probar varias ejecuciones de VECTOR_SEARCH con diferentes valores de argumentos, guardar los resultados en tablas y, a continuación, comparar los resultados.

Limpieza

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.