Auf dieser Seite wird beschrieben, wie Sie eine Suche nach Ähnlichkeitsvektoren in Spanner unter Verwendung der Kosinus-Distanz, der euklidischen Distanz und des Punkts Produktvektorfunktionen, um die K-nächsten Nachbarn zu finden. Bevor Sie diese Seite lesen, ist es wichtig, dass Sie die folgenden Konzepte verstehen:
- 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.
Sie können Vektor-Distanzfunktionen verwenden, um K-nächstgelegene Nachbarn (KNN) durchzuführen
Vektorsuche nach Anwendungsfällen wie Ähnlichkeitssuche oder Datenabruf
Generation. 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 Ihre aktiven Spanner-Daten als Vektoreinbettungen generiert und gespeichert haben, können Sie diese Vektoreinbettungen als Eingabeparameter in Ihrer Abfrage angeben, um die nächsten Vektoren im n-dimensionalen Raum zu finden und nach semantisch ähnlichen oder ähnlichen Elementen zu suchen.
Alle drei Distanzfunktionen verwenden die Argumente vector1
und vector2
, die
sind vom Typ array<>
, müssen dieselben Abmessungen aufweisen und
gleich lang sind. 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()
) - Wählen Sie eine der Vektor-Distanzfunktionen aus, um die Ähnlichkeit von Vektoreinbettungen zu messen.
Beispiele
Die folgenden Beispiele zeigen die KNN-Suche, die KNN-Suche in partitionierten Daten und mithilfe eines sekundären Index mit KNN.
In allen Beispielen wird EUCLIDEAN_DISTANCE()
verwendet. Sie können aber auch COSINE_DISTANCE()
verwenden. Wenn alle Vektoreinbettungen in Ihrem Dataset
normalisiert sind, können Sie DOT_PRODUCT()
als Entfernungsfunktion verwenden.
Beispiel 1: KNN-Suche
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 sekundäre Indexbereiche
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
Weitere Informationen zu den PostgreSQL-Funktionen
spanner.cosine_distance()
,spanner.euclidean_distance()
undspanner.dot_product()