【问题标题】:Does rsample::bootstraps store data rather than just row indices?rsample::bootstraps 是否存储数据而不仅仅是行索引?
【发布时间】:2021-05-18 19:23:34
【问题描述】:

我试图理解为什么rsample::bootstraps 函数显然存储了每个引导样本的整个数据集。我期待该函数只存储一次数据集,以及每个重新采样的引导索引。在下面您可以看到基本结构,每个重采样都会重复该结构:

> set.seed(1)
> test <- rsample::bootstraps(mtcars[, 1:3], times = 2)
> str(test)
bootstraps [2 × 2] (S3: bootstraps/rset/tbl_df/tbl/data.frame)
 $ splits:List of 2
  ..$ :List of 4
  .. ..$ data  :'data.frame':   32 obs. of  3 variables:
  .. .. ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
  .. .. ..$ cyl : num [1:32] 6 6 4 6 8 6 8 4 4 6 ...
  .. .. ..$ disp: num [1:32] 160 160 108 258 360 ...
  .. ..$ in_id : int [1:32] 25 4 7 1 2 29 23 11 14 18 ...
  .. ..$ out_id: logi NA
  .. ..$ id    : tibble [1 × 1] (S3: tbl_df/tbl/data.frame)
  .. .. ..$ id: chr "Bootstrap1"
  .. ..- attr(*, "class")= chr [1:2] "rsplit" "boot_split"
  ..$ :List of 4
  .. ..$ data  :'data.frame':   32 obs. of  3 variables:
  .. .. ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
  .. .. ..$ cyl : num [1:32] 6 6 4 6 8 6 8 4 4 6 ...
  .. .. ..$ disp: num [1:32] 160 160 108 258 360 ...
  .. ..$ in_id : int [1:32] 25 12 15 1 20 3 6 10 10 6 ...
  .. ..$ out_id: logi NA
  .. ..$ id    : tibble [1 × 1] (S3: tbl_df/tbl/data.frame)
  .. .. ..$ id: chr "Bootstrap2"
  .. ..- attr(*, "class")= chr [1:2] "rsplit" "boot_split"
 $ id    : chr [1:2] "Bootstrap1" "Bootstrap2"
 - attr(*, "times")= num 2
 - attr(*, "apparent")= logi FALSE
 - attr(*, "strata")= logi FALSEbootstraps [1 × 2] (S3: 

$data 项目似乎重复进行了额外的重采样,并且变化的重采样索引存储在 in_id 中。明显的代价是对象的大小与数据大小乘以重采样数成正比增长。 object.size(test) 的单个重采样大小为 7800 字节。对于 200 次重采样,它是 1236824 字节。

【问题讨论】:

    标签: r tidymodels rsample


    【解决方案1】:

    数据不是每次重采样都重复;你可以see an example of this in the README for the rsample package。不修改原始数据; R 不会复制。

    每次重采样都会有一些 RAM 开销,而 mtcars 有点小以至于能够很好地理解这一点,所以让我们看一个更大的数据集,例如 Ames 住房数据集(看看另一个示例的自述文件):

    library(rsample)
    library(lobstr)
    data(ames, package = "modeldata")
    
    obj_size(ames)
    #> 1,042,736 B
    
    set.seed(123)
    boots <- bootstraps(ames, times = 50)
    obj_size(boots)
    #> 1,670,760 B
    
    ## what is the object size per resample?
    obj_size(boots)/nrow(boots)
    #> 33,415.2 B
    
    ## what is the relative size of the bootstrap object compared to the original?
    as.numeric(obj_size(boots)/obj_size(ames))
    #> [1] 1.602285
    

    reprex package (v1.0.0) 于 2021 年 2 月 17 日创建

    远远少于 50! bootstrap 对象的内存比原始数据集大不到 50 倍。

    请注意,我使用lobstr 来比较大小,而不是object.size()。原因是因为object.size()does not entirely include the size of all environments in objects and is less accurate overall。如果您曾经尝试使用object.size() 测量 R 中对象的 RAM,并且对为什么它与您的操作系统所说的不匹配而感到困惑,这可能就是原因。使用lobstr::obj_size()可以解决这个问题。

    【讨论】:

    • 非常有帮助,谢谢。我刚刚在我的真实用例中验证了object.size 确实显示出比例增加。使用 1000 个引导程序,一个 18kb 的对象会增长到超过 17mb,但使用 obj_size 只会增长到 1mb。为什么str(boots)显示 对象是重复的?看起来好像它在每个重新采样中,这显然没有意义。而为什么object.size的“误测”是这样的? strobject.size 之间的一致性是我发布的原因。
    • 存储在 rsample 对象中的是对原始数据的引用,而不是整个数据,不幸的是,object.size() 不够聪明,无法正确测量。它does the same thing for ALTREP objects。当您调用 str() 时,它会获取参考中的实际内容,而不是参考。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2014-02-02
    • 1970-01-01
    • 2021-07-26
    • 2011-05-10
    • 2017-05-28
    相关资源
    最近更新 更多