シンプルにTFIDFを考える

Webチームの同僚がESの社内勉強会で検索の色々を紹介してくれたのですが、「複数のドキュメントがあるときに、このドキュメントを特徴つける単語とは?」を知るためにTFIDFというアルゴリズムが使われていることを知って、どうも気になっていたので色々調べました。

TFIDFとは?

TFIDFは、TF(Term Frequency)とIDF(Inverse Data Frequency)の二つが合わさったアルゴリズムです。

  • TF: それぞれのドキュメント内での単語の出現頻度を表現
  • IDF: それぞれの単語がいくつのドキュメント内で共通して使われているかを表現

TFIDFはそれぞれの積をとることで算出することができます。

難しそうな数式は正直さっぱりなので、数式を日本語におこして解釈すると以下のようにして求めることができそうです。

  • tf = ドキュメントに単語が現れた回数 / ドキュメントの総単語数
  • idf = log(ドキュメントの数 / その単語を含むドキュメント数)
  • tfidf = tf * idf

実際に計算してみる

ここで、例文を使ってどういうこと?を探っていきます。

  • Document A: The rabbit bit my finger.
  • Document B: The dog bit my bacon.

という2つのドキュメントがある時、bitmyみたいな単語は2つのドキュメントで共通に使われている単語なので特に特徴づける単語とはいえないと思いますが、rabbit, dogのような単語は2つのドキュメントを特徴づける単語の一つといえそうです。

DocumentAを例にとって計算をしてみました。

Word TF IDF TFIDF
The 1/7 log(2/2) = 0 0
Rabbit 1/7 log(2/1) = 0.69 0.13
Bit 1/7 log(2/2) = 0 0
My 1/7 log(2/2) = 0 0
Finger 1/7 log(2/1) = 0.69 0.13
Dog 0 log(2/1) = 0.69 0
Bacon 0 log(2/1) = 0.69 0

TFIDFで値が0の単語はDocumentAを特徴づける単語とは確かにいえなそうですが、rabbit, fingerのような単語は0以上の値がセットされているのでDocumentAを確かに特徴づける単語といえそう!という結果になりました。

pythonで実装

Pythonで実装したものをJupyter notebookにしてgithubに公開しています。おかしなところありましたら、レビューお待ちしてます。

https://github.com/garigari-kun/til/blob/master/src/ml/tfidf/tfidf%20notebook.ipynb

github.com