A = {"みかん":5,"りんご":8,"ぶどう":2}
B = {"みかん":5,"なし":8,"ぶどう":2,"もも":1}
辞書の要素は{単語:その出現頻度}という構成です.
この2つのベクトルの類似度を計算する尺度を紹介する.
PMIなど共起についての尺度は使わず,単純なベクトルの比較を行うものです.
コサイン類似度 (cosine similarity)
頻度を考慮した類似度計算.
よく使われる.
import math def dotProduct(dicX,dicY): '''return a dot product.''' sum = 0 for key in dicX: if key in dicY: sum += float(dicX[key])*float(dicY[key]) return sum def root_squareSum(vector): """the root of the sum of squares""" return math.sqrt(sum([int(x)**2 for x in vector])) def cosineSim(dicX,dicY): """this is a main""" if dicX=={} or dicY=={}: return 0 upper = dotProduct(dicX,dicY) bottom = root_powerSum(dicX.values()) * root_powerSum(dicY.values()) return float(upper)/bottom print cosineSim(A, B)
ジャカード係数 (Jaccard similarity Coefficient)
言語処理ではよく使われる.
コサイン類似度と違い,集合を計算する
def jaccardSim(dicX,dicY): if dicX=={} or dicY=={}: return 0 setX = set(dicX.keys()) setY = set(dicY.keys()) upper = len(setX&setY) bottom = len(setX|setY) if bottom!=0: return float(upper)/bottom else: return 0 print jaccardSim(A, B)
シンプソン係数 (Simpson similarity coefficient)
ジャカード係数と同じく集合から計算.
def simpsonSim(dicX,dicY): if dicX=={} or dicY=={}: return 0 setX = set(dicX.keys()) setY = set(dicY.keys()) upper = len(setX&setY) bottom = min(len(setX),len(setY)) return float(upper)/bottom
Match coefficient
日本語読みがあるかわかりません.
これは単純に共通部分をとっているだけです.
def matchCoeff(dicX,dicY): setX = set(dicX.keys()) setY = set(dicY.keys()) return len(setX&setY)
更に詳しい共起に関する論文はこちら
CiNii 論文 - 共起に基づく類似性尺度(<特集>自然言語とコンピュータ)