IA para Científicos Sociales

Sesión 1.2: Fundamentos de Machine Learning

Danilo Freire

Department of Data and Decision Sciences
Emory University

Fundamentos de Machine Learning

Agenda de la sesión

Primera parte

  • El flujo de trabajo de ML
  • Calidad de datos y preprocesamiento
  • Feature engineering
  • División train/test y validación cruzada

Segunda parte

  • Sobreajuste y sesgo-varianza
  • Métricas de evaluación
  • Selección de modelos
  • Reproducibilidad en ML

Elegir la métrica correcta

Fuente: AWS in Plain English

El flujo de trabajo de ML

El flujo de trabajo de ML

Del problema a la solución

Flujo de trabajo de ML
  1. Recoger datos: obtener observaciones relevantes al problema
  2. Preprocesar: limpiar, transformar variables y codificar categorías
  3. Dividir en entrenamiento y prueba
  1. Entrenar un modelo con los datos de entrenamiento
  2. Evaluar el rendimiento con datos que el modelo nunca vio

En la práctica, el proceso es iterativo: volvemos a pasos anteriores cuando algo falla

Pasos 1-2: recolección y preprocesamiento

Recolección de datos

  • Encuestas, registros administrativos, sensores, APIs, web scraping, etc
  • La calidad de los datos determina la calidad del modelo
  • “Basura entra, basura sale” (garbage in, garbage out)

Preprocesamiento

Ejemplo: datos de países

Datos crudos:
  país     | pib   | edu  | internet
  Uruguay  | 17020 | 4.9  | 87.7
  Bolivia  | NA    | 6.5  | 48.2
  Chile    | 15346 | 5.4  | NA

Después de preprocesar:
  país     | pib   | edu  | internet
  Uruguay  | 17020 | 4.9  | 87.7
  Bolivia  | 10500 | 6.5  | 48.2   ← imputado
  Chile    | 15346 | 5.4  | 72.3   ← imputado

El preprocesamiento es la mayor parte del trabajo en un proyecto real de ML

Calidad de datos: el factor más ignorado

Problemas comunes en datos reales:

  • Valores faltantes, ¿aleatorios o sistemáticos?
    • MCAR: completamente al azar
    • MAR: dependen de otras variables observadas
    • MNAR: dependen de la variable misma (más difícil)
  • Errores de medición: datos mal cargados o unidades inconsistentes
  • Duplicados que sesgan el modelo
  • Desbalance de clases (mucho más de una categoría que de otra)
  • Data leakage: información del futuro que se filtra al entrenamiento

Ejemplo de data leakage:

Quieren predecir si un paciente será hospitalizado

Variable: "días_en_hospital"

Si incluyen esta variable,
el modelo "aprende" que
días_en_hospital > 0 → hospitalizado

¡Pero esta información no existe
al momento de la predicción!


El data leakage es uno de los errores más difíciles de detectar y puede inflar artificialmente las métricas

Feature engineering

El arte de crear variables predictivas

  • Feature engineering, crear nuevas variables a partir de las existentes
  • Puede mejorar mucho el rendimiento de un modelo simple
  • Ejemplos comunes:
    • Transformaciones: log(ingreso), raíz cuadrada, bins
    • Interacciones entre variables (edad × educación)
    • Agregaciones, como el promedio de compras de los últimos 3 meses
    • Variables temporales: día de la semana, mes, año
    • Variables de texto (largo, cantidad de palabras)
  • El conocimiento del dominio es clave: ¿qué variables tienen sentido para el problema?

Ejemplo: predicción de abandono

Variables originales:

fecha_registro, ultima_compra,
monto_total, cantidad_compras

Variables derivadas:

dias_desde_registro
dias_sin_comprar         ← predictor fuerte
promedio_por_compra
frecuencia_compras
tendencia_reciente       ← ¿aumenta o baja?


Un buen feature engineering puede valer más que un modelo complejo

Paso 3: ¿por qué dividir los datos?

  • Queremos saber si el modelo funciona con datos nuevos, no solo con los datos que ya vio
  • Si evaluamos el modelo con los mismos datos que usamos para entrenarlo, no sabemos si realmente aprendió
  • Por eso dividimos:
    • Entrenamiento (~70-80%): el modelo aprende de estos datos
    • Prueba (~20-30%): evaluamos el rendimiento con datos que el modelo nunca vio
  • Regla de oro: nunca mirar los datos de prueba hasta el final

División train/test

División train/test y validación cruzada

División train/test

  • La forma más simple de evaluar un modelo
  • Dividimos los datos aleatoriamente en dos conjuntos
  • El modelo solo ve los datos de entrenamiento durante el ajuste
  • Evaluamos con los datos de prueba al final
  • Problemas potenciales:
    • Con pocos datos, una sola división puede no ser representativa
    • El resultado depende de qué observaciones cayeron en cada conjunto
  • Para datasets pequeños, necesitamos algo más: validación cruzada

División train/test

Validación cruzada K-fold

  • Dividimos los datos en K partes (folds) de tamaño similar
  • Entrenamos K veces, cada vez usando K-1 folds para entrenamiento y 1 fold para validación
  • Repetimos K veces, rotando el fold de validación
  • Promediamos los resultados de las K iteraciones
  • Cada observación es usada para validación exactamente una vez
  • Más confiable que una sola división, especialmente con pocos datos
  • K = 5 o K = 10 son los valores más comunes

Validación cruzada K-fold

¿Cuántos datos necesito?

  • Pregunta frecuente sin respuesta universal
  • Depende de varios factores:
    • Complejidad del problema: número de variables y tipo de relaciones
    • Cantidad de ruido en los datos (con datos limpios bastan menos)
    • Complejidad del modelo, ya que los más complejos piden más datos
    • Número de clases: más clases = más datos por clase
  • Reglas prácticas (muy aproximadas):
    • Para clasificación, al menos 50-100 por clase minoritaria
    • Deep learning: miles o millones de ejemplos

Curvas de aprendizaje

Con más datos, el rendimiento mejora, pero con rendimientos decrecientes.

A veces más datos ayudan más que un modelo más complejo

Sobreajuste y sesgo-varianza

¿Qué es el sobreajuste?

  • Sobreajuste (overfitting): el modelo funciona muy bien con los datos de entrenamiento pero mal con datos nuevos
  • El modelo ha memorizado el conjunto de entrenamiento, incluyendo su ruido y particularidades
  • No ha aprendido los patrones subyacentes
  • Señales de sobreajuste:
    • Rendimiento excelente en entrenamiento
    • Rendimiento pobre en test
    • La brecha crece con la complejidad del modelo
  • Piénsenlo así: memorizar las respuestas del examen vs. entender la materia
  • El estudiante que memoriza fracasa cuando las preguntas se reformulan

Sobreajuste visualizado

Fuente: X.com

Subajuste vs. sobreajuste

Subajuste

  • Modelo demasiado simple
  • Alto sesgo, baja varianza
  • Malo en entrenamiento Y en test
  • No captó el patrón
  • Solución: modelo más complejo

Buen ajuste

  • Complejidad adecuada
  • Sesgo y varianza equilibrados
  • Bueno en ambos conjuntos
  • Captura el patrón verdadero
  • Esto es lo que buscamos

Sobreajuste

  • Modelo demasiado complejo
  • Bajo sesgo, alta varianza
  • Excelente en entrenamiento, malo en test
  • Memorizó el ruido
  • Solución: regularización

El compromiso sesgo-varianza

  • El sesgo (bias) es el error por suposiciones simplificadoras: un modelo con alto sesgo “no presta atención” a los datos
  • La varianza, en cambio, es el error por sensibilidad excesiva al entrenamiento: cambia mucho con cada muestra
  • No se pueden minimizar ambos al mismo tiempo, ya que al reducir uno el otro tiende a aumentar
  • El objetivo es encontrar el punto medio donde el error total es mínimo
  • En la práctica:
    • Los modelos simples (regresión lineal) tienden a alto sesgo y baja varianza
    • Los modelos complejos (redes neuronales profundas) muestran bajo sesgo y alta varianza
    • La regularización controla la varianza sin aumentar mucho el sesgo (la veremos en detalle en el Día 2, con regresión)

Compromiso sesgo-varianza

A medida que el modelo se vuelve más complejo, el sesgo disminuye (la curva baja) pero la varianza aumenta (la curva sube)

Métricas de evaluación

La paradoja de la precisión

Escenario: están construyendo un modelo para predecir si los pacientes tienen una enfermedad rara que afecta a 1 de cada 1.000 personas

Un colega les muestra un modelo y les dice con orgullo: “Logra un 99,9% de accuracy (exactitud)”

Pregunta: ¿es bueno este modelo?

Piénsenlo 30 segundos…

La verdad incómoda: ese modelo “99,9% preciso” no detecta ni un solo caso real. Simplemente predice “sano” para todos. Cada paciente enfermo es ignorado

La accuracy (exactitud) no basta, especialmente con clases desbalanceadas

La matriz de confusión

  • Una tabla que muestra todos los resultados posibles de las predicciones
  • Cuatro cantidades clave:
    • Verdaderos Positivos (VP): correctamente predicho como positivo
    • Verdaderos Negativos (VN): correctamente predicho como negativo
    • Falsos Positivos (FP): predicho como positivo, pero era negativo (Error Tipo I)
    • Falsos Negativos (FN): predicho como negativo, pero era positivo (Error Tipo II)
  • Todas las métricas de clasificación se derivan de estos cuatro números

Visualización de la matriz de confusión

Precisión y recall

Precisión = VP / (VP + FP)

  • De todo lo que el modelo marcó como “sí”, ¿qué parte era “sí” de verdad?
  • Mide la confianza en la alarma: alta precisión, pocas falsas alarmas
  • Importa cuando un falso positivo cuesta caro (spam, moderación de contenido)

Recall = VP / (VP + FN)

  • De todo lo que era “sí” de verdad, ¿qué parte encontró el modelo?
  • Mide la cobertura: alto recall, no se nos escapa casi nada
  • Importa cuando un falso negativo cuesta caro (enfermedades, seguridad)

El trade-off entre precisión y recall

Fuente: Analytics Vidhya

Un ejemplo: de 1.000 pacientes, 10 están enfermos. El modelo marca a 8 personas y acierta en 6

  • Precisión = 6/8 = 75%: de cada cuatro alarmas, tres son reales
  • Recall = 6/10 = 60%: encontró 6 enfermos, y se le escaparon 4

Si bajamos el umbral, el modelo marca a más gente: sube el recall y baja la precisión. No se pueden maximizar ambos

Selección de modelos

¿Qué modelo usar?

  • No existe un modelo “mejor” para todos los problemas
  • Depende de:
    • Cantidad de datos disponibles
    • Interpretabilidad requerida
    • Tiempo de entrenamiento aceptable
    • Tipo de relaciones en los datos

Principio de parsimonia:

  • Empezar con modelos simples (regresión, árboles)
  • Aumentar complejidad solo si es necesario
  • Un modelo simple que funciona bien es mejor que uno complejo que funciona igual

Guía práctica

Situación Modelo sugerido
Pocos datos, interpretabilidad alta Regresión logística/lineal
Datos moderados, interpretabilidad media Árboles, Random Forest
Muchos datos, rendimiento máximo Gradient Boosting, Redes
Relaciones muy no lineales Random Forest, XGBoost
Texto Transformers, BERT


En la práctica, probar varios modelos y comparar con validación cruzada

Reproducibilidad en ML

¿Por qué importa la reproducibilidad?

  • Reproducibilidad: poder obtener los mismos resultados con los mismos datos y código
  • Necesaria para:
    • Verificar resultados propios y ajenos
    • Colaborar con otros investigadores
    • Debugging: entender qué salió mal
    • Producción: desplegar el mismo modelo que probamos

Problemas comunes:

  • Diferentes versiones de paquetes
  • Semillas aleatorias no fijadas
  • Datos no versionados
  • Código no documentado
  • Hiperparámetros no registrados

Buenas prácticas

  1. Fijar semillas aleatorias

    set.seed(2026)
  2. Documentar versiones

    sessionInfo()
  3. Usar control de versiones

    • Git para código
    • DVC para datos (si son grandes)
  4. Registrar experimentos

    • Qué modelo, qué hiperparámetros
    • Qué datos, qué preprocesamiento
    • Qué métricas obtuvieron

Herramientas para reproducibilidad

En R:

  • renv para gestionar dependencias y versiones de paquetes
  • targets: pipelines reproducibles
  • Quarto, código y documentación juntos
  • Git para control de versiones

En general:

  • Docker: contenedores con ambiente completo
  • MLflow para tracking de experimentos
  • DVC, versionado de datos

Ejemplo: estructura de proyecto reproducible

mi_proyecto/
├── README.md           ← descripción
├── renv.lock           ← versiones de paquetes
├── data/
│   ├── raw/            ← datos originales
│   └── processed/      ← datos procesados
├── scripts/
│   ├── 01-preprocess.R
│   ├── 02-train.R
│   └── 03-evaluate.R
├── models/             ← modelos guardados
└── reports/            ← resultados


Invertir en reproducibilidad ahorra tiempo a futuro

Resumen y preparación para el laboratorio

El ecosistema tidymodels

  • tidymodels es un conjunto de paquetes de R para modelado de datos
  • Sigue la filosofía del tidyverse: código legible, consistente y modular
  • Paquetes principales:
    • rsample divide los datos (train/test, validación cruzada)
    • parsnip para especificar modelos con una interfaz unificada
    • yardstick: métricas de evaluación
    • workflows combina preprocesamiento y modelo
    • recipes para preprocesar los datos
  • Ventaja: misma sintaxis para todos los modelos, ya sea regresión logística, random forest o redes neuronales
tidymodels
├── rsample    → dividir datos
├── recipes    → preprocesar
├── parsnip    → especificar modelo
├── workflows  → combinar todo
├── tune       → ajustar hiperparámetros
└── yardstick  → evaluar

El flujo de trabajo en código:

# 1. Dividir
datos_split <- initial_split(datos)

# 2. Especificar modelo
modelo <- logistic_reg() |>
  set_engine("glm")

# 3. Ajustar
ajuste <- fit(modelo, formula,
              training(datos_split))

# 4. Evaluar
predicciones <- predict(ajuste,
                        testing(datos_split))

rsample: dividir los datos

  • initial_split() separa los datos en entrenamiento y prueba. Con prop = 0.75 dejamos 75% para entrenar
  • strata = mantiene la misma proporción de clases en ambos conjuntos, algo importante cuando una categoría es poco frecuente
  • training() y testing() extraen cada parte del objeto que devuelve initial_split()
  • vfold_cv() arma los K folds de validación cruzada, siempre a partir del conjunto de entrenamiento
  • set.seed() antes de dividir: sin eso, cada ejecución da una división distinta y los resultados no son reproducibles
library(tidymodels)
set.seed(2026)

# 75% entrenamiento, 25% prueba
datos_split <- initial_split(
  datos,
  prop   = 0.75,
  strata = crecimiento_alto
)

datos_train <- training(datos_split)
datos_test  <- testing(datos_split)

# 5 folds para validación cruzada
folds <- vfold_cv(
  datos_train,
  v      = 5,
  strata = crecimiento_alto
)

parsnip: especificar y ajustar el modelo

Todo modelo se define con tres verbos:

  • El tipo de modelo: logistic_reg(), decision_tree(), rand_forest(), linear_reg(), etc.
  • set_engine(): qué paquete de R hace el cálculo por detrás (glm, rpart, ranger)
  • set_mode(): "classification" o "regression"

Después:

  • fit() ajusta el modelo con los datos de entrenamiento
  • La fórmula y ~ . significa “predecir y con todas las demás variables”
  • La ventaja: cambiar de modelo es cambiar dos líneas, no reescribir el análisis
# Regresión logística
modelo_log <- logistic_reg() |>
  set_engine("glm") |>
  set_mode("classification")

# Árbol de decisión: mismo patrón,
# solo cambian el tipo y el motor
modelo_arbol <- decision_tree() |>
  set_engine("rpart") |>
  set_mode("classification")

# Ajustar con los datos de entrenamiento
ajuste <- modelo_log |>
  fit(crecimiento_alto ~ .,
      data = datos_train)

Especificar el modelo y ajustarlo son pasos separados: podemos definir varios modelos y recién después decidir cuáles ajustar. La lista de modelos está en https://www.tidymodels.org/find/parsnip/

yardstick: evaluar el modelo

  • augment() agrega las predicciones (clase y probabilidades) al conjunto de prueba en una sola línea
  • conf_mat() arma la matriz de confusión que vimos antes
  • metric_set() junta varias métricas. En los labs usamos precision, recall y roc_auc en lugar de accuracy
  • roc_auc es el área bajo la curva ROC: mide qué tan bien separa el modelo las dos clases (0,5 = azar, 1 = perfecto)
  • event_level = "second" le indica cuál es la clase positiva, porque R ordena los niveles alfabéticamente y deja "si" en segundo lugar
  • Para la versión con validación cruzada: fit_resamples() entrena sobre los folds y collect_metrics() promedia los resultados
# Predicciones sobre el test set
pred_test <- ajuste |> augment(datos_test)

conf_mat(pred_test,
         truth    = crecimiento_alto,
         estimate = .pred_class)

# La misma evaluación, pero con
# validación cruzada sobre los folds
fit_resamples(modelo_log,
  crecimiento_alto ~ .,
  resamples = folds,
  metrics = metric_set(precision, recall, roc_auc),
  control = control_resamples(
    event_level = "second")
) |>
  collect_metrics()

Hoy pasamos la fórmula directamente a fit(). Mañana la vamos a reemplazar por recipe() + workflow(), pero el esqueleto sigue siendo este

Resumen de la sesión

Conceptos fundamentales:

  • El flujo de trabajo de ML tiene 5 pasos: recoger, preprocesar, dividir, entrenar, evaluar
  • La calidad de los datos determina la calidad del modelo
  • El feature engineering puede mejorar mucho un modelo simple
  • Dividimos los datos en entrenamiento y prueba para evaluar generalización
  • La validación cruzada es más confiable que una sola división

Problemas y soluciones:

  • El sobreajuste ocurre cuando el modelo memoriza en lugar de aprender
  • La accuracy no es suficiente: necesitamos precisión y recall
  • La reproducibilidad es necesaria para verificar y colaborar

Próximos pasos

  • Ahora: Laboratorio práctico (Sesiones 1.3 y 1.4)
    • Primer flujo de trabajo con tidymodels
    • Clasificación con regresión logística
    • Evaluación y comparación de modelos
  • Mañana (Día 2): Aprendizaje supervisado
    • Sesión 2.1: Clasificación (regresión logística, árboles de decisión, random forest)
    • Sesión 2.2: Regresión y predicción (LASSO, Ridge, Elastic Net)
  • Vamos a aplicar todo lo que vimos hoy con modelos más sofisticados

¡Nos vemos en el laboratorio! 🤓