Führen Sie in Spanner eine Suche nach Vektorähnlichkeit durch, indem Sie die K-nächsten Nachbarn ermitteln

Auf dieser Seite wird beschrieben, wie Sie in Spanner eine Suche nach Vektorähnlichkeiten ausführen, indem Sie die Kosinus-Distanz, die euklidische Distanz und die Punktproduktvektorfunktionen verwenden, um die K-nächsten Nachbarn zu ermitteln. Bevor Sie diese Seite lesen, sollten Sie sich mit den folgenden Konzepten vertraut machen:

  • Euklidischer Abstand: misst die kürzeste Entfernung zwischen zwei Vektoren.
  • Kosinus-Distanz: misst den Kosinus des Winkels zwischen zwei Vektoren.
  • Punktprodukt: berechnet den Kosinus des Winkels multipliziert mit dem Produkt des entsprechenden Vektors Größenordnungen. Wenn Sie wissen, dass alle Vektoreinbettungen in Ihrem Dataset normalisiert haben, können Sie DOT_PRODUCT() als Entfernungsfunktion verwenden.
  • K-nächste Nachbarn (KNN): ein überwachter ML-Algorithmus, der zur Klassifizierung oder Regressionsprobleme.

Mithilfe von Vektordistanzfunktionen können Sie eine KNN-Vektorsuche (K-Nearest Neighbor) für Anwendungsfälle wie Ähnlichkeitssuche oder die durch Abruf erweiterte Generierung ausführen. Spanner unterstützt COSINE_DISTANCE(), EUCLIDEAN_DISTANCE()- und DOT_PRODUCT()-Funktionen, die mit Vektoren arbeiten Einbettungen, mit denen Sie den KNN der Eingabeeinbettung ermitteln können.

Wenn Sie beispielsweise Ihren operativen Spanner generieren und speichern, Daten als Vektoreinbettungen enthalten, können Sie geben Sie diese Vektoreinbettungen als Eingabeparameter in Ihrer Abfrage an, um den nächste Vektoren im n-dimensionalen Raum, um nach semantisch ähnlichen oder verwandte Artikel.

Alle drei Distanzfunktionen nehmen die Argumente vector1 und vector2 vom Typ array<> an. Sie müssen dieselben Abmessungen haben und gleich lang sein. Weitere Informationen zu diesen Funktionen finden Sie unter:

Beispiele

Die folgenden Beispiele zeigen die KNN-Suche, die KNN-Suche in partitionierten Daten und die Verwendung eines sekundären Index mit KNN.

In den Beispielen wird immer EUCLIDEAN_DISTANCE() verwendet. Sie können aber auch COSINE_DISTANCE() verwenden. Wenn alle Vektor-Embeddings in Ihrem Dataset normalisiert sind, können Sie DOT_PRODUCT() auch als Distanzfunktion verwenden.

Beispiel: Eine Documents-Tabelle mit einer Spalte (DocEmbedding) mit vorausberechneten Werten Texteinbettungen aus der Spalte DocContents Byte.

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[]
);

Angenommen, eine Eingabeeinbettung für „Baseball, aber kein Profi-Baseball“ das Array [0.3, 0.3, 0.7, 0.7] ist, können Sie die fünf nächstgelegenen Dokumente finden Übereinstimmungen, mit der folgenden Abfrage:

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;

Die erwarteten Ergebnisse in diesem Beispiel:

Documents
+---------------------------+-----------------+
| DocId                     | DocEmbedding    |
+---------------------------+-----------------+
| 24                        | [8, ...]        |
+---------------------------+-----------------+
| 25                        | [6, ...]        |
+---------------------------+-----------------+
| 26                        | [3.2, ...]      |
+---------------------------+-----------------+
| 27                        | [38, ...]       |
+---------------------------+-----------------+
| 14229                     | [1.6, ...]      |
+---------------------------+-----------------+

Beispiel 2: KNN-Suche in partitionierten Daten

Sie können die Abfrage im vorherigen Beispiel ändern, indem Sie dem WHERE-Klausel, um die Vektorsuche auf eine Teilmenge Ihrer Daten zu beschränken. Eine gängige können Sie in partitionierten Daten suchen, wie z. B. in Zeilen, zu einer bestimmten UserId.

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;

Die erwarteten Ergebnisse in diesem Beispiel:

Documents
+-----------+-----------------+-----------------+
| UserId    | DocId           | DocEmbedding    |
+-----------+-----------------+-----------------+
| 18        | 234             | [12, ...]       |
+-----------+-----------------+-----------------+
| 18        | 12              | [1.6, ...]      |
+-----------+-----------------+-----------------+
| 18        | 321             | [22, ...]       |
+-----------+-----------------+-----------------+
| 18        | 432             | [3, ...]        |
+-----------+-----------------+-----------------+

Beispiel 3: KNN-Suche über Bereiche von sekundären Indizes

Wenn der Filter der WHERE-Klausel, den Sie verwenden, nicht Teil des Primärschlüssels der Tabelle ist, können Sie einen sekundären Index erstellen, um den Vorgang mit einem Nur Index-Scan.

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;

Die erwarteten Ergebnisse in diesem Beispiel:

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, ...]        |
+------------+-----------------+-----------------+

Nächste Schritte