r - R 中的 Bigglm : Limitations and Improvements of source code (E. g。调用 Fortran)

标签 r bigdata glm

我最近一直在使用 R 在 100 mb csv 文件(900 万行 x 5 列)上运行广义线性模型 (GLM)。该文件的内容包括 5 列,称为 depvar、var1、var2、var3、var4,并且都是随机分布的,因此这些列包含 0,1 或 2 的数字。基本上我已经使用 biglm 包来运行 GLM该数据文件和 R 在大约 2 分钟内处理了该文件。这是在一台使用 R 版本 2.10(我目前正在更新到 2.14)、4 核和 8 GB RAM 的 Linux 机器上。基本上我想在 30 到 60 秒左右更快地运行代码。一种解决方案是添加更多内核和 RAM,但这只是临时解决方案,因为我意识到数据集只会变得更大。理想情况下,我想找到一种方法使 bigglm 的代码更快。我已经在数据集上运行了一些 R 分析代码。添加以下代码(在我要运行以检查其速度的代码之前):

Rprof('method1.out')

然后在输入此命令后,我编写 bigglm 代码,如下所示:

x<-read.csv('file location of 100mb file')
form<-depvar~var1+var2+var3+var4
a<-bigglm(form, data=x, chunksize=800000, sandwich=FALSE, family=binomial())
summary(a)
AIC(a)
deviance(a)

运行这些代码(大约需要 2 到 3 分钟)后,我输入以下内容来查看我的分析代码:

Rprofsummary('method1.out')

然后我得到的是 bigglm 流程的分割以及哪些单独的行花费了很长时间。查看此内容后,我惊讶地发现有一个对 Fortran 代码的调用花费了很长时间(大约 20 秒)。此代码可以在 Bigglm 的基本文件中找到:

http://cran.r-project.org/web/packages/biglm/index.html

在bigglm 0.8.tar.gz文件中

基本上,我向社区询问的是这段代码能否变得更快?比如通过改变代码来调用Fortran代码来做QR分解。此外,还有其他函数,如 as.character 和 model.matrix ,也花费了很长时间。我没有在此处附加分析文件,因为我相信根据我提供的信息可以轻松复制它,但基本上我是在暗示大数据和在该大数据上处理 GLM 的大问题。这是 R 社区中共有的一个问题,我认为任何有关此问题的反馈或帮助将不胜感激。您可能可以使用不同的数据集轻松复制此示例,并查看 bigglm 代码中花费了这么长时间的时间,看看它们是否与我发现的相同。如果是的话,有人可以帮我弄清楚如何让 bigglm 运行得更快。在 Ben 请求后,我上传了我的分析代码片段以及 csv 文件的前 10 行:

 CSV File:

 var1,var2,var3,var4,depvar
   1,0,2,2,1
   0,0,1,2,0
   1,1,0,0,1
   0,1,1,2,0
   1,0,0,3,0
   0,0,2,2,0
   1,1,0,0,1
   0,1,2,2,0
   0,0,2,2,1

此 CSV 输出是从我的文本编辑器 UltraEdit 复制的,可以看到 var1 的值为 0 或 1,var2 的值为 0 和 1,var3 的值为 0,1,2,var4 的值为 0 ,1,2,3 和 depvar 取值 1 或 0。可以使用 RAND 函数在 Excel 中复制该 csv 最多大约 100 万行,然后可以多次复制和粘贴以获取大量行像 ultraedit 这样的文本编辑器。基本上将 RAND() 输入到一列中,表示 100 万列,然后在 RAND() 列旁边的列中进行舍入(列)以获得 1 和 0。同样的想法也适用于 0,1,2,3。

分析文件很长,所以我附加了花费最多时间的行:

 summaryRprof('method1.out')



$by.self
                        self.time self.pct total.time total.pct
"model.matrix.default"      25.40     20.5      26.76      21.6
".Call"                     20.24     16.3      20.24      16.3
"as.character"              17.22     13.9      17.22      13.9
"[.data.frame"              14.80     11.9      22.12      17.8
"update.bigqr"               5.72      4.6      14.38      11.6
"-"                          4.36      3.5       4.36       3.5
"anyDuplicated.default"      4.18      3.4       4.18       3.4
"|"                          3.98      3.2       3.98       3.2
"*"                          3.44      2.8       3.44       2.8
"/"                          3.18      2.6       3.18       2.6
"unclass"                    2.28      1.8       2.28       1.8
"sum"                        2.26      1.8       2.26       1.8
"attr"                       2.12      1.7       2.12       1.7
"na.omit"                    2.02      1.6      20.00      16.1
"%*%"                        1.74      1.4       1.74       1.4
"^"                          1.56      1.3       1.56       1.3
"bigglm.function"            1.42      1.1     122.52      98.8
"+"                          1.30      1.0       1.30       1.0
"is.na"                      1.28      1.0       1.28       1.0
"model.frame.default"        1.20      1.0      22.68      18.3
">"                          0.84      0.7       0.84       0.7
"strsplit"                   0.62      0.5       0.62       0.5

$by.total
                        total.time total.pct self.time self.pct
"standardGeneric"           122.54      98.8      0.00      0.0
"bigglm.function"           122.52      98.8      1.42      1.1
"bigglm"                    122.52      98.8      0.00      0.0
"bigglm.data.frame"         122.52      98.8      0.00      0.0
"model.matrix.default"       26.76      21.6     25.40     20.5
"model.matrix"               26.76      21.6      0.00      0.0
"model.frame.default"        22.68      18.3      1.20      1.0
"model.frame"                22.68      18.3      0.00      0.0
"["                          22.14      17.9      0.02      0.0
"[.data.frame"               22.12      17.8     14.80     11.9
".Call"                      20.24      16.3     20.24     16.3
"na.omit"                    20.00      16.1      2.02      1.6
"na.omit.data.frame"         17.98      14.5      0.02      0.0
"model.response"             17.44      14.1      0.10      0.1
"as.character"               17.22      13.9     17.22     13.9
"names<-"                    17.22      13.9      0.00      0.0
"<Anonymous>"                15.10      12.2      0.00      0.0
"update.bigqr"               14.38      11.6      5.72      4.6
"update"                     14.38      11.6      0.00      0.0
"data"                       10.26       8.3      0.00      0.0
"-"                           4.36       3.5      4.36      3.5
"anyDuplicated.default"       4.18       3.4      4.18      3.4
"anyDuplicated"               4.18       3.4      0.00      0.0
"|"                           3.98       3.2      3.98      3.2
"*"                           3.44       2.8      3.44      2.8
"/"                           3.18       2.6      3.18      2.6
"lapply"                      3.04       2.5      0.04      0.0
"sapply"                      2.44       2.0      0.00      0.0
"as.list.data.frame"          2.30       1.9      0.02      0.0
"as.list"                     2.30       1.9      0.00      0.0
"unclass"                     2.28       1.8      2.28      1.8
"sum"                         2.26       1.8      2.26      1.8
"attr"                        2.12       1.7      2.12      1.7
"etafun"                      1.88       1.5      0.14      0.1
"%*%"                         1.74       1.4      1.74      1.4
"^"                           1.56       1.3      1.56      1.3
"summaryRprof"                1.48       1.2      0.02      0.0
"+"                           1.30       1.0      1.30      1.0
"is.na"                       1.28       1.0      1.28      1.0
">"                           0.84       0.7      0.84      0.7
"FUN"                         0.70       0.6      0.36      0.3
"strsplit"                    0.62       0.5      0.62      0.5

我主要对调用 Fortran 的 .Call 函数感到惊讶。也许是我没明白。看来一旦使用这个函数,所有的计算就完成了。我认为这就像一个用于提取 Fortran 代码的链接函数。此外,如果 Fortran 正在完成所有工作和所有迭代加权最小二乘/QR,那么为什么其余代码要花这么长时间。

最佳答案

我的外行理解是,biglm 将数据分解成 block 并按顺序运行它们。

  • 因此,您可以通过将 block 的大小优化为内存允许的大小来加快速度。
  • 这也只是使用您的一个核心。这不是多线程代码。你需要施展一些魔法才能让它发挥作用。

关于r - R 中的 Bigglm : Limitations and Improvements of source code (E. g。调用 Fortran),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8712685/

相关文章:

python - 使用python提取回归系数

java - H2OGeneralizedLinearEstimator() - 预测误差

r - hclust 上的 pvclust 生成树状图

hadoop - 如何为 BucketingSink 函数 Flink 设置动态基本路径?

hadoop - 此存储桶的一部分可能包含部分数据 - kibana Issue

r - 从 glm 中提取 pvalue

r - 时间序列预测,处理已知的大订单

r - kableExtra : add a footnote to a rowname [kableExtra, Rmd]

javascript - 如何将Javascript代码插入到R中的Leaflet中,即使双击也不会触发单击

hadoop - Hive 分区表的记录数