このページでは、Spanner Graph でベクトル検索を使用して、K 最近傍(KNN)と近似最近傍(ANN)を見つける方法について説明します。ベクトル距離関数を使用して、生成 AI アプリケーションの類似検索や検索拡張生成などのユースケースで KNN と ANN のベクトル検索を実行できます。
Spanner Graph は、KNN ベクトル類似性検索を実行するために次の距離関数をサポートしています。
COSINE_DISTANCE()
: 2 つのベクトル間の最短距離を測定します。EUCLIDEAN_DISTANCE()
: 2 つのベクトル間の角度のコサインを測定します。DOT_PRODUCT()
: 角度のコサインに、対応するベクトルの大きさを掛けます。データセット内のすべてのベクトル エンベディングが正規化されていることがわかっている場合は、DOT_PRODUCT()
を距離関数として使用できます。
詳細については、k 近傍法を探索して Spanner でベクトル類似性検索を行うをご覧ください。
Spanner Graph は、ANN ベクトル類似性検索を実行するための次の近似距離関数もサポートしています。
APPROX_COSINE_DISTANCE
: 2 つのベクトル間の近似最短距離を測定します。APPROX_EUCLIDEAN_DISTANCE
: 2 つのベクトル間の角度の近似コサインを測定します。APPROX_DOT_PRODUCT
: 角度の近似コサインに、対応するベクトルの大きさを掛けます。データセット内のすべてのベクトル エンベディングが正規化されていることがわかっている場合は、DOT_PRODUCT()
を距離関数として使用できます。
詳細については、近似最近傍を検索してベクトル インデックスを作成し、ベクトル エンベディングをクエリするをご覧ください。
始める前に
このドキュメントのサンプルを実行するには、まずSpanner Graph を設定してクエリを実行するの手順に沿って、次の操作を行います。
必要なグラフデータを挿入したら、データベースに次の更新を行います。
グラフ データベースに追加のベクトルデータを挿入する
グラフ データベースに必要な更新を行う手順は次のとおりです。
Account
入力テーブルに新しい列nick_name_embeddings
を追加します。ALTER TABLE Account ADD COLUMN nick_name_embeddings ARRAY<FLOAT32>(vector_length=>4);
nick_name
列にデータを追加します。UPDATE Account SET nick_name = "Fund for a refreshing tropical vacation" WHERE id = 7; UPDATE Account SET nick_name = "Fund for a rainy day!" WHERE id = 16; UPDATE Account SET nick_name = "Saving up for travel" WHERE id = 20;
nick_name
列のテキストのエンベディングを作成し、新しいnick_name_embeddings
列に入力します。Spanner Graph 内の運用データの Vertex AI エンベディングを生成するには、Vertex AI テキスト エンベディングを取得するをご覧ください。
説明のため、これらの例では人工的な低次元ベクトル値を使用しています。
UPDATE Account SET nick_name_embeddings = ARRAY<FLOAT32>[0.3, 0.5, 0.8, 0.7] WHERE id = 7; UPDATE Account SET nick_name_embeddings = ARRAY<FLOAT32>[0.4, 0.9, 0.7, 0.1] WHERE id = 16; UPDATE Account SET nick_name_embeddings = ARRAY<FLOAT32>[0.2, 0.5, 0.6, 0.6] WHERE id = 20;
AccountTransferAccount
入力テーブルに 2 つの新しい列(notes
とnotes_embeddings
)を追加します。ALTER TABLE AccountTransferAccount ADD COLUMN notes STRING(MAX); ALTER TABLE AccountTransferAccount ADD COLUMN notes_embeddings ARRAY<FLOAT32>(vector_length=>4);
notes
列のテキストのエンベディングを作成し、notes_embeddings
列に入力します。Spanner Graph 内の運用データの Vertex AI エンベディングを生成するには、Vertex AI テキスト エンベディングを取得するをご覧ください。
説明のため、これらの例では人工的な低次元ベクトル値を使用しています。
UPDATE AccountTransferAccount SET notes = "for shared cost of dinner", notes_embeddings = ARRAY<FLOAT32>[0.3, 0.5, 0.8, 0.7] WHERE id = 16 AND to_id = 20; UPDATE AccountTransferAccount SET notes = "fees for tuition", notes_embeddings = ARRAY<FLOAT32>[0.1, 0.9, 0.1, 0.7] WHERE id = 20 AND to_id = 7; UPDATE AccountTransferAccount SET notes = 'loved the lunch', notes_embeddings = ARRAY<FLOAT32>[0.4, 0.5, 0.7, 0.9] WHERE id = 20 AND to_id = 16;
Account
入力テーブルとAccountTransferAccount
入力テーブルに新しい列を追加したら、次のステートメントを使用してプロパティグラフ定義を更新します。詳細については、既存のノード定義またはエッジ定義を更新するをご覧ください。CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES (Account, Person) EDGE TABLES ( PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers );
K 最近傍を検索する
次の例では、EUCLIDEAN_DISTANCE()
関数を使用して、グラフ データベースのノードとエッジに対して KNN ベクトル検索を実行します。
グラフノードで KNN ベクトル検索を実行する
Account
ノードの nick_name_embeddings
プロパティに対して KNN ベクトル検索を実行できます。この KNN ベクトル検索では、アカウント所有者の name
とアカウントの nick_name
が返されます。次の例では、レジャー旅行と休暇のアカウントのトップ 2 つの K 最近傍が結果に表示されます。これは、[0.2, 0.4, 0.9, 0.6]
ベクトル エンベディングで表されます。
GRAPH FinGraph
MATCH (p:Person)-[:Owns]->(a:Account)
RETURN p.name, a.nick_name
ORDER BY EUCLIDEAN_DISTANCE(a.nick_name_embeddings,
-- An illustrative embedding for 'accounts for leisure travel and vacation'
ARRAY<FLOAT32>[0.2, 0.4, 0.9, 0.6])
LIMIT 2;
結果
name | nick_name |
---|---|
Alex | 南国でリフレッシュする休暇の資金 |
Dana | 旅行のために貯金する |
グラフエッジで KNN ベクトル検索を行う
Owns
エッジの notes_embeddings
プロパティに対して KNN ベクトル検索を実行できます。この KNN ベクトル検索では、アカウント所有者の name
と転送の notes
が返されます。次の例では、結果に 食費のトップ 2 つの K 最近傍が表示されます。これは、[0.2, 0.4, 0.9, 0.6]
ベクトル エンベディングで表されます。
GRAPH FinGraph
MATCH (p:Person)-[:Owns]->(:Account)-[t:Transfers]->(:Account)
WHERE t.notes_embeddings IS NOT NULL
RETURN p.name, t.notes
ORDER BY EUCLIDEAN_DISTANCE(t.notes_embeddings,
-- An illustrative vector embedding for 'food expenses'
ARRAY<FLOAT32>[0.2, 0.4, 0.9, 0.6])
LIMIT 2;
結果
name | メモ |
---|---|
Lee | 夕食の費用を分担 |
Dana | ランチがとてもおいしかったです |
ベクトル インデックスを作成し、近似最近傍を検索する
ANN 検索を実行するには、Spanner Graph がベクトル検索を高速化するために使用する特殊なベクトル インデックスを作成する必要があります。ベクトル インデックスでは、特定の距離指標を使用する必要があります。distance_type
パラメータを COSINE
、DOT_PRODUCT
、EUCLIDEAN
のいずれかに設定すると、ユースケースに最も適した距離指標を選択できます。詳細については、VECTOR INDEX ステートメントをご覧ください。
次の例では、Account
入力テーブルの nick_name_embedding
列にユークリッド距離タイプを使用してベクトル インデックスを作成します。
CREATE VECTOR INDEX NickNameEmbeddingIndex
ON Account(nick_name_embeddings)
WHERE nick_name_embeddings IS NOT NULL
OPTIONS (distance_type = 'EUCLIDEAN', tree_depth = 2, num_leaves = 1000);
グラフノードで ANN ベクトル検索を実行する
ベクトル インデックスを作成したら、Account
ノードの nick_name
プロパティに対して ANN ベクトル検索を実行できます。ANN ベクトル検索は、アカウント所有者の name
とアカウントの nick_name
を返します。次の例では、レジャー旅行と休暇のアカウントの近似最近傍のトップ 2 が結果に表示されます。これは、[0.2, 0.4, 0.9, 0.6]
ベクトル エンベディングで表されます。
グラフ ヒントを使用すると、クエリ オプティマイザーはクエリ実行プランで指定されたベクトル インデックスを使用します。
GRAPH FinGraph
MATCH (@{FORCE_INDEX=NickNameEmbeddingIndex} a:Account)
WHERE a.nick_name_embeddings IS NOT NULL
RETURN a, APPROX_EUCLIDEAN_DISTANCE(a.nick_name_embeddings,
-- An illustrative embedding for 'accounts for leisure travel and vacation'
ARRAY<FLOAT32>[0.2, 0.4, 0.9, 0.6],
options => JSON '{"num_leaves_to_search": 10}') AS distance
ORDER BY distance
LIMIT 2
NEXT
MATCH (p:Person)-[:Owns]->(a)
RETURN p.name, a.nick_name;
結果
name | nick_name |
---|---|
Alex | 南国でリフレッシュする休暇の資金 |
Dana | 旅行のために貯金する |
次のステップ
- K 最近傍探索を行って Spanner でベクトル類似度検索を行う。
- 近似最近傍を検索し、ベクトル インデックスを作成し、ベクトル エンベディングに対してクエリを実行する。
- Vertex AI テキスト エンべディングを取得する
- Spanner Graph クエリの詳細を確認する。
- クエリをチューニングするためのベスト プラクティスを確認する。