🙋
「TF-IDF」って機械学習の本でよく見るんですけど、結局なにをするものなんですか?
🎓
ざっくり言うと「文章を数字の列に変える道具」だね。機械学習のモデルは文字をそのまま食べられない。だから「この文書には単語Aが何回、単語Bが何回…」という数値ベクトルに変換してやる必要がある。一番単純なのはただの出現回数を並べる方法だけど、それだと「は」「です」みたいな、どの文書にも山ほど出る語が一番大きな数字になってしまう。TF-IDF はそこを賢く補正して、「その文書らしさを表す語」に大きな重みが付くようにした手法なんだ。
🙋
名前の TF と IDF って、それぞれ何の略なんですか?
🎓
TF は Term Frequency、つまり「単語頻度」。その単語がいま見ている文書のなかで何回出たか。長い文書ほど数字が膨らむから、文書の総単語数で割って正規化することが多い。IDF は Inverse Document Frequency、「逆文書頻度」。コーパス全体で、その単語が何件の文書に出てくるかを見て、希少なほど大きい値になるよう ln(N/df) で計算する。この2つを掛け算したのが TF-IDF。左で「対象単語の出現回数」を上げると TF が、「その単語を含む文書数」を下げると IDF が伸びるのが見えるはずだよ。
🙋
なるほど、掛け算なんですね。じゃあ TF-IDF が大きい単語って、どういう単語なんですか?
🎓
「この文書ではよく出るのに、ほかの文書にはあまり出ない」単語だね。例えばニュース記事のコーパスを考えてみて。スポーツ記事のなかで「ホームラン」という語は何度も出るけど、政治記事や経済記事にはまず出てこない。だから TF が高く、df が低い=IDF も高い。掛け算の結果 TF-IDF が大きくなって、「この記事はスポーツだ」と機械に教える特徴量になる。逆に「ニュース」みたいに全記事に出る語は、TF が高くても IDF がほぼ 0 だから TF-IDF も小さい。
🙋
え、じゃあ「は」とか「the」みたいな語を消すストップワードのリストって、いらなくなるんですか?
🎓
そう、そこが TF-IDF の気持ちいいところ。ありふれた語はほぼ全文書に出るから df が N に近づく。すると ln(N/df) はゼロに潰れて、TF-IDF も自動的にほぼ 0 になる。手作業でストップワードを列挙しなくても、統計的に「ありふれた語=情報量が少ない」と判定して勝手に重みを下げてくれるんだ。左のスライダーで「その単語を含む文書数」を文書数いっぱいまで上げてみて。識別力が「低い(ありふれた語)」に変わって、ストップワード相当と表示されるはずだよ。
🙋
そんなに便利なら、いまの BERT みたいな新しい手法はなんで必要なんですか?
🎓
いい疑問だ。TF-IDF は「単語の出現回数」しか見ないから、語順や意味のつながりは表現できない。「犬が人をかんだ」と「人が犬をかんだ」は TF-IDF だと同じベクトルになってしまうし、「車」と「自動車」が似た意味だということも分からない。Word2Vec や BERT はそこを文脈から学習して捉える。ただ TF-IDF は計算が軽くて、結果の解釈もしやすく、学習データが少なくても安定する。だから実務では「まず TF-IDF で分類のベースラインを作り、足りなければ埋め込みへ」という順番がいまでも定番なんだ。
TF-IDF(Term Frequency – Inverse Document Frequency)は、文章を機械学習で扱える数値ベクトルに変換する古典的な手法です。各単語に「その文書での出現頻度 TF」と「コーパス全体での希少性 IDF」を掛け合わせた重みを与えます。TF-IDF が大きい単語は、その文書で頻出しつつ他の文書にはあまり出てこない、まさにその文書を特徴づける語です。検索エンジンのランキングや文書分類で長年使われてきた、解釈しやすい強力なベースライン手法です。
TF(単語頻度)は、対象単語のその文書内での出現回数を文書の総単語数で割って正規化します。tf = 出現回数 / 文書長。IDF(逆文書頻度)は標準式では idf = ln(N / df) で計算します(N はコーパスの文書数、df はその単語を含む文書数)。平滑化式 idf = ln((1+N)/(1+df)) + 1 を使うと、df が 0 のときの 0 除算を避けられ、全文書に出る語でも idf が完全な 0 にならないため安定します。TF-IDF = tf × idf です。
「は」「です」「the」「is」のような語は、コーパスのほぼ全文書に出現するため文書頻度 df が高くなります。IDF = ln(N/df) は df が N に近いと 0 へ向かうので、これらの語の TF-IDF は自動的にほぼ 0 まで下がります。つまり TF-IDF を使えば、手作りのストップワードリストを用意しなくても、ありふれた語が自然に低く重み付けされます。これが TF-IDF の大きな利点の一つです。
TF-IDF は単語の出現統計だけを使う疎(スパース)なベクトルで、語順や意味の近さは表現しません。一方 Word2Vec や BERT などの単語埋め込みは、文脈から学習した密(デンス)なベクトルで「車」と「自動車」が近いといった意味的類似を捉えます。ただし TF-IDF は計算が軽く、結果の解釈が容易で、学習データが少なくても安定して動きます。実務では分類タスクの強力なベースラインとして今も広く使われています。
検索エンジンと文書ランキング:初期の Web 検索や全文検索エンジンは、検索語の TF-IDF をスコアの中核に据えていました。クエリの単語が多く出現し(高 TF)、かつ他の文書には少ない希少な語ほど(高 IDF)、その文書を上位に押し上げます。現代の BM25 はこの TF-IDF を発展させ、TF の飽和や文書長による補正を加えたもので、Elasticsearch や Solr の既定スコアリングとして今も広く使われています。
文書分類とスパムフィルタ:ニュースのカテゴリ分け、メールのスパム判定、レビューのポジ・ネガ分類などでは、文書を TF-IDF ベクトルに変換し、ロジスティック回帰や線形 SVM、ナイーブベイズに入力するのが定番です。少ない計算資源で高速に学習でき、どの単語がどのクラスに効いたかを係数から読み取れるため、結果の説明が求められる業務システムで重宝されます。
キーワード抽出と要約:1つの文書のなかで TF-IDF が高い上位数語を取り出すと、その文書を代表するキーワードになります。記事の自動タグ付け、関連文書のレコメンド、ワードクラウドの生成などに使われます。複数文書から抽出した TF-IDF 上位語を比べると、各文書の話題の違いも定量的に把握できます。
クラスタリングと類似度計算:文書を TF-IDF ベクトルにすると、コサイン類似度で「文書どうしの近さ」を測れます。これを使って k-means で文書をクラスタにまとめたり、似た記事を探したりできます。検索結果の重複排除や、大量文書の俯瞰的な可視化(トピックの地図づくり)の前処理としても広く使われています。
まず多いのが、「IDF を学習データと評価データで別々に計算してしまう」誤りです。IDF はコーパス全体の統計量なので、学習時に求めた df と N を保存し、テスト文書や本番データにも同じ IDF を適用しなければなりません。評価データだけで IDF を計算し直すと、学習時と特徴量のスケールがずれて精度が落ちます。scikit-learn なら学習データで fit し、それ以降は transform のみを呼ぶ、という分離を徹底してください。これはあらゆる前処理に共通する「データリーク」回避の鉄則です。
次に、「TF-IDF が意味を理解している」と思い込むこと。TF-IDF はあくまで単語の出現回数の統計であり、語の意味も語順も知りません。「品質が良い」と「品質が良くない」は、否定語の有無で意味が正反対なのに、TF-IDF ベクトルとしてはほとんど同じになります。同義語(「車」と「自動車」)も別々の次元として扱われ、関連は捉えられません。意味的な近さや文脈が重要なタスクでは、TF-IDF をベースラインに留め、単語埋め込みや文脈モデルを併用する判断が要ります。
最後に、「前処理を軽視する」こと。TF-IDF の質は、その手前のトークン化(単語分割)・正規化に大きく左右されます。日本語は分かち書きされていないため、形態素解析器(MeCab・Sudachi 等)の選択や辞書で結果が変わります。大文字小文字の統一、活用形の見出し語化(lemmatization)、極端に希少な語や頻出語を min_df / max_df で足切りすることなども、ベクトルの次元数と精度に直結します。TF-IDF 自体の式はシンプルでも、入口のテキスト処理を丁寧に設計することが実務では最も効きます。