将验证数据包含在 NLP 词汇表中是否有效?

数据挖掘 机器学习 scikit-学习 nlp 信息论
2021-10-13 19:32:14

目前,我正在遵循最佳实践并使用来自训练数据的词汇表创建一个“词袋”向量。我的交叉验证(和测试)数据集使用此模型进行转换,使用训练集创建的相同词汇表。它们不贡献任何词汇,也不影响文档频率(用于“词频逆文档频率”计算)。

然而,这在某些方面是有限制的。首先,计算词袋模型的成本很高,因此这阻止了我进行 k 折交叉验证(因为它需要不断地重新计算词袋)。我的数据集大约有 1000 万个单词,我正在计算词袋和双元词袋,每次大约需要 5 分钟。

这也意味着我目前有交叉验证和测试集的保留数据,这是我不能用于训练的数据。

如果我在训练集和交叉验证集上都装上词袋,我的结果会显着偏差吗?换句话说,如果我使用验证集中的词汇来计算词袋的词汇?我认为,即使它们可能有助于词汇量,也不存在过度拟合的风险,因为在训练中不会看到这些特定样本的频率。这使我可以稍后根据自己的喜好对验证集进行切片,并且我仍然有一个“测试”集来准确预测泛化错误(直到测试时才看到测试集)。

我想知道这样的事情是否有任何先例,以及您的经历是否在做类似的事情。

1个回答

是的。那应该没问题。你的建议是有道理的,不应该对结果产生偏见。你给出的理由是好的。对于任何合理的分类器,如果一个属性的值在训练集中总是为零,那应该导致该属性基本上被忽略。

有一个简单的测试可以让您确认这一点。您可以尝试,对于验证集中的每个文档,将特征向量中对应于训练集中任何文档中不存在的单词的条目归零,并查看这是否会改变分类。如果没有,那么您就知道您的方法没有效果并且没有引入任何偏差。


如果您愿意,这是另一种选择:

从概念上讲,在理想世界中,每个折叠的词汇仅包括训练集中的单词。

作为实现的问题,当然可以以比重新生成词汇表和为每个折叠重新生成特征向量更有效的方式来实现它。只要您的实现生成相同的向量,它如何获得它们并不重要。

因此,您可以有一个如下所示的实现:

  • 生成一个“超集词汇表”,其中包括在数据集中任何位置找到的所有单词(不仅仅是训练集)。

  • 根据“超集词汇”为每个文档生成一个稀疏特征向量。我建议你以一种有效的方式来表示这些,例如,作为一个从单词映射到计数的 Python 字典。

  • 对于每个折叠:

    • 分成训练集和验证集。

    • 生成一个子集词汇表,仅包含训练集中的单词。可能有一个小集合小号超集词汇表中的单词而不是子集词汇表中的单词,因此我建议存储该集合小号.

    • 对于训练集和验证集中的每个文档,只使用子集词汇为文档生成一个派生的特征向量。我建议从超集词汇的特征向量开始生成它,然后删除小号. 这应该比从头开始重新生成特征向量更有效。

    • 现在训练和验证这些派生的特征向量。

这相当于“概念上理想”的方法,但会运行得更快。

也就是说,我认为你的建议是务实的,在实践中应该会产生相同的结果,而且速度会更快。