如何将不平衡的数据集拆分和重采样为训练、验证和测试

数据挖掘 Python 分类 scikit-学习 阶级失衡 不平衡学习
2022-02-09 10:54:14

我想了解如何使用二进制目标变量拆分不平衡数据集,其中 87% 的样本为负,13% 的样本为正。现在,我知道在进行任何类型的重新采样以避免信息泄漏之前,您应该始终将数据拆分为训练集和测试集,但是哪种策略可以提供更好的结果 - 随机train_test_split还是StratifiedShuffleSplit普遍的看法是,在数据集不平衡的情况下,后者似乎优于前者。顺便说一句,如何StratifiedShuffleSplit工作?

另外,如何考虑交叉验证集以及如何处理它?

它还应该包含与在训练集上进行的采样相同数量的正样本和负样本吗?

3个回答

Grzegorz 的回答触及了问题的根源 - 如果该模型将用于进行预测的未来数据将具有相同的分布,那么按类 % 分层是有意义的。

我想添加的一件事是我通常使用普通的 train_test_split 函数,并将类标签传递给它的分层参数,如下所示:

train_test_split(X, y, random_state=0, stratify=y, shuffle=True)

这将打乱数据集并匹配 train_test_split 结果中的类的 %s。

这一切都取决于你的目标是什么。例如,如果您部署一个模型,您希望测试数据(例如流数据)将具有相同的 pos/neg 分布,那么对您的拆分进行分层是有意义的。这样一来,您就会偏向于将学习过程更多地标记为负面。另一方面,如果你被告知要给予更多的权重来检测稀疏的正样本,那么你可能想要尝试平均分布。

对于大型数据集,非分层拆分通常是可以的。您必须考虑测试集和训练集之间的平衡存在显着差异的概率是多少。对我来说,数千条记录中的 13% 可能没有问题,但一百条记录中的 13% 可能有问题。

马克的回答解释了分层是如何工作的。StratifiedShuffleSplit 只是通过创建一个生成器来多次拆分它,从而在交叉验证的上下文中更容易做到这一点。您还可以将 random_state 传递给它,以便在迭代的每个折叠中拆分保持一致,这对于超参数调整很重要。查看文档中的示例。