class 失衡的 H2O 深度学习

H2O deeplearning with class imbalance

我正在使用 H2O 深度学习前馈深度神经网络进行二进制 class化。我的 classes 非常不平衡,我想使用像

这样的参数

balance_classes, class_sampling_factors

任何人都可以给我一个关于如何专门初始化这些参数以处理 class 不平衡问题的可重现示例。

首先,这是完整的、可重现的示例:

library(h2o)
h2o.init()

data(iris)  #Not required?
iris <- iris[1:120,] #Remove 60% of virginica
summary(iris$Species) #50/50/20

d <- as.h2o(iris)
splits = h2o.splitFrame(d,0.8,c("train","test"), seed=77)
train = splits[[1]]
test = splits[[2]]
summary(train$Species)  #41/41/14
summary(test$Species)  #9/9/6

m1 = h2o.randomForest(1:4, 5, train, model_id ="RF_defaults", seed=1)
h2o.confusionMatrix(m1)

m2 = h2o.randomForest(1:4, 5, train, model_id ="RF_balanced", seed=1,
  balance_classes = TRUE)
h2o.confusionMatrix(m2)

m3 = h2o.randomForest(1:4, 5, train, model_id ="RF_balanced", seed=1,
  balance_classes = TRUE,
  class_sampling_factors = c(1, 1, 2.5)
  )
h2o.confusionMatrix(m3)

第一行初始化 H2O,然后我故意修改 iris 数据集以丢弃 3 个 classes 中的 60%,以造成不平衡。

接下来的几行将该数据加载到 H2O 中,并创建 80%/20% train/test 数据拆分。种子是有意选择的,因此在训练数据中 virginica 占数据的 14.58%,而原始数据中为 16.67%,测试数据中为 25%。

然后我训练了三个随机森林模型。 m1都是默认的,它的混淆矩阵是这样的:

           setosa versicolor virginica  Error     Rate
setosa         41          0         0 0.0000 = 0 / 41
versicolor      0         39         2 0.0488 = 2 / 41
virginica       0          1        13 0.0714 = 1 / 14
Totals         41         40        15 0.0312 = 3 / 96

这里没什么可看的:它使用它找到的数据。

现在这里是 m2 的相同输出,它打开 balance_classes。您可以看到它对 virginica class 进行了过度采样,以使它们尽可能平衡。 (最右边的列显示 41、41、40,而不是之前输出中的 41、41、14。)

           setosa versicolor virginica  Error      Rate
setosa         41          0         0 0.0000 =  0 / 41
versicolor      0         41         0 0.0000 =  0 / 41
virginica       0          2        38 0.0500 =  2 / 40
Totals         41         43        38 0.0164 = 2 / 122

m3中我们仍然开启balance_classes,但也告诉它真相。 IE。实际数据是 16.67% virginica,而不是它在 train 数据中看到的 14.58%。 m3 的混淆矩阵表明它因此将 14 个 virginica 个样本变成了 37 个样本而不是 40 个样本。

           setosa versicolor virginica  Error      Rate
setosa         41          0         0 0.0000 =  0 / 41
versicolor      0         41         0 0.0000 =  0 / 41
virginica       0          2        35 0.0541 =  2 / 37
Totals         41         43        35 0.0168 = 2 / 119

我怎么知道要写 c(1, 1, 2.5),而不是 c(2.5, 1, 1)c(1, 2.5, 1)?文档说它必须在 "lexicographic order" 中。你可以找出那个订单是什么:

h2o.levels(train$Species)

这告诉我:

[1] "setosa"     "versicolor" "virginica"

意见位:balance_classes 很好打开,但 class_sampling_factors 仅当您有充分理由相信您的训练数据不具有代表性时才应使用。

注意:代码和解释改编自我即将出版的书《使用 H2O 进行实用机器学习》。