【问题标题】:H2O randomForest produces surprisingly large POJOsH2O randomForest 产生惊人的大 POJO
【发布时间】:2019-05-09 11:32:48
【问题描述】:

我正在使用基于树的模型,并注意到GBMrandomForest 在训练数据集大小如何影响生成的 POJO 大小方面存在很大差异。

我不认为训练数据集的大小会对模型对象的大小产生很大影响,* 这对于GBM 来说几乎是正确的。

但是,对于randomForest,训练集的行数和导出的 POJO 的大小之间似乎存在线性关系。这个结果:

Size of GBM with m =  1000 and p = 10: 0.15 MB (3281 lines)
Size of GBM with m =  1000 and p = 20: 0.16 MB (3501 lines)
Size of GBM with m = 10000 and p = 10: 0.18 MB (3833 lines)
Size of GBM with m = 10000 and p = 20: 0.19 MB (3899 lines)

Size of RF  with m =  1000 and p = 10:  4.38 MB ( 63908 lines)
Size of RF  with m =  1000 and p = 20:  4.40 MB ( 63606 lines)
Size of RF  with m = 10000 and p = 10: 45.84 MB (637168 lines) <- note 10x increase
Size of RF  with m = 10000 and p = 20: 46.08 MB (635059 lines)    on 10x training rows

是从我的基准脚本中获得的:

library(data.table)
library(h2o)

pojo_path <- getwd() # your folder here

options("h2o.use.data.table"=TRUE)
h2o.init(max_mem_size = '8G')
h2o.no_progress()

m_range <- c(1e3,1e4)  # of rows
p_range <- c(10,20)    # of columns

for(p in p_range){
  for(m in m_range){
    # bunch of random data
    set.seed(1)
    mtrx <- matrix(runif(n=m*p), nrow=m, ncol=p)

    # some really random outcome
    set.seed(2)
    y = rowSums(t( t(mtrx)*runif(n=p) )) + rnorm(n=m,sd=0.1)

    dt   <- data.table( mtrx) 
    dt[, `:=`(y = y, id = .I)]
    setkey(dt,id)

    gbm_nm <- paste0('gbm_m_',m,'_p_',p)
    rf_nm <- paste0('rf_m_',m,'_p_',p)
    dt_h2o <- as.h2o(dt)


    gbm <- h2o.gbm(
             x = paste0('V',1:p),
             y = 'y',
             training_frame = dt_h2o,
             nfolds=10,
             model_id = gbm_nm
           )
    rf <- h2o.randomForest(
             x = paste0('V',1:p),
             y = 'y',
             training_frame = dt_h2o,
             nfolds=10,
             model_id = rf_nm
           )

    pojo_gbm_path <- file.path(pojo_path,h2o.download_pojo(gbm, path=pojo_path ) )
    writeLines(paste0('Size of GBM with m = ', m,
                      ' and p = ',p,': ',
                      round(file.info(pojo_gbm_path
                                      )$size/(2^20),2),
                      ' MB (',length(readLines(pojo_gbm_path)),
                      ' lines)'
                      )
    )
    pojo_rf_path <- file.path(pojo_path,h2o.download_pojo(rf, path=pojo_path))
    writeLines(paste0('Size of RF  with m = ', m,
                      ' and p = ',p,': ',
                      round(file.info(pojo_rf_path
                                      )$size/(2^20),2),
                      ' MB (',length(readLines(pojo_rf_path)),
                      ' lines)'
    )
    )
  }
}

randomForest 对象的大小在我正在使用的数据集上变得异常大。

为什么会这样?这种行为是randomForest 所固有的(所以决定是下采样还是使用其他东西)还是我能做些什么?

[*] 我知道,如果 min_leaf_size 等参数具有约束力,更多的训练数据将允许更多的拆分。但在某一点之后,我们预计这些就足够了,并且对象大小停止增长。

[**] 我使用的是 H2O v 3.20.0.8,R 版本 3.5.1

【问题讨论】:

  • 请不要只是告诉我切换到 MOJO。我现在有一个需要 POJO 的工作流程。
  • 如果您的数据集有 N 行,并且您的随机森林的叶子大小为 X(固定),您希望得到多少叶子?
  • @HongOoi 我猜,最坏的情况是n.trees*2^max_depth,它不依赖于 N,对吧?

标签: r random-forest h2o


【解决方案1】:

尝试使用较小的深度。 DRF 中的默认深度比 GBM 大得多,并且大部分大小增长可能是由于这个原因。

您也可以使用较少数量的树。

切换到 MOJO 可能还会将大小减少大约 10 倍。

【讨论】:

  • 我可以确认,当 RF 设置为 max_depth=5(这是 GBM 的默认值)时,POJO 大小非常接近并且不会随着 N 增加。在默认的 max_depth 值下,GBM每棵树最多有 2^5 片叶子(我想,如果有丢失的数据,加上代理分裂),但 RF 最多有 2^20 或 1 片叶子。
  • 除非您需要 POJO,否则最好切换到 MOJO。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-13
  • 2015-07-25
  • 2017-08-17
  • 2018-04-01
  • 2017-12-19
  • 1970-01-01
  • 2016-12-31
相关资源
最近更新 更多