使用 Doc2vec 的句子相似度

数据挖掘 机器学习 nlp gensim
2022-03-11 04:16:46

我有一个 50k 句子的列表,例如:“骨头在发出噪音”、“鼻子在漏水”、“眼皮向下”等。

我正在尝试使用 Doc2Vec 从给定新句子的 50k 中找到最相似的句子。

tagged_data = [TaggedDocument(words=word_tokenize(_d.lower()), tags=[str(i)]) for i, _d in enumerate(data)]

max_epochs = 100
vec_size = 20
alpha = 0.025

model = Doc2Vec(size=vec_size,
                alpha=alpha, 
                min_alpha=0.025,
                min_count=1,
                dm =0)

model.build_vocab(tagged_data)

for epoch in range(max_epochs):
    print('iteration {0}'.format(epoch))
    model.train(tagged_data,
                total_examples=model.corpus_count,
                epochs=model.iter)
    # decrease the learning rate
    model.alpha -= 0.0002
    # fix the learning rate, no decay
    model.min_alpha = model.alpha

test_data = word_tokenize("The nose is leaking blood after head injury".lower())
v1 = model.infer_vector(test_data)
#print("V1_infer", v1)

similar_doc = model.docvecs.most_similar(positive=[model.infer_vector(test_data)],topn=3)

for i in range(0,len(similar_doc)):
    print(tagged_data[int(similar_doc[i][0])],similar_doc[i][1])

这样对于“头部受伤后鼻子在漏血”这句话,我想得到相似度最高的句子(我猜它会带来带有泄漏之类的词甚至是滴水之类的同义词的句子?)。但是我得到的句子是不相关的,并且每次迭代都会改变 model.infer_vector(test_data)

关于什么是错的任何想法?

1个回答

Doc2Vec(和词向量)需要大量数据来学习有用的向量表示。50k 句子对此是不够的。为了克服这个问题,您可以在网络的嵌入层中提供词向量作为初始权重。

例如,来自以下问题的代码:

如何使用 Doc2Vec 向量实现 LSTM?

model_doc2vec = Sequential()
model_doc2vec.add(Embedding(voacabulary_dim, 100, input_length=longest_document, weights=[training_weights], trainable=False))
model_doc2vec.add(LSTM(units=10, dropout=0.25, recurrent_dropout=0.25, return_sequences=True))
model_doc2vec.add(Flatten())
model_doc2vec.add(Dense(3, activation='softmax'))
model_doc2vec.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

“Flatten”层的输出将是句子/文档的向量表示。

带有示例代码的文章