当我仅使用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/