Votre problème peut être résolu avec Word2vec ainsi que Doc2vec. Doc2vec donnerait de meilleurs résultats car il prend en compte les phrases lors de l'apprentissage du modèle.
Solution Doc2vec
Vous pouvez former votre modèle doc2vec en suivant ce lien . Vous voudrez peut-être effectuer certaines étapes de prétraitement comme la suppression de tous les mots vides (des mots comme "le", "un", etc. qui n'ajoutent pas beaucoup de sens à la phrase). Une fois que vous avez formé votre modèle, vous pouvez trouver les phrases similaires en utilisant le code suivant.
import gensim
model = gensim.models.Doc2Vec.load('saved_doc2vec_model')
new_sentence = "I opened a new mailbox".split(" ")
model.docvecs.most_similar(positive=[model.infer_vector(new_sentence)],topn=5)
Résultats:
[('TRAIN_29670', 0.6352514028549194),
('TRAIN_678', 0.6344441771507263),
('TRAIN_12792', 0.6202734708786011),
('TRAIN_12062', 0.6163255572319031),
('TRAIN_9710', 0.6056315898895264)]
Les résultats ci-dessus sont une liste de tuples pour (label,cosine_similarity_score)
. Vous pouvez mapper les sorties aux phrases en faisant train[29670]
.
Veuillez noter que l'approche ci-dessus ne donnera de bons résultats que si votre modèle doc2vec contient des incorporations pour les mots trouvés dans la nouvelle phrase. Si vous essayez d'obtenir une similitude pour certaines phrases de charabia comme sdsf sdf f sdf sdfsdffg
, cela vous donnera peu de résultats, mais ce ne sont peut-être pas les phrases similaires réelles car votre modèle formé n'a peut-être pas vu ces mots de charabia lors de la formation du modèle. Essayez donc de former votre modèle sur autant de phrases que possible pour incorporer autant de mots pour de meilleurs résultats.
Solution Word2vec
Si vous utilisez word2vec, vous devez calculer le vecteur moyen pour tous les mots de chaque phrase et utiliser la similitude en cosinus entre les vecteurs.
def avg_sentence_vector(words, model, num_features, index2word_set):
#function to average all words vectors in a given paragraph
featureVec = np.zeros((num_features,), dtype="float32")
nwords = 0
for word in words:
if word in index2word_set:
nwords = nwords+1
featureVec = np.add(featureVec, model[word])
if nwords>0:
featureVec = np.divide(featureVec, nwords)
return featureVec
Calculer la similitude
from sklearn.metrics.pairwise import cosine_similarity
#get average vector for sentence 1
sentence_1 = "this is sentence number one"
sentence_1_avg_vector = avg_sentence_vector(sentence_1.split(), model=word2vec_model, num_features=100)
#get average vector for sentence 2
sentence_2 = "this is sentence number two"
sentence_2_avg_vector = avg_sentence_vector(sentence_2.split(), model=word2vec_model, num_features=100)
sen1_sen2_similarity = cosine_similarity(sentence_1_avg_vector,sentence_2_avg_vector)