我是一名NLP新手,但我试图在Python中根据语义相似性将一个句子列表匹配到另一个句子列表。举个例子:
list1 = ['what they ate for lunch', 'height in inches', 'subjectid']
list2 = ['food eaten two days ago', 'height in centimeters', 'id']
基于之前的帖子和先前的知识,似乎创建每个句子的文档向量并计算列表之间的余弦相似度得分是最佳方法。我找到的其他与Doc2Vec相关的帖子以及教程似乎都集中在预测方面。 这篇帖子手动计算了余弦相似度,但我认为 Doc2Vec 已经可以做到这一点了。 我正在使用的代码是:
import gensim
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
def build_model(train_docs, test_docs, comp_docs):
'''
Parameters
-----------
train_docs: list of lists - combination of known both sentence list
test_docs: list of lists - one of the sentence lists
comp_docs: list of lists - combined sentence lists to match the index to the sentence
'''
# Train model
model = Doc2Vec(dm = 0, dbow_words = 1, window = 2, alpha = 0.2)#, min_alpha = 0.025)
model.build_vocab(train_docs)
for epoch in range(10):
model.train(train_docs, total_examples = model.corpus_count, epochs = epoch)
#model.alpha -= 0.002
#model.min_alpha = model.alpha
scores = []
for doc in test_docs:
dd = {}
# Calculate the cosine similarity and return top 40 matches
score = model.docvecs.most_similar([model.infer_vector(doc)],topn=40)
key = " ".join(doc)
for i in range(len(score)):
# Get index and score
x, y = score[i]
#print(x)
# Match sentence from other list
nkey = ' '.join(comp_docs[x])
dd[nkey] = y
scores.append({key: dd})
return scores
这里有一个计算相似度得分的方法,但问题在于我需要对两个列表中的所有句子进行模型训练,然后再进行匹配。是否有一种方法可以使用Doc2Vec仅获取向量,然后计算余弦相似度?明确一下,我正在尝试找到两个列表之间最相似的句子。我期望的输出是:
scores = []
for s1 in list1:
for s2 in list2:
scores.append((s1, s2, similarity(s1, s2)))
print(scores)
[('what they ate for lunch', 'food eaten two days ago', 0.23567),
('what they ate for lunch', 'height in centimeters', 0.120),
('what they ate for lunch', 'id', 0.01023),
('height in inches', 'food eaten two days ago', 0.123),
('height in inches', 'height in centimeters', 0.8456),
('height in inches', 'id', 0.145),
('subjectid', 'food eaten two days ago', 0.156),
('subjectid', 'height in centimeters', 0.1345),
('subjectid', 'id', 0.9567)]
list1
中每个项目与list2
之间的成对相似度?看起来你已经有了可用的代码,那么还有什么需要解决的问题吗?(或者,你只是还没有一个“similarity()`函数吗?) - gojomoalpha
和train()
管理方面非常不典型,甚至有些荒谬。它进行了10次train()
,但第一次没有进行任何传递,最后一次进行了9次传递,并且每次train()
都会将有效的alpha从0.2
降至0.0001
- 这是一个上升下降的锯齿形模式。这是不合适的SGD,会导致早期文本始终以高alpha进行训练,而晚期文本始终以低alpha进行训练。使用更多默认/合理的做法可以获得更好的模型。 - gojomotrain()
,每个train()
执行更多的内部epochs
。也许500对于短语料库(也许是小的单个文档?)有所帮助,并且通过给予单词向量(通过dbow_words=1
)更多的训练可以继续帮助-这远远超出了更大的语料库和已发表作品的典型范围。 - gojomo