Questa pagina descrive come eseguire una ricerca di somiglianza vettoriale in Spanner utilizzando le funzioni vettoriali di distanza del coseno, distanza euclidea e prodotto scalare per trovare i vicini più prossimi K. Queste informazioni si applicano sia ai database con dialetto GoogleSQL sia ai database con dialetto PostgreSQL. Prima di leggere questa pagina, è importante comprendere i seguenti concetti:
- Distanza euclidea: misura la distanza più breve tra due vettori.
- Distanza del coseno: misura il coseno dell'angolo tra due vettori.
- Prodotto scalare: calcola il coseno dell'angolo moltiplicato per il prodotto delle grandezze dei vettori corrispondenti. Se sai che tutti i vector embedding nel tuo set di dati sono normalizzati, puoi utilizzare
DOT_PRODUCT()come funzione di distanza. - K-nearest neighbors (KNN): un algoritmo di machine learning supervisionato utilizzato per risolvere problemi di classificazione o regressione.
Puoi utilizzare le funzioni di distanza vettoriale per eseguire la ricerca vettoriale K-Nearest Neighbor (KNN) per casi d'uso come la ricerca di similarità o la generazione aumentata dal recupero. Spanner supporta le funzioni COSINE_DISTANCE(), EUCLIDEAN_DISTANCE() e DOT_PRODUCT(), che operano sui vector embedding, consentendoti di trovare il KNN dell'embedding di input.
Ad esempio, dopo aver generato e salvato i dati operativi di Spanner come vector embedding, puoi fornire questi vector embedding come parametro di input nella query per trovare i vettori più vicini nello spazio N-dimensionale per cercare elementi semanticamente simili o correlati.
Tutte e tre le funzioni di distanza accettano gli argomenti vector1 e vector2, che sono di tipo array<> e devono essere costituiti dalle stesse dimensioni e avere la stessa lunghezza. Per maggiori dettagli su queste funzioni, consulta:
COSINE_DISTANCE()in GoogleSQLEUCLIDEAN_DISTANCE()in GoogleSQLDOT_PRODUCT()in GoogleSQL- Funzioni matematiche in PostgreSQL
(
spanner.cosine_distance(),spanner.euclidean_distance()espanner.dot_product()) - Scegli tra le funzioni di distanza tra vettori per misurare la somiglianza dei vector embedding.
Esempi
Gli esempi seguenti mostrano la ricerca KNN, la ricerca KNN su dati partizionati e l'utilizzo di un indice secondario con KNN.
Tutti gli esempi utilizzano EUCLIDEAN_DISTANCE(). Puoi anche utilizzare COSINE_DISTANCE(). Inoltre, se tutti i vector embedding nel set di dati sono normalizzati, puoi utilizzare DOT_PRODUCT() come funzione di distanza.
Esempio 1: ricerca KNN
Considera una tabella Documents con una colonna (DocEmbedding) di text embedding precalcolati dalla colonna di byte DocContents. La specifica della lunghezza del vettore su DocEmbedding non è obbligatoria per le query KNN, ma è consigliata per ottimizzare le prestazioni di scansione e consentirti di creare un indice vettoriale in un secondo momento. Ometti la lunghezza del vettore se la colonna memorizza vettori di dimensioni variabili.
GoogleSQL
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES(MAX),
DocEmbedding ARRAY<FLOAT32>(vector_length=>4)
) PRIMARY KEY (UserId, DocId);
PostgreSQL
CREATE TABLE Documents (
UserId bigint NOT NULL,
DocId bigint NOT NULL,
Author varchar(1024),
DocContents bytea,
DocEmbedding float4[] VECTOR LENGTH 4,
PRIMARY KEY (UserId, DocId)
);
Supponendo che un embedding di input per "baseball, but not professional baseball"
sia l'array [0.3, 0.3, 0.7, 0.7], puoi trovare i primi cinque documenti più vicini
che corrispondono con la seguente query:
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;
I risultati previsti di questo esempio:
Documents
+---------------------------+-----------------+
| DocId | DocEmbedding |
+---------------------------+-----------------+
| 24 | [8, ...] |
+---------------------------+-----------------+
| 25 | [6, ...] |
+---------------------------+-----------------+
| 26 | [3.2, ...] |
+---------------------------+-----------------+
| 27 | [38, ...] |
+---------------------------+-----------------+
| 14229 | [1.6, ...] |
+---------------------------+-----------------+
Esempio 2: ricerca KNN su dati partizionati
La query nell'esempio precedente può essere modificata aggiungendo condizioni alla clausola WHERE per limitare la ricerca vettoriale a un sottoinsieme dei dati. Un'applicazione comune di questa funzionalità è la ricerca su dati partizionati, ad esempio righe che appartengono a un UserId specifico.
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;
I risultati previsti di questo esempio:
Documents
+-----------+-----------------+-----------------+
| UserId | DocId | DocEmbedding |
+-----------+-----------------+-----------------+
| 18 | 234 | [12, ...] |
+-----------+-----------------+-----------------+
| 18 | 12 | [1.6, ...] |
+-----------+-----------------+-----------------+
| 18 | 321 | [22, ...] |
+-----------+-----------------+-----------------+
| 18 | 432 | [3, ...] |
+-----------+-----------------+-----------------+
Esempio 3: ricerca KNN su intervalli di indici secondari
Se il filtro della clausola WHERE che utilizzi non fa parte della chiave primaria della tabella, puoi creare un indice secondario per accelerare l'operazione con una scansione solo indice.
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;
I risultati previsti di questo esempio:
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, ...] |
+------------+-----------------+-----------------+
Passaggi successivi
Scopri di più sulle funzioni GoogleSQL
COSINE_DISTANCE(),EUCLIDEAN_DISTANCE(),DOT_PRODUCT().Scopri di più sulle funzioni PostgreSQL
spanner.cosine_distance(),spanner.euclidean_distance(),spanner.dot_product().Scopri di più su come scegliere tra le funzioni di distanza vettoriale per misurare la somiglianza dei vector embedding.