当我仅使用glm进行训练时,一切都可以正常工作,而且我什至无法耗尽内存。但是,当我运行train(..., method='glm')时,内存不足。

这是因为train在交叉验证的每次迭代(或任何trControl过程)中都存储大量数据吗?我正在查看trainControl,但找不到如何防止这种情况...任何提示?我只关心性能摘要,也可能关心预测的响应。

(我知道,这与存储参数调整网格搜索的每次迭代中的数据无关,因为我认为没有用于glm的网格。)

最佳答案

问题有两个。 i) train不仅通过glm()拟合模型,还将引导该模型,因此即使使用默认设置,train()也会进行25个 bootstrap 样本,这与问题ii)一起是您的(或a)源问题和 ii) train()只是使用其默认值调用glm()函数。这些默认值是存储模型框架(参数model = TRUE?glm),其中包括模型框架样式的数据副本。 train()返回的对象已经在$trainingData中存储了数据的副本,而"glm"中的$finalModel对象也已存储了实际数据的副本。

此时,仅使用glm()运行train()将产生25个完全展开的model.frame和原始数据的副本,在重新采样过程中,所有这些副本都需要保存在内存中-不论是同时保存还是连续保存,都无法立即清除快速浏览一下代码,因为它是在lapply()调用中进行重采样的。还将有25个原始数据副本。

重新采样完成后,返回的对象将包含2个原始数据副本和model.frame的完整副本。如果您的训练数据相对于可用RAM而言很大,或者包含许多要在model.frame中扩展的因素,那么您可能很容易在使用大量内存时随身携带数据的副本。

如果您在火车通话中添加model = FALSE,则可能会有所不同。这是在clotting中使用?glm数据的一个小示例:

clotting <- data.frame(u = c(5,10,15,20,30,40,60,80,100),
                       lot1 = c(118,58,42,35,27,25,21,19,18),
                       lot2 = c(69,35,26,21,18,16,13,12,12))
require(caret)

然后
> m1 <- train(lot1 ~ log(u), data=clotting, family = Gamma, method = "glm",
+             model = TRUE)
Fitting: parameter=none
Aggregating results
Fitting model on full training set
> m2 <- train(lot1 ~ log(u), data=clotting, family = Gamma, method = "glm",
+             model = FALSE)
Fitting: parameter=none
Aggregating results
Fitting model on full training set
> object.size(m1)
121832 bytes
> object.size(m2)
116456 bytes
> ## ordinary glm() call:
> m3 <- glm(lot1 ~ log(u), data=clotting, family = Gamma)
> object.size(m3)
47272 bytes
> m4 <- glm(lot1 ~ log(u), data=clotting, family = Gamma, model = FALSE)
> object.size(m4)
42152 bytes

因此,返回的对象存在大小差异,并且训练期间的内存使用量会更低。降低多少取决于在重新采样过程中train()的内部结构是否将model.frame的所有副本都保留在内存中。
train()返回的对象也比glm()返回的对象大得多-正如@DWin在下面的注释中提到的那样。

要进一步进行研究,请更仔细地研究代码,或者给插入符的维护者Max Kuhn发送电子邮件,以查询有关减少内存占用的选项。

关于r - 为什么插入号训练会占用这么多内存?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6543999/

10-12 22:14