Как вычислить структурное сходство между предложениями?


12

Я работаю над проблемой, где мне нужно определить, похожи ли два предложения или нет. Я реализовал решение с использованием алгоритма BM25 и наборов словосетей для определения синтаксического и семантического сходства. Решение работает адекватно, и даже если порядок слов в предложениях перемешан, это означает, что два предложения похожи. Например

  1. Python - это хороший язык.
  2. Язык хороший питон.

Моя проблема состоит в том, чтобы определить, что эти два предложения похожи.

  • Что может быть возможным решением для структурного сходства?
  • Как я буду поддерживать структуру предложений?

Вы можете использовать векторы предложений и сравнивать их.
Эйден Гроссман

Я настоятельно рекомендую вам использовать Gensim ( radimrehurek.com/gensim ) для этой задачи. Особенно модели LSI и / или word2vec и fasttext
Робин

Ответы:


2

Самый простой способ добавить некоторую меру структурного сходства - это использовать n-граммы; в вашем случае биграмм может быть достаточно.

Просмотрите каждое предложение и соберите пары слов, такие как:

  • "python is", "is", "good", "good language".

Ваше другое предложение имеет

  • "язык а", "хороший", "хороший питон", "питон есть".

Из восьми биграмм у вас есть два одинаковых («питон есть» и «хороший»), так что вы можете сказать, что структурное сходство составляет 2/8.

Конечно, вы также можете быть более гибкими, если вы уже знаете, что два слова семантически связаны. Если вы хотите сказать, что Python является хорошим языком , структурно похожим / идентичным Java является отличным языком , то вы можете добавить это к сравнению, чтобы эффективно обработать «[PROG_LANG] - это [POSITIVE-ADJ] язык», или что-то подобное.


5

Во-первых, прежде чем мы начнем, я рекомендую вам обратиться к аналогичным вопросам в сети, таким как /datascience/25053/best-practical-algorithm-for-sentence-simility и https: // stackoverflow. ком / вопросы / 62328 / есть,-ан-алгоритм-что-говорит-на-семантическое-сходство-из-двух фраз

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

Подход, который мог бы определить структурное сходство предложений, заключался бы в усреднении векторов слов, генерируемых алгоритмами встраивания слов, т.е. word2vec. Эти алгоритмы создают вектор для каждого слова, а косинусное сходство между ними представляет семантическое сходство между словами. (Даниэль Л 2017)

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

  • Косинусное расстояние между вложениями слов
  • Евклидово расстояние между вложениями слов

Косинусное сходство является мерой сходства между двумя ненулевыми векторами внутреннего пространства произведений, которое измеряет косинус угла между ними. Угол косинуса - это мера совпадения предложений с точки зрения их содержания.

Евклидово расстояние между двумя векторами слов обеспечивает эффективный метод измерения лингвистического или семантического сходства соответствующих слов. (Фрэнк Д 2015)

В качестве альтернативы вы можете рассчитать собственный вектор предложений, чтобы определить сходство предложений.

Собственные векторы представляют собой особый набор векторов, связанных с линейной системой уравнений (т.е. матричным уравнением). Здесь матрица подобия предложения генерируется для каждого кластера и вычисляется собственный вектор для матрицы. Подробнее о подходе к ранжированию предложений на основе собственных векторов можно прочитать в этой статье https://pdfs.semanticscholar.org/ca73/bbc99be157074d8aad17ca8535e2cd956815.pdf

Для исходного кода Siraj Rawal имеет блокнот Python для создания набора векторов слов. Векторы слов затем могут быть использованы, чтобы найти сходство между словами. Исходный код доступен здесь https://github.com/llSourcell/word_vectors_game_of_thrones-LIVE.

Другой вариант - это учебник от Oreily, в котором для определения сходства документов используется библиотека Python gensin. Этот учебник использует NLTK для токенизации, а затем создает из корпуса модель tf-idf (термин частота-обратная частота документа). TF-IDF затем используется для определения сходства документов. Учебное пособие доступно здесь https://www.oreilly.com/learning/how-do-i-compare-document-sdentifity-using-python


Спасибо за предоставление ценных деталей для решения проблемы. Я видел пример gensim, но у меня есть вопрос, сможет ли он решить проблему, о которой я упоминал в вопросе. Хотя созданное мною решение прекрасно работает для нахождения сходства между предложениями, но оно застревает, когда порядок слов перепутан.
Шубхам Тивари

4

Лучший подход в это время (2019):

Наиболее эффективный подход в настоящее время заключается в использовании Universal Sentence Encoder от Google ( paper_2018 ), который вычисляет семантическое сходство между предложениями, используя скалярное произведение их вложений (то есть выученные векторы из 215 значений) . Сходство - это число с плавающей точкой между 0 (то есть без сходства) и 1 (т.е. сильное сходство).

Реализация теперь интегрирована в Tensorflow Hub и может быть легко использована. Вот готовый код для вычисления сходства между двумя предложениями. Здесь я получу сходство между «Python - хороший язык» и «Language a хороший питон», как в вашем примере.

Пример кода:

#Requirements: Tensorflow>=1.7 tensorflow-hub numpy

import tensorflow as tf
import tensorflow_hub as hub
import numpy as np

module_url = "https://tfhub.dev/google/universal-sentence-encoder-large/3" 
embed = hub.Module(module_url)
sentences = ["Python is a good language","Language a good python is"]

similarity_input_placeholder = tf.placeholder(tf.string, shape=(None))
similarity_sentences_encodings = embed(similarity_input_placeholder)

with tf.Session() as session:
  session.run(tf.global_variables_initializer())
  session.run(tf.tables_initializer())
  sentences_embeddings = session.run(similarity_sentences_encodings, feed_dict={similarity_input_placeholder: sentences})
  similarity = np.inner(sentences_embeddings[0], sentences_embeddings[1])
  print("Similarity is %s" % similarity)

Выход:

Similarity is 0.90007496 #Strong similarity

Другой вариант в 2019 году - встраивание предложений BERT - пример кода можно посмотреть здесь - github.com/hanxiao/bert-as-service
Adnan S
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.