为什么在R中使用h2o.randomForest比randomForest包能够做出更好的预测?

3
setwd("D:/Santander")

## import train dataset
train<-read.csv("train.csv",header=T)


dim(train)

summary(train)

str(train)

prop.table(table(train2$TARGET))

stats<-function(x){
  length<-length(x)
  nmiss<-sum(is.na(x))
  y<-x[!is.na(x)]
  freq<-as.data.frame(table(y))
  max_freq<-max(freq[,2])/length
  min<-min(y)
  median<-median(y)
  max<-max(y)
  mean<-mean(y)
  freq<-length(unique(y))
  return(c(nmiss=nmiss,min=min,median=median,mean=mean,max=max,freq=freq,max_freq=max_freq))
}


var_stats<-sapply(train,stats)

var_stats_1<-t(var_stats)

###将最大频数类别比例超过0.9999,其它类别小于1/10000的变量全删除

exclude_var<-rownames(var_stats_1)[var_stats_1[,7]>0.9999]

train2<-train[,! colnames(train) %in% c(exclude_var,"ID")]




rm(list=setdiff(ls(),"train2"))

train2<-train2[1:10000,]

write.csv(train2,"example data.csv",row.names = F)

##随机将数据分为训练集与测试集
set.seed(1)
ind<-sample(c(1,2),size=nrow(train2),replace=T,prob=c(0.8,0.2))

train2$TARGET<-factor(train2$TARGET)
train_set<-train2[ind==1,]
test_set<-train2[ind==2,]

rm(train2)
##1\用R randomForest构建预测模型 100棵树
library(randomForest)

memory.limit(4000)

random<-randomForest(TARGET~.,data=train_set,ntree=50)

print(random)

random.importance<-importance(random)

p_train<-predict(random,train_set,type="prob")

pred.auc<-prediction(p_train[,2],train_set$TARGET)

performance(pred.auc,"auc")

##train_set auc=0.8177


## predict test_set
p_test<-predict(random,newdata = test_set,type="prob")

pred.auc<-prediction(p_test[,2],test_set$TARGET)
performance(pred.auc,"auc")

##test_set auc=0.60


#________________________________________________#

##_________h2o.randomForest_______________

library(h2o)
h2o.init()

train.h2o<-as.h2o(train_set)
test.h2o<-as.h2o(test_set)

random.h2o<-h2o.randomForest(,"TARGET",training_frame = train.h2o,ntrees=50)


importance.h2o<-h2o.varimp(random.h2o)

p_train.h2o<-as.data.frame(h2o.predict(random.h2o,train.h2o))

pred.auc<-prediction(p_train.h2o$p1,train_set$TARGET)

performance(pred.auc,"auc")

##auc=0.9388, bigger than previous one

###test_set prediction

p_test.h2o<-as.data.frame(h2o.predict(random.h2o,test.h2o))

pred.auc<-prediction(p_test.h2o$p1,test_set$TARGET)

performance(pred.auc,"auc")

###auc=0.775

我尝试使用Kaggle竞赛:Santander客户满意度来进行预测:https://www.kaggle.com/c/santander-customer-satisfaction 当我在R中使用randomForest包时,在测试数据的AUC=0.57的时候得到了最终结果,但是当我使用h2o.randomForest时,在测试数据中获得了AUC=0.81的最终结果。两个函数中的参数都相同,我只使用了默认参数,ntree=100。 那么为什么h2o.randomForest比randomForest包本身能做出更好的预测呢?


不同的算法,还是相同算法的不同(超)参数化?例如,在大小方面,R和H2O RF模型如何进行比较 - H2O RF模型对象可能包含三倍于R RF模型的节点数。 - user1808924
1个回答

6
首先,正如用户1808924所指出的那样,算法及其默认超参数存在差异。例如,R的randomForest基于Gini准则进行分裂,而H2O树基于减少平方误差进行分裂(即使是用于分类)。H2O还使用直方图进行分割,并且可以处理分类变量的分割,无需虚拟编码(或独热编码)(尽管我认为这在Santander数据集完全是数字的情况下并不重要)。有关H2O分割的其他信息可以在此处找到(这在GBM部分中,但两种算法的分割方式相同)。
如果您查看R randomForest模型的预测结果,您会发现它们都是以0.02的增量递增的。 R的randomForest构建非常深的树,导致叶节点纯净。这意味着每棵树中观察值的预测结果要么是0,要么是1,而且由于您设置了ntrees=50,因此所有预测结果都以0.02的增量递增。您获得糟糕的AUC分数的原因是,在AUC中,预测结果的顺序很重要,而由于您的所有预测结果都是[0.00、0.02、0.04...],所以有很多平局。H2O的随机森林中的树不像R的那么深,因此不太纯净,可以进行更细粒度的预测,并且可以更好地排序以获得更好的AUC分数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接