本文へスキップ
BecomeCoder

RAGコース · 第3章 ベクトルと検索 · レッスン9

テキストをベクトルに ― TF-IDFを体験する

ブラウザで完結

導入

文字列のままでは「どの文書が似ているか」を計算できません。まずは文章を数値の並び(ベクトル)に変換する必要があります。定番の手法がTF-IDFです。

説明

TF-IDFは「Term Frequency(単語の出現頻度)× Inverse Document Frequency(文書の逆頻度)」の略です。考え方はシンプルで、その文書によく出てくる単語ほど重要(TF)、でも、どの文書にも出てくるようなありふれた単語(“the” や “a” など)は重要度を下げる(IDF)、という2つを掛け合わせて単語の重みを決めます。たとえば “cat” という単語が特定の文書にだけ何度も出てくれば、その文書を特徴づける重要な単語だと判断されます。

from sklearn.feature_extraction.text import TfidfVectorizer

docs = [
    "the cat sat on the mat",
    "the dog sat on the log",
    "cats and dogs are pets",
]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(docs)

print("Vocabulary:", vectorizer.get_feature_names_out())
print("Matrix shape:", X.shape)   # (文書数, 語彙数)
print(X.toarray().round(2))

fit_transform が2つの仕事を一度にやっています。fit(全文書から語彙を作り、それぞれの重要度の基準を計算する)と transform(各文書をその基準でベクトルに変換する)です。結果の X は「行が1文書、列が1語」の行列で、各セルの値がその文書におけるその単語の重みになります。"the" のようにどの文書にも出てくる単語は値が低く、特定の文書だけに出てくる単語は値が高くなっているはずです。

なお、この変換は単語を空白で区切って数える仕組みなので、日本語のようにスペースなしで単語が連続する言語にはそのままでは使えません(別途「分かち書き」という下処理が必要になります)。そのため、このレッスン以降の実行例はすべて英語の文書で試します。

やってみよう

docs に文章をもう1つ追加してから実行し直し、Matrix shape の文書数・語彙数がどう変わるか確かめてみましょう。

演習

vectorizer語彙(vocabulary)の数print で表示してください。

ヒント1を見る

vectorizer.get_feature_names_out() で語彙の一覧(配列)が得られます。

ヒント2を見る

その配列の長さを len() で数えれば語彙数になります。

実際に動かしてみよう

下のエディタにPythonを書いて「実行」を押すと、scikit-learn(TF-IDF)とnumpyで本物の「検索」をその場で動かせます。RAGの検索フェーズ――文書のチャンク分割・ベクトル化・類似度計算・並べ替え――が実際に動きます。scikit-learn を使う回は初回の読み込みに数十秒かかることがあります。検索デモのサンプル文書は英語です(TF-IDFの既定トークナイザが日本語を分割できないため。日本語検索の対処は読み物で解説します)。LLMの生成や本物の埋め込みAPIは、APIキーが要るため読み物の回でコードを示します。

Python — ライブラリ付きで実行(Pyodide)

numpy / pandas / matplotlib が使える本物のPython(Pyodide)を読み込みます。初回のみ読み込みに少し時間がかかります(以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。