Su problema se puede resolver con Word2vec y Doc2vec. Doc2vec daría mejores resultados porque toma en cuenta las oraciones al entrenar el modelo.
Solución Doc2vec
Puede entrenar su modelo doc2vec siguiendo este enlace . Es posible que desee realizar algunos pasos de preprocesamiento, como eliminar todas las palabras de detención (palabras como "the", "an", etc. que no agregan mucho significado a la oración). Una vez que haya entrenado su modelo, puede encontrar oraciones similares usando el siguiente código.
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)
Resultados:
[('TRAIN_29670', 0.6352514028549194),
('TRAIN_678', 0.6344441771507263),
('TRAIN_12792', 0.6202734708786011),
('TRAIN_12062', 0.6163255572319031),
('TRAIN_9710', 0.6056315898895264)]
Los resultados anteriores son una lista de tuplas para (label,cosine_similarity_score)
. Puede asignar salidas a oraciones haciendo train[29670]
.
Tenga en cuenta que el enfoque anterior solo dará buenos resultados si su modelo doc2vec contiene incrustaciones para las palabras que se encuentran en la nueva oración. Si trata de obtener similitud para alguna oración de galimatías sdsf sdf f sdf sdfsdffg
, le dará pocos resultados, pero esas podrían no ser las oraciones similares reales ya que su modelo entrenado puede no haber visto estas palabras de galimatías mientras entrenaba el modelo. Así que trate de entrenar a su modelo en tantas oraciones como sea posible para incorporar tantas palabras para obtener mejores resultados.
Solución de Word2vec
Si está usando word2vec, necesita calcular el vector promedio para todas las palabras en cada oración y usar la similitud de coseno entre vectores.
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
Calcular similitud
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)