Comment calculer la similitude structurelle entre les phrases?


12

Je travaille sur un problème où je dois déterminer si deux phrases sont similaires ou non. J'ai implémenté une solution utilisant l'algorithme BM25 et les synsets wordnet pour déterminer la similitude syntaxique et sémantique. La solution fonctionne correctement, et même si l'ordre des mots dans les phrases est brouillé, elle mesure que deux phrases sont similaires. Par exemple

  1. Python est un bon langage.
  2. Le langage est un bon python.

Mon problème est de déterminer si ces deux phrases sont similaires.

  • Quelle pourrait être la solution possible à la similitude structurelle?
  • Comment vais-je conserver la structure des phrases?

Vous pourrez peut-être utiliser des vecteurs de phrases et les comparer.
Aiden Grossman

Je vous suggère fortement d'utiliser Gensim ( radimrehurek.com/gensim ) pour cette tâche. Surtout les modèles LSI et / ou word2vec et fasttext
Robin

Réponses:


2

La façon la plus simple d'ajouter une sorte de mesure de similitude structurelle est d'utiliser des n-grammes; dans votre cas, les bigrammes pourraient suffire.

Parcourez chaque phrase et collectez des paires de mots, tels que:

  • "python est", "est un", "un bon", "bon langage".

Votre autre phrase a

  • "langage un", "un bon", "bon python", "python est".

Sur huit bigrammes, vous en avez deux qui sont identiques ("python is" et "a good"), vous pouvez donc dire que la similitude structurelle est de 2/8.

Bien sûr, vous pouvez également être plus flexible si vous savez déjà que deux mots sont liés sémantiquement. Si vous voulez dire que Python est un bon langage est structurellement similaire / identique à Java est un grand langage , alors vous pouvez ajouter cela à la comparaison afin que vous traitez efficacement "[PROG_LANG] est un langage [POSITIVE-ADJ]", ou quelque chose de similaire.


5

Tout d'abord, avant de commencer, je vous recommande de vous référer à des questions similaires sur le réseau telles que /datascience/25053/best-practical-algorithm-for-sentence-similarity et https: // stackoverflow. com / questions / 62328 / est-il-un-algorithme-qui-dit-la-similitude-sémantique-de-deux-phrases

Pour déterminer la similitude des phrases, nous devons considérer le type de données dont nous disposons. Par exemple, si vous aviez un ensemble de données étiqueté, c'est-à-dire des phrases similaires et des phrases différentes, une approche simple aurait pu être d'utiliser un algorithme supervisé pour classer les phrases.

Une approche qui pourrait déterminer la similitude structurelle des phrases serait de faire la moyenne des vecteurs de mots générés par les algorithmes d'intégration de mots, c'est-à-dire word2vec. Ces algorithmes créent un vecteur pour chaque mot et la similitude cosinus entre eux représente la similitude sémantique entre les mots. (Daniel L 2017)

En utilisant des vecteurs de mots, nous pouvons utiliser les métriques suivantes pour déterminer la similitude des mots.

  • Distance cosinus entre les intégrations de mots des mots
  • Distance euclidienne entre les intégrations de mots des mots

La similitude de cosinus est une mesure de la similitude entre deux vecteurs non nuls d'un espace de produit interne qui mesure le cosinus de l'angle entre eux. L'angle cosinus est la mesure du chevauchement entre les phrases en termes de leur contenu.

La distance euclidienne entre deux vecteurs de mots fournit une méthode efficace pour mesurer la similitude linguistique ou sémantique des mots correspondants. (Frank D 2015)

Alternativement, vous pouvez calculer le vecteur propre des phrases pour déterminer la similitude des phrases.

Les vecteurs propres sont un ensemble spécial de vecteurs associés à un système linéaire d'équations (c'est-à-dire une équation matricielle). Ici, une matrice de similarité de phrase est générée pour chaque cluster et le vecteur propre de la matrice est calculé. Vous pouvez en savoir plus sur l'approche basée sur Eigenvector pour le classement des phrases sur cet article https://pdfs.semanticscholar.org/ca73/bbc99be157074d8aad17ca8535e2cd956815.pdf

Pour le code source, Siraj Rawal dispose d'un bloc-notes Python pour créer un ensemble de vecteurs de mots. Les vecteurs de mots peuvent ensuite être utilisés pour trouver la similitude entre les mots. Le code source est disponible ici https://github.com/llSourcell/word_vectors_game_of_thrones-LIVE

Une autre option est un tutoriel d'Oreily qui utilise la bibliothèque gensin Python pour déterminer la similitude entre les documents. Ce didacticiel utilise NLTK pour créer des jetons, puis crée un modèle tf-idf (terme fréquence-fréquence de document inverse) à partir du corpus. Le tf-idf est ensuite utilisé pour déterminer la similitude des documents. Le tutoriel est disponible ici https://www.oreilly.com/learning/how-do-i-compare-document-similarity-using-python


Merci d'avoir fourni des informations précieuses sur le problème. J'avais vu l'exemple du gensim mais j'ai une question est-ce qu'il pourra résoudre le problème que j'ai mentionné en question. Bien que la solution que j'ai créée fonctionne bien pour trouver la similitude entre les phrases, mais elle se bloque lorsque l'ordre des mots est brouillé.
Shubham Tiwari

4

La meilleure approche en ce moment (2019):

L'approche la plus efficace consiste maintenant à utiliser Universal Phrase Encoder by Google ( paper_2018 ) qui calcule la similitude sémantique entre les phrases en utilisant le produit scalaire de leurs plongements (c'est-à-dire des vecteurs appris de 215 valeurs) . La similitude est un nombre flottant compris entre 0 (c.-à-d. Aucune similitude) et 1 (c.-à-d. Forte similitude).

L'implémentation est désormais intégrée à Tensorflow Hub et peut facilement être utilisée. Voici un code prêt à l'emploi pour calculer la similitude entre 2 phrases. Ici, j'obtiendra la similitude entre "Python est un bon langage" et "Langage un bon python est" comme dans votre exemple.

Exemple de code:

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

Production:

Similarity is 0.90007496 #Strong similarity

Une autre option en 2019 est l'intégration des phrases BERT - vous pouvez voir un exemple de code ici - github.com/hanxiao/bert-as-service
Adnan S
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.