Косинусное сходство между списками предложений с использованием Doc2Vec - PullRequest
1 голос
/ 08 марта 2019

Я новичок в NLP, но я пытаюсь сопоставить список предложений с другим списком предложений в Python на основе их семантического сходства. Например,

list1 = ['what they ate for lunch', 'height in inches', 'subjectid']
list2 = ['food eaten two days ago', 'height in centimeters', 'id']

Основываясь на предыдущих постах и ​​предшествующих знаниях, казалось, что наилучшим способом было создать векторы документов для каждого предложения и вычислить оценку сходства косинусов между списками. Другие посты, которые я нашел в отношении Doc2Vec, а также учебник, похоже, сосредоточены на предсказании. Этот пост хорошо выполняет вычисления вручную, но я подумал, что Doc2Vec уже может это сделать. Я использую код

import gensim
from gensim.models.doc2vec import Doc2Vec, TaggedDocument

def build_model(train_docs, test_docs, comp_docs):
    '''
    Parameters
    -----------
    train_docs: list of lists - combination of known both sentence list
    test_docs: list of lists - one of the sentence lists
    comp_docs: list of lists - combined sentence lists to match the index to the sentence 
    '''
    # Train model
    model = Doc2Vec(dm = 0, dbow_words = 1, window = 2, alpha = 0.2)#, min_alpha = 0.025)
    model.build_vocab(train_docs)
    for epoch in range(10):
        model.train(train_docs, total_examples = model.corpus_count, epochs = epoch)
        #model.alpha -= 0.002
        #model.min_alpha = model.alpha


    scores = []

    for doc in test_docs:
        dd = {}
        # Calculate the cosine similarity and return top 40 matches
        score = model.docvecs.most_similar([model.infer_vector(doc)],topn=40)
        key = " ".join(doc)
        for i in range(len(score)):
            # Get index and score
            x, y = score[i]
            #print(x)
            # Match sentence from other list
            nkey = ' '.join(comp_docs[x])
            dd[nkey] = y
        scores.append({key: dd})

    return scores

, который работает для вычисления оценок сходства, но проблема здесь в том, что мне нужно обучить модель всем предложениям из обоих списков или одного из списков, а затем сопоставить. Есть ли способ использовать Doc2Vec, чтобы просто получить векторы, а затем вычислить косинусное сходство? Чтобы было понятно, я пытаюсь найти наиболее похожие предложения между списками. Я ожидал бы вывод как

scores = []
for s1 in list1:
    for s2 in list2:
        scores.append((s1, s2, similarity(s1, s2)))

print(scores)
[('what they ate for lunch', 'food eaten two days ago', 0.23567),
 ('what they ate for lunch', 'height in centimeters', 0.120),
 ('what they ate for lunch', 'id', 0.01023),
 ('height in inches', 'food eaten two days ago', 0.123),
 ('height in inches', 'height in centimeters', 0.8456),
 ('height in inches', 'id', 0.145),
 ('subjectid', 'food eaten two days ago', 0.156),
 ('subjectid', 'height in centimeters', 0.1345),
 ('subjectid', 'id', 0.9567)]

1 Ответ

0 голосов
/ 08 марта 2019

Doc2vec может сгенерировать вектор, если вы предоставите ему слова, для которых вы хотите сгенерировать вектор, хотя модель doc2vec должна существовать. Однако эта модель не обязательно должна обучаться предложениям, которые вы пытаетесь сравнить. Я не знаю, существуют ли предварительно сгенерированные модели doc2vec, но я знаю, что вы можете импортировать модели word2vec с предварительно подготовленными векторами. Независимо от того, хотите ли вы сделать это, немного зависит от типов предложений, которые вы сравниваете - как правило, модели word2vec обучаются на корпусах, таких как Википедия или 20newsgroup. Таким образом, они могут не иметь векторов (или плохих векторов) для слов, которые не часто встречаются в этих статьях, то есть, если вы пытались сравнить предложения с множеством научных терминов, вы можете не захотеть использовать предварительно обученную модель. Однако вы не сможете сгенерировать вектор без предварительной подготовки модели (я думаю, что это ваш основной вопрос).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...