Integración de Artefactos de Modelo

Conectando la Ciencia de Datos con la Aplicación de Usuario.

El Modelo como Artefacto

En un flujo MLOps maduro, el entrenamiento de modelos y el desarrollo de aplicaciones son dos procesos completamente separados. Un científico de datos experimenta, entrena y valida un modelo, y el resultado de su trabajo es un artefacto: un archivo que encapsula la lógica predictiva. La aplicación Shiny actúa entonces como un consumidor de este artefacto.

¿Por qué esta separación?

Rendimiento

El entrenamiento puede tardar horas. Una app web debe cargar en segundos. Desacoplar asegura que la app solo cargue el modelo final, no que lo entrene.

Reproducibilidad

El artefacto se versiona junto con el código que lo generó, garantizando que siempre sepamos qué versión del modelo está en producción.

Colaboración

Permite que los científicos de datos (creadores de modelos) y los desarrolladores (creadores de apps) trabajen en paralelo y de forma independiente.

En R, la forma más común de guardar un modelo es como un archivo .rds usando las funciones saveRDS() y readRDS().

Guía Práctica: De un Modelo a un Simulador Interactivo

Vamos a simular el ciclo completo: crearemos un script que "entrena" un modelo, lo guardará como un artefacto y luego lo integraremos en nuestra app Shiny para crear un simulador de puntajes.

Paso 1: Crear el Artefacto de Entrenamiento

Este script simula el trabajo de un científico de datos. Su única responsabilidad es entrenar un modelo y guardar el resultado en la carpeta /models, como dicta nuestra arquitectura.

Acción: Dentro de la carpeta /R, crea un nuevo archivo llamado model_training.R.

# Contenido: R/model_training.R

# Cargamos las librerías necesarias para este script
library(readr)
library(dplyr)

# 1. Cargamos los datos crudos (simulando un entorno de entrenamiento)
datos_crudos <- read_delim("data/raw/Examen_Saber_11_20242.txt", delim = ";", show_col_types = FALSE) %>% na.omit()

# 2. Entrenamos un modelo lineal simple
# El objetivo es predecir el puntaje de matemáticas basándose en los otros puntajes
modelo_puntaje <- lm(
  punt_matematicas ~ punt_lectura_critica + punt_sociales_ciudadanas + punt_ciencias_naturales,
  data = datos_crudos
)

# 3. Guardamos el modelo entrenado como un artefacto en la carpeta /models
# Este es el único resultado que nos importa de este script
saveRDS(modelo_puntaje, "models/modelo_puntaje_mat.rds")

message("==> Modelo entrenado y guardado exitosamente en /models/modelo_puntaje_mat.rds")

Para ejecutarlo: Abre una consola de R en tu proyecto y corre source("R/model_training.R"). Verás que aparece un nuevo archivo modelo_puntaje_mat.rds en tu carpeta /models.

Paso 2: Versionar el Modelo y su Script

Ahora tenemos dos nuevos archivos: el código que crea el modelo y el modelo mismo. Ambos deben ser versionados.

  • mi-proyecto/
    • R/
      • data_processing.R
      • model_training.R   <-- NUEVO
    • models/
      • modelo_puntaje_mat.rds   <-- NUEVO
    • ...

Acción: Versiona estos cambios con Git.

git add R/model_training.R models/modelo_puntaje_mat.rds
git commit -m "feat(model): Crea script de entrenamiento y guarda artefacto de modelo lineal"
git push

Paso 3: Cargar el Artefacto del Modelo en la App

Al igual que con el pipeline de datos, el global.R es el lugar ideal para cargar el modelo. Se carga una sola vez y queda disponible para que el server lo use.

Acción: Añade la carga del modelo a tu global.R.

# En global.R, después de cargar los datos

# 4. Cargar el artefacto del modelo pre-entrenado
modelo_matematicas <- readRDS("models/modelo_puntaje_mat.rds")

message("==> Modelo de predicción cargado en memoria.")

Paso 4: Crear la Interfaz del Simulador en la UI

Necesitamos controles para que el usuario ingrese los datos para la predicción y un lugar para mostrar el resultado.

Acción: Modifica tu ui.R para añadir una nueva pestaña.

# En ui.R, dentro del tabsetPanel

tabPanel("Simulador de Puntaje",
    sidebarLayout(
        sidebarPanel(
            h3("Ingrese los puntajes:"),
            numericInput("sim_lectura", "Puntaje Lectura Crítica:", 100, min = 0, max = 100),
            numericInput("sim_sociales", "Puntaje Sociales:", 100, min = 0, max = 100),
            numericInput("sim_ciencias", "Puntaje Ciencias Naturales:", 100, min = 0, max = 100),
            actionButton("run_prediction", "Predecir Puntaje de Matemáticas", icon = icon("calculator"))
        ),
        mainPanel(
            h2("Resultado de la Predicción"),
            div(
                style = "background-color: #1e1e1e; padding: 30px; border-radius: 15px; text-align: center;",
                h3("El puntaje predicho en matemáticas es:"),
                h1(style="color: #28a745; font-size: 5rem;", textOutput("prediction_result"))
            )
        )
    )
)

Paso 5: Implementar la Lógica de Predicción en el Server

Finalmente, conectamos los inputs del usuario con el modelo cargado para generar y mostrar la predicción.

Acción: Añade este bloque de código a tu server.R.

# En server.R

# Lógica para la predicción del puntaje
puntaje_predicho <- eventReactive(input$run_prediction, {
    
    # 1. Crear un dataframe con los datos de entrada del usuario
    #    Los nombres de las columnas DEBEN COINCIDIR EXACTAMENTE con los del modelo.
    nuevos_datos <- data.frame(
        punt_lectura_critica = input$sim_lectura,
        punt_sociales_ciudadanas = input$sim_sociales,
        punt_ciencias_naturales = input$sim_ciencias
    )
    
    # 2. Usar la función predict() con el modelo cargado
    prediccion <- predict(modelo_matematicas, newdata = nuevos_datos)
    
    # 3. Devolver el resultado redondeado
    return(round(prediccion))
})

# 4. Renderizar el resultado en la UI
output$prediction_result <- renderText({
    puntaje_predicho()
})

¡Ciclo MLOps Completado!

¡Felicidades! Has conectado todo el ciclo: un script de entrenamiento produce un artefacto, la app carga ese artefacto y lo usa para servir predicciones a un usuario final. Este es el corazón de un producto de datos funcional.