2015-05-09 17 views
5

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

Trả lời

7

Cosine đo góc giữa hai vectơ và không tính chiều dài của hai véc tơ vào tài khoản. Khi bạn chia cho độ dài của cụm từ, bạn chỉ rút ngắn vectơ, không thay đổi vị trí góc của nó. Vì vậy, kết quả của bạn trông đúng với tôi.

+0

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/ –

Các vấn đề liên quan