nltk.TextCollection.tf_idf の使い方

nltk.text.TextCollection クラスの説明は以下にある:
http://nltk.googlecode.com/svn/trunk/doc/api/nltk.text.TextCollection-class.html

TF-IDF とは

  • TF(term frequency): 文書 d におけるトークン t の出現頻度
  • IDF(inverted document frequency) : 「コーパスに含まれる文書数 / トークン t が現れる文書数」の対数

TF-IDFはこれらの積であり,その値が大きいほど文書中でのトークン t の重要度が大きいと捉える。
(注意)nltk.TextCollection.tf_idf(term,text) における TF は相対頻度で与えられ,IDF では自然対数が用いられる。

例題

nltk.text.TextCollection.tf_idf の動作を検証するため,簡単な例題を用いて手計算で TF-IDF 値を求めておく。

対象とする文書は以下の3つ:

d1 : 明日, の, 天気, は, 晴れ
d2 : 今日, の, 天気, は, 曇
d3 : 昨日, の, 天気, は, 晴れ

各トークンの DF 値は以下のとおり:

df(明日)=1
df(今日)=1
df(昨日)=1
df(の)=3
df(天気)=3
df(は)=1
df(晴れ)=2
df(曇)=1

文書 d1 におけるトークン「明日」の TF-IDF 値の計算:

tf(明日, d1) = 1 / 5 = 0.2  ・・・nltk の tf は正規化されているため。
w(明日, d1) = 0.2 * log(3 / 1) = 0.2 * 1.0986123 = 0.21972246

同様に「晴れ」の値:

tf(晴れ, d1) = 1 / 5 = 0.2
w(晴れ, d1) = 0.2 * log(3 / 2) = 0.2 * 0.40546511 = 0.081093022

「天気」は全ての文書に出現するため,TF-IDF 値はゼロとなる。

tf(天気, d1) = 1 / 5 = 0.2
w(天気, d1) = 0.2 * log(3 / 3) = 0.0

nltk.text.TextCollection.tf_idf の利用

プログラムを以下に示す:

#coding: utf-8

import nltk

docs = [
    ['明日','の','天気','は','晴れ'],
    ['今日','の','天気','は','曇'],
    ['昨日','の','天気','は','晴れ']]

collection = nltk.TextCollection(docs)
uniqTerms = list(set(collection))

for doc in docs:
    print "===================="
    for term in uniqTerms:
        print "%s : %f" % (term, collection.tf_idf(term, doc))
    print "===================="

実行結果は次のようになり,手計算の結果と一致した。

====================
今日 : 0.000000
晴れ : 0.081093
天気 : 0.000000
昨日 : 0.000000
は : 0.000000
の : 0.000000
明日 : 0.219722
曇 : 0.000000
====================
====================
今日 : 0.219722
晴れ : 0.000000
天気 : 0.000000
昨日 : 0.000000
は : 0.000000
の : 0.000000
明日 : 0.000000
曇 : 0.219722
====================
====================
今日 : 0.000000
晴れ : 0.081093
天気 : 0.000000
昨日 : 0.219722
は : 0.000000
の : 0.000000
明日 : 0.000000
曇 : 0.000000
====================