Ваша проблема может быть решена с помощью Word2vec, а также Doc2vec. Doc2vec даст лучшие результаты, потому что он учитывает предложения при обучении модели.
Решение Doc2vec
Вы можете обучить свою модель doc2vec по этой ссылке . Возможно, вы захотите выполнить некоторые шаги предварительной обработки, такие как удаление всех стоп-слов (таких слов, как «the», «an» и т. Д., Которые не добавляют большого значения к предложению). После того, как вы обучили свою модель, вы можете найти похожие предложения, используя следующий код.
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)
Результаты:
[('TRAIN_29670', 0.6352514028549194),
('TRAIN_678', 0.6344441771507263),
('TRAIN_12792', 0.6202734708786011),
('TRAIN_12062', 0.6163255572319031),
('TRAIN_9710', 0.6056315898895264)]
Приведенные выше результаты являются списком кортежей для (label,cosine_similarity_score)
. Вы можете сопоставить результаты с предложениями, выполнив train[29670]
.
Обратите внимание, что описанный выше подход даст хорошие результаты, только если ваша модель doc2vec содержит вложения для слов, найденных в новом предложении. Если вы попытаетесь получить сходство для какого-то напыщенного предложения, например sdsf sdf f sdf sdfsdffg
, оно даст вам несколько результатов, но это могут быть не совсем похожие предложения, поскольку ваша обученная модель, возможно, не видела эти напыщенные слова во время обучения модели. Поэтому постарайтесь обучить свою модель как можно большему числу предложений, чтобы включить как можно больше слов для достижения лучших результатов.
Решение Word2vec
Если вы используете word2vec, вам нужно вычислить средний вектор для всех слов в каждом предложении и использовать косинусное сходство между векторами.
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
Рассчитать сходство
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)