おそらくこのように考えることができます。100個のサンプル(クラス 'A'に90個、クラス 'B'に10個)があるデータセットがあるとします。この非常に不均衡な設計では、通常のランダム化グループを実行すると、「B」クラスの非常に少数(またはEVEN NONE!)でモデルを構築することになります。他のクラスが非常に少ない、またはまったくないデータでトレーニングされたモデルを構築している場合、よりまれなグループを効果的に予測するにはどうすればよいでしょうか?階層化された相互検証により、ランダム化が可能になりますが、これらの不均衡なデータセットが両方のクラスの一部を持つことも確認されます。
より「バランスのとれた」データセットで成層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
ご覧のとおり、バランスのとれたデータセットでは、フォールドは偶然に似たような分布になります。したがって、階層化されたCVは、これらの状況における単なる保証手段です。ただし、差異に対処するには、各分割の分布を調べる必要があります。状況によっては(50-50から始まる場合でも)、ランダムに30-70に分割されたフォールドが発生する可能性があります(上記のコードを実行すると、実際に起こっていることがわかります!)。これにより、モデルを正確に予測するのに十分なクラスがないため、全体的なCV分散が増加するため、パフォーマンスが低下する可能性があります。これは明らかに、分布に非常に極端な違いがある可能性が高い「制限された」サンプルがある場合により重要です。
非常に大きなデータセットでは、折り畳みは少なくとも「rarer」クラスのかなりの割合を含む可能性が高いため、階層化は必要ありません。ただし、私の個人的な意見では、データの量に関係なく、サンプルのバランスが取れていない場合、計算上の損失はなく、層別化を無視する本当の理由はありません。