・お題:文章同士の関係を評価する際に、まずは文章を数値で表現することがあるらしい。今回は、TF-IDFというやつで文章を数値で表現してみたい。
・以下のサイトを参考にさせて頂いた。正確なことはそちらをご参照いただきたい。
・TF-IDFはTF(Term Frequency)とIDF(Inverse Document Frequency)から算出される。TF-IDFが大きいほど、その文章におけるその単語の重要度が高いことになるみたい。
・TFは出現頻度に基づく単語の重要度を表す。「この文章で〇〇はたくさん出てきたから、この文章で〇〇は大事っぽい」という感じ。IDFはある単語のレア度。「単語〇〇が出てくる文章の数は、全文章の数からするとほんのちょっとなので、この単語はレアっぽい」という感じ。それぞれ求めて追いかけてみる。
・まずは文章を作成する。
A="I am a doctor."
B="My dream is to become a doctor."
C="My father is a doctor."
D="I am a lawyer."
E="My father is a lawyer and I am a lawyer too."
F="My mother is a lawyer"
import pandas as pd
df=pd.DataFrame({"ID":["A","B","C","D","E","F"],
"text":[A,B,C,D,E,F]})
・TFを求めてみる。sklearnに、文章を解析するモジュールも入っている。それを利用してみる。
from sklearn.feature_extraction.text import CountVectorizer
count_vectorizer=CountVectorizer(token_pattern="(?u)\\b\\w+\\b",lowercase=False)
#token_pattern="(?u)\\b\\w+\\b"を入れないと一文字の単語が消える。
count_matrix = count_vectorizer.fit_transform(df["text"])
counts=count_matrix.toarray()
#countsは各文章でどの単語が何回出てきたか数えたもの。
terms = count_vectorizer.get_feature_names()
#termsは各文章で登場した単語のリスト。
df2=pd.DataFrame(counts,
index=df["ID"],
columns=terms)
・これで、どの文章でどの単語が何回出てきたかが分かる。この表から、TF(各文章に登場した単語のうち、各単語が占める割合)を求めてみる。df2.sum(axis=1)で各文章中にある単語の全数を算出して、それぞれの値を割り算する。
df_TF=df2/df2.sum(axis=1).values.reshape(-1, 1)
pd.options.display.precision = 2 #表示桁数を小数点以下2桁に設定。
・次に、IDFを求めてみる。IDFの定義には結構いろいろなパターンがある。後に備えて、logは自然対数、分数のところに分母分子に1を足す、最後に1を足す定義を採用した。IDFは単語のレア度なので、単語ごとに算出されるみたい。
import numpy as np
df3=df2>0#0より大きい数字が入っていればTrueを返す。足せば>0の数を数えられる。
df_IDF=np.log( ( len( df3 )+1 )/( df3.sum( axis=0 )+1 ) )+1 #logの底はe
・最後に、TFにIDFをかけて、今回はL2 normalizationする。
from sklearn.preprocessing import normalize
df_TFIDF=pd.DataFrame(normalize(df_TF*df_IDF),
index=df["ID"],
columns=terms)
・TF-IDFは、scikit-learnのモジュールで一発で算出できる。scikit-learnのTF-IDFの定義には少し癖があると感じた。。
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vectorizer = TfidfVectorizer(token_pattern='(?u)\\b\\w+\\b',lowercase=False)
tfidf_matrix = tfidf_vectorizer.fit_transform(df["text"])
terms = tfidf_vectorizer.get_feature_names()
tfidfs = tfidf_matrix.toarray()
df_TFIDF2=pd.DataFrame(tfidfs,
index=df["ID"],
columns=terms)
おわり。