Tôi đang sử dụng word2vec để biểu diễn một cụm từ nhỏ (3 đến 4 từ) dưới dạng một vectơ duy nhất, bằng cách thêm từng từ nhúng riêng lẻ hoặc bằng cách tính trung bình của các từ nhúng.word2vec, tổng hợp hoặc từ khóa trung bình?
Từ các thử nghiệm tôi đã thực hiện, tôi luôn nhận được sự giống nhau về cosin giống nhau. Tôi nghi ngờ nó đã làm với các vectơ từ được tạo ra bởi word2vec được định mức để đơn vị chiều dài (chuẩn Euclide) sau khi đào tạo? hoặc tôi có một BUG trong mã, hoặc tôi đang thiếu một cái gì đó.
Đây là mã:
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()
và đây là kết quả:
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
Tôi đang sử dụng sự tương đồng cosin như định nghĩa ở đây Cosine Similarity (Wikipedia). Các giá trị cho các chỉ tiêu và các sản phẩm dấu chấm thực sự khác nhau.
Có ai có thể giải thích lý do tại sao cosin giống nhau không?
Cảm ơn bạn, David
Cảm ơn câu trả lời của bạn. Tôi tìm thấy trang này giải thích rằng tương tự Cosine, tương quan Pearson và hệ số OLS tất cả có thể được xem dưới dạng biến thể trên sản phẩm bên trong (ví dụ: vị trí và tỷ lệ hoặc thứ gì đó tương tự). http://brenocon.com/blog/2012/03/cosine-similarity-pearson-correlation-and-ols-coefficients/ –