[python] Python으로 Gensim의 word2vec 모델을 사용하여 문장 유사성을 계산하는 방법

Gensim Word2Vec 에 따르면 gensim 패키지의 word2vec 모델을 사용하여 두 단어 사이의 유사성을 계산할 수 있습니다.

예 :

trained_model.similarity('woman', 'man')
0.73723527

그러나 word2vec 모델은 문장 유사성을 예측하지 못합니다. gensim에서 문장 유사성을 가진 LSI 모델을 찾았지만 word2vec 모델과 결합 할 수없는 것 같습니다. 내가 가지고있는 각 문장의 말뭉치 길이는 그리 길지 않습니다 (10 단어 미만). 그렇다면 목표를 달성하는 간단한 방법이 있습니까?



답변

이것은 실제로 당신이 묻는 꽤 어려운 문제입니다. 문장 유사성을 계산하려면 문장의 문법적 모델을 구축하고 동등한 구조를 이해해야합니다 (예 : “그는 어제 가게에 걸어 갔다”및 “어제 가게에 걸어갔습니다”). 대명사와 동사뿐 아니라 고유 명사, 많은 실제 텍스트 예제에서 통계적 동시 발생 / 관계 찾기 등

시도해 볼 수있는 가장 간단한 방법은-이것이 얼마나 잘 수행 될지 그리고 확실히 최적의 결과를 제공하지는 못하지만-먼저 모든 “중지”단어 ( “the”, “an “등)을 입력하고 두 문장의 단어에 대해 word2vec를 실행하고 한 문장의 벡터를 합산하고 다른 문장의 벡터를 합산 한 다음 차이점을 찾습니다. 합계. 단어 별 차이 대신 요약하면 적어도 단어 순서에 영향을받지 않을 것입니다. 즉, 이것은 많은 방법으로 실패 할 것이며 어떤 방법으로도 좋은 해결책이 아닙니다 (이 문제에 대한 좋은 해결책은 거의 항상 NLP, 기계 학습 및 기타 영리함을 포함합니다).

따라서 간단히 대답 할 수는 없습니다.이 작업을 수행하는 쉬운 방법은 없습니다 (적어도 제대로 수행하지 않음).


답변

gensim을 사용하고 있으므로 아마도 doc2vec 구현을 사용해야합니다. doc2vec는 word2vec를 구문, 문장 및 문서 수준으로 확장 한 것입니다. 여기에 설명 된 매우 간단한 확장입니다.

http://cs.stanford.edu/~quocle/paragraph_vector.pdf

Gensim은 직관적이고 빠르며 유연하기 때문에 훌륭합니다. 멋진 점은 공식 word2vec 페이지에서 사전 훈련 된 단어 임베딩을 가져올 수 있고 gensim의 Doc2Vec 모델의 syn0 레이어가 노출되어 이러한 고품질 벡터로 단어 임베딩을 시드 할 수 있다는 것입니다!

GoogleNews-vectors-negative300.bin.gz ( Google 코드에 링크 됨 )

저는 gensim이 벡터 공간에 문장을 삽입하는 가장 쉬운 도구라고 생각합니다.

위의 Le & Mikolov의 논문에서 제안 된 것과 다른 문장-벡터 기법이 있습니다. Stanford의 Socher와 Manning은 확실히이 분야에서 일하는 가장 유명한 연구자입니다. 그들의 작업은 구성 원칙에 기반을두고 있습니다. 문장의 의미는 다음과 같습니다.

1. semantics of the words

2. rules for how these words interact and combine into phrases

그들은 문장 수준의 표현을 구축하기 위해 구성 성을 사용하는 방법에 대해 몇 가지 그러한 모델을 제안했습니다 (갈수록 복잡 해짐).

2011- 재귀 적 오토 인코더 전개 (매우 비교적 간단합니다. 관심이 있으면 여기에서 시작)

2012- 행렬-벡터 신경망

2013- 신경 텐서 네트워크

2015- 트리 LSTM

그의 논문은 모두 socher.org에서 볼 수 있습니다. 이 모델 중 일부를 사용할 수 있지만 여전히 gensim의 doc2vec을 권장합니다. 우선 2011 URAE는 그다지 강력하지 않습니다. 또한 뉴스와 같은 데이터를 패러 프레이징하는 데 적합한 가중치로 사전 학습됩니다. 그가 제공하는 코드로는 네트워크를 재교육 할 수 없습니다. 또한 다른 단어 벡터로 바꿀 수 없으므로 Turian의 2011 년 pre-word2vec 임베딩에 갇혀 있습니다. 이러한 벡터는 확실히 word2vec 또는 GloVe 수준이 아닙니다.

아직 Tree LSTM을 사용하지 않았지만 매우 유망 해 보입니다!

tl; dr 예, gensim의 doc2vec를 사용하십시오. 그러나 다른 방법이 존재합니다!


답변

word2vec를 사용하는 경우 모든 문장 / 문서의 모든 단어에 대한 평균 벡터를 계산하고 벡터간에 코사인 유사성을 사용해야합니다.

import numpy as np
from scipy import spatial

index2word_set = set(model.wv.index2word)

def avg_feature_vector(sentence, model, num_features, index2word_set):
    words = sentence.split()
    feature_vec = np.zeros((num_features, ), dtype='float32')
    n_words = 0
    for word in words:
        if word in index2word_set:
            n_words += 1
            feature_vec = np.add(feature_vec, model[word])
    if (n_words > 0):
        feature_vec = np.divide(feature_vec, n_words)
    return feature_vec

유사성 계산 :

s1_afv = avg_feature_vector('this is a sentence', model=model, num_features=300, index2word_set=index2word_set)
s2_afv = avg_feature_vector('this is also sentence', model=model, num_features=300, index2word_set=index2word_set)
sim = 1 - spatial.distance.cosine(s1_afv, s2_afv)
print(sim)

> 0.915479828613


답변

Word Mover의 거리 알고리즘을 사용할 수 있습니다. 여기 에 WMD에 대한 간단한 설명이 있습니다.

#load word2vec model, here GoogleNews is used
model = gensim.models.KeyedVectors.load_word2vec_format('../GoogleNews-vectors-negative300.bin', binary=True)
#two sample sentences 
s1 = 'the first sentence'
s2 = 'the second text'

#calculate distance between two sentences using WMD algorithm
distance = model.wmdistance(s1, s2)

print ('distance = %.3f' % distance)

추신 : 가져 오기에 대한 오류가 발생하는 경우 pyemd 라이브러리 하면 다음 명령을 사용하여 설치할 수 있습니다.

pip install pyemd


답변

두 단어 벡터 세트의 합을 계산하면 diff가 아닌 벡터 사이의 코사인을 취해야합니다. 코사인은 정규화 된 두 벡터의 내적을 취하여 계산할 수 있습니다. 따라서 단어 수는 요인이 아닙니다.


답변

문서 에서 단어 목록을 가져와 유사점을 비교 하는 기능이 있습니다 .

s1 = 'This room is dirty'
s2 = 'dirty and disgusting room' #corrected variable name

distance = model.wv.n_similarity(s1.lower().split(), s2.lower().split())


답변

문장의 의미 적 유사성을 계산하려는 사람들을 돕기 위해 기존 솔루션을 업데이트하고 싶습니다.

1 단계:

gensim을 사용하여 적합한 모델을로드하고 문장의 단어에 대한 단어 벡터를 계산하여 단어 목록으로 저장

2 단계 : 문장 벡터 계산

문장 사이의 의미 적 유사성 계산은 이전에는 어려웠지만 최근에는 문장 내 단어 벡터의 가중 평균을 계산하고 제거하는 간단한 접근 방식을 제안하는 ” A SIMPLE BUT TOUGH-TO-BEAT BASELINE FOR SENTENCE EMBEDDINGS “라는 논문 이 제안되었습니다. 첫 번째 주성분에 대한 평균 벡터의 투영 여기에서 단어 w의 가중치는 매개 변수가되는 a / (a ​​+ p (w))이고 p (w)는 부드러운 역 주파수라고하는 (추정 된) 단어 빈도입니다. .이 방법이 훨씬 더 잘 수행됩니다.

논문에서 제안한 방법 인 SIF (smooth inverse frequency)를 이용하여 문장 벡터를 계산하는 간단한 코드가 여기에 있습니다.

3 단계 : sklearn cosine_similarity를 ​​사용하여 문장에 대해 두 개의 벡터를로드하고 유사성을 계산합니다.

이것은 문장 유사성을 계산하는 가장 간단하고 효율적인 방법입니다.