Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ベクトルストア入門

hmatsu47
February 01, 2025

 ベクトルストア入門

BuriKaigi2025
2025/2/1
ルーム:マス 17:00-

hmatsu47

February 01, 2025
Tweet

More Decks by hmatsu47

Other Decks in Technology

Transcript

  1. 自己紹介 松久裕保(@hmatsu47) • https://qiita.com/hmatsu47 • Web インフラのお守り係をしています • 普段は JAWS-UG

    名古屋(・浜松)や PostgreSQL アンカンファレンスで DB ネタを中心に話しています • 実務では MySQL 系の DBを中心に扱っています 2/22(土)に PHP カンファレンス名古屋 2025(名古屋駅前・ ウインクあいち)で MySQL 8.4 以降の話をします 2
  2. ところで…ベクトルって? • いくつかの意味がある:例えば ◦ ①大きさと向きを持った量 ◦ ②数字の組(縦や横に並べたもの) ◦ … 7

    この話の中で主に扱うのはこれ 縦向き・横向きがあるが、ここでは主に (1, 2, 3, …) のように横向きに表記する (ベクトルストアで扱う上でも横向きがイメージしやすい)
  3. 突然ですが • A さんに近いのは誰でしょう? 10 名前 身長 身長差 A さん

    170.0 cm - B さん 174.5 cm 4.5 cm C さん 167.2 cm 2.8 cm 差を計算すればわかりやすい D さん 186.7 cm 16.7 cm
  4. 体重を加えて… • A さんに近いのは誰でしょう? 11 名前 身長 体重 ?? A

    さん 170.0 cm 64.0 kg B さん 174.5 cm 82.7 kg C さん 167.2 cm 46.8 kg D さん 186.7 cm 76.2 kg
  5. 体重を加えて… • A さんに近いのは誰でしょう? 12 名前 身長 体重 BMI A

    さん 170.0 cm 64.0 kg 22.15 B さん 174.5 cm 82.7 kg 27.16 C さん 167.2 cm 46.8 kg 16.74 比べたいのは 肥満度? 体型? 体の大きさ? D さん 186.7 cm 76.2 kg 21.86
  6. 近さ・類似度をはかる方法はいくつかある • コサイン類似度 17 向きの近さ(原点から見て) cosθ:-1(全く似ていない)〜 0(無関係)〜 1(同じ) • 身長・体重の例では(感覚的に)

     マンハッタン距離・ユークリッド距離は「体の大きさ」  コサイン類似度は「体型」 の近さをはかるのに使えそう? θ ほかにも「内積」などがあるが、 ここでは一旦省略
  7. ここで注意! • 次元ごとに値の単位や値が取る範囲が違うベクトルで は、各次元の「1」が表す意味に差が生じてしまう ◦ 例えば身長の単位が「cm」ではなく「mm」だったら計算結果は さらに変わってしまう ◦ そういうときは各次元の値を正規化または標準化して使う手も ▪

    正規化・標準化(前処理)の方法によっても計算結果が変わるので注意 19 前処理の結果、全次元の値が「0」になると コサイン類似度が計算できなくなる問題も(ゼロ(零)ベクトル)
  8. 正規化・標準化してみる • まずは 0 ~ 1 の範囲に正規化(計算式などは省略) 20 名前 (身長,

    体重) マンハッタン距離 ユークリッド距離 コサイン類似度 A さん (0.144, 0.479) 0.000 0.000 1.0000 B さん (0.374, 1.000) 0.751 0.570 0.9978 C さん (0.000, 0.000) 0.623 0.500 - D さん (1.000, 0.819) 1.196 0.921 0.8295
  9. 正規化・標準化してみる • まずは 0 ~ 1 の範囲に正規化(計算式などは省略) 21 名前 (身長,

    体重) マンハッタン距離 ユークリッド距離 コサイン類似度 A さん (0.144, 0.479) 0.000 0.000 1.0000 B さん (0.374, 1.000) 0.751 0.570 0.9978 C さん (0.000, 0.000) 0.623 0.500 - D さん (1.000, 0.819) 1.196 0.921 0.8295 距離は「同じものが 0」になる 値が小さいほど似ている
  10. 正規化・標準化してみる • まずは 0 ~ 1 の範囲に正規化(計算式などは省略) 22 名前 (身長,

    体重) マンハッタン距離 ユークリッド距離 コサイン類似度 A さん (0.144, 0.479) 0.000 0.000 1.0000 B さん (0.374, 1.000) 0.751 0.570 0.9978 C さん (0.000, 0.000) 0.623 0.500 - D さん (1.000, 0.819) 1.196 0.921 0.8295 類似度は「同じものが 1」に 値が大きいほど似ている
  11. 正規化・標準化してみる • まずは 0 ~ 1 の範囲に正規化(計算式などは省略) 23 名前 (身長,

    体重) マンハッタン距離 ユークリッド距離 コサイン類似度 A さん (0.144, 0.479) 0.000 0.000 1.0000 B さん (0.374, 1.000) 0.751 0.570 0.9978 C さん (0.000, 0.000) 0.623 0.500 - D さん (1.000, 0.819) 1.196 0.921 0.8295 長さ・向きが0 (ゼロベクトル)
  12. 正規化・標準化してみる • 標準化(平均 0・標準偏差 1・計算式などは省略) 24 名前 (身長, 体重) マンハッタン距離

    ユークリッド距離 コサイン類似度 A さん (-0.617, -0.251) 0.000 0.000 1.0000 B さん (-0.013, 1.117) 1.972 1.495 -0.3660 C さん (-0.993, -1.509) 1.634 1.313 0.8240 D さん ( 1.623, 0.642) 3.133 2.411 -1.0000
  13. 正規化・標準化してみる • 標準化(平均 0・標準偏差 1・計算式などは省略) 25 名前 (身長, 体重) マンハッタン距離

    ユークリッド距離 コサイン類似度 A さん (-0.617, -0.251) 0.000 0.000 1.0000 B さん (-0.013, 1.117) 1.972 1.495 -0.3660 C さん (-0.993, -1.509) 1.634 1.313 0.8240 D さん ( 1.623, 0.642) 3.133 2.411 -1.0000 こっちはまあわかる?
  14. 正規化・標準化してみる • 標準化(平均 0・標準偏差 1・計算式などは省略) 26 名前 (身長, 体重) マンハッタン距離

    ユークリッド距離 コサイン類似度 A さん (-0.617, -0.251) 0.000 0.000 1.0000 B さん (-0.013, 1.117) 1.972 1.495 -0.3660 C さん (-0.993, -1.509) 1.634 1.313 0.8240 D さん ( 1.623, 0.642) 3.133 2.411 -1.0000 こっちはピンとこないかも? 「平均値から見てどうか?」の視点が必要?
  15. イメージしやすくするために • 今回は正規化・標準化せずに比較してみる 27 名前 (身長, 体重) マンハッタン距離 ユークリッド距離 コサイン類似度

    A さん (170.0, 64.0) 0 0 1.0000 B さん (174.5, 82.7) 23.2 19.2 0.9966 C さん (167.2, 46.8) 20.0 17.4 0.9962 D さん (186.7, 76.2) 28.9 20.7 0.9996
  16. イメージしやすくするために • 今回は正規化・標準化せずに比較してみる 28 名前 (身長, 体重) マンハッタン距離 ユークリッド距離 コサイン類似度

    A さん (170.0, 64.0) 0 0 1.0000 B さん (174.5, 82.7) 23.2 19.2 0.9966 C さん (167.2, 46.8) 20.0 17.4 0.9962 D さん (186.7, 76.2) 28.9 20.7 0.9996 どちらの距離も 「Cさんが一番近い」と判定
  17. イメージしやすくするために • 今回は正規化・標準化せずに比較してみる 29 名前 (身長, 体重) マンハッタン距離 ユークリッド距離 コサイン類似度

    A さん (170.0, 64.0) 0 0 1.0000 B さん (174.5, 82.7) 23.2 19.2 0.9966 C さん (167.2, 46.8) 20.0 17.4 0.9962 D さん (186.7, 76.2) 28.9 20.7 0.9996 「Dさんが最も似ている」
  18. 要素(次元)が増えても大丈夫 • 「腹囲」が増えた 30 名前 (身長, 体重, 腹囲) マンハッタン距離 ユークリッド距離

    コサイン類似度 A さん (170.0, 64.0, 77.0) 0 0 1.0000 B さん (174.5, 82.7, 86.6) 32.8 21.5 0.9969 C さん (167.2, 46.8, 71.8) 25.2 18.2 0.9967 D さん (186.7, 76.2, 67.1) 38.8 22.9 0.9965
  19. 要素(次元)が増えても大丈夫 • 「腹囲」が増えた 31 名前 (身長, 体重, 腹囲) マンハッタン距離 ユークリッド距離

    コサイン類似度 A さん (170.0, 64.0, 77.0) 0 0 1.0000 B さん (174.5, 82.7, 86.6) 32.8 21.5 0.9969 C さん (167.2, 46.8, 71.8) 25.2 18.2 0.9967 D さん (186.7, 76.2, 67.1) 38.8 22.9 0.9965 Bさんに変わった (Dさんお腹周りが細すぎ?)
  20. もう一つ注意 • 次元数が異なるベクトルの比較はできない ◦ 例:MLB 2023 日本人選手 32 名前 打率

    本塁打 打点 盗塁 勝利 敗戦 セーブ 防御率 大谷翔平 オオタニサン .304 44 95 20 10 5 0 3.14 鈴木誠也 セイヤサン .285 20 74 6 吉田正尚 マッチョマン .289 15 72 8
  21. もう一つ注意 • 次元数が異なるベクトルの比較はできない ◦ 例:MLB 2023 日本人選手 33 名前 打率

    本塁打 打点 盗塁 勝利 敗戦 セーブ 防御率 大谷翔平 オオタニサン .304 44 95 20 10 5 0 3.14 鈴木誠也 セイヤサン .285 20 74 6 吉田正尚 マッチョマン .289 15 72 8 打者成績だけで 比較する必要がある
  22. ベクトル検索の使い道の例 [1] • レコメンド(推薦)システム ◦ 例:オンラインショップで閲覧中の商品に似た商品を「お勧め」 欄に表示 ▪ あらかじめ商品の属性(分類や性質など)をベクトル化 ▪

    ベクトルが近いほうから順に、いくつかの商品をピックアップ ◦ 後述のキーワード検索に近い手法を取ることも ▪ 商品の入れ替わりが速い・一点ものの販売→属性を個別に登録するのは煩雑 ▪ 商品名や説明文を単語に分解してベクトル化 36
  23. ベクトル検索の使い道の例 [2] • キーワード検索 ◦ キーワードの一致度高→検索結果上位に表示 ◦ あらかじめ文章を単語別に分解してベクトル化 ◦ 例文:

    ▪ ①ブリ会議に来た ▪ ②ブリ会議でブリを食べる ▪ ③ハマチを食べたい これを形態素解析などの方法で単語に分解して… 37
  24. ベクトル検索の使い道の例 [2] • キーワード検索 ◦ 例えば、単語ごとの出現回数をカウントしてベクトル化する 38 例文 No. ブリ

    会議 に 来 た で を 食べ る ハマチ たい ① 1 1 1 1 1 0 0 0 0 0 0 ② 2 1 0 0 0 1 1 1 1 0 0 ③ 0 0 0 0 0 0 1 1 0 1 1
  25. ベクトル検索の使い道の例 [2] • キーワード検索 ◦ 「ブリ会議」でベクトル検索:①と②が上位の候補に ◦ 39 例文 No.

    ブリ 会議 に 来 た で を 食べ る ハマチ たい ① 1 1 1 1 1 0 0 0 0 0 0 ② 2 1 0 0 0 1 1 1 1 0 0 ③ 0 0 0 0 0 0 1 1 0 1 1
  26. ベクトル検索の使い道の例 [2] • キーワード検索 ◦ 「ブリ会議」でベクトル検索:①と②が上位の候補に 40 例文 No. ブリ

    会議 に 来 た で を 食べ る ハマチ たい ① 1 1 1 1 1 0 0 0 0 0 0 ② 2 1 0 0 0 1 1 1 1 0 0 ③ 0 0 0 0 0 0 1 1 0 1 1 「0」の次元がたくさん  →疎ベクトル
  27. ベクトル検索の使い道の例 [3] • セマンティック検索 ◦ キーワードの一致度ではなく意味の近さで文章を検索 ◦ 文章のベクトル化には主に LLM の埋め込みモデルを使う

    ▪ 数百~数千次元の高次元ベクトル化 ▪ 文章を適切な長さ(チャンクサイズ)に分割してベクトル化する ◦ RAG(検索拡張生成)の仕組みの中で使われている ▪ LLM が持たない外部知識を追加情報として渡す際に、外部知識をベクトルス トアから検索して取り出す 42
  28. ベクトル検索の使い道の例 [3] • Cohere embed-multilingual-v3.0 ベクトル出力例 43 $ curl --location

    --request POST 'https://api.cohere.com/v1/embed' \ > --header 'Authorization: BEARER XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \ > --header 'Content-Type: application/json' \ > --data-raw '{ > "model": "embed-multilingual-v3.0", > "texts": ["ブリ会議に参加。懇親会でブリしゃぶを食べたい。"], > "input_type": "search_document", > "truncate": "NONE" > }' {"id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","texts":["ブリ会議に参加。懇親会でブリしゃぶを食べた い。"],"embeddings":[[-0.0034770966,0.025360107,0.023635864,-0.032226562,-0.002254486,-0.0002734661,-0.01 8218994,-0.0670166,0.0074768066,-0.011772156,0.0061912537,0.04937744,0.00060653687,0.01663208,0.00049591 064,0.026382446,0.026748657,-0.013877869,0.018661499,0.00058841705,-0.0084991455,0.012893677,0.040649414 ,-0.057739258,-0.036499023,0.013702393,0.013961792,0.007835388,-0.044769287,-0.037078857,-0.051116943,0. 03189087,-0.018127441,0.012649536,-0.018310547,-0.020614624,0.005836487,-0.042907715,0.00037646294,0.030 349731,0.02104187,0.01335144,-0.027267456,0.027236938,-0.035064697,0.020706177,0.028259277,0.038238525,0 .025512695,0.039093018,0.023162842,-0.050354004,0.016677856,0.023254395,0.033294678,-0.002363205,…
  29. 【参考】LLM の埋め込みモデルの多くでは • コサイン類似度を推奨しているが内積で代用可能 ◦ OpenAI「Vector embeddings」のページ ▪ https://platform.openai.com/docs/guides/embeddings 44

    Which distance function should I use? We recommend cosine similarity. The choice of distance function typically doesn't matter much. OpenAI embeddings are normalized to length 1, which means that: • Cosine similarity can be computed slightly faster using just a dot product • Cosine similarity and Euclidean distance will result in the identical ranking コサイン類似度を推奨 長さを1に正規化 ドット積(内積)の ほうがわずかに速い
  30. 【参考】LLM の埋め込みモデルの多くでは • コサイン類似度を推奨しているが内積で代用可能 ◦ OpenAI「Vector embeddings」のページ ▪ https://platform.openai.com/docs/guides/embeddings 45

    Which distance function should I use? We recommend cosine similarity. The choice of distance function typically doesn't matter much. OpenAI embeddings are normalized to length 1, which means that: • Cosine similarity can be computed slightly faster using just a dot product • Cosine similarity and Euclidean distance will result in the identical ranking ユークリッド距離でも 同じランキングになる
  31. 【参考】LLM の埋め込みモデルの多くでは • コサイン類似度を推奨しているが内積で代用可能 ◦ 内積:𝒂・𝒃 = |𝒂| |𝒃| cosθ

    𝒂 と 𝒃 の長さを 1 に正規化すると「cosθ」だけが残る →内積で代用可能 46 → → → → θ → 𝒃 → 𝒂 →  → A B O
  32. 【参考】LLM の埋め込みモデルの多くでは • コサイン類似度を推奨しているが内積で代用可能 ◦ 同時に、コサイン類似度↑でユークリッド距離↓ コサイン類似度が高い(A と B が近い)ほど

    ユークリッド距離(青色の⇔)は小さくなる → LLM の埋め込みモデルではベクトルの長さを 1 に正規化しているか、または  正規化できるケースが多い 47 θ → 𝒃 → 𝒂 A B O
  33. ベクトルストアの機能 [1] • ベクトルを含むデータ(行・レコード)の保管・更新 ◦ PostgreSQL+pgvector(RDB のベクトルストア)ではテーブル内の データとして保管(ベクトルはベクトル型カラムへ) ▪ Pinecone

    のような非 RDB のベクトルストアではベクトルデータをインデッ クスとして保管し、ベクトル以外の属性をメタデータとして保管(ベクトル のフィルタリング・絞り込みに使う) 50
  34. ベクトルストアの機能 [1] • PostgreSQL+pgvector の例(以降同じ) ◦ 先の A さん〜 D

    さんのデータを登録・保管 51 // pgvector有効化 postgres=# CREATE EXTENSION vector; CREATE EXTENSION // テーブル作成 postgres=# CREATE TABLE persons (id bigserial PRIMARY KEY, name varchar(50) NOT NULL, physique vector(3)); CREATE TABLE // データ登録 postgres=# INSERT INTO persons (name, physique) VALUES ('Aさん', '[170.0,64.0,77.0]') ,('Bさ ん', '[174.5,82.7,86.6]'), ('Cさん', '[167.2,46.8,71.8]'), ('Dさん', '[186.7,76.2,67.1]'); INSERT 0 4 vector 32ビット精度・2000次元まで halfvec 16ビット精度・4000次元まで bit 1ビット(バイナリ)64000次元まで(後述) sparsevec 疎ベクトル(0以外の値を持つ次元1000まで)
  35. ベクトルストアの機能 [1] • PostgreSQL+pgvector の例(以降同じ) ◦ 先の A さん〜 D

    さんのデータを登録・保管 52 // pgvector有効化 postgres=# CREATE EXTENSION vector; CREATE EXTENSION // テーブル作成 postgres=# CREATE TABLE persons (id bigserial PRIMARY KEY, name varchar(50) NOT NULL, physique vector(3)); CREATE TABLE // データ登録 postgres=# INSERT INTO persons (name, physique) VALUES ('Aさん', '[170.0,64.0,77.0]') ,('Bさ ん', '[174.5,82.7,86.6]'), ('Cさん', '[167.2,46.8,71.8]'), ('Dさん', '[186.7,76.2,67.1]'); INSERT 0 4
  36. ベクトルストアの機能 [1] • PostgreSQL+pgvector の例 ◦ 登録データを確認 53 // 登録データ確認

    postgres=# SELECT * FROM persons; id | name | physique ----+-------+------------------- 1 | Aさん | [170,64,77] 2 | Bさん | [174.5,82.7,86.6] 3 | Cさん | [167.2,46.8,71.8] 4 | Dさん | [186.7,76.2,67.1] (4 rows)
  37. ベクトルストアの機能 [2] • ベクトルを含むデータ(行・レコード)の検索 ◦ 例:A さんとユークリッド距離が近い(小さい)順に表示 54 // ユークリッド距離が近い順に表示

    postgres=# SELECT name FROM persons WHERE id != 1 ORDER BY physique <-> (SELECT physique FROM persons WHERE id = 1); name ------- Cさん Bさん Dさん (3 rows) <+> マンハッタン距離 <-> ユークリッド距離 <=> コサイン距離 (1-コサイン類似度) <#> 負の内積(-1✖内積) idでフィルタ
  38. ベクトルストアの機能 [3] • ベクトル間の距離・類似度の計算 ◦ 例:A さんとのコサイン距離(1-コサイン類似度)を表示 55 // コサイン距離を表示(コサイン距離の昇順)

    postgres=# SELECT name, cosine_distance((SELECT physique FROM persons WHERE id = 1), physique) AS dist FROM persons WHERE id != 1 ORDER BY dist; name | dist -------+----------------------- Bさん | 0.0030710384673471314 Cさん | 0.0032670664285965323 Dさん | 0.0035040553323729684 (3 rows) コサイン類似度とは大小が逆になる(値の範囲:0〜2) 唐突に出てきた「コサイン距離」について 「小さいほうが近い」を表すために、ベクトル検索ではコサイン類似度 よりもコサイン距離が使われるケースが多い (数学的な距離の公理を満たしていない→擬距離)
  39. ベクトルストアの機能 [3] • ベクトル間の距離・類似度の計算 ◦ 例:A さんとのコサイン距離(1-コサイン類似度)を表示 56 // コサイン距離を表示(コサイン距離の昇順)

    postgres=# SELECT name, cosine_distance((SELECT physique FROM persons WHERE id = 1), physique) AS dist FROM persons WHERE id != 1 ORDER BY dist; name | dist -------+----------------------- Bさん | 0.0030710384673471314 Cさん | 0.0032670664285965323 Dさん | 0.0035040553323729684 (3 rows) l1_distance(vector, vector) マンハッタン距離 l2_distance(vector, vector) ユークリッド距離 cosine_distance(vector, vector) コサイン距離 (1-コサイン類似度) inner_product(vector, vector) 内積
  40. ベクトルストアの機能 [4] • 例:HNSW(Hierarchical Navigable Small World)Index ◦ 階層的なグラフ構造を持つインデックス ◦

    多くのベクトルストアでサポートされている ◦ 近さをはかるのに使う「距離」の種類を指定して作成する ▪ 近いもの同士をグラフで繋げる→距離のはかり方が違えばグラフの構造も変 わる可能性がある 58
  41. ベクトルストアの機能 [4] • HNSW Index での検索例(注:イメージです) 59 ID x y

    A 18 15 B 4 14 C 8 17 D 5 5 E 9 11 F 14 8 G 19 4 H 13 13 この2次元ベクトルの 中から (8, 8) に最も近いものを検索 するときの流れ (3層のグラフ構造を持つ  HNSW Indexを検索)
  42. ベクトルストアの機能 [4] • HNSW Index での検索例 60 ID x y

    A 18 15 B 4 14 C 8 17 D 5 5 E 9 11 F 14 8 G 19 4 H 13 13 第3層のグラフの始点A から探索開始 (8, 8) に近いのは? →B
  43. ベクトルストアの機能 [4] • HNSW Index での検索例 61 ID x y

    A 18 15 B 4 14 C 8 17 D 5 5 E 9 11 F 14 8 G 19 4 H 13 13 第2層のグラフはBを 始点に探索開始 B→H→Fと進む DはFより遠い →Fが最も近い
  44. ベクトルストアの機能 [4] • HNSW Index での検索例 62 ID x y

    A 18 15 B 4 14 C 8 17 D 5 5 E 9 11 F 14 8 G 19 4 H 13 13 第1層のグラフはFを 始点に探索開始 F→Eと進む グラフで繋がる別の点 はEより遠い →Eが最も近い
  45. ベクトルストアの機能 [4] • PostgreSQL+pgvector で HNSW Index 作成 ◦ 例:ユークリッド距離用の

    HNSW Index を作成 63 // ユークリッド距離用の HNSW INDEXを作成 postgres=# CREATE INDEX ON persons USING hnsw (physique vector_l2_ops); CREATE INDEX vector_l1_ops マンハッタン距離用 vector_l2_ops ユークリッド距離用 vector_cosine_ops コサイン距離用 vector_ip_ops 内積用
  46. ベクトルストアの機能 [5] • ベクトルの圧縮・量子化 ◦ 一般的に、ベクトル 1 次元は 32 ビット(浮動小数点数)

    ▪ 次元数 × データ数が多いと容量が膨大に ◦ メモリ容量を超えるベクトルデータを検索すると遅くなる ▪ HNSW Index は構造的にランダムアクセスが多くなるため、メモリ容量を超 えるサイズになると検索も作成も極端に遅くなる 64
  47. ベクトルストアの機能 [5] • ベクトルの圧縮・量子化 ◦ 大量のベクトルデータは圧縮・量子化して容量を削減すると良い ▪ 例:32 ビットを 1

    ビットに→バイナリ量子化 ◦ PostgreSQL+pgvector ではベクトルデータを量子化せずに ANN インデックスだけ量子化する方法もある 65
  48. ベクトルストアの機能 [5] • PostgreSQL+pgvector でバイナリインデックス ◦ 例:LLM の埋め込みモデルを使用して Re-rank 検索

    ▪ https://zenn.dev/hmatsu47/articles/pgvector070-binaryvector (一部改変) ▪ バイナリインデックスではハミング距離(「0」「1」が異なる次元の数)を 使って「近さ」をはかる ▪ 埋め込みモデルとして Amazon の Titan Text Embeddings V2を使用 (1024 次元・正規化有効) 66
  49. ベクトルストアの機能 [5] • PostgreSQL+pgvector でバイナリインデックス ◦ テーブル・インデックス作成 67 // テーブル作成(1024次元のTitan

    Text Embeddings V2埋め込み用)
 CREATE TABLE rerank_test (id INTEGER PRIMARY KEY, data TEXT, embedding vector(1024)); // バイナリインデックス作成( HNSW・ハミング距離用・ 1次元を1ビットに)
 CREATE INDEX ON rerank_test USING hnsw ((binary_quantize(embedding)::bit(1024)) bit_hamming_ops); バイナリ量子化 バイナリ量子化を指定 bit バイナリ精度
  50. ベクトルストアの機能 [5] • PostgreSQL+pgvector でバイナリインデックス ◦ テーブル・インデックス作成 68 // テーブル作成(1024次元のTitan

    Text Embeddings V2埋め込み用)
 CREATE TABLE rerank_test (id INTEGER PRIMARY KEY, data TEXT, embedding vector(1024)); // バイナリインデックス作成( HNSW・ハミング距離用・ 1次元を1ビットに)
 CREATE INDEX ON rerank_test USING hnsw ((binary_quantize(embedding)::bit(1024)) bit_hamming_ops); bit_hamming_ops ハミング距離用 bit_jaccard_ops ジャッカード距離用 (いずれもバイナリ量子化ベクトル用の距離)
  51. ベクトルストアの機能 [5] • PostgreSQL+pgvector でバイナリインデックス ◦ Re-rank 検索(低精度のインデックスで抽出したものを元の精度でソート) 69 //

    バイナリインデックスを使用して Re-rank検索 // (バイナリインデックスで上位 20件抽出→32ビット精度でコサイン距離を比較して上位 5件抽出)
 SELECT id, (embedding <=> (SELECT embedding FROM rerank_test WHERE id = 100000)) AS dist, data FROM (SELECT * FROM rerank_test WHERE id < 100000 ORDER BY binary_quantize(embedding)::bit(1024) <~> (SELECT binary_quantize(embedding)::bit(1024) FROM rerank_test WHERE id = 100000) LIMIT 20) ORDER BY dist LIMIT 5; // 結果表示は省略 <~> ハミング距離 <%> ジャッカード距離
  52. ベクトルストアの機能 [6] その他 • 近似最近傍探索(ANN)用インデックスの進化系として ◦ メモリ容量を超えても実用になる DiskANN Index ▪

    マイクロソフトが開発 ▪ PostgreSQL+pgvector では対応していないが pgvectorscale で同系統の StreamingDiskANN Index に対応 ▪ Azure Database for PostgreSQL の pg_dikann で DiskANN Index にプレビュー対応 ▪ 参考:https://engineers.ntt.com/entry/202412-diskann/entry 70
  53. ベクトルストアの機能 [6] その他 • バイナリ量子化の改良版として ◦ 値の範囲を意識して「0」「1」に分割→統計的バイナリ量子化 ▪ 通常のバイナリ量子化では「0 または負の数」「正の数」でざっくり分割し

    て「0」「1」にしてしまうため、(-1 ~ 1 への)正規化や標準化をしてい ないベクトルには向かない(この資料の例の大半がそう) ▪ PostgreSQL+pgvector では対応していないが pgvectorscale で対応 71
  54. 参考資料 • 九州大学 数理・データサイエンス教育研究センター 講義資料 ◦ https://mdsc.kyushu-u.ac.jp/wp/wp-content/uploads/2023/07/a85dfe612a31b1a1e0a4b399a9b 073bf.pdf ◦ https://mdsc.kyushu-u.ac.jp/wp/wp-content/uploads/2023/07/458290da747eff72c614ee500e1b

    aa27.pdf • Pinecone 社の Hierarchical Navigable Small Worlds (HNSW) 説明ページ ◦ https://www.pinecone.io/learn/series/faiss/hnsw/ • Timescale 社のブログ記事 ◦ https://www.timescale.com/blog/how-we-made-postgresql-as-fast-as-pinecone-for-vector-data 75