我有一组包含4个类别的数据,正在尝试构建一个分类器。其中一个类别有大约1000个向量,另一个类别有大约10^4个向量,第三个类别有大约10^5个向量,第四个类别有大约10^6个向量。我希望使用交叉验证,因此查看了scikit-learn文档。
我的第一次尝试是使用StratifiedShuffleSplit,但这会为每个类别分配相同的百分比,导致类别仍然严重不平衡。
有没有一种方法可以进行交叉验证,同时在训练集和测试集中平衡类别?
顺便提一下,我无法区分StratifiedShuffleSplit和StratifiedKFold之间的区别。它们的描述对我来说看起来非常相似。
回答:
我的第一次尝试是使用StratifiedShuffleSplit,但这会为每个类别分配相同的百分比,导致类别仍然严重不平衡。
我感觉你可能对分层策略的作用有些误解,但要确定具体情况,你需要展示你的代码和结果(是与原始数据集中相同的百分比,还是在返回的训练/测试集中相同的百分比?前者才是正确的做法)。
顺便提一下,我无法区分StratifiedShuffleSplit和StratifiedKFold之间的区别。它们的描述对我来说看起来非常相似。
其中一个肯定能解决你的问题。第一个的描述确实有点 confusing,但这是它们的作用。
StratifiedShuffleSplit
提供训练/测试索引以将数据分割成训练和测试集。
这意味着它将你的数据分割成训练集和测试集。分层部分意味着在这种分割中将保持百分比。所以如果你的数据中有10%
属于类别1,90%
属于类别2,这将确保你的训练集中10%
属于类别1,90%
属于类别2。测试集也是如此。
你的帖子听起来像是你希望测试集中每个类别占50%
。这不是分层所做的,分层是保持原始百分比。你应该保持这些百分比,否则你会对分类器的性能产生不相关的看法:谁会在意它在50/50
分割上的表现如何,而在实际中你会看到10/90
的分割?
StratifiedKFold
这种交叉验证对象是KFold的一种变体,它返回分层的折叠。折叠是通过保持每个类别的样本百分比来制作的。
参见k折交叉验证。没有分层,它只是将你的数据分割成k
个折叠。然后,每个折叠1 <= i <= k
被用作一次测试集,而其他折叠用于训练。最后结果会进行平均。这类似于运行ShuffleSplit
k
次。
分层将确保你整个数据中每个类别的百分比在每个单独的折叠中相同(或非常接近)。
有很多文献处理类别不平衡问题。一些简单易用的方法包括使用类别权重和分析ROC曲线。我建议以下资源作为这方面的起点: