Il tuo problema può essere risolto con Word2vec e Doc2vec. Doc2vec darebbe risultati migliori perché tiene conto delle frasi durante l'addestramento del modello.
Soluzione Doc2vec
Puoi addestrare il tuo modello doc2vec seguendo questo link . Potresti voler eseguire alcuni passaggi di pre-elaborazione come la rimozione di tutte le parole di arresto (parole come "the", "an", ecc. Che non aggiungono molto significato alla frase). Una volta addestrato il tuo modello, puoi trovare frasi simili usando il seguente codice.
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)
risultati:
[('TRAIN_29670', 0.6352514028549194),
('TRAIN_678', 0.6344441771507263),
('TRAIN_12792', 0.6202734708786011),
('TRAIN_12062', 0.6163255572319031),
('TRAIN_9710', 0.6056315898895264)]
I risultati sopra riportati sono un elenco di tuple per (label,cosine_similarity_score)
. Puoi mappare gli output in frasi facendo train[29670]
.
Si noti che l'approccio sopra riportato darà buoni risultati solo se il modello doc2vec contiene incorporamenti per le parole trovate nella nuova frase. Se si tenta di ottenere la somiglianza per alcune frasi incomprensibili come sdsf sdf f sdf sdfsdffg
, si otterranno pochi risultati, ma quelle potrebbero non essere le stesse frasi simili poiché il modello addestrato potrebbe non aver visto queste parole incomprensibili durante l'allenamento del modello. Quindi prova a formare il tuo modello su quante più frasi possibile per incorporare quante più parole per risultati migliori.
Soluzione Word2vec
Se si utilizza word2vec, è necessario calcolare il vettore medio per tutte le parole in ogni frase e utilizzare la somiglianza del coseno tra i vettori.
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
Calcola somiglianza
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)