我正在使用h2o进行一些建模,并且已经调整了模型,我现在希望它用于执行大约6bln预测/行的大量预测,每个预测行需要80列数据< / p>
数据集我已经将输入数据集向下分解,因此它大约有500 x 1200万个行块,每个行块都有相关的80列数据。
然而,上传一个1200万乘80列到h2o的data.table
需要相当长的时间,对我来说这样做需要花费相当长的时间...我认为这是因为它正在解析对象在上传之前的第一个。
预测部分比较快......
有没有建议加快这部分的速度?改变核心数量有帮助吗?
以下是问题的可重现的例子......
# Load libraries
library(h2o)
library(data.table)
# start up h2o using all cores...
localH2O = h2o.init(nthreads=-1,max_mem_size="16g")
# create a test input dataset
temp <- CJ(v1=seq(20),
v2=seq(7),
v3=seq(24),
v4=seq(60),
v5=seq(60))
temp <- do.call(cbind,lapply(seq(16),function(y){temp}))
colnames(temp) <- paste0('v',seq(80))
# this is the part that takes a long time!!
system.time(tmp.obj <- as.h2o(localH2O,temp,key='test_input'))
#|======================================================================| 100%
# user system elapsed
#357.355 6.751 391.048
答案 0 :(得分:11)
由于您在本地运行H2O,您希望将该数据保存为文件,然后使用:
h2o.importFile(localH2O, file_path, key='test_intput')
这将让每个线程并行读取它们的文件部分。如果在单独的服务器上运行H2O,则需要将数据复制到服务器可以读取的位置(大多数人不要将服务器设置为从其笔记本电脑上的文件系统读取)。
as.h2o()
将文件串行上传到H2O。使用h2o.importFile()
,H2O服务器找到该文件并并行读取它。
看起来你正在使用H2O的第2版。相同的命令可以在H2Ov3中使用,但是一些参数名称已经改变了一点。新参数名称位于:http://cran.r-project.org/web/packages/h2o/h2o.pdf
答案 1 :(得分:0)
也为此问题苦苦挣扎,我进行了一些测试,发现对于R内存中的对象(即,您已经没有以.csv或.txt格式提供对象的奢望),这是迄今为止最快的方法加载它们(〜21 x)是使用data.table中的fwrite function将csv写入磁盘并使用h2o.importFile读取。
我尝试过的四种方法: 1.)直接使用as.h2o() 2.)使用write.csv()写入磁盘,然后使用h2o.importFile()加载 3.)将数据分成两半,在每半部分上以as.h2o()运行,然后使用h2o.rbind()合并 4.使用fwrite()从data.table写入磁盘,然后使用h2o.importFile()加载
我对大小不同的data.frame进行了测试,结果看起来很清晰。
下面的代码(如果有人对复制感兴趣)。
library(h2o)
library(data.table)
h2o.init()
testdf <-as.data.frame(matrix(nrow=4000000,ncol=100))
testdf[1:1000000,] <-1000 # R won't let me assign the whole thing at once
testdf[1000001:2000000,] <-1000
testdf[2000001:3000000,] <-1000
testdf[3000001:4000000,] <-1000
resultsdf <-as.data.frame(matrix(nrow=20,ncol=5))
names(resultsdf) <-c("subset","method 1 time","method 2 time","method 3 time","method 4 time")
for(i in 1:20){
subdf <- testdf[1:(200000*i),]
resultsdf[i,1] <-100000*i
# 1: use as.h2o()
start <-Sys.time()
as.h2o(subdf)
stop <-Sys.time()
resultsdf[i,2] <-as.numeric(stop)-as.numeric(start)
# 2: use write.csv then h2o.importFile()
start <-Sys.time()
write.csv(subdf,"hundredsandthousands.csv",row.names=FALSE)
h2o.importFile("hundredsandthousands.csv")
stop <-Sys.time()
resultsdf[i,3] <-as.numeric(stop)-as.numeric(start)
# 3: Split dataset in half, load both halves, then merge
start <-Sys.time()
length_subdf <-dim(subdf)[1]
h2o1 <-as.h2o(subdf[1:(length_subdf/2),])
h2o2 <-as.h2o(subdf[(1+length_subdf/2):length_subdf,])
h2o.rbind(h2o1,h2o2)
stop <-Sys.time()
resultsdf[i,4] <- as.numeric(stop)-as.numeric(start)
# 4: use fwrite then h2o.importfile()
start <-Sys.time()
fwrite(subdf,file="hundredsandthousands.csv",row.names=FALSE)
h2o.importFile("hundredsandthousands.csv")
stop <-Sys.time()
resultsdf[i,5] <-as.numeric(stop)-as.numeric(start)
plot(resultsdf[,1],resultsdf[,2],xlim=c(0,4000000),ylim=c(0,900),xlab="rows",ylab="time/s",main="Scaling of different methods of h2o frame loading")
for (i in 1:3){
points(resultsdf[,1],resultsdf[,(i+2)],col=i+1)
}
legendtext <-c("as.h2o","write.csv then h2o.importFile","Split in half, as.h2o and rbind","fwrite then h2o.importFile")
legend("topleft",legend=legendtext,col=c(1,2,3,4),pch=1)
print(resultsdf)
flush.console()
}