PythonによるTF-IDF
この記事に書かれていること
TF-IDFについて
PythonによるTF-IDFの実装
TF-IDFってなに?
TF-IDFはある文章(ツイートとかブログの記事等々)を特徴付ける単語を求める方法の1つで、
TF値(Term Frequency)とIDF値(Inverse Document Frequency)の積で表されます。
ツイートや文章などをこの様な尺度で表現することで、機械学習やクラスタリングを行うことが出来ます。
TF値
TF値は次の式で求めることが出来ます。
いろいろな変数が有りますね。変数は次の様に定義されています。
:単語
:文章
:文章に単語が含まれている数
:文章に含まれている全ての単語の集合
この式は、各単語に付いて、出現数を文章内に出現する単語の個数の総和で割っています。
沢山出現している単語程TF値は高くなります。
IDF値
IDF値は次の式で求める事が出来ます。
この式の変数は次のようになっています。
:単語
:全ての文章の数
:単語が出現する文章の数
この式は、単語についてそれぞれの文章にどの程度出現するかを求めています。それぞれの文章を見ていった際に、めったに出現しない単語はの値が小さくなり、idf値が大きくなります。めったに出てこない単語は、文章を特徴付けていると言う事です。
TF-IDF値
TF-IDF値は次の式で求めることが出来ます。
この式は、TF値とIDF値の積となり、文章中に沢山出てきて、尚且つ全文章に対して珍しい単語の値が大きくなる性質が有ります。
PythonによるTF-IDFの実装
__author__ = 'emoson' def tf(terms, document): """ TF値の計算。単語リストと文章を渡す :param terms: :param document: :return: """ tf_values = [document.count(term) for term in terms] return list(map(lambda x: x/sum(tf_values), tf_values)) def idf(terms, documents): """ IDF値の計算。単語リストと全文章を渡す :param terms: :param documents: :return: """ import math return [math.log10(len(documents)/sum([bool(term in document) for document in documents])) for term in terms] def tf_idf(terms, documents): """ TF-IDF値を計算。文章毎にTF-IDF値を計算 :param terms: :param documents: :return: """ return [[_tf*_idf for _tf, _idf in zip(tf(terms, document), idf(terms, documents))] for document in documents]
次のように実行すると、TF-IDF値を求めることが出来ます。
terms = ["リンゴ", "ゴリラ", "ラッパ"] documents = ["リンゴ、リンゴ", "リンゴとゴリラ", "ゴリラとラッパ"] print(tf_idf(terms, documents))
実行結果
[[0.17609125905568124, 0.0, 0.0], [0.08804562952784062, 0.08804562952784062, 0.0], [0.0, 0.08804562952784062, 0.23856062735983122]]
1つ目の文章 「リンゴ、リンゴ」に付いて、各単語のTF-IDF値は次のようになります。
リンゴ・・・0.176
ゴリラ・・・0.0
ラッパ・・・0.0
同様に、2つ目の文章 「リンゴとゴリラ」の各単語のTF-IDF値は
リンゴ・・・0.088
ゴリラ・・・0.088
ラッパ・・・0.0
3つ目の文章 「ゴリラとラッパ」の各単語のTF-IDF値は
リンゴ・・・0.0
ゴリラ・・・0.088
ラッパ・・・0.239
最もTF-IDF値が高くなる単語は3つ目の文章のラッパとなります。これはラッパが他の文章に出現していない為高くなっています。
また、リンゴとゴリラは共に2つの文章に出現していますが、リンゴは1つ目の文章に2回出現している為、1つ目のリンゴのTF-IDF値は2つ目のゴリラに対し高くなっています。