也许您可以这样想。假设您有一个数据集,其中有100个样本,“ A”类为90个,“ B”类为10个。在这种非常不平衡的设计中,如果您进行正常的随机分组,则最终可能会使用“ B”类中的极少数(甚至没有!)来构建模型。如果您要建立一个训练有素的模型,而该模型的数据很少,甚至没有,那么您如何期望它有效地预测稀有群体呢?分层交叉验证可实现随机化,但也可确保这些不平衡数据集同时具有这两个类别。
为了消除对将分层CV与更多“平衡”数据集一起使用的担忧,让我们看一个使用R代码的示例。
require(mlbench)
require(caret)
require(cvTools)
# using the Sonar dataset (208 samples)
data(Sonar)
# see the distribution of classes are very well balanced
prop.table(table(Sonar$Class))
> prop.table(table(Sonar$Class))
M R
0.5336538 0.4663462
# stratified
# set seed for consistency
# caret::createFolds does stratified folds by default
set.seed(123)
strat <- createFolds(Sonar$Class, k=10)
# non-stratified using cvTools
set.seed(123)
folds <- cvFolds(nrow(Sonar), K=10, type="random")
df <- data.frame(fold = folds$which, index = folds$subsets)
non_strat <- lapply(split(df, df$fold), FUN=function(x) x$index)
# calculate the average class distribution of the folds
strat_dist <- colMeans(do.call("rbind", lapply(strat, FUN = function(x) prop.table(table(Sonar$Class[x])))))
non_strat_dist <- colMeans(do.call("rbind", lapply(non_strat, FUN = function(x) prop.table(table(Sonar$Class[x])))))
strat_dist
> strat_dist
M R
0.5338312 0.4661688
non_strat_dist
> non_strat_dist
M R
0.5328571 0.4671429
如您所见,在平衡良好的数据集中,褶皱的随机机会具有相似的分布。因此,在这种情况下,分层简历只是一种保证措施。但是,要解决差异,您需要查看每个折的分布。在某些情况下(甚至从50-50开始),您可能会遇到随机折叠30-70的折叠(您可以运行上面的代码,看看这实际上是怎么回事!)。这可能会导致性能更差的模型,因为它没有足够的一类准确地预测它,从而增加了总体CV方差。当您拥有“有限”样本时,分布更有极端的差异,这显然更为重要。
现在有了非常大的数据集,分层可能就没有必要了,因为褶皱足够大,以至于仍可能包含至少一部分“稀有”类。但是,如果您的样本不平衡,无论您个人拥有多少数据,实际上都不会造成计算上的损失,也没有真正的理由放弃分层。