📝

やさしい言葉で浅くベクトル検索を理解してみる

に公開

最近の AI の進化って、本当に目まぐるしいですよね。自分のまわりでも、「どうやって活用しようか?」という話題が日常的に出るようになってきました。

そんな中で自分がやってみたいと思ったのが、「この API って何をしているの?」と質問したら、それに近い過去の説明や仕様ドキュメントを見つけてくれて、分かりやすく教えてくれるような仕組みを作ること。その方法を調べていく中で、「ベクトル検索」という技術が、似た意味を持つデータを見つけるのにとても役立つことが分かりました。

名前は聞いたことがあっても、実際にどんな仕組みなのかをちゃんと理解しようと思ったことはありませんでした。そこで今回は、できるだけ難しい言葉を使わずに、ベクトル検索についてやさしく整理してみようと思います。

ベクトルとは?

ベクトル(vector)とは「たくさんの数字が集まったデータ」のこと。たとえば、 [0.3, -1.2, 4.5] のような数字のセットのこと。
これは「3次元のベクトル」と呼ばれる。文章・画像・音声などの意味や特徴を、AI はこのような「数字のかたまり(=ベクトル)」に変えて扱っている。

エンベディングとは?

「エンベディング(embedding)」という言葉もよく出てきますが、これは「意味や特徴をベクトルに変換すること」を指す。
たとえば、
「犬」 → [0.1, 0.8, -0.3, …]
「猫」 → [0.12, 0.75, -0.2, …]
このように、似たような意味を持つ単語は近いベクトルになる。

ベクトル検索とは?

ベクトル検索とは、「あるベクトルに一番近いものを探す検索方法」のこと。
たとえば、

「この質問と似た過去の質問ってある?」

このようなケースで、文章をエンベディングしてベクトルに変換し、データベースに保存されたベクトルの中から「近いもの」を探してくれるのがベクトル検索です。

ユーザーの入力からコンテンツを返すまでの、シンプルなフローを表した概念図。

類似度ってどうやって測るの?

ベクトルがどれくらい似ているかを測るには、「類似度(距離)」という考え方を使う。よく使われる指標には以下のものがある。

類似度の指標 どんな意味? 特徴
コサイン類似度 ベクトルの「向き」がどれだけ似てるか 意味検索や自然言語処理でよく使われる
ユークリッド距離 ベクトル同士の「実際の距離」 数値の大小を重視した比較に使う
内積(ドット積) ベクトル同士をかけ算して足した値 スコアやランキング処理などで使われる
ジャッカード係数 共通している要素の割合を比較 タグ・キーワードの重なり具合を測るのに便利
ハミング距離 ビット(0/1)の何個が違うかを見る ハッシュやエンコード文字列の比較に使う

とくに自然言語処理などでよく使われるのが「コサイン類似度」とのこと。

コサイン類似度とは?

これは、ベクトルの「向き」がどれくらい似ているかを見る。

  • 「犬」と「猫」 → 向きが似ている → 類似度が高い
  • 「犬」と「冷蔵庫」 → 向きが違う → 類似度が低い

向きが似ている、というのは「意味が近い」ことの数学的な表現。

ベクトルを扱うにはそのための仕組みが必要で、色々とあるようですが、ここでは PostgreSQL でそれを可能にする pgvector を取り上げます。

pgvector とは?

pgvector は、PostgreSQL でベクトル検索を可能にする拡張モジュールで、自然言語処理や生成AI(RAGなど)で広く使われているようです。次のダイアグラムは、それを使用したシンプルなプロセスを表現したものです。

pgvectorで使える類似度タイプと選び方

距離タイプ 演算子 比較の観点 向いている用途 スコアの見方
コサイン距離(Cosine) <#> ベクトルの向き 意味の近さで文章を比較したい 小さいほど近い(0が最も近い)
L2距離(ユークリッド距離) <-> 実際の距離 数値の差で判断したい 小さいほど近い
内積(ドット積) <=> 値の大きさ・重み 重みスコアでランク付けしたい 大きいほど近い

使い方の例

-- コサイン類似度で近いデータを検索
SELECT * FROM items
ORDER BY embedding <#> '[0.2, 0.5, -1.3]'::vector
LIMIT 5;

pgvector の良いところは、PostgreSQL にそのまま組み込めて、ふつうの SQL でベクトル検索ができるところです。

おわりに

自分の知りたいことを AI を活用して調べてみました。今後は冒頭に記載したことの実現に向けて動いていけたらと思っています!

Discussion