web-dev-qa-db-fra.com

Comment calculer la similarité des phrases en utilisant le modèle Word2vec de gensim avec python

Selon le Gensim Word2Vec , je peux utiliser le modèle Word2vec du paquet gensim pour calculer la similarité entre 2 mots.

par exemple.

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

Cependant, le modèle Word2vec ne permet pas de prédire la similarité des phrases. Je découvre le modèle LSI avec une similarité de phrase dans le gensim, mais il ne semble pas que cela puisse être combiné avec le modèle Word2vec. La longueur du corpus de chaque phrase que j'ai n'est pas très longue (moins de 10 mots). Alors, y a-t-il des moyens simples d'atteindre l'objectif?

89
zhfkt

C'est en fait un problème assez difficile que vous posez. Pour calculer la similarité d'une phrase, il faut créer un modèle grammatical, comprendre des structures équivalentes (par exemple, "il a marché jusqu'au magasin hier" et "hier, il a marché jusqu'au magasin"), en trouvant la similitude non seulement dans les pronoms et les verbes, mais trouver des noms propres, trouver des cooccurrences/relations statistiques dans de nombreux exemples textuels réels, etc.

La chose la plus simple que vous puissiez essayer - même si je ne sais pas à quel point cela fonctionnerait et ne vous donnerait certainement pas les résultats optimaux - serait d’abord de supprimer tous les mots "stop" (des mots comme "le", "et" ", etc. qui n'ajoutent pas beaucoup de sens à la phrase) puis exécutez Word2vec sur les mots des deux phrases, résumez les vecteurs dans une phrase, résumez les vecteurs dans l'autre phrase, puis déterminez la différence entre les sommes. En les résumant au lieu de faire une différence en termes de Word, vous ne serez au moins pas soumis à l'ordre de Word. Cela dit, cela échouera à bien des égards et n’est en aucun cas une bonne solution (bien que les bonnes solutions à ce problème impliquent presque toujours une certaine quantité de PNL, d’apprentissage automatique et d’autres astuces).

Donc, la réponse est non, il n’ya pas de moyen facile de le faire (du moins, de ne pas le faire bien).

70

Puisque vous utilisez gensim, vous devriez probablement utiliser son implémentation doc2vec. doc2vec est une extension de Word2vec au niveau phrase, phrase et document. C'est une extension assez simple, décrite ici

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

Gensim, c'est Nice parce que c'est intuitif, rapide et flexible. Ce qui est génial, c’est que vous pouvez récupérer les images Word pré-entraînées sur la page officielle Word2vec et que la couche syn0 du modèle Doc2Vec de Gensim est exposée de sorte que vous puissiez ensemencer les images embarquées avec ces vecteurs de haute qualité!

GoogleNews-vectors-negative300.bin.gz

Je pense que gensim est certainement l’outil le plus facile (et jusqu’à présent, le meilleur) pour incorporer une phrase dans un espace vectoriel.

Il existe d'autres techniques phrase à vecteur que celle proposée dans l'article de Le & Mikolov ci-dessus. Socher et Manning de Stanford sont certainement deux des chercheurs les plus célèbres travaillant dans ce domaine. Leur travail est basé sur le principe de composition - la sémantique de la phrase provient de:

1. semantics of the words

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

Ils ont proposé quelques modèles (de plus en plus complexes) sur la manière d'utiliser la compositionnalité pour créer des représentations au niveau de la phrase.

2011 - dévoilement autoencoder récursif (très relativement simple. Commence ici si intéressé)

2012 - réseau neuronal matrice-vecteur

2013 - réseau de tenseurs neuronaux

2015 - Tree LSTM

ses papiers sont tous disponibles sur socher.org. Certains de ces modèles sont disponibles, mais je recommanderais toujours le doc2vec de gensim. D'une part, l'URAE 2011 n'est pas particulièrement puissant. De plus, il est fourni avec des poids pré-entraînés pour la paraphrasage des données d’actualité. Le code qu'il fournit ne vous permet pas de recycler le réseau. De plus, vous ne pouvez pas permuter différents vecteurs Word. Vous êtes donc coincé avec les incorporations antérieures à Word2vec de 2011 par Turian. Ces vecteurs ne sont certainement pas au niveau de Word2vec ou de GloVe.

Je n'ai pas encore travaillé avec Tree LSTM, mais cela semble très prometteur!

oui, utilisez le doc2vec de gensim. Mais d'autres méthodes existent!

63
Willie

Si vous utilisez Word2vec, vous devez calculer le vecteur moyen pour tous les mots de chaque phrase/document et utiliser la similarité cosinus entre les vecteurs:

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

Calculer la similarité:

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
27
tbmihailov

vous pouvez utiliser l'algorithme Distance de Word Mover. Voici une description facile à propos des 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 .: si vous rencontrez une erreur concernant la bibliothèque d'importation pyemd , vous pouvez l'installer à l'aide de la commande suivante:

pip install pyemd
19
Ehsan

Une fois que vous calculez la somme des deux ensembles de vecteurs Word, vous devez prendre le cosinus entre les vecteurs et non le diff. Le cosinus peut être calculé en prenant le produit scalaire des deux vecteurs normalisé. Ainsi, le nombre de mots n'est pas un facteur. 

16
Rani Nelken

Je voudrais mettre à jour la solution existante pour aider les personnes qui vont calculer la similarité sémantique des phrases.

Étape 1:

Chargez le modèle approprié à l'aide de gensim et calculez les vecteurs Word pour les mots de la phrase et stockez-les en tant que liste de mots.

Étape 2: Calcul du vecteur de phrase

Le calcul de la similarité sémantique entre les phrases était difficile auparavant. Récemment, un article intitulé " UN RÉGIME DE BASE DE LA SENTENCE SIMPLE MAIS DIFFICILE À SUPPORTER EMBEDDINGS " propose une approche simple en calculant la moyenne pondérée de Word vecteurs dans la phrase, puis supprimez les projections des vecteurs moyens sur leur première composante principale.Voici le poids d'un mot w est a/(a ​​+ p(w)), avec étant un paramètre et p(w) la fréquence Word (estimée) appelée fréquence inverse lisse. Cette méthode donne des résultats nettement meilleurs.

Un code simple pour calculer le vecteur de phrase en utilisant SIF (Lisse inverse fréquence) la méthode proposée dans l'article a été donné ici

Étape 3: En utilisant sklearn cosine_similarity, chargez deux vecteurs pour les phrases et calculez la similarité.

C'est la méthode la plus simple et la plus efficace pour calculer la similarité de phrases.

8
Poorna Prudhvi

J'utilise la méthode suivante et cela fonctionne bien .. Vous devez d'abord exécuter un POSTagger, puis filtrer votre phrase pour éliminer les mots vides (déterminants, conjonctions, ...). Je recommande TextBlob APTagger . Ensuite, vous créez un Word2vec en prenant la moyenne de chaque vecteur Word de la phrase. La méthode n_similarity dans Gemsim Word2vec fait exactement cela en permettant de transmettre deux ensembles de mots à comparer.

8
lechatpito

Il existe des extensions de Word2Vec destinées à résoudre le problème de la comparaison de longs morceaux de texte tels que des phrases ou des phrases. L'un d'eux est paragraph2vec ou doc2vec.

"Représentations distribuées de peines et de documents" http://cs.stanford.edu/~quocle/inéa_vector.pdf

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

6
Max

J'ai essayé les méthodes fournies par les réponses précédentes. Cela fonctionne, mais l’inconvénient majeur est que plus les phrases sont longues, plus la similarité sera grande (pour calculer la similarité, j’utilise le score cosinus des deux combinaisons moyennes de deux phrases quelconques) car plus les mots sont longs, plus les effets sémantiques sont positifs. sera ajouté à la phrase. 

Je pensais que je devrais changer d'avis et utiliser la phrase incorporée à la place comme étudié dans ce document et ceci

3
lerner

Il existe une fonction dans documentation qui consiste à prendre une liste de mots et à comparer leurs similitudes.

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

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

Le groupe de recherche Facebook a publié une nouvelle solution appelée InferSent Les résultats et le code sont publiés sur Github, vérifiez leur rapport. C'est vraiment génial. Je prévois de l'utiliser. https://github.com/facebookresearch/InferSent

leur papier https://arxiv.org/abs/1705.02364 Résumé: De nombreux systèmes de PNL modernes reposent sur des imbrications Word, préalablement formés de manière non supervisée sur de grands corpus . Les efforts pour obtenir des imbrications pour des morceaux de texte plus volumineux, tels que des phrases, n’ont toutefois pas été aussi fructueux. Plusieurs tentatives d'apprentissage de représentations non supervisées de phrases n'ont pas abouti à des performances suffisantes pour être largement adoptées. Dans cet article, nous montrons comment les représentations de phrases universelles formées à l'aide des données supervisées des jeux de données Inférence en langage naturel de Stanford peuvent systématiquement surperformer les méthodes non supervisées telles que les vecteurs SkipThought sur un large éventail de tâches de transfert. Tout comme la vision par ordinateur utilise ImageNet pour obtenir des fonctionnalités, qui peuvent ensuite être transférées à d'autres tâches, nos travaux tendent à indiquer la pertinence de l'inférence en langage naturel pour le transfert de l'apprentissage vers d'autres tâches de la PNL. Notre encodeur est disponible publiquement.

2
Ayman Salama

Gensim implémente un modèle appelé Doc2Vec pour insertion de paragraphe .

Il existe différents tutoriels présentés sous forme de blocs-notes IPython:

Une autre méthode s'appuierait sur Word2Vec et sur Word Mover's Distance (WMD), comme indiqué dans ce tutoriel:

Une autre solution consisterait à utiliser des vecteurs moyens:

from gensim.models import KeyedVectors
from gensim.utils import simple_preprocess    

def tidy_sentence(sentence, vocabulary):
    return [Word for Word in simple_preprocess(sentence) if Word in vocabulary]    

def compute_sentence_similarity(sentence_1, sentence_2, model_wv):
    vocabulary = set(model_wv.index2Word)    
    tokens_1 = tidy_sentence(sentence_1, vocabulary)    
    tokens_2 = tidy_sentence(sentence_2, vocabulary)    
    return model_wv.n_similarity(tokens_1, tokens_2)

wv = KeyedVectors.load('model.wv', mmap='r')
sim = compute_sentence_similarity('this is a sentence', 'this is also sentence', wv)
print(sim)

Enfin, si vous pouvez exécuter Tensorflow, essayez: https://tfhub.dev/google/universal-sentence-encoder/2 }

0
Wok