pythonのscikit-learnライブラリには、tf/idf処理を行うTfidfVectorizer()という関数があります。
また、TfidfVectorizer()はtf-idf値の計算に内部的に TfidfTransformer()という関数を使用しています。
今回は、このTfidfTransformer()関数の仕様を確認してみます。
関数仕様
関数仕様は以下の通りです。
パッケージ: sklearn.feature_extraction.text
TfidfTransformer(norm=’l2’, use_idf=True, smooth_idf=True, sublinear_tf=False)
関数の仕様
TfidfVectorizer()は,度数分布の行列を正規化されたtfもしくはtf-idfに変換します。
Tfというのは単語の頻度のことで、tf-idfはtfの結果とidf(inverse document-frequency)を掛けることを意味します。
これは、情報の特徴抽出における一般的な用語の重み付け方式で、文書の分類にも適しています。
与えられた文書中の単語の出現頻度を使う代わりにtf-idfを使用する目的ですが、与えられたドキュメントの中で非常に頻繁に発生する単語の影響をスケールダウンすることです。
tfは、文書中の特徴語を探す上で出てくる頻度が高い単語は"特徴的である"という解釈です。ですが、助詞"てにをは"などは出現頻度が高いのですが、どんな文書にも出現する語なので、これらの単語を文書の特徴語とするのには違和感があります。このため、idfという考え方を使って他の文書にも出てくるようなよくある単語はスコアを下げる(ペナルティを与える)を与えます。どの語にどれくらいのペナルティを与えるかの計算式がidfです。
このため、tf-idf処理は文書処理における初期処理として使われることが多いです。
tf-idfの計算式
TfidfTransformer()関数に置ける、tf-idfの計算式を説明します。
文書内の単語tに対するtf-idf値は下記の式で計算します。
tf-idf(d, t) = tf(t) * idf(d, t)
式の中にidf(d,t)が出てきますが,これは以下の計算を行う関数です
idf(d, t) = log[ n / df(d, t) ] + 1
※smooth_idf=Falseの場合
n :文書の数
df(d, t) :文書dの中に単語tが出てくる頻度です。
上記の式ではidfに1を加算しているのですが、これを行う理由はidfが0になる単語(全ての文書に出てくる単語)を完全に無視しないためです。
教科書にあるような一般的なidf()関数では、idf()を以下のように定義しており、本処理とは異なっていることに注意が必要です
idf(d, t) = log[n /(df(d、t)+ 1)]
smooth_idfパラメータの意味
関数にはパラメータsmooth_idfがあり、これはTruleがデフォルトです。
smooth_idf=Trueの場合idfを求める関数は以下の式になります。
idf(d,t) = log[ (1+n) / (1+df(d,t)) ] +1
分母と分子にそれぞれ1を加算していますが、これは0除算を防ぐのが目的です。
tf, idfの計算式を差し替える
最初にも記載しましたが、TfidfTransformer関数には、下記の4つの引数があります。
TfidfTransformer(norm=’l2’, use_idf=True, smooth_idf=True, sublinear_tf=False)
tfおよびidfを計算するために使用される式は、以下の引数によって変更することができます。
sublinear_tfパラメータ: tf()関数のカスタマイズ
デフォルトではn(自然)ですが、sublinear_tf = Trueで指定するとl(対数)になります。
use_idfパラメータ: idf()の使用有無
デフォルトではidf()関数による重み付けを行いますが、use_idf=Falseで指定すると、idf()の計算を行いません
normパラメータ: 単語ベクトルの正規化
デフォルトでは正規化を行いませんが、norm='l2'を指定すると単語ベクトルの長さが1になるようコサイン正規化を行います