从句子开头构建 word2vec (CBOW) 训练数据
Construct word2vec (CBOW) training data from beginning of sentence
在为 CBOW 构建训练数据时,Mikolov et al. 建议使用上下文中心的词 window。在句子的 beginning/end 处捕获单词的“最佳”方法是什么(我将 best 放在引号中,因为我确信这取决于任务)。我在网上看到的实现是这样的:
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: 该方法将不平衡的焦点放在句子的中间。例如,句子的第一个词只能出现在1个上下文中window,永远不会作为目标词出现。将此与句子中的第 4 个词进行比较,它将出现在 4 个上下文 windows 中,并且也是一个目标词。这将是一个问题,因为一些词经常出现在句子的开头(即然而,因此等)。这种方法不会减少它们的使用吗?
- 问题2:4个或更少单词的句子被完全忽略,短句的重要性被最小化。例如5个单词的句子只能贡献一个训练样本,而8个单词的句子将贡献4个训练样本。
任何人都可以提供有关这些问题对结果的影响程度或构建训练数据的任何替代方法的见解吗? (我考虑过让第一个词作为目标词并使用接下来的 N 个词作为上下文,但这会产生它自己的问题)。
Stack Exchange 上的相关问题:
Construct word2vec (CBOW) training data from beginning of sentence
我见过的所有实际实现,回到 Mikolov 的原始 word2vec.c
,倾向于让每个词轮流成为 'center target word',但将 context-window 截断为什么都有。
因此,例如,window=5
(两边),'center word' 作为文本的第一个词,仅使用后面的 5 个词。如果中心词是第二个词,则使用前1个词和后5个词。
这很容易实现并且在实践中效果很好。
在 CBOW 模式下,每个中心词仍然是相同数量的 neural-network forward-propagations 的一部分(粗略地,预测尝试),尽管词 'near the ends' 作为输入参与的稍微少一些经常。但即便如此,它们也会受到越来越大的更新 - 例如当它们只是 5 个单词中的 1 个,而不是 10 个单词中的 1 个时。
(在 SG 模式下,单词 near-the-ends 都会输入,而 target-words 的频率略低。)
您的示例代码 - 显示没有完整上下文的单词 windows 永远不会成为中心目标 - 不是我见过的东西,我只希望在 buggy/unsophisticated 实现中做出这种选择。
因此,您的两个问题都不会出现在文本长度超过 1 个单词的常见实现中。 (即使在 2 个单词的文本中,第一个单词将仅使用第二个单词的 window 进行预测,而第二个单词将仅使用第一个单词的 window 进行预测。)
虽然实际的 word-sampling 确实会导致 slightly-different 两端对单词的处理,但我很难想象 word-treatment 中的这些细微差异会对结果产生任何影响,在适合 word2vec 的训练语料库——大而多变,所有相关词都有大量对比示例。
(也许这在一些小型或合成语料库中会是一个问题,其中一些 rare-but-important 标记仅出现在前导或 ending-positions 中。但这与 word2vec 的通常用法相去甚远。 )
另请注意,虽然一些描述和 API 将 word2vec 训练的单位描述为 'sentences',但该算法实际上只适用于 'lists of tokens'。通常每个 list-of-tokens 都会跨越段落或文档。有时他们会保留标点符号之类的东西,包括 sentence-ending 个句点,如 pseudo-words。将 windows 渗入 sentence-boundaries 很少有伤害,而且通常会有所帮助,因为从一个句子引出并进入下一个句子的单词同时出现可能与一个句子中单词的同时出现一样具有指导意义。因此,在 many-sentence 训练文本的常见做法中,更少的 'near-the-ends' 单词具有您可能认为的 slightly-different 采样处理。
在为 CBOW 构建训练数据时,Mikolov et al. 建议使用上下文中心的词 window。在句子的 beginning/end 处捕获单词的“最佳”方法是什么(我将 best 放在引号中,因为我确信这取决于任务)。我在网上看到的实现是这样的:
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: 该方法将不平衡的焦点放在句子的中间。例如,句子的第一个词只能出现在1个上下文中window,永远不会作为目标词出现。将此与句子中的第 4 个词进行比较,它将出现在 4 个上下文 windows 中,并且也是一个目标词。这将是一个问题,因为一些词经常出现在句子的开头(即然而,因此等)。这种方法不会减少它们的使用吗?
- 问题2:4个或更少单词的句子被完全忽略,短句的重要性被最小化。例如5个单词的句子只能贡献一个训练样本,而8个单词的句子将贡献4个训练样本。
任何人都可以提供有关这些问题对结果的影响程度或构建训练数据的任何替代方法的见解吗? (我考虑过让第一个词作为目标词并使用接下来的 N 个词作为上下文,但这会产生它自己的问题)。
Stack Exchange 上的相关问题: Construct word2vec (CBOW) training data from beginning of sentence
我见过的所有实际实现,回到 Mikolov 的原始 word2vec.c
,倾向于让每个词轮流成为 'center target word',但将 context-window 截断为什么都有。
因此,例如,window=5
(两边),'center word' 作为文本的第一个词,仅使用后面的 5 个词。如果中心词是第二个词,则使用前1个词和后5个词。
这很容易实现并且在实践中效果很好。
在 CBOW 模式下,每个中心词仍然是相同数量的 neural-network forward-propagations 的一部分(粗略地,预测尝试),尽管词 'near the ends' 作为输入参与的稍微少一些经常。但即便如此,它们也会受到越来越大的更新 - 例如当它们只是 5 个单词中的 1 个,而不是 10 个单词中的 1 个时。
(在 SG 模式下,单词 near-the-ends 都会输入,而 target-words 的频率略低。)
您的示例代码 - 显示没有完整上下文的单词 windows 永远不会成为中心目标 - 不是我见过的东西,我只希望在 buggy/unsophisticated 实现中做出这种选择。
因此,您的两个问题都不会出现在文本长度超过 1 个单词的常见实现中。 (即使在 2 个单词的文本中,第一个单词将仅使用第二个单词的 window 进行预测,而第二个单词将仅使用第一个单词的 window 进行预测。)
虽然实际的 word-sampling 确实会导致 slightly-different 两端对单词的处理,但我很难想象 word-treatment 中的这些细微差异会对结果产生任何影响,在适合 word2vec 的训练语料库——大而多变,所有相关词都有大量对比示例。
(也许这在一些小型或合成语料库中会是一个问题,其中一些 rare-but-important 标记仅出现在前导或 ending-positions 中。但这与 word2vec 的通常用法相去甚远。 )
另请注意,虽然一些描述和 API 将 word2vec 训练的单位描述为 'sentences',但该算法实际上只适用于 'lists of tokens'。通常每个 list-of-tokens 都会跨越段落或文档。有时他们会保留标点符号之类的东西,包括 sentence-ending 个句点,如 pseudo-words。将 windows 渗入 sentence-boundaries 很少有伤害,而且通常会有所帮助,因为从一个句子引出并进入下一个句子的单词同时出现可能与一个句子中单词的同时出现一样具有指导意义。因此,在 many-sentence 训练文本的常见做法中,更少的 'near-the-ends' 单词具有您可能认为的 slightly-different 采样处理。