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 una if()...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))
>
> m1 <- lm(y ~ x, data = df)
>
> save(m1, file = "my_model1.rda")
>
>
> newdf <- data.frame(x = rnorm(20))
>
> load("my_model1.rda")
>
> 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:
df <- data.frame(x = rnorm(20))
df <- transform(df, y = 5 + (2.3 * x) + rnorm(20))
if(file.exists("my_model1.rda")) {
load("my_model1.rda")
} else {
m1 <- lm(y ~ x, data = df)
}
newdf <- data.frame(x = rnorm(20))
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:
m2 <- update(m1, . ~ ., data = df)
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), y df
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))
>
> m1 <- lm(y ~ x, data = df)
> m1
Call:
lm(formula = y ~ x, data = df)
Coefficients:
(Intercept) x
4.960 2.222
>
>
> newdf <- data.frame(x = rnorm(20))
> newdf <- transform(newdf, y = 5 + (2.3 * x) + rnorm(20))
>
> df <- rbind(df, newdf)
>
>
> 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
>
>
> 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. Si update()
hay métodos disponibles para la función de ajuste de su modelo (que son para muchas funciones de ajuste comunes, como glm()
), 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.
data
argumento ... suponiendo que lo entendí correctamente ...