はじめに
前回の記事では、TF-IDFの「TF(Term Frequency)」について解説しました。
【前回のあらすじ】
- TFは「ある文書の中での単語の出現頻度」。
- TFを計算することで、その文書内でどの単語が重要そうか、という指標が得られる。
- しかし、TFだけでは「は」「が」「です」のような、どの文書にも頻出する単語のスコアが高くなってしまう、という課題が残った。
今回は、この課題を解決するための最強のパートナー、IDF (Inverse Document Frequency) の登場です。
この記事を読み終える頃には、あなたは…
- IDFがなぜ「魔法の仕組み」と呼ばれるのか、その核心を理解できる。
- IDFを実際に計算し、一般的な単語のスコアを下げ、専門的な単語のスコアを上げる体験ができる。
- そしてついに、TFとIDFを組み合わせてTF-IDFスコアを算出し、「単語の重要度」を測る真の力を手に入れることができる。
さあ、物語のクライマックスです。TF-IDFを完全に理解しましょう!
1. IDFって、そもそも何?
IDFは Inverse Document Frequency の略です。日本語にすると 「逆文書頻度」 となります。
…なんだか余計に分かりにくいですね。大丈夫、分解すれば簡単です。
まず、"Document Frequency" (DF、文書頻度) から考えましょう。
これは、「その単語が、いくつの文書に出現したか」 という数です。
DF = ある単語が出現した文書の数
次に、"Inverse"(逆) です。
これは文字通り、DFの「逆」の考え方をします。
- DFが高い(色々な文書に出てくる)単語ほど、重要度は低い。
- 例:「は」「です」「ます」→ どの文書にも出てくるので、特徴的な単語とは言えない。
- DFが低い(特定の文書にしか出てこない)単語ほど、重要度は高い。
- 例:「機械学習」「特異点」→ これらの単語が出てくれば、その文書は専門的な内容だと推測できる。
つまりIDFとは、「みんなが使っているありふれた単語の価値を下げ、特定のジャンルでしか使われないレアな単語の価値を上げる」 ための指標なのです。
TFが「文書内のミクロな視点」だったのに対し、IDFは「全文書を横断したマクロな視点」と言えます。
2. IDFを計算してみよう!【いよいよ本番】
では、この「レア度」を数値化していきましょう。
ここでも、3つの文書を例に考えてみます。
文書A:『リンゴの魅力』
「私はリンゴが大好きです。真っ赤なリンゴは、甘くて美味しい。」
文書B:『今日のランチ』
「今日のランチはパスタでした。デザートにリンゴを一つ食べました。」
文書C:『プログラミング奮闘記』
「Pythonは初心者に最適な言語です。Pythonを使えば、機械学習も学べます。」
(※全文書数は 3
とします)
Step 1: Document Frequency (DF) を数える
まず、それぞれの単語がいくつの文書に出現したか(DF)を数えます。
- DF("リンゴ"): 文書A, B に出現 → 2
- DF("パスタ"): 文書B のみに出現 → 1
- DF("Python"): 文書C のみに出現 → 1
- DF("は"): 文書A, B, C に出現 → 3
- DF("です"): 文書A, C に出現 → 2
Step 2: IDFを計算する【数式登場】
DFの考え方(値が小さいほどレア)を数式に落とし込みます。
IDFの計算式は、以下のようになります。
$$
idf(t) = \log \left( \frac{\text{全文書数}}{\text{単語tが出現した文書数 (DF)}} \right)
$$
なぜここで log
が出てくるのか?
これは、DFのインパクトを緩やかにするためです。例えば、全100万文書の中で、DFが1の単語とDFが10の単語ではレア度に絶大な差がありますが、DFが10万の単語とDFが10万10の単語では、どちらも「ありふれた単語」という点であまり差はありません。この感覚を log
を使って表現しているのです。(TF編の応用で出てきた考え方と同じですね!)
それでは、先ほどの例でIDFを計算してみましょう。(log
は自然対数ln
で計算します)
-
idf("リンゴ"):
$$
\log \left( \frac{3}{2} \right) = \log(1.5) \approx 0.405
$$ -
idf("パスタ"):
$$
\log \left( \frac{3}{1} \right) = \log(3) \approx 1.098
$$ -
idf("Python"):
$$
\log \left( \frac{3}{1} \right) = \log(3) \approx 1.098
$$ -
idf("は"):
$$
\log \left( \frac{3}{3} \right) = \log(1) = 0
$$
見てください!
レアな単語である「パスタ」や「Python」はIDF値が高くなりました。
そして、どの文書にも出現する「は」のIDF値は、見事に 0
になりました!
これで、ありふれた単語の価値を自動的にゼロにする仕組みが完成しました。
※ ちょっと補足:ゼロ除算を避けるスムージング
実用上は、分母のDFが0になる(=未知の単語)場合や、log(1)
で0になるのを避けるために、分子と分母に +1
をするなどの調整(スムージング)がよく行われます。
$$
idf(t) = \log \left( \frac{\text{全文書数} + 1}{\text{単語tが出現した文書数} + 1} \right) + 1
$$
今回は概念を理解するため、簡単な式で進めます。
3. 最終形態!TF-IDFの計算
長かった旅もいよいよ終わりです。
私たちは今、2つの武器を手にしました。
- TF (Term Frequency): 文書内での単語の重要度
- IDF (Inverse Document Frequency): 文書全体での単語のレア度
この2つを組み合わせることで、最強の指標 TF-IDF が生まれます。
計算式は、驚くほどシンプルです。
$$
\text{tf-idf}(t, d) = tf(t, d) \times idf(t)
$$
そう、ただ掛け算するだけです。
この式が意味することは、
「ある文書dにおける単語tの重要度」は、
「文書d内でその単語tがたくさん使われていて(TF高)」
「かつ、その単語tが他の文書ではあまり使われていない(IDF高)」
場合に、最も高くなるということです。
最終計算:文書Cの各単語のTF-IDFを求める
それでは、文書C『プログラミング奮闘記』 における「Python」と「です」のTF-IDFスコアを計算して、その威力を確かめてみましょう。
文書C: 「Python は 初心者 に 最適な 言語 です。 Python を 使えば、機械学習 も 学べます。」
- 総単語数: 14
- "Python"の出現回数: 2
- "です"の出現回数: 2
1. TFの計算(文書の総単語数で割る正規化TFを使用)
- $tf(\text{Python}, \text{文書C}) = \frac{2}{14} \approx 0.143$
- $tf(\text{です}, \text{文書C}) = \frac{2}{14} \approx 0.143$
この時点では、TF値は両方とも同じです。
2. IDFの計算(先ほど計算した値)
- $idf(\text{Python}) \approx 1.098$
- $idf(\text{です}) = \log(\frac{3}{2}) \approx 0.405$ (※失礼しました、文書A, Cの2つに出現なのでDF=2です)
3. TF-IDFの計算
-
tf-idf("Python", 文書C):
$0.143 \times 1.098 \approx \bf{0.157}$ -
tf-idf("です", 文書C):
$0.143 \times 0.405 \approx \bf{0.058}$
ついに、差が出ました!
同じくらい文書内に出現していても(TFが同じでも)、レアな単語である「Python」の方が、「です」よりも約2.7倍も重要度が高いという結果になりました。
これこそが、私たちが求めていた「文書を特徴づける単語」を数値化する技術です。
まとめ
2回にわたる長い冒険でしたが、これでTF-IDFの全てを理解することができました。
- TF(単語頻度): 文書内での単語の出現回数。その文書のローカルな重要度を示す。
- IDF(逆文書頻度): その単語がどれだけレアか。文書全体でのグローバルな重要度(レア度) を示す。
- TF-IDF: TFとIDFの積。「その文書を特徴づける、重要でレアな単語」 を見つけ出すための最強の指標。
TF-IDFは、検索エンジンが検索クエリと関連性の高い文書を見つけたり、文書の要約で重要なキーワードを抽出したりと、現代の多くの情報技術の裏側で活躍しています。
この概念を理解したあなたは、自然言語処理の世界への大きな一歩を踏み出しました。
今後の学習でTF-IDFという言葉に出会っても、もう恐れることはありません。自信を持って「完全に理解した」と言えるはずです!