我试图将数据集的实例分类为两个类之一,a或b。b是少数类,仅占数据集的8%。为所有实例分配一个id,指示哪个主题生成了数据。因为每个主题生成的多个实例id在数据集中频繁重复。
下面的表只是一个例子,真实的表大约有100,000个实例。每个主题id在表中大约有100个实例。正如你在下面看到的"larry"一样,每个科目都只与一个类联系在一起。
* field * field * id * class
*******************************************
0 * _ * _ * bob * a
1 * _ * _ * susan * a
2 * _ * _ * susan * a
3 * _ * _ * bob * a
4 * _ * _ * larry * b
5 * _ * _ * greg * a
6 * _ * _ * larry * b
7 * _ * _ * bob * a
8 * _ * _ * susan * a
9 * _ * _ * susan * a
10 * _ * _ * bob * a
11 * _ * _ * greg * a
... ... ... ... ...
我想使用交叉验证来调整模型,并且必须对数据集进行分层,以便每个折叠包含少数类b的几个示例。问题是我有第二个约束,相同的id必须永远不会出现在两个不同的折叠中,因为这会泄露有关主题的信息。
我使用python的scikit-learn库。我需要一个结合了LabelKFold的方法,它确保标签(id)不会在折叠之间分裂,以及StratifiedKFold,它确保每个折叠都有相似的类比例。如何使用scikit-learn完成上述任务?如果在sklearn中不可能拆分两个约束,我如何通过手动或使用其他python库有效地拆分数据集?
下面的内容在索引方面有点棘手(如果使用像Pandas这样的东西会有所帮助),但概念上很简单。
假设您创建了一个虚拟数据集,其中自变量只有id
和class
。此外,在此数据集中,删除重复的id
条目。
对于交叉验证,在虚拟数据集上运行分层交叉验证。每次迭代:
-
找出哪些
id
s被选作列车和试验 -
返回到原始数据集,根据需要将所有属于
id
的实例插入到训练集和测试集中。
之所以有效是因为:
-
如您所述,每个
id
与单个标签相关联。 -
由于我们运行分层CV,每个类别都按比例表示。
-
由于每个
id
只出现在训练集或测试集中(但不是同时出现),因此也标记了它。