Python >> Tutoriel Python >  >> Python Tag >> Gensim

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

C'est en fait un problème assez difficile que vous posez. Calculer la similarité des phrases nécessite de construire un modèle grammatical de la phrase, de comprendre les structures équivalentes (par exemple "il est allé au magasin hier" et "hier, il est allé au magasin"), de trouver des similitudes non seulement dans les pronoms et les verbes mais aussi dans le noms propres, trouver des cooccurrences / relations statistiques dans de nombreux exemples textuels réels, etc.

La chose la plus simple que vous pourriez essayer -- bien que je ne sache pas si cela fonctionnerait bien et cela ne vous donnerait certainement pas les résultats optimaux -- serait de supprimer d'abord tous les mots "stop" (des mots comme "le", "un ", etc. qui n'ajoutent pas beaucoup de sens à la phrase), puis exécutez word2vec sur les mots des deux phrases, additionnez les vecteurs dans une phrase, additionnez les vecteurs dans l'autre phrase, puis trouvez la différence entre les sommes. En les résumant au lieu de faire une différence mot par mot, vous ne serez au moins pas soumis à l'ordre des mots. Cela étant 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 NLP, d'apprentissage automatique et d'autres habiletés).

Donc, la réponse courte est, non, il n'y a pas de moyen facile de le faire (du moins de ne pas le faire bien).


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

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

Gensim est agréable car il est intuitif, rapide et flexible. Ce qui est génial, c'est que vous pouvez récupérer les incorporations de mots pré-entraînés sur la page officielle word2vec et la couche syn0 du modèle Doc2Vec de gensim est exposée afin que vous puissiez ensemencer les incorporations de mots avec ces vecteurs de haute qualité !

GoogleNews-vectors-negative300.bin.gz (tel que lié dans Google Code)

Je pense que gensim est définitivement l'outil le plus simple (et jusqu'à présent pour moi, le meilleur) pour intégrer 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 a été basé sur le principe de la 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 ce type (de plus en plus complexes) sur la façon d'utiliser la compositionnalité pour construire des représentations au niveau de la phrase.

2011 - auto-encodeur récursif déplié (très relativement simple. commencez ici si vous êtes intéressé)

2012 - réseau neuronal matrice-vecteur

2013 - réseau de tenseurs neuronaux

2015 - Arbre LSTM

ses articles 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 pré-entraîné avec des poids adaptés pour paraphraser les données d'actualité. Le code qu'il fournit ne permet pas de recycler le réseau. Vous ne pouvez pas non plus échanger différents vecteurs de mots, vous êtes donc bloqué avec les intégrations pré-word2vec de 2011 de Turian. Ces vecteurs ne sont certainement pas au niveau de word2vec ou GloVe.

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

tl;dr Oui, utilisez le doc2vec de gensim. Mais d'autres méthodes existent !


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