Scikit-Learn 中的分层标记 K 折交叉验证

Stratified Labeled K-Fold Cross-Validation In Scikit-Learn

我正在尝试 class 将数据集的实例确定为两个 class 之一,a 或 b。 B 是少数class,只占数据集的 8%。所有实例都分配有一个 id,指示哪个主题生成了数据。因为每个主题生成的多个实例 id 在数据集中经常重复。

下面的table只是一个例子,真正的table大约有10万个实例。每个主题 ID 在 table 中有大约 100 个实例。正如您在下面的 "larry" 中看到的那样,每个主题都与一个 class 相关联。

    * 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
 ...   ...      ...      ...       ...

我想使用交叉验证来调整模型,并且必须对数据集进行分层,以便每个折叠都包含少数 class 的一些示例,b。问题是我有第二个约束,同一个 id 绝不能出现在两个不同的折叠中,因为这会泄露有关主题的信息。

我正在使用 python 的 scikit-learn 库。我需要一种结合 LabelKFold 和 StratifiedKFold 的方法,LabelKFold 确保标签 (id's) 不会在折叠之间拆分,StratifiedKFold 确保每个折叠都具有相似的 classes 比率。如何使用 scikit-learn 完成上述任务?如果无法在 sklearn 中拆分两个约束,我如何有效地手动或与其他 python 库拆分数据集?

以下内容在索引方面有点棘手(如果您使用 Pandas 之类的东西会有所帮助),但概念上很简单。

假设您制作了一个虚拟数据集,其中自变量仅为 idclass。此外,在此数据集中,删除重复的 id 个条目。

对于交叉验证,运行 对虚拟数据集进行了分层交叉验证。在每次迭代中:

  1. 找出哪些 id 被选择用于训练和测试

  2. 回到原始数据集,根据需要将属于id的所有实例插入到训练集和测试集中。

之所以有效,是因为:

  1. 正如您所说,每个 id 都与一个标签相关联。

  2. 由于我们运行 对 CV 进行了分层,每个 class 都按比例表示。

  3. 由于每个 id 只出现在训练集或测试集中(但不是两者),它也被标记了。