Benzersiz bir vektör olarak küçük bir tümceyi (3 ila 4 kelime) temsil etmek için word2vec kullanıyorum, her bir gömülü kelimeyi katıştırarak veya kelime sıralarının ortalamasını hesaplayarak.word2vec, toplam veya ortalama kelime göbekleri?
Yaptığım deneylerden hep aynı kosinüs benzerliğini elde ediyorum. Eğitimden sonra word2vec tarafından birim uzunluk (Euclidean normu) normuna getirilen kelime vektörleri ile ilgili olması gerektiğinden şüpheleniyorum. Ya da kodda bir HATA var ya da bir şey eksik. İşte
kodudur:import numpy as np
from nltk import PunktWordTokenizer
from gensim.models import Word2Vec
from numpy.linalg import norm
from scipy.spatial.distance import cosine
def pattern2vector(tokens, word2vec, AVG=False):
pattern_vector = np.zeros(word2vec.layer1_size)
n_words = 0
if len(tokens) > 1:
for t in tokens:
try:
vector = word2vec[t.strip()]
pattern_vector = np.add(pattern_vector,vector)
n_words += 1
except KeyError, e:
continue
if AVG is True:
pattern_vector = np.divide(pattern_vector,n_words)
elif len(tokens) == 1:
try:
pattern_vector = word2vec[tokens[0].strip()]
except KeyError:
pass
return pattern_vector
def main():
print "Loading word2vec model ...\n"
word2vecmodelpath = "/data/word2vec/vectors_200.bin"
word2vec = Word2Vec.load_word2vec_format(word2vecmodelpath, binary=True)
pattern_1 = 'founder and ceo'
pattern_2 = 'co-founder and former chairman'
tokens_1 = PunktWordTokenizer().tokenize(pattern_1)
tokens_2 = PunktWordTokenizer().tokenize(pattern_2)
print "vec1", tokens_1
print "vec2", tokens_2
p1 = pattern2vector(tokens_1, word2vec, False)
p2 = pattern2vector(tokens_2, word2vec, False)
print "\nSUM"
print "dot(vec1,vec2)", np.dot(p1,p2)
print "norm(p1)", norm(p1)
print "norm(p2)", norm(p2)
print "dot((norm)vec1,norm(vec2))", np.dot(norm(p1),norm(p2))
print "cosine(vec1,vec2)", np.divide(np.dot(p1,p2),np.dot(norm(p1),norm(p2)))
print "\n"
print "AVG"
p1 = pattern2vector(tokens_1, word2vec, True)
p2 = pattern2vector(tokens_2, word2vec, True)
print "dot(vec1,vec2)", np.dot(p1,p2)
print "norm(p1)", norm(p1)
print "norm(p2)", norm(p2)
print "dot(norm(vec1),norm(vec2))", np.dot(norm(p1),norm(p2))
print "cosine(vec1,vec2)", np.divide(np.dot(p1,p2),np.dot(norm(p1),norm(p2)))
if __name__ == "__main__":
main()
ve burada çıktı şöyledir: Burada Cosine Similarity (Wikipedia) tanımlanan ben kosinüs benzerliği kullanıyorum
Loading word2vec model ...
Dimensions 200
vec1 ['founder', 'and', 'ceo']
vec2 ['co-founder', 'and', 'former', 'chairman']
SUM
dot(vec1,vec2) 5.4008677771
norm(p1) 2.19382594282
norm(p2) 2.87226958166
dot((norm)vec1,norm(vec2)) 6.30125952303
cosine(vec1,vec2) 0.857109242583
AVG
dot(vec1,vec2) 0.450072314758
norm(p1) 0.731275314273
norm(p2) 0.718067395416
dot(norm(vec1),norm(vec2)) 0.525104960252
cosine(vec1,vec2) 0.857109242583
. Normlar ve nokta ürünleri için değerler gerçekten farklı.
Neden herkes kosinüsün aynı olduğunu açıklayabilir mi?
David
Cevabınız için teşekkür ederiz. Kosinüs benzerliğinin, Pearson korelasyonlarının ve OLS katsayılarının içsel ürün üzerinde (yani, yer ve ölçek veya bunun gibi bir şey) varyantları olarak görülebilen bu sayfayı buldum. http://brenocon.com/blog/2012/03/cosine-similarity-pearson-correlation-and-ols-coefficients/ –