問題は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
類似度を計算する
#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)