TF-IDF ベクトル化シミュレーター 戻る
機械学習

TF-IDF ベクトル化シミュレーター

文章を機械学習が扱える数値ベクトルに変換する古典的手法「TF-IDF」を体験するツールです。文書数・単語の出現回数・文書長を変えると、単語頻度 TF・逆文書頻度 IDF・TF-IDF 重みがリアルタイムで分かり、どの語がその文書を特徴づけるかが見えてきます。

パラメータ設定
コーパスの文書数 N
学習に使う文書の総数
対象単語の出現回数
その文書内で対象単語が出た回数
文書の総単語数
対象文書に含まれる単語の延べ数
その単語を含む文書数 df
コーパス中、対象単語が1回以上出る文書の数
IDF の計算方式
逆文書頻度の定義式を切り替えます
計算結果
単語頻度 TF
逆文書頻度 IDF
TF-IDF 重み
文書頻度 DF (%)
単語の識別力
ストップワード判定
コーパスと単語の重み — ベクトル化の可視化

並んだアイコンがコーパスの各文書。対象単語を含む文書は色付きで脈動します。下のバーは TF-IDF 重みの大きさを表し、TF と IDF の寄与に分けて示しています。

TF-IDF vs 出現文書数 df
TF-IDF vs 単語頻度(出現回数)
理論・主要公式

$$\text{TF-IDF}=\underbrace{\frac{f_{t,d}}{n_d}}_{\text{TF}}\times\underbrace{\ln\frac{N}{df_t}}_{\text{IDF}}$$

単語 t の文書 d における重み。$f_{t,d}$:その文書での出現回数、$n_d$:文書の総単語数、$N$:コーパスの文書数、$df_t$:その単語を含む文書数。ある文書で頻出しつつコーパス全体では希少な語ほど TF-IDF が高くなる。

$$\text{idf}_{\text{smooth}}=\ln\frac{1+N}{1+df_t}+1$$

平滑化 IDF。分母・分子に 1 を足して 0 除算を避け、末尾の +1 で全文書に出る語でも重みが完全な 0 にならないようにする。scikit-learn の TfidfVectorizer の既定式に近い。

TF-IDFとは

🙋
「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 自体の式はシンプルでも、入口のテキスト処理を丁寧に設計することが実務では最も効きます。

使い方ガイド

  1. 対象文書数(nDocsNum)を設定します。例えば技術文書1000件のコーパスを想定した場合、1000を入力します
  2. 単語の出現頻度(termFreqNum)と対象文書の長さ(docLengthNum)を指定し、TF値を計算します。TF=出現回数/文書長で、長さ500語の文書に「機械学習」が15回出現すればTF=0.03となります
  3. その単語を含む文書数(docsWithTermNum)を入力するとIDF値が算出されます。IDF=log(全文書数/当該単語を含む文書数)で、1000文書中100文書に出現すればIDF=log(1000/100)=1.0になります
  4. TF-IDF重み、文書頻度DF、識別力スコアがリアルタイム計算され、ストップワード判定が自動実行されます

具体的な計算例

金融レポート500文書のコーパスで「リスク管理」を分析する場合:単語出現頻度8回、文書長320語でTF=8/320=0.025。当該単語を含む文書数180件とするとIDF=log(500/180)=0.44。TF-IDF重み=0.025×0.44=0.011。DF=180/500=36%。識別力スコア0.011で、高頻出ワード(DF>50%)ではないため機械学習特徴として有用です。これに対し「こと」という助動詞が全400文書に出現すればDF=80%でストップワード扱いとなり、特徴抽出から除外されます

実務での注意点