使用H2O深度学习处理类别不平衡

我正在使用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》。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注