Esta página describe cómo realizar una búsqueda de vectores de similitud en Spanner usando la distancia coseno, la distancia euclidiana y el punto funciones de vector de producto para encontrar K-vecinos más cercanos. Antes de leer esta página, es importante que comprendas los siguientes conceptos:
- Distancia euclidiana: mide la distancia más corta entre dos vectores.
- Distancia de coseno: mide el coseno del ángulo entre dos vectores.
- Dot product: calcula la
coseno del ángulo multiplicado por el producto del vector correspondiente
magnitudes reales. Si sabes que todas las incorporaciones vectoriales en tu conjunto de datos
normalizado, puedes usar
DOT_PRODUCT()
como función de distancia. - Vecinos más cercanos (KNN): un algoritmo de aprendizaje automático supervisado que se usa para resolver problemas de problemas de regresión.
Puedes usar funciones de distancia vectorial para determinar los vecinos K-más cercanos (KNN)
búsqueda de vectores para casos de uso como la búsqueda de similitud o la recuperación
generación. Spanner admite COSINE_DISTANCE()
,
las funciones EUCLIDEAN_DISTANCE()
y DOT_PRODUCT()
, que operan en un vector
lo que te permite encontrar el KNN de la incorporación de entrada.
Por ejemplo, después de generar y guardar tu Spanner como incorporaciones vectoriales, puedes estas incorporaciones vectoriales como parámetro de entrada en tu consulta para encontrar la vectores más cercanos en el espacio n-dimensional para buscar vectores semánticamente similares o elementos relacionados.
Las tres funciones de distancia toman los argumentos vector1
y vector2
, que
son del tipo array<>
y deben tener las mismas dimensiones y contener la
la misma duración. Para obtener más detalles sobre estas funciones, consulta:
COSINE_DISTANCE()
en GoogleSQLEUCLIDEAN_DISTANCE()
en GoogleSQLDOT_PRODUCT()
en GoogleSQL- Funciones matemáticas en PostgreSQL
(
spanner.cosine_distance()
,spanner.euclidean_distance()
yspanner.dot_product()
) - Elige entre funciones de distancia vectorial para medir la similitud de las incorporaciones vectoriales.
Ejemplos
Los siguientes ejemplos muestran la búsqueda KNN y la búsqueda KNN en datos particionados, y usando un índice secundario con KNN.
Todos los ejemplos usan EUCLIDEAN_DISTANCE()
. También puedes usar COSINE_DISTANCE()
. Además, si todas las incorporaciones de vectores de tu conjunto de datos están normalizadas, puedes usar DOT_PRODUCT()
como una función de distancia.
Ejemplo 1: Búsqueda de KNN
Considera una tabla Documents
que tenga una columna (DocEmbedding
) de procesamiento previo
de texto de la columna DocContents
bytes.
GoogleSQL
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES,
DocEmbedding ARRAY<FLOAT32>
) PRIMARY KEY (UserId, DocId);
PostgreSQL
CREATE TABLE Documents (
UserId bigint primary key,
DocId bigint primary key,
Author varchar(1024),
DocContents bytea,
DocEmbedding float4[]
);
Suponer que una incorporación de entrada para “béisbol, pero no béisbol profesional”
es el array [0.3, 0.3, 0.7, 0.7]
, puedes encontrar los cinco documentos más cercanos
que coincidan con la siguiente 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;
Estos son los resultados esperados de este ejemplo:
Documents
+---------------------------+-----------------+
| DocId | DocEmbedding |
+---------------------------+-----------------+
| 24 | [8, ...] |
+---------------------------+-----------------+
| 25 | [6, ...] |
+---------------------------+-----------------+
| 26 | [3.2, ...] |
+---------------------------+-----------------+
| 27 | [38, ...] |
+---------------------------+-----------------+
| 14229 | [1.6, ...] |
+---------------------------+-----------------+
Ejemplo 2: Búsqueda de KNN en datos particionados
La consulta del ejemplo anterior puede modificarse agregando condiciones a la
WHERE
para limitar la búsqueda vectorial a un subconjunto de tus datos. Un problema común
su aplicación es buscar datos particionados, como filas que pertenecen
a un 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;
Estos son los resultados esperados de este ejemplo:
Documents
+-----------+-----------------+-----------------+
| UserId | DocId | DocEmbedding |
+-----------+-----------------+-----------------+
| 18 | 234 | [12, ...] |
+-----------+-----------------+-----------------+
| 18 | 12 | [1.6, ...] |
+-----------+-----------------+-----------------+
| 18 | 321 | [22, ...] |
+-----------+-----------------+-----------------+
| 18 | 432 | [3, ...] |
+-----------+-----------------+-----------------+
Ejemplo 3: Búsqueda de KNN en rangos de índices secundarios
Si el filtro de cláusula WHERE
que usas no forma parte de la clave primaria de la tabla, puedes crear un índice secundario para acelerar la operación con un análisis de solo í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;
Estos son los resultados esperados de este ejemplo:
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, ...] |
+------------+-----------------+-----------------+
¿Qué sigue?
Obtén más información sobre las funciones
COSINE_DISTANCE()
,EUCLIDEAN_DISTANCE()
yDOT_PRODUCT()
de GoogleSQL.Obtén más información sobre las funciones de PostgreSQL
spanner.cosine_distance()
,spanner.euclidean_distance()
yspanner.dot_product()
.Obtén más información sobre cómo elegir entre las funciones de distancia vectorial para medir la similitud de las incorporaciones vectoriales.