首页 > 解决方案 > 将具有相同主题的多个条目的数据集拆分为具有预定义比例的训练/验证/测试,并且拆分中没有相同的主题

问题描述

我有一个看起来像这样的大型数据集(Pandas DataFrame)(例如,随机数):

特色一 特色二 特色三 主题代码 标签
1 -5.86 0.99 4.39 1 一个
2 0.63 1.26 0.94 1 一个
3 0.97 -0.47 9.22 2 一个
4 4.53 0.46 -1.48 2
5 0.82 4.27 -0.9 2 C
.. .. .. .. .. ..
X 1.68 7.22 5.34 9419 一个

现在,为了机器学习的目的,我想将此数据集分成三组:训练、验证和使用特定样本比例(例如 0.8、0.1、0.1)进行测试。但是,我拥有的数据集具有同一主题的多个数据点(“主题代码”)。我不希望同一主题的条目同时出现在多个拆分(训练/验证/测试)中,以防止偏见。我的问题是:如何做到这一点?有没有办法将数据集分成三组,条件是相同的主题代码只出现在一个组中?我见过的解决方案只允许基于特定比例的“主题代码”进行拆分,但有些主题的数据点比其他主题多得多,这会导致不同的样本比例。

来自 scikit-learn 之类的函数train_test_split似乎不支持将这样的条件添加到拆分中。

非常感谢!

编辑:主题代码和主题标签将在拆分后从数据集中删除。主题代码可以解释为某人的姓名(唯一的人标识符),主题标签是我试图用模型预测的目标变量。

标签: pythonpandasdataframescikit-learn

解决方案


老实说,我认为这不是正确的方法。如果您这样做,您将在仅对主题子集进行测试时对您的模型进行估计。也就是说,您对您的模型如何推广到其他主题几乎没有线索。在我看来,更好的解决方案是切换到不同的验证方法。在这种情况下,LeaveOneGroupOutGroupKFold是有价值的替代方案,具体取决于数据集的大小。前者在除一个以外的所有科目上训练模型,并在其余科目上进行测试,直到所有科目都经过测试。后者将数据拆分为 K 个不重叠的折叠,这样一个主题就永远不会出现在训练和测试集中。然后,它使用 k-1 折进行训练,使用 1 折进行测试,直到测试所有折。无论哪种方式,您将只有训练集和测试集(没有验证集),但最终结果证明您对模型的泛化有更好的概述。

关于科目的比例,这是你必须提前处理的事情。您使用的数据集train_test_split或其他验证方法将不平衡。随机过采样随机欠采样是您可以开始使用的两种技术,尽管存在更高级的技术。

最后,您的(示例)数据集表明,随着时间的推移观察到给定的主题。这使您处于时间序列分析的上下文中。在这种情况下,我建议您使用前向验证。在 walk-forward 中,数据集表示可以划分为可排序部分的时间序列,例如日期时间。这些部分是按时间顺序排列的,并且在每次运行中,将要预测的部分之前的所有可用数据用作训练集,而要预测的部分用作测试集,从而防止测试集具有先于训练的数据-放。之后,模型性能被计算为运行之间的平均值。
迭代次数等于零件数减一。具体来说,您将在第一个n上训练每个模型日期(不管一个主题是否多次出现)并在第(n+1)个日期进行测试。


推荐阅读