문장 유사성 예측


15

다음과 같은 문제를 해결하려고합니다. 데이터 세트로 문장 세트가 있고 새로운 문장을 입력하고 새로운 문장이 데이터 세트에서 가장 유사한 문장을 찾고 싶습니다. 예를 들면 다음과 같습니다.

새로운 문장 : " I opened a new mailbox"

데이터 세트에 기반한 예측 :

Sentence                       | Similarity
A dog ate poop                   0%
A mailbox is good                50%
A mailbox was opened by me       80%

나는 코사인 유사성 이 tf-idf와 짝을 이루는 이러한 종류의 문제를 해결하는 데 사용될 수 있고 (RNN은 기본 방법을 크게 개선해서는 안 됨) 비슷한 단어에 대해 단어 2vec 가 사용 된다는 것을 읽었습니다 . 이 특정한 경우에도 실제로 사용할 수 있습니까? 이 문제를 해결하기위한 다른 기술 / 알고리즘이 있습니까 (바람직하게는 Python 및 SKLearn을 사용하지만 TensorFlow에 대해서도 배울 수 있습니다)?


확실히 Bert를 확인하십시오 . 여기 좋은 구현이 있습니다. 그것은 당신이 꽤 좋은 결과를 찾고 정확하게 수행
GioGio

답변:


26

Word2vec 및 Doc2vec를 사용하여 문제를 해결할 수 있습니다. Doc2vec는 모델을 훈련시키는 동안 문장을 고려하기 때문에 더 나은 결과를 제공합니다.

Doc2vec 솔루션
링크에 따라 doc2vec 모델을 교육 할 수 있습니다 . 모든 중지 단어 ( "the", "an"등과 같이 문장에 큰 의미를 부여하지 않는 단어)를 제거하는 등 일부 전처리 단계를 수행 할 수 있습니다 . 모델을 훈련하면 다음 코드를 사용하여 유사한 문장을 찾을 수 있습니다.

import gensim  

model = gensim.models.Doc2Vec.load('saved_doc2vec_model')  

new_sentence = "I opened a new mailbox".split(" ")  
model.docvecs.most_similar(positive=[model.infer_vector(new_sentence)],topn=5)

결과 :

[('TRAIN_29670', 0.6352514028549194),
 ('TRAIN_678', 0.6344441771507263),
 ('TRAIN_12792', 0.6202734708786011),
 ('TRAIN_12062', 0.6163255572319031),
 ('TRAIN_9710', 0.6056315898895264)]

위의 결과는에 대한 튜플 목록입니다 (label,cosine_similarity_score). 을 수행하여 출력을 문장에 매핑 할 수 있습니다 train[29670].

doc2vec 모델에 새로운 문장에 포함 된 단어가 포함 된 경우 위의 접근 방식만으로도 좋은 결과를 얻을 수 있습니다. 와 같은 일부 횡설수설에 대해 유사성을 얻으려고 시도 sdsf sdf f sdf sdfsdffg하면 결과가 거의 나타나지 않지만 훈련 된 모델이 모델을 훈련하는 동안 이러한 횡설수설 단어를 보지 못할 수 있으므로 실제와 유사한 문장이 아닐 수도 있습니다. 따라서 더 나은 결과를 위해 최대한 많은 단어를 포함하도록 가능한 한 많은 문장으로 모델을 훈련 시키십시오.

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

def avg_sentence_vector(words, model, num_features, index2word_set):
    #function to average all words vectors in a given paragraph
    featureVec = np.zeros((num_features,), dtype="float32")
    nwords = 0

    for word in words:
        if word in index2word_set:
            nwords = nwords+1
            featureVec = np.add(featureVec, model[word])

    if nwords>0:
        featureVec = np.divide(featureVec, nwords)
    return featureVec

유사도 계산

from sklearn.metrics.pairwise import cosine_similarity

#get average vector for sentence 1
sentence_1 = "this is sentence number one"
sentence_1_avg_vector = avg_sentence_vector(sentence_1.split(), model=word2vec_model, num_features=100)

#get average vector for sentence 2
sentence_2 = "this is sentence number two"
sentence_2_avg_vector = avg_sentence_vector(sentence_2.split(), model=word2vec_model, num_features=100)

sen1_sen2_similarity =  cosine_similarity(sentence_1_avg_vector,sentence_2_avg_vector)

감사합니다! 주말 에이 작업을 수행하지만 솔루션은 언뜻보기에는 완벽 해 보입니다. 명성!
lte__

훈련을 위해 문장을 토큰 화해야합니까?
pyd

네 @ pyd 우리는해야합니다! sentence_1.split()동일합니다.
Harman

4

단어 이동기 거리 (WMD) 는 문장 사이의 거리를 찾기위한 알고리즘입니다. WMD는 단어의 의미 적 의미를 고밀도 벡터로 인코딩하는 단어 임베딩 (예 : word2vec)을 기반으로합니다.

WMD 거리는 한 문서의 포함 된 단어가 다른 문서의 포함 된 단어에 도달하기 위해 "이동"해야하는 최소 거리로 두 텍스트 문서 간의 비 유사성을 측정합니다.

예를 들면 다음과 같습니다.

여기에 이미지 설명을 입력하십시오 출처 : "워드 임베딩에서 문서 거리까지"

gensim 패키지는대량 살상 무기 (WMD) 구현을 .

문제의 경우 입력 한 문장을 다른 모든 문장과 비교하고 WMD가 가장 낮은 문장을 반환합니다.


2

sklearn 을 사용하여 쉬운 해결책을 시도해 볼 수 있습니다 .

  • tfidfvectorizer 를 사용 하여 각 텍스트의 벡터 표현을 얻으십시오

  • 맞춤 제거, 데이터로 벡터화를 정지 단어를.

  • 이전에 훈련 된 벡터 라이저를 사용하여 새 항목 변환

  • 이 표현과 데이터 세트의 각 요소 표현 사이 의 코사인 유사성을 계산합니다 .

휴 데이터 세트가있는 경우 표현을 얻은 후 및 새 데이터를 예측하기 전에 데이터 세트를 클러스터링 할 수 있습니다 (예 : scikit learn의 KMeans 사용).

이 코드는이 모든 단계를 수행합니다. 내 github repo 에서 확인할 수 있습니다 .

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.metrics import adjusted_rand_score
import numpy

texts = ["This first text talks about houses and dogs",
        "This is about airplanes and airlines",
        "This is about dogs and houses too, but also about trees",
        "Trees and dogs are main characters in this story",
        "This story is about batman and superman fighting each other", 
        "Nothing better than another story talking about airplanes, airlines and birds",
        "Superman defeats batman in the last round"]

# vectorization of the texts
vectorizer = TfidfVectorizer(stop_words="english")
X = vectorizer.fit_transform(texts)
# used words (axis in our multi-dimensional space)
words = vectorizer.get_feature_names()
print("words", words)


n_clusters=3
number_of_seeds_to_try=10
max_iter = 300
number_of_process=2 # seads are distributed
model = KMeans(n_clusters=n_clusters, max_iter=max_iter, n_init=number_of_seeds_to_try, n_jobs=number_of_process).fit(X)

labels = model.labels_
# indices of preferible words in each cluster
ordered_words = model.cluster_centers_.argsort()[:, ::-1]

print("centers:", model.cluster_centers_)
print("labels", labels)
print("intertia:", model.inertia_)

texts_per_cluster = numpy.zeros(n_clusters)
for i_cluster in range(n_clusters):
    for label in labels:
        if label==i_cluster:
            texts_per_cluster[i_cluster] +=1 

print("Top words per cluster:")
for i_cluster in range(n_clusters):
    print("Cluster:", i_cluster, "texts:", int(texts_per_cluster[i_cluster])),
    for term in ordered_words[i_cluster, :10]:
        print("\t"+words[term])

print("\n")
print("Prediction")

text_to_predict = "Why batman was defeated  by superman so easy?"
Y = vectorizer.transform([text_to_predict])
predicted_cluster = model.predict(Y)[0]
texts_per_cluster[predicted_cluster]+=1

print(text_to_predict)
print("Cluster:", predicted_cluster, "texts:", int(texts_per_cluster[predicted_cluster])),
for term in ordered_words[predicted_cluster, :10]:
print("\t"+words[term])

코사인 유사성을 사용하는 예를 보여줄 수 있다면 정말 좋을까요?
Tido

이봐, 파트 2가 먼저 오지 말고 알 데이터에 맞추고 이것을 사용하여 각 텍스트를 변환해야합니까? 코사인 유사성을 사용하는 예를 보여줄 수 있다면 정말 좋을까요?
Tido

1

RNN 모델에는 Variational Auto-Encoder를 기반으로하는 최근 작업이 있습니다. pytorch 구현 을 사용하여 연속 공간에서 문장 생성 : github code .
그들은 문장의 의미 론적, 구문 적 전역 적 특징을 유한 한 10-30 개의 독립적 인 랜덤 변수 (인자 분포)로 표현 될 수있는 잠재 공간으로 압축했다.
이 작품의 참신한 아이디어는 두 문장 사이를 보간합니다. 결과는 정말 놀라웠습니다.


0

일반화 된 솔루션은 다음 단계로 구성됩니다.

  1. 문장의 특징 또는 단어 삽입.
  2. 문장 사이에 유사성 메트릭을 적용합니다.

1의 경우 : word2vec가 최선의 선택이지만 word2vec를 사용하지 않으려면 근사값을 지정할 수 있습니다. 한 가지 방법은 훈련 된 문장에서 단어의 동시 발생 행렬을 만든 다음 TSVD 를 적용 하는 것입니다. 코커 런스 매트릭스엑스 로 변환시 차원 엑스 차원,의 단어 벡터를 만듭니다 치수.

각 단어에 단어를 삽입하면 각 문장에 코사인 유사성 등의 유사성 메트릭을 적용하여 다른 단어와의 유사성을 측정 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.