我有一个数据集,其中连续响应变量(大约 50%)有很多 0 值。我想了解梯度提升/随机森林如何处理这个问题。我的同事建议做一个包含分类的两部分模型,第一步是预测 0,第二步是做回归。这是必要的吗?
ps 我在 R 中使用 xgboost。
我有一个数据集,其中连续响应变量(大约 50%)有很多 0 值。我想了解梯度提升/随机森林如何处理这个问题。我的同事建议做一个包含分类的两部分模型,第一步是预测 0,第二步是做回归。这是必要的吗?
ps 我在 R 中使用 xgboost。
更新的问题陈述
给定数据:
显示:
解决方案
这是我们的数据。
过程:
执行
名义拟合(员工是否离职)
#library
library(h2o) #gbm
#spin up h2o
h2o.init(nthreads = -1) #use this computer to the max
#import data
mydata <- h2o.importFile("HR_comma_sep.csv")
mydata[,7] <- as.factor(mydata[,7])
#split data
splits <- h2o.splitFrame(mydata,
c(0.8))
train.hex <- h2o.assign(splits[[1]], "train.hex")
valid.hex <- h2o.assign(splits[[2]], "valid.hex")
#stage for gbm
idxx <- 1:10
idxx <- idxx[-c(1,7)]
idxy <- 7
Nn <- 300
Lambda <- 0.1
#fit data
my_fit.gbm <- h2o.gbm(y=idxy,
x=idxx,
training_frame = train.hex,
validation_frame = valid.hex,
model_id = "my_fit.gbm",
ntrees=Nn,
learn_rate = Lambda,
score_each_iteration = TRUE)
h2o.confusionMatrix(my_fit.gbm)
训练/验证的目的是“调入参数”到一个合适的水平,并估计操作的不确定性。当刻度盘设置好后,我们估计了第 1 步的错误是多少,然后我们对整个数据进行训练以进入第二步。在这种情况下,我正在快速移动,所以这里没有完成。我预测用于调整参数的模型。
这是基线射频
my_fit.rf <- h2o.randomForest(y=idxy,
x=idxx,
training_frame = train.hex,
validation_frame = valid.hex,
model_id = "my_fit.rf",
ntrees=150,
score_each_iteration = TRUE)
h2o.confusionMatrix(my_fit.rf)
其混淆矩阵为:
Confusion Matrix (vertical: actual; across: predicted) for max f1 @ threshold = 0.469005852414851:
0 1 Error Rate
0 9008 100 0.010979 =100/9108
1 98 2762 0.034266 =98/2860
Totals 9106 2862 0.016544 =198/11968
将此与来自 GBM 拟合的混淆矩阵进行比较表明,我们有大约 93.6% 的阳性预测值,并且我们处于正确的区域,不会过度拟合。
这是GBM的混淆矩阵:
Confusion Matrix (vertical: actual; across: predicted) for max f1 @ threshold = 0.410323012296247:
0 1 Error Rate
0 9030 87 0.009543 =87/9117
1 103 2723 0.036447 =103/2826
Totals 9133 2810 0.015909 =190/11943
所以让我们预测整个数据的“他们离开了吗”,并用它来建模“satisfaction_level”。
在这里,我们预测和扩充数据
pred_left.hex <- h2o.predict(my_fit.gbm,
newdata = mydata,
destination_frame="pred_left.hex")
mydata2 <- h2o.cbind(mydata, pred_left.hex)
在这里我们对“满意度”进行预测
#stage for second gbm
idxx2 <- 1:13
idxx2 <- idxx2[-c(1,7)]
idxy2 <- 1
Nn <- 300
Lambda <- 0.05
#split data
splits2 <- h2o.splitFrame(mydata2,
c(0.8))
train2.hex <- h2o.assign(splits2[[1]], "train2.hex")
valid2.hex <- h2o.assign(splits2[[2]], "valid2.hex")
#fit data
my_fit2.gbm <- h2o.gbm(y=idxy2,
x=idxx2,
training_frame = train2.hex,
validation_frame = valid2.hex,
model_id = "my_fit2.gbm",
ntrees=Nn,
learn_rate = Lambda,
score_each_iteration = TRUE)
只要它是一个“公平”的模型,变量重要性就会显示它是否有用。
这是“作为总体现实检查的 RF”
my_fit2.rf <- h2o.randomForest(y=idxy2,
x=idxx2,
training_frame = train2.hex,
validation_frame = valid2.hex,
model_id = "my_fit2.rf",
ntrees=150,
score_each_iteration = TRUE)
射频收敛
拟合指标给出大约 0.13
这是GBM结果
现在,我几乎没有在真正的调音方面做任何事情。一个像样的 GBM 通常可以在准确度上胜过 RF 相当多。它也可能过拟合,这是一件坏事,需要一点时间和精力来解决。
我们典型的 13% 误差规模(mae = 平均绝对误差)还不错。它与 RF 一致,但还有一些更有趣的东西。
请注意,“P0”,即留下的概率,是集合中信息量最大的第 2 个值。它比工资、工作时间、事故或以前的审查重要得多。事实上,尽管它是它们的函数,但它比底部 8 个变量的组合更能提供信息。
由此我们可以说,任何声称所有“满意度分数”都是平等的HR,给定这些数据,都是垃圾;我们不应该像他们一样对“最优秀和最有经验的员工过早离职”感到惊讶。只需做一点工作,预测值就应该移到 90 年代后期,即使是在真实数据上也是如此。
这也显示了将类概率作为输入是如何提供大量信息的。
想法:
更新:
还有一个名为“lime”的包,它是关于从随机森林等黑盒模型中解包变量重要性。(参考)