Doc2Vec 模型未产生预期的相似性分数
Doc2Vec model not producing expected similarity scores
我正在尝试比较两个句子并获得它们之间的余弦相似度。
我有大约 50 个句子,我使用 genism 的预训练 doc2vec 并在这 50 个句子上训练模型以稍微调整权重。然而,两个句子之间的余弦相似度并不能真正反映相似度。例如,sentence1 在英语中与 sentence2 并不接近,但它们的嵌入非常相似。
我的问题是,我如何着手比较 2 个句子的相似性(因为 doc2vec 对我不起作用)。这似乎是由于调整权重的训练输入量较少,但我想知道是否有另一种技术可以完成此任务。
例如目前粗略实施
s1 = "This is a sentence"
s2 = "This is also a sentence"
...
s50 ="This is the last sentence
list = [s1,s2..s50]
tagged_data = [TaggedDocument(words=word_tokenize(_d.lower()), tags=[
str(i)]) for i, _d in enumerate(list)]
model = Doc2Vec(vector_size=vec_size,
alpha=alpha,
min_alpha=0.00025,
min_count=1,
dm=1)
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=100)
# decrease the learning rate
model.alpha -= 0.0002
# fix the learning rate, no decay
model.min_alpha = model.alpha
然后我遍历每个句子并执行 model.infer_vector(sent_tokens)
以获得嵌入。但正如我所说,在使用相似性时,它们甚至都不是正确的。
如果我做错了什么请告诉我。
没有“gensim 的预训练 doc2vec”,所以如果实际上您使用的是来自某个第 3 方的一些预训练模型,则您需要描述源代码才能知道这里有什么用。 (但是,您的代码似乎显示了一个仅从 50 个句子训练而来的新模型。)
50 个句子不足以训练 Doc2Vec
(或 Word2Vec
或 FastText
等相关算法)。他们需要大量数据,其中包含任何感兴趣的每个单词的许多微妙变化的实际用法示例,以创建有用的向量。
将 min_count=1
与 Doc2Vec
和类似算法一起使用几乎总是一个坏主意,因为它们取决于多个不同上下文对一个词的影响。如果一个单词只有 1 次或几次使用,那么为该单词学习的任何向量都可能与该外观不同,而不具有普遍用途。此外,许多此类稀有词(在通常的自然语言语料库中)的存在可能意味着此类垃圾词在模型中充当噪声,以稀释和干扰其他词的训练 are 合适的例子。如果您完全丢弃这些不常用的词,模型通常会工作得更好 - 这就是默认值为 min_count=5
.
的原因
我还没有看到有人在预训练的 Doc2Vec
模型上使用少量新数据进行微小的后续调整的任何好文章 – 所以我不建议有人尝试这样做刚从 Doc2Vec
开始。 (如果它完全有效,则需要专家进行实验和调整。)
在循环中多次调用 .train()
并在通常的默认和自动之外调整 alpha
/min_alpha
几乎总是一个误导和容易出错的想法管理。有关详细信息,请参阅此答案:
如果您使用大型语料库正确训练,然后检查训练数据代表的文本的成对相似性,您应该会看到更合理的相似性值。
我正在尝试比较两个句子并获得它们之间的余弦相似度。
我有大约 50 个句子,我使用 genism 的预训练 doc2vec 并在这 50 个句子上训练模型以稍微调整权重。然而,两个句子之间的余弦相似度并不能真正反映相似度。例如,sentence1 在英语中与 sentence2 并不接近,但它们的嵌入非常相似。
我的问题是,我如何着手比较 2 个句子的相似性(因为 doc2vec 对我不起作用)。这似乎是由于调整权重的训练输入量较少,但我想知道是否有另一种技术可以完成此任务。
例如目前粗略实施
s1 = "This is a sentence"
s2 = "This is also a sentence"
...
s50 ="This is the last sentence
list = [s1,s2..s50]
tagged_data = [TaggedDocument(words=word_tokenize(_d.lower()), tags=[
str(i)]) for i, _d in enumerate(list)]
model = Doc2Vec(vector_size=vec_size,
alpha=alpha,
min_alpha=0.00025,
min_count=1,
dm=1)
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=100)
# decrease the learning rate
model.alpha -= 0.0002
# fix the learning rate, no decay
model.min_alpha = model.alpha
然后我遍历每个句子并执行 model.infer_vector(sent_tokens)
以获得嵌入。但正如我所说,在使用相似性时,它们甚至都不是正确的。
如果我做错了什么请告诉我。
没有“gensim 的预训练 doc2vec”,所以如果实际上您使用的是来自某个第 3 方的一些预训练模型,则您需要描述源代码才能知道这里有什么用。 (但是,您的代码似乎显示了一个仅从 50 个句子训练而来的新模型。)
50 个句子不足以训练 Doc2Vec
(或 Word2Vec
或 FastText
等相关算法)。他们需要大量数据,其中包含任何感兴趣的每个单词的许多微妙变化的实际用法示例,以创建有用的向量。
将 min_count=1
与 Doc2Vec
和类似算法一起使用几乎总是一个坏主意,因为它们取决于多个不同上下文对一个词的影响。如果一个单词只有 1 次或几次使用,那么为该单词学习的任何向量都可能与该外观不同,而不具有普遍用途。此外,许多此类稀有词(在通常的自然语言语料库中)的存在可能意味着此类垃圾词在模型中充当噪声,以稀释和干扰其他词的训练 are 合适的例子。如果您完全丢弃这些不常用的词,模型通常会工作得更好 - 这就是默认值为 min_count=5
.
我还没有看到有人在预训练的 Doc2Vec
模型上使用少量新数据进行微小的后续调整的任何好文章 – 所以我不建议有人尝试这样做刚从 Doc2Vec
开始。 (如果它完全有效,则需要专家进行实验和调整。)
在循环中多次调用 .train()
并在通常的默认和自动之外调整 alpha
/min_alpha
几乎总是一个误导和容易出错的想法管理。有关详细信息,请参阅此答案:
如果您使用大型语料库正确训练,然后检查训练数据代表的文本的成对相似性,您应该会看到更合理的相似性值。