≪ Today I learned.
RSS購読
    公開日
    タグ
    AI , Mathematics
    著者
    ダーシノ

    生成AIを支える技術: 埋め込みモデル、ベクトル変換、ベクトル検索を手計算で理解する

    筆者は、検索機能を強化する「RAG」について学びたいが、具体的にどのような仕組みで動いているか理解できていない。そこで、まずは生成AIの基礎知識を身につけるためにすべて人力でモデル作成、ベクトル変換、ベクトル検索を行うことで仕組みを理解したい。

    RAGの基礎知識

    RAG(Retrieval-Augmented Generation、検索拡張生成)は、外部の知識をLLM(Large Language Model、大規模言語モデル)に取り込むことで、より正確な回答生成をするための手法である。

    RAGを構築するには、以下のステップが必要になる。

    1. データ収集 … 知識となるデータを収集する
    2. データの前処理 … テキストの抽出、チャンク化(意味ある単位で分割)、メタデータの付与など
    3. 埋め込みベクトルへの変換 … チャンクを埋め込みモデルを使ってベクトル化する
    4. ベクトルデータベースへの格納 … 生成したベクトルを保存し検索できるようにする

    「1.データ収集」「2.データの前処理」はイメージもしやすいが、「3.埋め込みベクトルへの変換」「4.ベクトルデータベースへの格納」は抽象的でわかりづらい。当記事ではわかりづらいこれらのステップを人力で再現していく。

    埋め込みモデル作成とベクトル変換

    埋め込みモデルは、文章を意味のある単位に変える仕組みで、単語間の意味的な関係性を数値で表現することで類似性を計算できるようになる。

    埋め込みモデルを作成するには以下のステップが必要になる。

    1. 文章データを収集する
    2. 共起表をつくる
    3. ベクトルに変換する

    1.文章データを収集する

    知識のもととなるデータを大量に用意する。

    - 犬が走る
    - 猫が寝る
    - うさぎがにんじんを食べる
    - ロボットが動く
    ...

    2.共起表をつくる

    共起とは、ある単語が他の単語といっしょに出現する現象を指す。

    どの単語がどの単語といっしょに出現するかを調べて、関連性が高ければ数値も高くなるように設定し共起表を作成する。

    単語1/単語2走る寝る食べる歩く動く
    101320
    915300
    うさぎ521010
    ロボット000512

    上記の共起表からは以下のような情報が読み取れる。

    共起表の具体的な作成ステップ

    1. 「A は B です」 … A→Bは近い
    2. 「A は C です」 … A→C は近い、かつ C→B とも近い
    3. 「B は D です」 … B→D は近い、かつ同じくBが現れる D→A とも近い
    4. 「A は B です」 … 同じ文章があるので他の C、D よりも A→B のほうがより近い

    のように大量の文章を解析し学習していくことで、精度の高い共起表が作成できる。

    3.ベクトルに変換する

    使われ方の傾向を数値で表すために、共起表の行ごとにベクトルへ変換する。

    ベクトル検索

    次に、これらのベクトルを使って意味が近い単語を見つける検索を行う。 たとえば以下のような意味空間があるとする。

    ^
    |  犬     猫
    |    うさぎ
    |
    |           ロボット
    +-------------------->

    「犬」、「猫」、「うさぎ」は互いに近く、「ロボット」は離れている。

    この距離を数値で表すのがユークリッド距離やコサイン類似度である。(ここでは計算が簡単なユークリッド距離を使う)

    y
    ^
    |
    |  ●(x1, y1)
    |   \
    |     \  ← この距離を求める
    |       \
    |         ●(x2, y2)
    | 
    +----------------> x
    d=(x2x1)2+(y2y1)2d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}

    たとえば「犬」と「猫」、「犬」と「ロボット」の距離を計算すると以下のようになる。

    =[101320]=[915300]ロボット=[000512]\text{犬} = \begin{bmatrix} 10 & 1 & 3 & 2 & 0 \end{bmatrix} \quad \text{猫} = \begin{bmatrix} 9 & 15 & 3 & 0 & 0 \end{bmatrix} \quad \text{ロボット} = \begin{bmatrix} 0 & 0 & 0 & 5 & 12 \end{bmatrix} d(,)=(109)2+(115)2+(33)2+(20)2+(00)2=1+196+0+4+0=201=14.18\begin{aligned} d(\text{犬}, \text{猫}) &= \sqrt{(10 - 9)^2 + (1 - 15)^2 + (3 - 3)^2 + (2 - 0)^2 + (0 - 0)^2} \\ &= \sqrt{1 + 196 + 0 + 4 + 0} \\ &= \sqrt{201} \\ &= 14.18 \end{aligned} d(,ロボット)=(100)2+(10)2+(30)2+(25)2+(012)2=100+1+9+9+144=263=16.22\begin{aligned} d(\text{犬}, \text{ロボット}) &= \sqrt{(10 - 0)^2 + (1 - 0)^2 + (3 - 0)^2 + (2 - 5)^2 + (0 - 12)^2} \\ &= \sqrt{100 + 1 + 9 + 9 + 144} \\ &= \sqrt{263} \\ &= 16.22 \end{aligned}

    上記の計算結果から

    よって「犬」は「猫」のほうが意味的に近いと判断できる。このように完全一致ではなく、意味が近い単語や文を見つけるのがベクトル検索であり、RAGの根幹技術である。

    まとめ

    RAGの基礎を理解するために、埋め込みモデルの作成とベクトル変換、ベクトル検索の流れを人力で再現してみた。これらの処理はライブラリや既存のモデルを使われることが多い。ただ、実際に手を動かしてみることで、RAGの仕組みやベクトル検索の考え方がより深く理解できた。

    補足: マルコフ連鎖とベクトル検索の違い

    同じように文章を分析し、新たな文章を作るという手法においては、ベクトル検索のほかにマルコフ連鎖(Markov Chain)がある。

    どちらも共起頻度を数値化し関連性を測る手法だが、マルコフ連鎖は単語と単語の発生順を確率的に予測するもので、ベクトル検索とは異なるアプローチである。

    マルコフ連鎖とは

    ここでは説明を簡単にするために、履歴の参照は直前の1単語のみに限定する。

    以下の3つの文章があった場合:

    以下のように確率モデルが作られる。

    単語次に来る単語確率
    (START)0.333
    1.0
    走る0.333
    走る(END)1.0
    (START)0.333
    1.0
    寝る0.333
    寝る(END)1.0
    (START)ロボット0.333
    ロボット1.0
    動く0.333
    動く(END)1.0

    マルコフ連鎖の遷移テーブルを用いて文章生成を行う。

    まずSTARTとなる単語が1/3の確率で選択される。そこで「犬」が与えられた場合は、次は必ず「が」が選ばれる。しかし「が」が与えられた場合は、次に「走る」「寝る」「動く」のいずれかが同確率で選ばれる。

    ベクトルによる類似性などは考慮されない。そのため、「犬が動く」や「ロボットが寝る」のような不自然な文章が生成されることがある。

    マルコフ連鎖による文章生成の精度を高める

    関連する単語数を増やすことで文章生成の精度が向上する。

    単語1単語2単語3確率
    (START)0.333
    ゆっくり1.0
    ゆっくり走る1.0
    ゆっくり走る(END)1.0
    (START)0.333
    ぐっすり1.0
    ぐっすり寝る1.0
    ぐっすり寝る(END)1.0
    (START)ロボット0.333
    ロボットすばやく1.0
    すばやく動く1.0
    すばやく動く(END)1.0

    単語数を増やした結果、「犬 が」のあとには「ゆっくり 走る」が、「ロボット が」のあとには「すばやく 動く」が続くように学習される。

    ただし、類似性ではなく確率に基づいているため、ベクトル検索のような自然な文章生成は難しい。

    参考リンク