从句子开头构建word2vecCBOW训练数据

问题描述

在为CBOW构建训练数据时,Mikolov et al.建议使用上下文窗口中心的单词。什么是捕获句子开头/结尾的单词的“最佳”方法(我最好用引号引起来,因为我确定这取决于任务)。我在网上看到的实现方式是这样的:

for i in range(2,len(raw_text) - 2):
    context = [raw_text[i - 2],raw_text[i - 1],raw_text[i + 1],raw_text[i + 2]]

我看到这种方法引起了两个问题。

  • 问题1:方法使句子中间的重点不平衡。例如,句子的第一个单词只能出现在一个上下文窗口中,而永远不会作为目标单词出现。将此与句子中的第四个单词进行比较,该单词将出现在四个上下文窗口中,并且也是目标单词。这将是一个问题,因为某些单词经常出现在句子的开头(例如,等等)。这种方法会减少使用吗?
  • 问题2:具有4个或更少单词的句子将被完全忽略,并且使简短句子的重要性降至最低。例如,一个有5个单词的句子只能贡献一个训练样本,而一个长度为8的句子将贡献4个训练样本。

任何人都可以提供有关这些问题对结果有多大影响的洞察力,或提供任何其他构建培训数据的方法的见解? (我考虑过让第一个单词作为目标单词,并使用接下来的N个单词作为上下文,但这会产生问题。)

有关Stack Exchange的相关问题: Construct word2vec (CBOW) training data from beginning of sentence

解决方法

我所见过的所有实际实现,可以追溯到Mikolov最初的word2vec.c,都倾向于让每个单词轮流成为“中心目标单词”,但是将上下文窗口截断为可用的内容。

例如,以window=5(在两面)和“中心词”作为文本的第一个词,仅使用后面的五个词。如果中心单词是第二个单词,将使用前面的1个单词和后面的5个单词。

这很容易实现,并且在实践中效果很好。

在CBOW模式下,每个中心词仍然是相同数量的神经网络正向传播的一部分(大致是预测尝试),尽管“接近尾端”的词作为输入的参与频率略低。但是即使那样,它们也会受到越来越大的更新-例如,当它们是5个单词中的1个而不是10个中的1个时。

(在SG模式下,接近尾部的单词会同时减少输入和目标单词的频率。)

您的示例代码(显示没有完整上下文窗口的单词永远不会成为中心目标)不是我所看到的,并且我只希望在错误的/简单的实现中选择该选项。

因此,您的所有问题都不会出现在文本长度超过1个字长的常见实现中。 (即使在2个单词的文本中,第一个单词也将仅使用第二个窗口来预测,而第二个单词将仅使用第一个窗口来预测。)

尽管实际的单词采样确实会导致两端单词的处理稍有不同,但我很难想象在对word2vec进行适当训练的语料库中,单词处理的这些细微差别会导致结果有所不同–大而所有相关单词都有大量对比示例。

(在某些小型或合成语料库中可能会出现问题,其中一些稀有但重要的标记仅出现在开头或结尾位置。但这与word2vec的通常用法相去甚远。)

还要注意,尽管一些描述和API将word2vec训练的单位描述为“句子”,但该算法实际上仅适用于“令牌列表”。通常,每个令牌列表将跨越段落或文档。有时,它们保留诸如标点符号之类的东西(包括句子结尾句段)作为伪单词。在句子边界处流血很少会造成伤害,并且通常会有所帮助,因为从一个句子引出并进入另一个句子的单词的共现可能与在一个句子内的单词的共现一样具有启发性。因此,在多句子训练文本的常见实践中,甚至更少的“近端”单词甚至会有您可能想到的稍微不同的采样处理。