Как вычислить подобие предложения, используя модель word2vec gensim с python

по словам Word2Vec Gensim, Я могу использовать модель word2vec в пакете gensim для вычисления сходства между 2 словами.

например

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

однако модель word2vec не может предсказать сходство предложения. Я узнаю модель LSI с подобием предложения в gensim, но, похоже, это не может быть объединено с моделью word2vec. Длина корпуса каждого предложения у меня не очень долго (менее 10 слов). Так есть ли простые способы достижения цели?

11 ответов


Это на самом деле довольно сложная проблема, которую вы задаете. Вычисление подобия предложения требует построения грамматической модели предложения, понимания эквивалентных структур (например, "вчера он пошел в магазин" и "вчера он пошел в магазин"), нахождения сходства не только в местоимениях и глаголах, но и в собственных существительных, нахождения статистических совпадений / отношений во многих реальных текстовых примерах и т. д.

самое простое, что вы можно было бы попробовать-хотя я не знаю, насколько хорошо это сработает, и это, конечно, не даст вам оптимальных результатов-сначала удалить все слова "стоп" (такие слова, как "the", "an" и т. д. это не добавляет много смысла в предложение), а затем запустите word2vec на словах в обоих предложениях, суммируйте векторы в одном предложении, суммируйте векторы в другом предложении, а затем найдите разницу между суммами. Суммируя их вместо того, чтобы делать разницу в словах, вы, по крайней мере, не подчиняться порядку слов. Тем не менее, это потерпит неудачу во многих отношениях и никоим образом не является хорошим решением (хотя хорошие решения этой проблемы почти всегда включают некоторое количество НЛП, машинного обучения и другого ума).

Итак, короткий ответ, Нет, нет простой способ сделать это (по крайней мере, не делать это хорошо).


поскольку вы используете gensim, вы, вероятно, должны использовать его реализацию doc2vec. doc2vec-это расширение word2vec до уровня фразы, предложения и документа. Это довольно простое расширение, описанное здесь

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

Gensim хорош, потому что он интуитивно понятен, быстр и гибок. Что здорово, что вы можете захватить pretrained word embeddings с официальной страницы word2vec и слоя syn0 модели Doc2Vec gensim подвергается так, что вы можете засеять встраивания слова с этими векторами высокого качества!

GoogleNews-векторы-negative300.бункер.gz

Я думаю, что gensim, безусловно, самый простой (и до сих пор для меня лучший) инструмент для встраивания наказание в векторном пространстве.

существуют и другие предложения-для-векторный методы, чем предлагаемая в статье Ле & Mikolov по. Сочер и Мэннинг из Стэнфорда, безусловно, являются двумя из самых известных исследователи, работающие в этой области. Их работа была основана на принципе композиционно-семантики предложения, исходящего из:

1. semantics of the words

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

они предложили несколько таких моделей (становящихся все более сложными) для использования композиционности для построения представлений на уровне предложений.

2011-разворачивающийся рекурсивный автоэнкодер (очень сравнительно простой. начните здесь, Если интересно)

2012-матрица-векторная нейронная сеть

2013(?) - нейронная тензорная сеть

2015-дерево LSTM

все его документы доступны по адресу socher.org - ... Некоторые из этих моделей доступны, но я все равно рекомендую doc2vec gensim. Во-первых, УРА 2011 года не особенно мощная. Кроме того, она поставляется pretrained с весами подходит для пересказа новостей-y данных. Код он не позволяет переобучить сеть. Вы также не можете поменять местами в разных векторах слов, поэтому вы застряли с встраиваниями 2011 pre-word2vec от Туриан. Эти векторы, конечно, не на уровне word2vec или перчаток.

еще не работал с деревом LSTM, но это кажется очень многообещающим!

tl; dr да, используйте doc2vec gensim. Но существуют и другие методы!


Если вы используете 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

Как только вы вычислите сумму двух наборов векторов слов, вы должны взять Косинус между векторами, а не diff. Косинус можно вычислить, взяв точечное произведение двух нормализованных векторов. Таким образом, слово count не является фактором.


вы можете использовать алгоритм расстояния 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)

P. s.: если вы столкнулись с ошибкой об импорте pyemd библиотека, вы можете установить его с помощью следующей команды:

pip install pyemd

Я использую следующий метод, и он работает хорошо. Сначала вам нужно запустить POSTagger, а затем отфильтровать предложение, чтобы избавиться от стоп-слов (детерминанты, союзы, ...). Я рекомендую TextBlob APTagger. Затем вы строите word2vec, принимая среднее значение каждого вектора слова в предложении. The метод n_similarity в Gemsim word2vec делает именно это, позволяя пройти два набора слов для сравнения.


существуют расширения Word2Vec, предназначенные для решения проблемы сравнения более длинных фрагментов текста, таких как фразы или предложения. Один из них-paragraph2vec или doc2vec.

"распространенные представления предложений и документов" http://cs.stanford.edu / ~quocle / paragraph_vector.pdf

http://rare-technologies.com/doc2vec-tutorial/


Я хотел бы обновить существующее решение, чтобы помочь людям, которые собираются рассчитать семантическое сходство предложений.

Шаг 1:

загрузите подходящую модель с помощью gensim и вычислите векторы слов для слов в предложении и сохраните их как список слов

Шаг 2 : Вычисление вектора предложения

расчет семантического сходства между предложениями был трудным до, но недавно статья под названием"A ПРОСТАЯ, НО ЖЕСТКАЯ К ИЗБИЕНИЮ БАЗОВАЯ ЛИНИЯ ДЛЯ ПРИГОВОРА Вложения" был предложен простой подход путем вычисления средневзвешенного значения векторов слов в предложении, а затем удаления проекций средних векторов на их первую главную составляющую.Здесь вес слова w равен A / (A + p(w)) с параметром A и P (w) (оценочной) частотой слова, называемой гладкой обратной частотой.этот метод работает значительно лучше.

простой код вычислить вектор предложения с помощью SIF (гладкой обратной частоты) метод, предложенный в статье, был дан здесь

Шаг 3: используя sklearn cosine_similarity загрузите два вектора для предложений и вычислите сходство.

Это самый простой и эффективный метод вычисления подобия предложения.


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

Я думал, что я должен изменить свое мнение и использовать вложение предложения вместо того, как изучено в этой статье и этой.


существует функция из документация взятие списка слов и сравнение их сходства.

s1 = 'This room is dirty'
s3 = 'dirty and disgusting room'

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

Facebook Research group выпустила новое решение под названием InferSent Результаты и код публикуются на Github, проверьте их РЕПО. Это довольно круто. Я планирую использовать его. https://github.com/facebookresearch/InferSent

их бумаги https://arxiv.org/abs/1705.02364 Абстрактный: Многие современные системы НЛП полагаются на встраивание слов, ранее обученных бесконтрольно на больших корпорациях, как на базовые функции. Усилия по получению вложений для больших кусков текста, таких как предложения, однако, не были столь успешными. Несколько попыток обучения неконтролируемому представлению предложений не достигли достаточной эффективности, чтобы их можно было широко применять. В этой статье мы покажем, как универсальные представления предложений, обученные с использованием контролируемых данных наборов данных вывода естественного языка Стэнфорда, могут последовательно превосходить неконтролируемые методы, такие как векторы пропусков, в широком диапазоне задач передачи. Как компьютерное зрение использует ImageNet для получения функций, которые затем могут быть перенесены на другие задачи, наша работа, как правило, указывает на пригодность вывода естественного языка для переноса обучения на другие задачи НЛП. Наш кодировщик публично доступен.