我正在使用H2O深度学习的前馈深度神经网络进行二元分类。我的类别极不平衡,我想使用以下参数:
balance_classes, class_sampling_factors
有谁能提供一个可复现的示例,展示如何具体初始化这些参数来处理类别不平衡问题吗?
回答:
首先,这里是完整的、可复现的示例:
library(h2o)h2o.init()data(iris) #Not required?iris <- iris[1:120,] #Remove 60% of virginicasummary(iris$Species) #50/50/20d <- 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/14summary(test$Species) #9/9/6m1 = 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数据集,丢弃了三个类别之一的60%,以制造类别不平衡的情况。
接下来的几行代码将数据加载到H2O中,并创建了80%/20%的训练/测试数据分割。选择了特定的种子,使得在训练数据中,virginica占比14.58%,而在原始数据中是16.67%,在测试数据中是25%。
然后我训练了三个随机森林模型。m1
使用的是默认设置,其混淆矩阵如下所示:
setosa versicolor virginica Error Ratesetosa 41 0 0 0.0000 = 0 / 41versicolor 0 39 2 0.0488 = 2 / 41virginica 0 1 13 0.0714 = 1 / 14Totals 41 40 15 0.0312 = 3 / 96
这里没有什么特别的:它使用了它找到的数据。
现在是m2
的相同输出,它开启了balance_classes
。你可以看到它对virginica类进行了过采样,以尽可能平衡它们。(最右边的列显示为41,41,40,而不是之前输出的41,41,14。)
setosa versicolor virginica Error Ratesetosa 41 0 0 0.0000 = 0 / 41versicolor 0 41 0 0.0000 = 0 / 41virginica 0 2 38 0.0500 = 2 / 40Totals 41 43 38 0.0164 = 2 / 122
在m3
中,我们仍然开启了balance_classes
,但也告诉了它实际情况。即实际数据中virginica占比16.67%,而不是在train
数据中看到的14.58%。m3
的混淆矩阵显示,它因此将14个virginica样本变成了37个样本,而不是40个样本。
setosa versicolor virginica Error Ratesetosa 41 0 0 0.0000 = 0 / 41versicolor 0 41 0 0.0000 = 0 / 41virginica 0 2 35 0.0541 = 2 / 37Totals 41 43 35 0.0168 = 2 / 119
我是如何知道要写c(1, 1, 2.5)
而不是c(2.5, 1, 1)
或c(1, 2.5, 1)
的?文档说必须按“字典顺序”。你可以用以下命令找出这个顺序:
h2o.levels(train$Species)
它告诉我:
[1] "setosa" "versicolor" "virginica"
我的观点是:开启balance_classes
是个好主意,但class_sampling_factors
只有在你有充分理由相信你的训练数据不具代表性时才应该使用。
注意:代码和解释改编自我即将出版的书《Practical Machine Learning with H2O》。