Este documento guía paso a paso la construcción de un modelo de
regresión lineal usando el framework
tidymodels. El objetivo es predecir la masa
corporal (body_mass_g) de pingüinos del
Archipiélago Palmer a partir de sus características físicas.
Dataset:
palmerpenguins— una alternativa moderna y amigable al clásico Iris dataset.
El siguiente bloque detecta automáticamente si las librerías necesarias están instaladas; si no, las descarga e instala antes de cargarlas.
paquetes <- c("tidyverse", "tidymodels", "palmerpenguins", "vip")
faltantes <- paquetes[!paquetes %in% rownames(installed.packages())]
if (length(faltantes) > 0) {
install.packages(faltantes)
}
library(tidyverse)
library(tidymodels)
library(palmerpenguins)
library(vip)| Paquete | Rol en este ejercicio |
|---|---|
tidyverse |
Manipulación y visualización de datos |
tidymodels |
Framework unificado para modelado (split, receta, workflow, métricas) |
palmerpenguins |
Dataset de entrenamiento |
vip |
Visualización de importancia de variables |
Cargamos el dataset penguins y eliminamos las filas con
valores faltantes (NA), que representan una fracción
pequeña del total y podrían sesgar el modelo.
## Rows: 333
## Columns: 8
## $ species <fct> Adelie, Adelie, Adelie, Adelie, Adelie, Adelie, Adel…
## $ island <fct> Torgersen, Torgersen, Torgersen, Torgersen, Torgerse…
## $ bill_length_mm <dbl> 39.1, 39.5, 40.3, 36.7, 39.3, 38.9, 39.2, 41.1, 38.6…
## $ bill_depth_mm <dbl> 18.7, 17.4, 18.0, 19.3, 20.6, 17.8, 19.6, 17.6, 21.2…
## $ flipper_length_mm <int> 181, 186, 195, 193, 190, 181, 195, 182, 191, 198, 18…
## $ body_mass_g <int> 3750, 3800, 3250, 3450, 3650, 3625, 4675, 3200, 3800…
## $ sex <fct> male, female, female, female, male, female, male, fe…
## $ year <int> 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007…
Tras la limpieza, contamos con 333 observaciones y 8 variables. Las variables que usaremos como predictores son:
flipper_length_mm — Longitud de la aletabill_length_mm — Longitud del picospecies — Especie del pingüinosex — Sexo del individuoAntes de modelar, visualizamos las relaciones más importantes entre las variables.
ggplot(df_penguins, aes(x = flipper_length_mm, y = body_mass_g, color = species)) +
geom_point(alpha = 0.6, size = 2) +
geom_smooth(method = "lm", se = FALSE, linewidth = 0.8) +
scale_color_brewer(palette = "Set1") +
labs(
title = "Longitud de aleta vs. masa corporal",
subtitle = "Separado por especie — cada una sigue su propia tendencia lineal",
x = "Longitud de aleta (mm)",
y = "Masa corporal (g)",
color = "Especie"
) +
theme_minimal(base_size = 13)ggplot(df_penguins, aes(x = sex, y = body_mass_g, fill = sex)) +
geom_boxplot(alpha = 0.7, outlier.colour = "grey40") +
scale_fill_manual(values = c("female" = "#F4A2A2", "male" = "#A2C4F4")) +
labs(
title = "Distribución de masa corporal por sexo",
subtitle = "Los machos tienden a ser significativamente más pesados",
x = "Sexo",
y = "Masa corporal (g)"
) +
theme_minimal(base_size = 13) +
theme(legend.position = "none")Separamos el dataset en 80% entrenamiento y 20% prueba, usando estratificación por especie para garantizar una distribución proporcional en ambas particiones.
set.seed(123) # Semilla para reproducibilidad
penguin_split <- initial_split(df_penguins, prop = 0.80, strata = species)
train_data <- training(penguin_split)
test_data <- testing(penguin_split)
cat("Observaciones en entrenamiento:", nrow(train_data), "\n")## Observaciones en entrenamiento: 265
## Observaciones en prueba: 68
tidymodelsEl workflow de tidymodels separa claramente tres
responsabilidades: preprocesamiento (receta),
especificación del modelo y ensamblado
(workflow).
## Linear Regression Model Specification (regression)
##
## Computational engine: lm
Aplicamos el modelo entrenado sobre el conjunto de prueba y calculamos las métricas principales.
results <- test_data %>%
bind_cols(predict(penguin_fit, test_data))
# Métricas: RMSE, R² y MAE
metrics(results, truth = body_mass_g, estimate = .pred)La línea punteada roja representa el ajuste perfecto (predicción = valor real). Cuanto más cercanos estén los puntos a esa línea, mejor el modelo.
ggplot(results, aes(x = body_mass_g, y = .pred)) +
geom_point(alpha = 0.6, color = "#3A7DC9", size = 2) +
geom_abline(lty = 2, color = "red", linewidth = 0.8) +
labs(
title = "Predicción vs. Realidad",
subtitle = "Los puntos deben alinearse sobre la diagonal para un buen modelo",
x = "Masa corporal real (g)",
y = "Masa corporal predicha (g)"
) +
theme_minimal(base_size = 13)¿Qué características fueron las más determinantes para el modelo?
penguin_fit %>%
extract_fit_parsnip() %>%
vip(num_features = 10, aesthetics = list(fill = "#3A7DC9", alpha = 0.85)) +
labs(
title = "Importancia de Variables",
subtitle = "Basada en el valor absoluto de los coeficientes estandarizados"
) +
theme_minimal(base_size = 13)El modelo de regresión lineal entrenado con tidymodels
logró un R² de 0.888 y un RMSE de 283.4
g, lo que indica que explica la mayoría de la varianza en la
masa corporal de los pingüinos.
Los puntos clave del ejercicio son:
recipe → workflow → fit → predict de
tidymodels hace el proceso reproducible y fácil de escalar
a modelos más complejos.Generado automáticamente con R 4.5.3 y tidymodels
1.4.1.