Al construir un modelo en R, ¿cómo guarda las especificaciones del modelo para poder reutilizarlo en datos nuevos? Digamos que construyo una regresión logística sobre datos históricos pero no tendré nuevas observaciones hasta el próximo mes. ¿Cuál es el mejor enfoque?
Cosas que he considerado:
- Guardar el objeto del modelo y cargarlo en una nueva sesión
- Sé que algunos modelos se pueden exportar con PMML, pero realmente no he visto nada sobre la importación de PMML
Simplemente, estoy tratando de tener una idea de lo que hace cuando necesita usar su modelo en una nueva sesión.
Gracias por adelantado.
data
argumento ... suponiendo que lo entendí correctamente ...Respuestas:
Reutilizar un modelo para predecir nuevas observaciones
Si el modelo no es computacionalmente costoso, tiendo a documentar todo el proceso de construcción del modelo en un script R que vuelvo a ejecutar cuando es necesario. Si un elemento aleatorio está involucrado en el ajuste del modelo, me aseguro de establecer una semilla aleatoria conocida.
Si el modelo es computacionalmente costoso de calcular, todavía uso un script como el anterior, pero guardo los objetos del modelo usando
save()
into y rda object. Luego tiendo a modificar el script de modo que si el objeto guardado existe, lo cargue o, si no, reajuste el modelo, usando unaif()...else
cláusula simple envuelta alrededor de las partes relevantes del código.Al cargar su objeto de modelo guardado, asegúrese de volver a cargar los paquetes necesarios, aunque en su caso, si el modelo logit se ajusta a través de
glm()
, no habrá paquetes adicionales para cargar más allá de R.Aquí hay un ejemplo:
> set.seed(345) > df <- data.frame(x = rnorm(20)) > df <- transform(df, y = 5 + (2.3 * x) + rnorm(20)) > ## model > m1 <- lm(y ~ x, data = df) > ## save this model > save(m1, file = "my_model1.rda") > > ## a month later, new observations are available: > newdf <- data.frame(x = rnorm(20)) > ## load the model > load("my_model1.rda") > ## predict for the new `x`s in `newdf` > predict(m1, newdata = newdf) 1 2 3 4 5 6 6.1370366 6.5631503 2.9808845 5.2464261 4.6651015 3.4475255 7 8 9 10 11 12 6.7961764 5.3592901 3.3691800 9.2506653 4.7562096 3.9067537 13 14 15 16 17 18 2.0423691 2.4764664 3.7308918 6.9999064 2.0081902 0.3256407 19 20 5.4247548 2.6906722
Si quisiera automatizar esto, probablemente haría lo siguiente en un script:
## data df <- data.frame(x = rnorm(20)) df <- transform(df, y = 5 + (2.3 * x) + rnorm(20)) ## check if model exists? If not, refit: if(file.exists("my_model1.rda")) { ## load model load("my_model1.rda") } else { ## (re)fit the model m1 <- lm(y ~ x, data = df) } ## predict for new observations ## new observations newdf <- data.frame(x = rnorm(20)) ## predict predict(m1, newdata = newdf)
Por supuesto, el código de generación de datos sería reemplazado por un código que cargue sus datos reales.
Actualizar un modelo previamente ajustado con nuevas observaciones
Si desea reajustar el modelo utilizando nuevas observaciones adicionales. Entonces
update()
es una función útil. Todo lo que hace es reajustar el modelo con uno o más de los argumentos del modelo actualizados. Si desea incluir nuevas observaciones en los datos utilizados para ajustar el modelo, agregue las nuevas observaciones al marco de datos pasado al argumento'data'
y luego haga lo siguiente:donde
m1
es el ajuste del modelo original, guardado,. ~ .
son los cambios de fórmula del modelo, que en este caso significa incluir todas las variables existentes en los lados izquierdo y derecho de~
(en otras palabras, no hacer cambios en la fórmula del modelo), ydf
es el marco de datos utilizado para ajustarse al modelo original, ampliado para incluir las observaciones recientemente disponibles.Aquí hay un ejemplo de trabajo:
> set.seed(123) > df <- data.frame(x = rnorm(20)) > df <- transform(df, y = 5 + (2.3 * x) + rnorm(20)) > ## model > m1 <- lm(y ~ x, data = df) > m1 Call: lm(formula = y ~ x, data = df) Coefficients: (Intercept) x 4.960 2.222 > > ## new observations > newdf <- data.frame(x = rnorm(20)) > newdf <- transform(newdf, y = 5 + (2.3 * x) + rnorm(20)) > ## add on to df > df <- rbind(df, newdf) > > ## update model fit > m2 <- update(m1, . ~ ., data = df) > m2 Call: lm(formula = y ~ x, data = df) Coefficients: (Intercept) x 4.928 2.187
Otros han mencionado en los comentarios
formula()
, que extraen la fórmula de un modelo ajustado:> formula(m1) y ~ x > ## which can be used to set-up a new model call > ## so an alternative to update() above is: > m3 <- lm(formula(m1), data = df)
Sin embargo, si el ajuste del modelo implica argumentos adicionales, como
'family'
o'subset'
argumentos en funciones de ajuste del modelo más complejas. Siupdate()
hay métodos disponibles para la función de ajuste de su modelo (que son para muchas funciones de ajuste comunes, comoglm()
), proporciona una forma más sencilla de actualizar un ajuste de modelo que extraer y reutilizar la fórmula del modelo.Si tiene la intención de hacer todo el modelado y la predicción futura en R, realmente no parece tener mucho sentido abstraer el modelo a través de PMML o similar.
fuente
update
míSi usa el mismo nombre del marco de datos y las variables, puede (al menos para
lm()
yglm()
) usar la funciónupdate
en el modelo guardado:Df <- data.frame(X=1:10,Y=(1:10)+rnorm(10)) model <- lm(Y~X,data=Df) model Df <- rbind(Df,data.frame(X=2:11,Y=(10:1)+rnorm(10))) update(model)
Por supuesto, esto es sin ninguna preparación de los datos y así sucesivamente. Simplemente reutiliza el conjunto de especificaciones del modelo. Tenga en cuenta que si cambia los contrastes mientras tanto, el nuevo modelo se actualiza con los nuevos contrastes, no con el anterior.
Entonces, el uso de un script es en la mayoría de los casos la mejor respuesta. Se pueden incluir todos los pasos en una función de conveniencia que solo toma el marco de datos, para que pueda obtener el script y luego usar la función en cualquier conjunto de datos nuevo. Vea también la respuesta de Gavin para eso.
fuente