TfidfVectorizer:应该仅用于火车还是火车+测试

机器算法验证 Python 火车 scikit-学习
2022-03-02 08:24:05

在训练模型时,可以仅在训练集或测试集的语料库上训练 Tfidf。

在训练模型时包含测试语料库似乎没有意义,尽管由于它没有监督,也可以在整个语料库上进行训练。

做什么比较好?

4个回答

使用已使用整个语料库(训练和测试子集相结合)计算的 TF-IDF 向量,同时训练模型可能会引入一些数据泄漏,因此会产生过于乐观的性能指标。这是因为训练集的 TF-IDF 特征的 IDF 部分将包含来自测试集的信息。

为训练集和测试集完全分开计算它们也不是一个好主意,因为除了测试模型的质量之外,您还将测试 IDF 估计的质量。而且由于测试集通常很小,这将是一个糟糕的估计,并且会恶化您的性能指标。

因此,我建议(类似于缺失值的常见平均插补)分别对训练集执行 TF-IDF 归一化,然后使用训练集中的 IDF 向量来计算测试集的 TF-IDF 向量。

通常,正如该站点的名称所暗示的那样,您希望将训练、交叉验证和测试数据集分开。正如@Alexey Grigorev 所提到的,主要关注的是确定您的模型可以推广到一些看不见的数据集。

以更直观的方式,您希望您的模型能够掌握每一行的特征与每一行的预测之间的关系,并稍后将其应用于不同的、看不见的 1 行或更多行。

这些关系是在行级别的,但它们是通过查看整个训练数据来深入学习的。那么,泛化的挑战是确保模型掌握一个公式,而不是依赖于(过度拟合)特定的训练值集。

因此,关于您如何考虑您的语料库,我将区分两种 TFIDF 场景

1.语料在行级别

我们有 1 个或多个要 TFIDF 的文本特征,以便识别该行的一些词频。通常它是一个大文本字段,“本身”很重要,就像在房屋销售数据集中描述房屋购买合同的附加文档。在这种情况下,文本特征应该像所有其他特征一样在行级别进行处理。

2.语料在数据集层面

除了具有行上下文之外,每一行的文本特征在整个数据集的上下文中有意义。通常是较小的文本字段(如句子)。这里的 TFIDF 想法可能是计算单词的一些“稀有度”,但在更大的上下文中。更大的上下文可能是来自训练甚至测试数据集的整个文本列,因为我们拥有的语料库知识越多 - 我们就越能确定稀有性。我什至会说你可以使用来自看不见的数据集的文本,甚至是外部语料库。此处的 TFIDF 可帮助您从外部(更大的,类似查找表的)知识进行行级别的特征工程

看看HashingVectorizer,一个“无状态”矢量化器,适用于可变语料库

增量方法对泄漏具有鲁棒性。

用例:针对大型语料库训练文档分类模型并在一组新文档上进行测试。

在训练时:在训练数据上计算 TF-IDF 并用作分类模型的特征。

在测试时间:向语料库添加新文档并在整个语料库上重新计算 TF-IDF。使用新文档的 TF-IDF 值作为评分模型的输入。

如果正在测试/评分的文档数量很少,为了加快流程,您可能希望仅重新计算 TF 并使用现有的 IDF 数字,因为它们不会受到少量文档的太大影响。

现场使用:与测试相同。即该方法对于现场使用来说是健壮的并且不会泄漏。

理想情况下,它应该适合整个语料库,以便学习词汇并为每个语料打分。

语料库 = 围绕某个实体或整个语料库的分组数据。训练 = 从某个实体或整个语料库拆分训练数据。测试 = 从某个实体或整个语料库拆分测试数据。

vec = TfidfVectorizer() vec.fit(语料库) trainx = tf.transform(train) testx = tf.transform(test)