cos類似度とは
ベクトル空間モデルにおいて、文書間の類似度を調べる手法です。
cos類似度を計算することによって、文章の似てる度合いを計算できます。
cos(A, B) = \frac{AB}{|A||B|}
分母はそれぞれの文書ベクトル長をかけ合わせたもので、
分子は文書Aと文書Bの内積です。
実装
cos.py
# coding: utf-8
import math
def calc_cos(dictA, dictB):
"""
cos類似度を計算する関数
@param dictA 1つ目の文章
@param dictB 2つ目の文章
@return cos類似度を計算した結果。0〜1で1に近ければ類似度が高い。
"""
# 文書Aのベクトル長を計算
lengthA = 0.0
for key,value in dictA.items():
lengthA = lengthA + value*value
lengthA = math.sqrt(lengthA)
# 文書Bのベクトル長を計算
lengthB = 0.0
for key,value in dictB.items():
lengthB = lengthB + value*value
lengthB = math.sqrt(lengthB)
# AとBの内積を計算
dotProduct = 0.0
for keyA,valueA in dictA.items():
for keyB,valueB in dictB.items():
if keyA==keyB:
dotProduct = dotProduct + valueA*valueB
# cos類似度を計算
cos = dotProduct / (lengthA*lengthB)
return cos
def words_to_freqdict(words):
"""
単語の配列を、単語と頻度の辞書に変換する関数
例: ["X","X","Y","Z","X"] => {"X":3, "Y":1, "Z":1}
@param words 単語の配列
@return 単語と頻度の辞書
"""
freqdict = {}
for word in words:
if word in freqdict:
freqdict[word] = freqdict[word] + 1
else:
freqdict[word] = 1
return freqdict
def main():
docA = ["リンゴ", "ぶどう", "リンゴ", "パイナップル", "リンゴ"]
docB = ["バスケ", "サッカー", "野球", "ぶどう", "テニス"]
docC = ["ぶどう", "リンゴ", "マンゴー", "ぶどう"]
freqdictA = words_to_freqdict(docA) # {"リンゴ":3, "ぶどう":1, "パイナップル":1}
freqdictB = words_to_freqdict(docB) # {"バスケ":1, "サッカー":1, "野球":1, "ぶどう":1. "テニス":1}
freqdictC = words_to_freqdict(docC) # {"ぶどう":2, "リンゴ":1, "マンゴー":1}
cosAB = calc_cos(freqdictA,freqdictB)
cosAC = calc_cos(freqdictA,freqdictC)
print(cosAB) # 0.134839972493
print(cosAC) # 0.615457454897
if __name__ == "__main__":
main()
参考