🤡

【非エンジニア向け】ベクトルDBとは?

2024/11/11に公開

生成AI界隈ではRAGが話題になることが多いですが、RAGのベースアーキテクチャの1つであるベクトルDBについて、今回はかなり初歩的なところから解説します。ちなみに、数学が苦手な人でも感覚的にわかるような解説を目標にします。

そもそもベクトルとは?

世代にもよるとは思いますが、多くが高校数学で出てくるテーマだと思います。ベクトルとは、方向と大きさを持つ量です。例えば、力や速度などがベクトルとして表されます。イメージとしてはこんな感じで習ったのでは?と思います。

続いて、成分表示について解説します。ベクトルは方向と大きさを表現しますが、それだとわかりにくいので、起点になる部分からの座標のような感じで表現します。図の場合、Aを(0,0)として、Bのほうを(6,4)の座標で表現しています。要するに、向きと大きさを座標で表現する、ということです。

この図の場合は2次元ですが、3次元にすることもできます。

xが6、yが7、zが4の場合、こんな感じになります。(x,y,z)の場合(6,7,4)と表現できます。

感覚的に3次元まではわかりやすいですが、4次元:(6,7,4,5)、5次元:(6,7,4,5,3)というように次元を増やすことは可能です。

※数字は適当です

なお、内積や外積などの演算方法までは不要なので、ここでは割愛します。

ベクトルDBとは?

ベクトルDBは文字通りベクトル形式のデータを格納するデータベースです。ベクトルのところで解説したような、2次元、3次元のようなものではく、数十、数百、それ以上の次元を管理するデータベースになります。128次元というと、感覚的に何のことを言っているのかがわからなくなりますが、要するに(x,y,z)のような、カンマで区切られた要素が増えて行っているものと考えればシンプルだと思います。

# 例: 画像の特徴ベクトル
image_vector = [0.1, 0.3, 0.5, ..., 0.2]  # 128次元のベクトル

# 例: 音声の特徴ベクトル
audio_vector = [0.2, 0.4, 0.1, ..., 0.3]  # 40次元のベクトル(MFCCの場合)

データの格納方法はこのような感じでイメージできたと思います。次に利用方法を解説します。普通のデータベースの場合、格納したデータを引き出すためにクエリ(問い合わせ)を発行します。例えば、Aさんの預金残高を知りたい場合、Aさんの口座番号をキーにして残高を取得します。発想としては、Aさんの口座番号で完全一致させてデータを取得します。完全一致させずに他の人のデータにアクセスできてしまうと大事故になってしまいます。

ところが、ベクトルDBの場合この感覚が違います。ベクトルDBの場合、完全一致を求めずに似ているものを取得することができます。細かくは説明しませんが、例えば「k-近傍探索」の場合、クエリベクトルに対して、上位k個の近いベクトルを検索します。この「似ている」というのがポイントで、似ているということは事象の特徴を捉えているということになります。このロジックが非常にAIにマッチしていて、最近の生成AIのRAGで使用されています。例えば犬種の画像認識のAIがあったとして、元の学習した犬の画像と、今読み込ませている犬の画像が完全一致することはないでしょう。犬でも個性が合って顔つきも違いますからね。でも同じ犬と判断するには特徴が似ている必要があるということです。

ベクトルDBにデータを格納するためのエンベディング

生成AI(例えば、GPTなどの大規模言語モデル:LLM)は、テキストデータをベクトル形式に変換するために「エンベディング(埋め込み)」と呼ばれる技術を使用します。エンベディングは、テキストの意味や文脈を数値ベクトルとして表現する方法です。

例えばテキストデータをエンベディングすると、固定長(決められた次元数)の数値ベクトルに変換することができます。この数値ベクトルは、テキストの意味や文脈を特徴として捉えている数値になります。ベクトルDBのところでも解説したように、「特徴を捉えている数値ベクトル」というのが大事で、検索する時に似たような特徴として判断することが可能になります。

エンベディングのコード例はこんな感じです。

import openai

# ①OpenAI APIキーを設定
openai.api_key = 'your-api-key-here'

# ②テキストデータ
text = "This is an example sentence to generate embeddings using GPT-4."

# ③エンベディングを生成する関数
def get_gpt4_embedding(text):
    response = openai.Embedding.create(
        model="text-embedding-ada-002",  # GPT-4のエンベディングモデルを指定
        input=text
    )
    embedding = response['data'][0]['embedding']
    return embedding

# ④エンベディングを取得
embedding = get_gpt4_embedding(text)
print("Generated Embedding:", embedding)

今回はかなり初心者向きの解説なので、ポイントだけ解説します。

①エンベディングはAPIアクセス
エンベディングはLLMのようにAPIキーを利用します。この例はOpenAIのエンベディングを利用している例になります。

②エンベディングするテキストデータを準備
この例だと短い文章(This is ~ GPT-4)ですが、実際にはもっと長い文章にします。

③実行前の準備
コードだと関数と書かれているところですが、ここは実行前の準備だと思ってください。

④エンベディングの実行
準備した関数を実行し、文字列から数値に変換します。

例えば、RAGをする時に、文章を先に格納しておく必要がありますが、文章格納時にこのエンベディング処理を行っています。PDFファイルを使ってRAGする場合、PDFファイルをエンベディングしてベクトル化し、そのデータをベクトルDBに格納しておきます。そして実際に問い合わせする時に、問い合わせの文字列をエンベディングして、格納してあるベクトルDBと比較して、特徴が似ているものをマッチングさせるという処理を行います。

まとめ

今まで感覚的にRAGという言葉を使っている方も多いのでは?と思っていますが、実際にどういう処理を行っているのかを少しイメージするだけで、理解度が変わってくると思います。AIが行っている裏の処理を想像することで、AIが得意な処理も想像しやすくなるので、一歩踏み込んで理解して効率的にAIを使っていければと思います。

Discussion