¿Por qué el caret train está ocupando tanta memoria?




memory glm (2)

Creo que las respuestas anteriores son un poco anticuadas. Los paquetes caret y caretEnsemble ahora incluyen un parámetro adicional en el 'ajuste' de trainControl. Inicialmente, el ajuste se establece en FALSO, pero cambiarlo a VERDADERO disminuirá significativamente el tamaño del modelo. Debe usar esto en combinación con returnData = FALSE para los tamaños de modelo más pequeños posibles. Si está utilizando un conjunto de modelos, también debe especificar estos dos parámetros en el conjunto de controles codiciosos / apilados.

Para mi caso, un modelo de 1.6 gb se redujo a ~ 500 mb con ambos parámetros en el control de conjunto y se redujo aún más a ~ 300 mb usando también los parámetros en el control de conjunto codicioso.

Ensemble_control_A9 <- trainControl(trim=TRUE, method = "repeatedcv", number = 3, repeats = 2, verboseIter = TRUE, returnData = FALSE, returnResamp = "all", classProbs = TRUE, summaryFunction = twoClassSummary, savePredictions = TRUE, allowParallel = TRUE, sampling = "up")


Ensemble_greedy_A5 <- caretEnsemble(Ensemble_list_A5, metric="ROC",  trControl=trainControl(number=2, trim=TRUE, returnData = FALSE, summaryFunction=twoClassSummary, classProbs=TRUE))

Cuando entreno usando glm , todo funciona y ni siquiera me acerco a la memoria agotadora. Pero cuando corro train(..., method='glm') , me quedo sin memoria.

¿Se debe a que train está almacenando una gran cantidad de datos para cada iteración de la validación cruzada (o cualquiera que sea el procedimiento de control)? Estoy mirando trainControl y no puedo encontrar cómo prevenir esto ... ¿alguna pista? Solo me importa el resumen de rendimiento y quizás las respuestas predichas.

(Sé que no está relacionado con el almacenamiento de datos de cada iteración de la búsqueda de cuadrícula de ajuste de parámetros porque creo que no hay una cuadrícula para glm's).


El problema es doble. i) el train no solo se ajusta a un modelo a través de glm() , sino que también arrancará ese modelo, por lo que incluso con los valores predeterminados, train() hará 25 muestras de bootstrap, que, junto con el problema ii) es la fuente (o a ) de su problema, y ii) train() simplemente llama a la función glm() con sus valores predeterminados. Y esos valores predeterminados son almacenar el marco del modelo (argumento model = TRUE de ?glm ), que incluye una copia de los datos en el estilo del marco del modelo. El objeto devuelto por train() ya almacena una copia de los datos en $trainingData , y el objeto "glm" en $finalModel también tiene una copia de los datos reales.

En este punto, simplemente ejecutando glm() utilizando train() se producirán 25 copias del model.frame completamente expandido. model.frame y datos originales, todos los cuales deberán mantenerse en la memoria durante el proceso de remuestreo, ya sea que se mantengan simultáneamente o De manera consecutiva, no queda claro inmediatamente después de un rápido vistazo al código, ya que el remuestreo ocurre en una llamada lapply() . También habrá 25 copias de los datos en bruto.

Una vez finalizado el remuestreo, el objeto devuelto contendrá 2 copias de los datos en bruto y una copia completa del model.frame . Si sus datos de entrenamiento son grandes en relación con la memoria RAM disponible o contienen muchos factores que se pueden expandir en el model.frame del model.frame , entonces podría estar usando fácilmente enormes cantidades de memoria que solo llevan copias de los datos.

Si agrega model = FALSE a su llamada de tren, eso podría marcar la diferencia. Aquí hay un pequeño ejemplo utilizando los datos de clotting en ?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)

entonces

> 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

Por lo tanto, hay una diferencia de tamaño en el objeto devuelto y el uso de memoria durante el entrenamiento será menor. Cuánto menos dependerá de si las model.frame internas de train() mantienen todas las copias del model.frame en la memoria durante el proceso de remuestreo.

El objeto devuelto por train() también es significativamente más grande que el devuelto por glm() , como lo menciona @DWin en los comentarios, a continuación.

Para profundizar más en esto, estudie el código más de cerca o envíe un correo electrónico a Max Kuhn, el encargado de la gestión de caret , para preguntar sobre las opciones para reducir la huella de memoria.





r-caret