Wie berechne ich die strukturelle Ähnlichkeit zwischen Sätzen?

12

Ich arbeite an einem Problem, bei dem ich feststellen muss, ob zwei Sätze ähnlich sind oder nicht. Ich implementierte eine Lösung mit BM25-Algorithmus und Wordnet-Synsets zur Bestimmung der syntaktischen und semantischen Ähnlichkeit. Die Lösung funktioniert angemessen, und selbst wenn die Wortreihenfolge in den Sätzen durcheinander ist, sind zwei Sätze ähnlich. Beispielsweise

  1. Python ist eine gute Sprache.
  2. Sprache ist eine gute Python.

Mein Problem ist festzustellen, dass diese beiden Sätze ähnlich sind.

  • Was könnte die mögliche Lösung für strukturelle Ähnlichkeit sein?
  • Wie pflege ich die Satzstruktur?
Shubham Tiwari
quelle
Möglicherweise können Sie Satzvektoren verwenden und diese vergleichen.
Aiden Grossman
Ich empfehle Ihnen dringend, Gensim ( radimrehurek.com/gensim ) für diese Aufgabe zu verwenden. Vor allem die Modelle LSI und / oder word2vec und Fasttext
Robin

Antworten:

2

Der einfachste Weg, eine Art strukturelles Ähnlichkeitsmaß hinzuzufügen, ist die Verwendung von n-Gramm. in deinem Fall könnten Bigramme ausreichen.

Gehen Sie jeden Satz durch und sammeln Sie Wörterpaare wie:

  • "Python ist", "ist eine", "eine gute", "gute Sprache".

Dein anderer Satz hat

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

Von acht Bigrams haben Sie zwei, die gleich sind ("Python ist" und "ein guter"). Sie können also sagen, dass die strukturelle Ähnlichkeit 2/8 beträgt.

Natürlich können Sie auch flexibler sein, wenn Sie bereits wissen, dass zwei Wörter semantisch zusammenhängen. Wenn Sie sagen möchten, dass Python eine gute Sprache ist, die strukturell ähnlich / mit Java eine großartige Sprache ist , können Sie dies zum Vergleich hinzufügen, damit Sie effektiv verarbeiten, dass "[PROG_LANG] eine [POSITIVE-ADJ] -Sprache ist". oder etwas ähnliches.

Oliver Mason
quelle
5

Erstens empfehle ich, dass Sie sich vor Beginn mit ähnlichen Fragen im Netzwerk befassen, z. B. /datascience/25053/best-practical-algorithm-for-sentence-similarity und https: // stackoverflow. com / questions / 62328 / gibt es einen Algorithmus, der die semantische Ähnlichkeit zweier Phrasen beschreibt?

Um die Ähnlichkeit von Sätzen zu bestimmen, müssen wir überlegen, über welche Art von Daten wir verfügen. Wenn Sie beispielsweise einen beschrifteten Datensatz hatten, dh ähnliche Sätze und ungleiche Sätze, könnte ein einfacher Ansatz darin bestanden haben, einen überwachten Algorithmus zur Klassifizierung der Sätze zu verwenden.

Ein Ansatz, der die Satzstrukturähnlichkeit bestimmen könnte, wäre, die Wortvektoren zu mitteln, die durch Worteinbettungsalgorithmen, dh word2vec, erzeugt werden. Diese Algorithmen erzeugen einen Vektor für jedes Wort und die Kosinusähnlichkeit zwischen ihnen repräsentiert die semantische Ähnlichkeit zwischen Wörtern. (Daniel L 2017)

Unter Verwendung von Wortvektoren können wir die folgenden Metriken verwenden, um die Ähnlichkeit von Wörtern zu bestimmen.

  • Kosinusabstand zwischen Worteinbettungen der Wörter
  • Euklidischer Abstand zwischen Worteinbettungen der Wörter

Die Kosinusähnlichkeit ist ein Maß für die Ähnlichkeit zwischen zwei Nicht-Null-Vektoren eines inneren Produktraums, der den Kosinus des Winkels zwischen ihnen misst. Der Kosinuswinkel ist das Maß für die inhaltliche Überlappung der Sätze.

Der euklidische Abstand zwischen zwei Wortvektoren bietet eine effektive Methode zur Messung der sprachlichen oder semantischen Ähnlichkeit der entsprechenden Wörter. (Frank D 2015)

Alternativ können Sie den Eigenvektor der Sätze berechnen, um die Ähnlichkeit der Sätze zu bestimmen.

Eigenvektoren sind eine spezielle Menge von Vektoren, die einem linearen Gleichungssystem (dh einer Matrixgleichung) zugeordnet sind. Hier wird für jeden Cluster eine Satzähnlichkeitsmatrix erzeugt und der Eigenvektor für die Matrix berechnet. Sie können mehr über den auf Eigenvector basierenden Ansatz für das Satzranking in diesem Artikel lesen: https://pdfs.semanticscholar.org/ca73/bbc99be157074d8aad17ca8535e2cd956815.pdf

Für den Quellcode hat Siraj Rawal ein Python-Notizbuch, um eine Reihe von Wortvektoren zu erstellen. Die Wortvektoren können dann verwendet werden, um die Ähnlichkeit zwischen Wörtern zu finden. Der Quellcode ist hier verfügbar: https://github.com/llSourcell/word_vectors_game_of_thrones-LIVE

Eine andere Option ist ein Tutorial von Oreily, das die gensin Python-Bibliothek verwendet, um die Ähnlichkeit zwischen Dokumenten zu bestimmen. In diesem Lernprogramm wird NLTK zum Tokenisieren verwendet und anschließend aus dem Korpus ein tf-idf-Modell (term frequency-inverse document frequency) erstellt. Die tf-idf wird dann verwendet, um die Ähnlichkeit der Dokumente zu bestimmen. Das Tutorial finden Sie hier https://www.oreilly.com/learning/how-do-i-compare-document-similarity-using-python

Seth Simba
quelle
Vielen Dank für die Bereitstellung wertvoller Details für das Problem. Ich hatte das Beispiel von Gensim gesehen, aber ich habe eine Frage, ob es das Problem lösen kann, das ich in Frage gestellt habe. Obwohl die Lösung, die ich erstellt habe, gut funktioniert, wenn es darum geht, die Ähnlichkeit zwischen Sätzen zu finden, bleibt sie hängen, wenn die Reihenfolge der Wörter durcheinander gebracht wird.
Shubham Tiwari
4

Der derzeit beste Ansatz (2019):

Der effizienteste Ansatz besteht nun darin, den universellen Satzcodierer von Google ( paper_2018 ) zu verwenden, der die semantische Ähnlichkeit zwischen Sätzen anhand des Skalarprodukts ihrer Einbettungen berechnet (dh gelernte Vektoren mit 215 Werten) . Ähnlichkeit ist eine Gleitkommazahl zwischen 0 (dh keine Ähnlichkeit) und 1 (dh starke Ähnlichkeit).

Die Implementierung ist jetzt in Tensorflow Hub integriert und kann problemlos verwendet werden. Hier ist ein gebrauchsfertiger Code, um die Ähnlichkeit zwischen zwei Sätzen zu berechnen. Hier werde ich die Ähnlichkeit zwischen "Python ist eine gute Sprache" und "Sprache, die eine gute Python ist" wie in Ihrem Beispiel feststellen.

Codebeispiel:

#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)

Ausgabe:

Similarity is 0.90007496 #Strong similarity
HLeb
quelle
Eine weitere Option im Jahr 2019 ist das Einbetten von BERT-Sätzen - Beispielcode finden Sie hier - github.com/hanxiao/bert-as-service
Adnan S