Esegui la ricerca vettoriale di similarità in Spanner trovando i risultati vicini K-nearest

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 in dialetto GoogleSQL sia ai database in 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 magnitudini dei vettori corrispondenti. Se sai che tutti gli embedding vettoriali nel tuo set di dati sono normalizzati, puoi utilizzare DOT_PRODUCT() come funzione di distanza.
  • K-Nearest Neighbor (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 somiglianze o la generazione con il recupero avanzato. Spanner supporta le funzioni COSINE_DISTANCE(), EUCLIDEAN_DISTANCE() e DOT_PRODUCT(), che operano sugli embedding vettoriali, consentendoti di trovare il KNN dell'embedding di input.

Ad esempio, dopo aver generato e salvato i dati operativi di Spanner come incorporamenti vettoriali, puoi fornire questi incorporamenti vettoriali 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 ulteriori dettagli su queste funzioni, consulta:

Esempi

Gli esempi riportati di seguito mostrano la ricerca KNN, la ricerca KNN sui 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 gli embedding vettoriali nel set di dati sono normalizzati, puoi utilizzare DOT_PRODUCT() come funzione di distanza.

Prendi in considerazione una tabella Documents con una colonna (DocEmbedding) di embedding di testo precomputati dalla colonna di byte DocContents.

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 NOT NULL,
DocId        bigint NOT NULL,
Author       varchar(1024),
DocContents  bytea,
DocEmbedding float4[],
PRIMARY KEY  (UserId, DocId)
);

Supponendo che un embedding di input per "baseball, ma non baseball professionistico" sia l'array [0.3, 0.3, 0.7, 0.7], puoi trovare i cinque documenti più vicini corrispondenti 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 sui dati partizionati

La query nell'esempio precedente può essere modificata aggiungendo condizioni alla clausola WHERE per limitare la ricerca di vettori a un sottoinsieme di dati. Un'applicazione comune di questo approccio è la ricerca in dati partizionati, ad esempio righe appartenenti 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 negli intervalli dell'indice secondario

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 dell'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