Table of Content
目的
TF-IDFによる2013年参議院選挙のパンフレットの解析で使用した文章の類似度を調べる処理をsklearnとJanomeを使用して実行してみます。
実験コード
from janome.tokenizer import Tokenizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
def stems(doc):
result = []
t = Tokenizer()
tokens = t.tokenize(doc)
for token in tokens:
result.append(token.surface.strip())
return result
documents = [
"私は猫と犬と神が好きだ",
"私は猫と犬と神が好きではない",
"私は神です",
"私は戦争が好きだ",
"ウンコティンティン!ウンコティンティン!",
]
vectorizer = TfidfVectorizer(analyzer=stems)
t = Tokenizer()
tfidf_matrix = vectorizer.fit_transform(documents)
for ix in range(len(documents)):
print(documents[ix], '------------------------')
similarities = cosine_similarity(tfidf_matrix[ix], tfidf_matrix)
for similarity in similarities:
for ix2 in range(len(similarity)):
if ix2 == ix:
continue
print(' ', documents[ix2], similarity[ix2])
出力結果
私は猫と犬と神が好きだ ------------------------
私は猫と犬と神が好きではない 0.8161301674485676
私は神です 0.29355926474682525
私は戦争が好きだ 0.47854281861265613
ウンコティンティン!ウンコティンティン! 0.0
私は猫と犬と神が好きではない ------------------------
私は猫と犬と神が好きだ 0.8161301674485676
私は神です 0.32643300489571514
私は戦争が好きだ 0.3486675556492787
ウンコティンティン!ウンコティンティン! 0.0
私は神です ------------------------
私は猫と犬と神が好きだ 0.29355926474682525
私は猫と犬と神が好きではない 0.32643300489571514
私は戦争が好きだ 0.24652369447564157
ウンコティンティン!ウンコティンティン! 0.0
私は戦争が好きだ ------------------------
私は猫と犬と神が好きだ 0.47854281861265613
私は猫と犬と神が好きではない 0.3486675556492787
私は神です 0.24652369447564157
ウンコティンティン!ウンコティンティン! 0.0
ウンコティンティン!ウンコティンティン! ------------------------
私は猫と犬と神が好きだ 0.0
私は猫と犬と神が好きではない 0.0
私は神です 0.0
私は戦争が好きだ 0.0
tf-idfを使用した類似度の算出は単語の頻度によって類似度が決まります。
すなわち意味までは解析しないので「私は猫と犬と神が好きだ」と「私は猫と犬と神が好きではない」は類似度が高い文章として扱われます。
コードの説明
TfidfVectorizerはドキュメントのコレクションをTF-IDF機能のマトリックスに変換するクラスです。
インスタンスを作成する際に、文章を解析するための関数をanalyzerに渡します。
上記の例ではstems関数を渡しており、この処理の中でJanomeを使用して形態素解析を行い単語単位に分割した結果の一覧を返します。
TfidfVectorizer.fit_transformでは解析対象のドキュメントの一覧を与えてドキュメント用語マトリックスを返します。
その用語魔トリックを用いてcosine_similarityは類似度を計算します。