我想通过R使用H2O来构建一个大型数据集(~10GB)的多个模型子集。这个数据集是一年的数据,我尝试着构建51个模型(即在第一周进行训练,在第二周进行预测等),每周有约1.5-2.5百万行和8个变量。
我已经在循环中完成了这个任务,但我知道这不是R中最好的方法之一。另一个问题是H2O实体会累积先前的对象,因此我创建了一个函数来删除除主数据集以外的所有对象。
脚本运行一段时间后就会崩溃,经常会出现内存不足并开始交换到磁盘的错误。以下是伪代码描述该过程。
我的问题是,在一个独立实体(这不是在hadoop或群集上运行-只是一个大型EC2实例(~ 64gb RAM + 12个CPU))中管理数据和内存的正确方法是什么? 在每次循环后杀死并重新创建H2O实体(这是原始流程,但每次从文件读取数据需要增加约10分钟的迭代时间)? 是否有适当的方式在每次循环后进行垃圾回收或释放内存?如有建议,请告知。
我已经在循环中完成了这个任务,但我知道这不是R中最好的方法之一。另一个问题是H2O实体会累积先前的对象,因此我创建了一个函数来删除除主数据集以外的所有对象。
h2o.clean <- function(clust = localH2O, verbose = TRUE, vte = c()){
# Find all objects on server
keysToKill <- h2o.ls(clust)$Key
# Remove items to be excluded, if any
keysToKill <- setdiff(keysToKill, vte)
# Loop thru and remove items to be removed
for(i in keysToKill){
h2o.rm(object = clust, keys = i)
if(verbose == TRUE){
print(i);flush.console()
}
}
# Print remaining objects in cluster.
h2o.ls(clust)
}
脚本运行一段时间后就会崩溃,经常会出现内存不足并开始交换到磁盘的错误。以下是伪代码描述该过程。
# load h2o library
library(h2o)
# create h2o entity
localH2O = h2o.init(nthreads = 4, max_mem_size = "6g")
# load data
dat1.hex = h2o.importFile(localH2O, inFile, key = "dat1.hex")
# Start loop
for(i in 1:51){
# create test/train hex objects
train1.hex <- dat1.hex[dat1.hex$week_num == i,]
test1.hex <- dat1.hex[dat1.hex$week_num == i + 1,]
# train gbm
dat1.gbm <- h2o.gbm(y = 'click_target2', x = xVars, data = train1.hex
, nfolds = 3
, importance = T
, distribution = 'bernoulli'
, n.trees = 100
, interaction.depth = 10,
, shrinkage = 0.01
)
# calculate out of sample performance
test2.hex <- cbind.H2OParsedData(test1.hex,h2o.predict(dat1.gbm, test1.hex))
colnames(test2.hex) <- names(head(test2.hex))
gbmAuc <- h2o.performance(test2.hex$X1, test2.hex$click_target2)@model$auc
# clean h2o entity
h2o.clean(clust = localH2O, verbose = F, vte = c('dat1.hex'))
} # end loop
我的问题是,在一个独立实体(这不是在hadoop或群集上运行-只是一个大型EC2实例(~ 64gb RAM + 12个CPU))中管理数据和内存的正确方法是什么? 在每次循环后杀死并重新创建H2O实体(这是原始流程,但每次从文件读取数据需要增加约10分钟的迭代时间)? 是否有适当的方式在每次循环后进行垃圾回收或释放内存?如有建议,请告知。
h2o.rm(localH2O, "keyDataWhichIWantDelete")
- Fedorenko Kristina