Auf dieser Seite wird beschrieben, wie Sie in Spanner eine Vektorähnlichkeitssuche durchführen. Dazu verwenden Sie die Vektorfunktionen für Kosinus-Distanz, euklidische Distanz und Punktprodukt, um die k-nächsten Nachbarn zu finden. Diese Informationen gelten sowohl für Datenbanken im GoogleSQL-Dialekt als auch für Datenbanken im PostgreSQL-Dialekt. Bevor Sie diese Seite lesen, sollten Sie die folgenden Konzepte kennen:
- Euklidische Distanz: Misst die kürzeste Distanz zwischen zwei Vektoren.
- Kosinus-Distanz: Misst den Kosinus des Winkels zwischen zwei Vektoren.
- Punktprodukt: Berechnet den
Kosinus des Winkels multipliziert mit dem Produkt der entsprechenden Vektor
größen. Wenn Sie wissen, dass alle Vektoreinbettungen in Ihrem Dataset normalisiert sind, können Sie
DOT_PRODUCT()als Distanzfunktion verwenden. - K-Nearest Neighbors (KNN): Ein Algorithmus für überwachtes maschinelles Lernen, der zur Lösung von Klassifizierungs- oder Regressionsproblemen verwendet wird.
Sie können Vektordistanzfunktionen verwenden, um eine KNN-Vektorsuche (K-Nearest Neighbors) für Anwendungsfälle wie die Ähnlichkeitssuche oder die Retrieval-Augmented Generation durchzuführen. Spanner unterstützt die Funktionen COSINE_DISTANCE(), EUCLIDEAN_DISTANCE() und DOT_PRODUCT(), die auf Vektoreinbettungen angewendet werden. So können Sie die KNN der Eingabeeinbettung finden.
Alle drei Distanzfunktionen verwenden die Argumente vector1 und vector2 vom Typ array<>. Sie müssen dieselben Dimensionen und dieselbe Länge haben. Weitere Informationen zu diesen Funktionen finden Sie unter:
COSINE_DISTANCE()in GoogleSQLEUCLIDEAN_DISTANCE()in GoogleSQLDOT_PRODUCT()in GoogleSQL- Mathematische Funktionen in PostgreSQL
(
spanner.cosine_distance(),spanner.euclidean_distance()undspanner.dot_product()) - Vektordistanzfunktionen auswählen, um die Ähnlichkeit von Vektoreinbettungen zu messen.
Beispiele
In den folgenden Beispielen werden die KNN-Suche, die KNN-Suche in partitionierten Daten und die Verwendung eines sekundären Index mit KNN gezeigt.
In allen Beispielen wird EUCLIDEAN_DISTANCE() verwendet. Sie können auch COSINE_DISTANCE() verwenden. Wenn alle Vektoreinbettungen in Ihrem Dataset normalisiert sind, können Sie außerdem DOT_PRODUCT() als Distanzfunktion verwenden.
Beispiel 1: KNN-Suche
Angenommen, es gibt eine Tabelle Documents mit einer Spalte (DocEmbedding) mit vorab berechneten Texteinbettungen aus der Byte-Spalte DocContents.
GoogleSQL
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES(MAX),
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)
);
Angenommen, eine Eingabeeinbettung für „Baseball, aber nicht professioneller Baseball“ ist das Array [0.3, 0.3, 0.7, 0.7]. Mit der folgenden Abfrage können Sie die fünf nächstgelegenen Dokumente finden, die übereinstimmen:
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;
Erwartete Ergebnisse dieses Beispiels:
Documents
+---------------------------+-----------------+
| DocId | DocEmbedding |
+---------------------------+-----------------+
| 24 | [8, ...] |
+---------------------------+-----------------+
| 25 | [6, ...] |
+---------------------------+-----------------+
| 26 | [3.2, ...] |
+---------------------------+-----------------+
| 27 | [38, ...] |
+---------------------------+-----------------+
| 14229 | [1.6, ...] |
+---------------------------+-----------------+
Beispiel 2: KNN-Suche in partitionierten Daten
Die Abfrage im vorherigen Beispiel kann geändert werden, indem Sie der WHERE-Klausel Bedingungen hinzufügen, um die Vektorsuche auf eine Teilmenge Ihrer Daten zu beschränken. Ein häufiger Anwendungsfall ist die Suche in partitionierten Daten, z. B. Zeilen, die zu einer bestimmten UserId gehören.
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;
Erwartete Ergebnisse dieses Beispiels:
Documents
+-----------+-----------------+-----------------+
| UserId | DocId | DocEmbedding |
+-----------+-----------------+-----------------+
| 18 | 234 | [12, ...] |
+-----------+-----------------+-----------------+
| 18 | 12 | [1.6, ...] |
+-----------+-----------------+-----------------+
| 18 | 321 | [22, ...] |
+-----------+-----------------+-----------------+
| 18 | 432 | [3, ...] |
+-----------+-----------------+-----------------+
Beispiel 3: KNN-Suche in sekundären Indexbereichen
Wenn der WHERE Klausel-Filter, den Sie verwenden, nicht Teil des Primärschlüssels der Tabelle ist, können Sie einen sekundären Index erstellen, um den Vorgang mit einer reinen Indexsuche zu beschleunigen.
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;
Erwartete Ergebnisse dieses Beispiels:
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
Weitere Informationen zu den GoogleSQL
COSINE_DISTANCE(),EUCLIDEAN_DISTANCE(),DOT_PRODUCT()FunktionenWeitere Informationen zu den PostgreSQL
spanner.cosine_distance(),spanner.euclidean_distance(),spanner.dot_product()Funktionen.