先月ぐらいから自然言語処理頑張ろうとして入門っぽいTF-IDFをPythonから理解しようとしたけど使いどころわからんくて無事死亡。
今日は式から理解しようとしてやってみた。
対数がわからん
ぐぐってもいいけど、この本もっていたので軽く理解。
式がわからん
※tf-idfって書きたいのにハイフンが引き算になるのでつらい
tf
はあるドキュメントd
の単語の出現頻度
idf
は逆文章頻度
- はドキュメントの総数
df(t, d)
は単語t
を含んでいるドキュメントd
の個数を表す。分母の1
はdf
が0の場合ゼロ除算を防ぐため
scikit-learnに実装されている式は下記らしい
tfidfはこちら
- ある文章
d
で出現頻度が大きいt
は重要である可能性が高い
- しかし、とある文章を感情分析したい場合、肯定的、否定的な文章どちらにも同じ単語が出現することはよくある
- そこで多くの文章中
d
に存在する単語t
は、1つの文章の特徴としてはなりづらくしよう -> idf
ってな感じかな
idf
は分母と分子が同じだと1になり、対数で計算すると0になるので、値は小さくなる(はず
なるほど。
scikit-learnで試す
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
vectorizer = TfidfVectorizer()
x = vectorizer.fit_transform(surfaces)
terms = vectorizer.get_feature_names()
print(len(terms))
vec_matrix = x.toarray()
words = []
for doc in range(len(surfaces)):
feature_index = x.toarray()[doc, :].nonzero()[0]
tfidf_scores = zip(feature_index, [vec_matrix[doc, x] for x in feature_index])
for w, s in [(terms[i], s) for (i, s) in tfidf_scores]:
words.append(w)
word_dict = {}
for w in words:
if w in word_dict.keys():
word_dict[w] += 1
else:
word_dict[w] = 1
word_df = pd.DataFrame([[k, v] for k, v in word_dict.items()], columns=['word', 'count'])
word_df.head()
これで重要そうな単語を確認することができる?
(ちなみにこれを実装したときに確認した単語リストは前処理が甘くjs,css,htmlのタグ名が多く上がっていた。。。orz)