R中的Bootstrap采样大数据(太大而无法容纳在RAM中)

时间:2014-08-07 01:45:12

标签: r bigdata sampling

是否可以从.Rdata对象或存储在磁盘上的任何其他大型数据对象中绘制引导样本?我目前从非常大的数据中采样的方法是构建一个本地MySQL数据库,然后使用SQL将随机样本绘制到R中。不幸的是,MySQL中的采样和排序根本没有效率。我想知道是否有人为此用例设计了更好的解决方案。

要了解我当前的解决方案,请参阅MySQL中的采样问题: Simple Random Samples from a Sql database

1 个答案:

答案 0 :(得分:5)

一般性评论

您不必将所有数据加载到样本,只需加载行的ID,并从ids中加样。然后仅加载采样行的数据。更详细:

  1. E.g。如果数据库中有一个名为ID的列,则只加载此列。这应该很快,特别是如果ID是一个整数。即使你有(比方说)20亿条记录,你只需要8GB内存来存储20亿个整数,所以这应该是可能的。

  2. 然后从这些ID中采样。

  3. 然后仅加载带有采样ID的记录。

  4. 想一想。如果你想从在线书店Siren购买三本随机书籍,你会怎么做? Siren有数百万本书,你不能订购它们,然后在它们之间随机选择,然后发回其余的,对吧?所以你要做的是,你向Siren索取书籍ID列表(ISBN会这样做),这个大小适合于适度的计算机。您可以从列表中随机选择三个,并从Siren中订购这三个。

    Rdata文件

    这显然不适用于.Rdata文件,但.Rdata文件无论如何都是无望的,因为你无法加载一段.Rdata文件。所以你需要一些索引的格式。

    源码

    但是你可以使用sqlite和RSQLite包。 RSQLite支持与数据帧绑定,因此要加载采样数据,只需将采样的id放入名为samp_ids的数据框(名为id的单列)中,然后再说

    之类的东西
    ...
    my_samp <- dbGetQuery(con, "SELECT * FROM mytable WHERE id = :id", 
                          bind.data = samp_ids)
    ...
    

    这将读取带有采样ID的记录。

    的MySQL

    上次我检查RMySQL时不支持绑定,所以这可能不是可行的方法。如果你坚持使用MySQL,那么我要尝试的第一件事是创建一个临时表,其中只包含采样的行ID,然后将这个表与数据表一起加入。这由RMySQL支持,它的工作方式如下:

    dbSendQuery(con, "CREATE TEMPORARY TABLE tmp (id INTEGER);")
    
    ## Stupid, but this seems to be necessary to really create the
    ## temporary table, it is an RMySQL bug that I reported long time
    ## ago: https://github.com/jeffreyhorner/RMySQL/issues/10
    try(dbSendQuery(con, "CREATE TEMPORARY TABLE tmp (id INTEGER);"))
    
    dbWriteTable(con, "tmp", samp_ids, row.names=FALSE, append=TRUE)
    

    然后,您可以编写SELECT以加入临时表tmp和原始数据表。