📄

Zennで学ぶスパムメール分類講座:初級編 - AIを賢くする最初のテクニック「TF-IDF」

に公開

はじめに

こんにちは、神楽 朔です!

前回の記事(別サイト)
【Python初心者向け】1時間でスパムメール分類モデルを作ってみた(SIGNATEチュートリアル徹底解説)
では、無事にスパムメール分類AIを完成させることができました。
しかし、提出したスコアを見て、こう思いませんでしたか?

SIGNATEの練習問題「スパムメール分類」チュートリアルを完走した皆さん、お疲れ様でした。自分の手で機械学習モデルを構築するプロセスは、非常に有益な経験になったことと思います。

しかし、チュートリアルを終えた多くの方が、次にこのような疑問を抱くのではないでしょうか。
「このモデルの精度を、さらに向上させるにはどうすれば良いのだろう?」

この講座は、チュートリアルから次の一歩を踏出すためのガイドです。
初級編である今回は、AIが単語の「重要度」を判断できるようにするための基本的ながら極めて強力な手法、TF-IDF について解説します。

チュートリアルモデルの限界点

まず、チュートリアルで採用されたCountVectorizerの特性と、その限界について理解しましょう。

CountVectorizerは、その名の通り、各文書における単語の出現回数を数え上げる(カウントする)手法です。非常にシンプルで直感的なアプローチですが、大きな弱点を抱えています。

Consider these two emails:

Spam Email: "The winner is you! Click the link!"
Normal Email: "The meeting is scheduled."

CountVectorizerは、これらのテキストを処理する際、"The"や"is"といった単語が両方のメールに共通して出現していることを認識します。しかし、これらの単語は一般的にどの文書にも頻出するため、スパムメールを見分けるための有益な情報(特徴)とは言えません。

人間であれば、"winner"や"Click"といった単語こそがスパムらしさを示す重要な手がかりであると判断できます。CountVectorizerには、この単語の重要度の差異を区別する能力がありません。これが、モデルの精度向上が頭打ちになる根本的な原因です。

基本にして強力な手法「TF-IDF」

この問題を解決するのが TF-IDF (Term Frequency-Inverse Document Frequency) です。
TF-IDFは、単語の重要度を以下の2つの指標の積によって算出します。

  1. TF (Term Frequency) - 項目の出現頻度
    これは、特定の文書内における単語の出現頻度です。「ある文書内で頻繁に出現する単語は、その文書のトピックを表す上で重要である」という考え方に基づきます。

  2. IDF (Inverse Document Frequency) - 逆文書頻度
    これがTF-IDFの核心です。IDFは、「多くの文書に横断的に出現する単語は、特徴としての価値が低い」という考え方に基づきます。IDF値は、ある単語が出現する文書数が少ないほど高くなります。

    • the, a, isのように、あらゆる文書に登場する一般的な単語は、IDF値が低くなります。
    • viagra, lotteryのように、特定のトピックの文書にしか出現しない専門的または特徴的な単語は、IDF値が高くなります。

最終的なTF-IDFスコアは、これら2つの指標を掛け合わせることで得られます。

TF-IDFスコア = TF (文書内での出現頻度) × IDF (単語の希少性)

このスコアリングにより、モデルは 「分析対象の文書内では頻繁に出現するが、文書全体で見ると希少性が高い単語」 を重要視するようになります。これにより、より的確な特徴抽出が可能になるのです。

実装:CountVectorizerからTfidfVectorizer

TF-IDFの導入は、理論的な背景とは裏腹に、驚くほど簡単です。
scikit-learnでは、CountVectorizerTfidfVectorizerに置き換えるだけで実装できます。

main.py
# 従来の手法
# from sklearn.feature_extraction.text import CountVectorizer

# TF-IDFを実装するためのTfidfVectorizerをインポート
from sklearn.feature_extraction.text import TfidfVectorizer

# ... (データの読み込みや前処理はチュートリアルと同様) ...

# ------------------------------------------------
# CountVectorizerをTfidfVectorizerに置き換える
# ------------------------------------------------
# vectorizer = CountVectorizer()
vectorizer = TfidfVectorizer()
# ------------------------------------------------

# これ以降の .fit_transform や .transform のAPIは全く同じ
X_train_array = vectorizer.fit_transform(X_train).toarray()
X_valid_array = vectorizer.transform(X_valid).toarray()

# モデルの学習と評価も同様
model.fit(X_train_array, y_train)
# ...

わずかなコード変更ですが、これによりモデルの学習プロセスは大きく変わります。AIは単語の重み付けを学習し、より精度の高い分類が可能になります。
このコードでスコアを再評価すれば、チュートリアルからの明確な改善が確認できるはずです。

まとめと次のステップ

本記事では、スパムメール分類モデルの精度を向上させるための第一歩として、TF-IDFの概念と実装方法を解説しました。

  • 課題: CountVectorizerは単語の重要度を区別できない。
  • 解決策: TF-IDFを用いて、単語の「出現頻度」と「希少性」を考慮したスコアリングを行う。

TF-IDFは、自然言語処理における特徴量エンジニアリングの基本であり、多くの場面で有効なテクニックです。この概念を理解することで、テキスト分類タスクへのアプローチがより洗練されるでしょう。

しかし、TF-IDFにもまだ改善の余地があります。現在のモデルは、単語を個別にしか評価していません。「click」と「here」という単語は認識できても、「click here」という連続した単語の組み合わせ(N-gram) が持つ特有の意味は捉えられていません。

次の中級編では、この単語の組み合わせを特徴として取り入れる N-gram について解説します。

Discussion