r-从sqlite将非常大的数据集导入到h2o中



我有一个大约500G的数据库。它由16个表组成,每个表包含2或3列(第一列可以丢弃(和1375328760行。我需要在h2o中将所有表连接为一个数据帧,因为它们是在XGB模型中运行预测所必需的。我曾尝试使用as.h2o将单个sql表转换到h2o环境中,并将它们一次绑定2或3个表,直到它们成为一个数据集。然而,在转换了4个表后,我得到了"超过GC开销限制:java.lang.OutOfMemoryError"。有办法绕过这个吗?我的机器规格是124G RAM、OS(Rhel 7.8(、Root(1tb(、Home(600G(和2TB外部硬盘。该模型在本地机器上运行,最大_mem_size设置为100G。代码的详细信息如下。

library(data.table)
library(h2o)          
h2o.init(
nthreads=14,          
max_mem_size = "100G")    
h2o.removeAll() 
setwd("/home/stan/Documents/LUR/era_aq")
l1.hex <- as.h2o(d2)
l2.hex <- as.h2o(lai)
test_l1.hex <-h2o.cbind(l1.hex,l2.hex[,-1])
h2o.rm (l1.hex,l2.hex)
l3.hex <- as.h2o(lu100)
l4.hex <- as.h2o(lu1000)
test_l2.hex <-h2o.cbind(l3.hex,l4.hex[,-1])
h2o.rm(l3.hex,l4.hex)
l5.hex <- as.h2o(lu1250)
l6.hex <- as.h2o(lu250)
test_l3.hex <-h2o.cbind(l5.hex,l6.hex[,-1])
h2o.rm(l5.hex,l6.hex)
l7.hex <- as.h2o(pbl)
l8.hex <- as.h2o(msl)
test_l4.hex <-h2o.cbind(l7.hex,l8.hex[,-1])
h2o.rm(ll7.hex,l8.hex)
test.hex <-h2o.cbind(test_l1.hex,test_l2.hex[,-1],test_l3.hex[,-1],test_l4.hex[,-1])
test <- test.hex[,-1]
test[1:3,]```

首先,正如Tom在评论中所说,你需要一艘更大的船。H2O将所有数据保存在内存中,通常你需要3到4倍的数据大小才能用它做任何有用的事情。500GB的数据集意味着你需要集群的总内存为1.5-2TB。

(H2O存储压缩后的数据,我认为sqlite不会,在这种情况下,您可能只需要1TB就可以了。(

其次,as.h2o()是一种加载大数据集的低效方法。将要发生的是,您的数据集加载到R的内存空间中,然后将其保存到csv文件中,然后该csv文件通过TCP/IP流式传输到H2O进程。

因此,更好的方法是直接从sqlite导出到csv文件。然后使用h2o.importFile()将csv文件加载到H2O中。

h2o.cbind()还将涉及大量的复制。如果你能在导入之前找到一个工具或脚本来列绑定csv文件,这可能会更有效。快速搜索找到了csvkit,但我不确定它是否需要将文件加载到内存中,或者是否可以完全在磁盘上处理文件。

由于内存非常昂贵,并且所有R都在RAM中运行,因此请避免在全局环境中存储大型助手data.tableh20对象。考虑设置一个函数以生成一个列表进行编译,当函数超出范围时,该列表将删除临时对象。理想情况下,您可以直接从文件源构建h2o对象:

# BUILD LIST OF H20 OBJECTS WITHOUT HELPER COPIES
h2o_list <- lapply(list_of_files, function(f) as.h2o(data.table::fread(f))[-1])
# h2o_list <- lapply(list_of_files, function(f) h2o.importFile(f)[-1])
# CBIND ALL H20 OBJECTS
test.h2o <- do.call(h2o.cbind, h2o_list)

或者甚至将这两行与命名函数结合起来,而不是使用匿名函数。然后,处理后只剩下最后一个对象。

build_h2o <- function(f) as.h2o(data.table::fread(f))[-1])
# build_h2o <- function(f) h2o.importFile(f)[-1]
test.h2o <- do.call(h2o.cbind, lapply(list_of_files, build_h2o))

对于一些需要保留或不保留第一列的数据集,使用if扩展函数。

build_h2o <- function(f) {
if (grepl("lai|lu1000|lu250|msl", f)) { tmp <- fread(f)[-1] }
else { tmp <- fread(f) }
return(as.h2o(tmp))
}

最后,如果可能的话,利用data.table方法,如cbindlist:

final_dt <- cbindlist(lapply(list_of_files, function(f) fread(f)[-1]))
test.h2o <- as.h2o(final_dt)
rm(final_dt)
gc()

相关内容

  • 没有找到相关文章

最新更新