我有4个类的数据,我正在尝试构建一个分类器 . 我有一个类的〜1000个向量,另一个有~10 ^ 4,第三个为~10 ^ 5,第四个为~10 ^ 6 . 我希望使用交叉验证,所以我看了scikit-learn docs .
我的第一次尝试是使用StratifiedShuffleSplit但是这给了每个类相同的百分比,使得类仍然严重失衡 .
有没有办法进行交叉验证,但培训和测试集中的课程是否 balancer ?
作为旁注,我无法解决StratifiedShuffleSplit和StratifiedKFold之间的区别 . 描述与我非常相似 .
2 回答
我觉得你会混淆分层策略会做什么,但你需要显示你的代码和结果,以确定发生了什么(与原始集合中的百分比相同的百分比,或相同返回的火车/测试集中的百分比?第一个是它应该如何) .
其中一个绝对应该工作 . 对第一个的描述肯定有点令人困惑,但这就是他们所做的 .
StratifiedShuffleSplit
这意味着它将您的数据拆分为火车和测试集 . 分层部分意味着 percentages will be maintained in this split . 因此,如果您的数据的
10%
在类1中,90%
在类2中, this will ensure that 10% of your train set will be in class 1 and 90% will be in class 2 . 对于测试集也是如此 .你的帖子听起来好像你想要测试集中每个类的
50%
. 那不是给你自己一个关于你的分类器性能的无关的想法:谁在乎它如何分类50/50
分裂,在实践中你会看到10/90
分裂?StratifiedKFold
见k-fold cross validation . 如果没有分层,它只会将您的数据拆分为
k
折叠 . 然后,每个折叠1 <= i <= k
用作测试集一次,而其他折叠用于训练 . 结果平均到最后 . 它类似于运行ShuffleSplit
k
次 .分层将确保整个数据中每个类别的百分比在每个单独的折叠中相同(或非常接近) .
有很多文献涉及不 balancer 的阶级 . 一些简单易用的方法涉及使用类权重和分析ROC曲线 . 我建议以下资源为此起点:
A scikit-learn example of using class weights .
A quora question about implementing neural networks for imbalanced data .
This stats.stackexchange question with more in-depth answers .
K-Fold CV
K-Fold CV通过将数据随机分区为
k
(相当)相等的分区来工作 . 如果您的数据在[0,1,0,1,0,1,0,1,0,1]
等类之间均衡 balancer ,则随机抽样(或不进行替换)将为您提供大约等于0
和1
的样本大小 .但是,如果您的数据更像是
[0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0]
,其中一个类表示数据,那么没有加权采样的k-fold cv会给您带来错误的结果 .如果你使用普通的k-fold CV,而不是从均匀采样中调整采样权重,那么你就可以获得类似的东西
哪里有明显的分裂,没有两个类的有用表示 .
k倍CV的点是在所有数据子集上训练/测试模型,而在每次试验中留下1个子集并训练k-1个子集 .
在这种情况下,您希望使用split by strata . 在上面的数据集中,有27个
0s
和5个1s
. 如果你将1
的分层划分为5个子集是合理的 . 一个更好的解决方案是将其分成k <5个子集,例如2.由于's much larger. Then while training, you'从数据集中具有2 x 5
的简单乘积,因此0s
的层可以保持k = 5个分裂 . 这是一些代码来说明此方法可以完成将数据拆分为分区,其中最终省略所有分区以进行测试 . 应该注意的是,并非所有统计学习方法都允许加权,因此调整CV等方法至关重要抽样比例 .