Sta*_*ean 4 python scikit-learn
我正在处理多标签数据,我想使用分层抽样。假设我有 10 个类,我们称它们为“ABCDEFGHIJ”。我有一个包含 10 列的数据框,对应于每个标签,其中包含有关条目的其余信息。我可以在 n_entry*10 矩阵中提取这 10 列,我将其称为 label_values
例如,一行 label_values 看起来像 [0,0,1,1,0,0,0,0,0,0] 并且这个特定的行意味着条目具有标签 C 和标签 D。
我想在训练和验证集中对我的数据进行拆分,并且我希望在训练和验证中每个标签的比例相同。为了执行我的拆分,我使用了 Sklearn train_test_split 函数(在我需要分层之前),它恰好有一个参数分层。目前的行为是将multi_label行为变成multiclass one(我们认为[A,B]是一个全新的类,与A类和B类完全不同)。因此,有些类只有 1 个元素,这会引发错误:
ValueError("The least populated class in y has only 1"
" member, which is too few. The minimum"
" number of groups for any class cannot"
" be less than 2.")
Run Code Online (Sandbox Code Playgroud)
来自 StratifiedShuffleSplit 类的 _iter_indices 的 sklearn/model_selection/_split.py :
if np.min(class_counts) < 2:
raise ValueError("The least populated class in y has only 1"
" member, which is too few. The minimum"
" number of groups for any class cannot"
" be less than 2.")
Run Code Online (Sandbox Code Playgroud)
我的解决方法是覆盖此方法以删除此检查。这有效,并且我在训练和验证之间更好地重新分配了我的标签。但是,我的一个带有 2 个元素的标签完全在训练集中。这是正常的吗?
其他问题:这是进行此操作的好方法,还是您认为有更好的方法在 multi_label 中对 train_test_split 进行分层?
正如您所注意到的,scikit-learn 的train_test_split()分层不会单独考虑标签,而是将其视为“标签集”。这对于多标签数据根本不起作用,因为独特组合的数量随着标签数量呈指数增长。在您的示例中,有 1024 种不同的可能标签组合。您需要至少两倍才能执行双向拆分,即使如此,每次拆分也只能获得每个组合的一个示例。
禁用检查的拆分可能有些有效,因为重复标签集能够分层,但对于唯一标签集,您只是允许 scikit-learn 随机拆分它们,这没有用或无效。
Sechidis、Tsoumakas 和 Vlahavas 于 2011 年提出了一种称为迭代分层的算法,该算法通过分别考虑每个标签来拆分多标签数据集,从具有最少正例的标签开始,并以最好的方式工作。
目前有两种您可以使用的实现:
假设您想要对这些 3-label (L1,L2,L3) 样本进行双向拆分:
L1 L2 L3
--------
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
Run Code Online (Sandbox Code Playgroud)
有 8 个唯一的标签集,但每个标签有 4 个正例。迭代分层不是随机拆分,而是尝试为您提供两个拆分,其中包含来自每个标签的平衡数量的示例。示例拆分可能如下所示:
Split 1
-------
L1 L2 L3
0 0 1
0 1 0
1 0 1
1 1 0
Split 2
-------
L1 L2 L3
0 0 0
0 1 1
1 0 0
1 1 1
Run Code Online (Sandbox Code Playgroud)
请注意,即使每个标签集仍然是唯一的,现在每个标签在分割之间都有一个很好的平衡。
| 归档时间: |
|
| 查看次数: |
2922 次 |
| 最近记录: |