Taller 3 - KNN
1 Introducción
En el Taller 2 se construyó un modelo de regresión
lineal múltiple para explicar la esperanza de vida al
nacer (exp_vida_nacer) en función de variables de
salud materno-infantil y gasto en salud, usando datos del Banco Mundial
a nivel de país.
En este taller retomamos el mismo contexto, la misma base y la misma variable dependiente, pero con un objetivo distinto: comparar el desempeño predictivo del modelo lineal frente a un modelo de k vecinos más cercanos (k-NN) de regresión, evaluado fuera de muestra.
La pregunta orientadora es: ¿el modelo que mejor explicaba el fenómeno en el Taller 2 también es el que mejor predice en datos nuevos?
2 Librerías y datos
La variable dependiente es exp_vida_nacer y los
predictores son los mismos del Taller 2:
parto_Profesional_salud, anemia_madre,
mort_materna y gasto_salud.
3 Partición train / test
Se utiliza la convención del curso: semilla 123 y
división 80/20.
set.seed(123)
split_test <- initial_split(base_modelo2, prop = 0.80)
train <- training(split_test)
test <- testing(split_test)
tibble(
conjunto = c("train", "test"),
n = c(nrow(train), nrow(test)),
porcentaje = round(c(nrow(train), nrow(test)) / nrow(base_modelo2) * 100, 1)
)## # A tibble: 2 × 3
## conjunto n porcentaje
## <chr> <int> <dbl>
## 1 train 42 79.2
## 2 test 11 20.8
4 Modelo de regresión lineal
4.1 Selección de variables
Se mantienen las mismas variables explicativas seleccionadas en el
Taller 2 (parto_Profesional_salud,
anemia_madre, mort_materna y
gasto_salud), dado que previamente se verificó su
significancia estadística y su relevancia teórica en la explicación de
la esperanza de vida al nacer.
Esto permite realizar una comparación directa entre el modelo lineal y k-NN sin introducir cambios adicionales en la especificación.
modelo_lm <- lm(
exp_vida_nacer ~ parto_Profesional_salud + anemia_madre + mort_materna + gasto_salud,
data = train
)
summary(modelo_lm)##
## Call:
## lm(formula = exp_vida_nacer ~ parto_Profesional_salud + anemia_madre +
## mort_materna + gasto_salud, data = train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.8085 -1.1956 0.1072 1.5077 4.1145
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 69.8331338 5.7716170 12.099 2e-14 ***
## parto_Profesional_salud 0.1397219 0.0572279 2.441 0.019529 *
## anemia_madre -0.2888084 0.0718641 -4.019 0.000276 ***
## mort_materna -1.8691006 1.3346269 -1.400 0.169704
## gasto_salud 0.0006173 0.0002405 2.567 0.014451 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.231 on 37 degrees of freedom
## Multiple R-squared: 0.8773, Adjusted R-squared: 0.864
## F-statistic: 66.14 on 4 and 37 DF, p-value: 2.397e-16
El modelo lineal conserva la misma estructura del Taller 2 y mantiene signos coherentes en los coeficientes:
- Un mayor porcentaje de partos atendidos por profesionales de salud se asocia con mayor esperanza de vida.
- Mayores niveles de anemia materna y mortalidad materna se relacionan negativamente con la esperanza de vida.
- El gasto en salud presenta una relación positiva.
Estos resultados son consistentes con el análisis previo y refuerzan la interpretación del modelo como herramienta explicativa.
5 Modelo k-NN de regresión
5.1 Preprocesamiento
Dado que k-NN se basa en distancias euclidianas, es necesario
estandarizar las variables numéricas (centrado y
escalado). En este caso todos los predictores son cuantitativos, por lo
que no se requiere codificación dummy. El preprocesamiento se
hace dentro de caret para que los parámetros de escalado se
estimen solo con los datos de entrenamiento y se
apliquen al test (evitando fuga de información).
5.2 Selección de k por validación cruzada
Se utilizan 5 folds sobre el conjunto de entrenamiento, explorando
k = 1, 2, ..., 25 y eligiendo el valor que minimiza el
RMSE.
set.seed(123)
control_cv <- trainControl(method = "cv", number = 5)
set.seed(123)
modelo_knn <- train(
exp_vida_nacer ~ parto_Profesional_salud + anemia_madre + mort_materna + gasto_salud,
data = train,
method = "knn",
trControl = control_cv,
tuneGrid = data.frame(k = 1:25),
preProcess = c("center", "scale"),
metric = "RMSE"
)
modelo_knn## k-Nearest Neighbors
##
## 42 samples
## 4 predictor
##
## Pre-processing: centered (4), scaled (4)
## Resampling: Cross-Validated (5 fold)
## Summary of sample sizes: 33, 34, 33, 34, 34
## Resampling results across tuning parameters:
##
## k RMSE Rsquared MAE
## 1 2.474845 0.7876812 1.945990
## 2 2.191073 0.8296757 1.678448
## 3 2.108448 0.8548408 1.627141
## 4 2.355878 0.8514014 1.875605
## 5 2.633424 0.8400084 2.095982
## 6 2.857947 0.8235043 2.206803
## 7 3.040969 0.8243582 2.298689
## 8 3.175154 0.8221814 2.379760
## 9 3.307823 0.8073322 2.464234
## 10 3.453376 0.8029037 2.519086
## 11 3.566605 0.7907404 2.608369
## 12 3.639571 0.7922942 2.666296
## 13 3.767255 0.7815581 2.785481
## 14 3.831306 0.7930800 2.876187
## 15 3.859493 0.8054427 2.911582
## 16 3.981314 0.8030547 3.003973
## 17 4.052387 0.8149915 3.075048
## 18 4.159279 0.8145268 3.147689
## 19 4.291906 0.7813119 3.240265
## 20 4.434278 0.7707633 3.356948
## 21 4.502335 0.7881743 3.421586
## 22 4.543811 0.8084697 3.485732
## 23 4.665051 0.8108029 3.594207
## 24 4.715230 0.8215879 3.664928
## 25 4.819851 0.8130758 3.761314
##
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was k = 3.
El mejor valor de k seleccionado por validación cruzada
es:
## k
## 3 3
6 Evaluación en el conjunto de prueba
Se generan predicciones con ambos modelos sobre test y
se calculan RMSE y MAE.
pred_lm <- predict(modelo_lm, newdata = test)
pred_knn <- predict(modelo_knn, newdata = test)
comparacion <- tibble(
Modelo = c("Regresión lineal", "k-NN"),
RMSE = c(rmse_vec(test$exp_vida_nacer, pred_lm),
rmse_vec(test$exp_vida_nacer, pred_knn)),
MAE = c(mae_vec(test$exp_vida_nacer, pred_lm),
mae_vec(test$exp_vida_nacer, pred_knn))
)
comparacion## # A tibble: 2 × 3
## Modelo RMSE MAE
## <chr> <dbl> <dbl>
## 1 Regresión lineal 3.02 2.13
## 2 k-NN 2.69 2.09
df_plot <- tibble(
obs = rep(test$exp_vida_nacer, 2),
pred = c(pred_lm, pred_knn),
Modelo = rep(c("Regresión lineal", "k-NN"), each = nrow(test))
)
ggplot(df_plot, aes(obs, pred, color = Modelo, fill = Modelo)) +
geom_abline(slope = 1, intercept = 0, linetype = "dashed") +
geom_smooth(
data = filter(df_plot, Modelo == "Regresión lineal"),
method = "lm", se = TRUE, level = 0.95, alpha = 0.2
) +
geom_point(size = 2, alpha = 0.9) +
facet_wrap(~ Modelo) +
labs(x = "Esperanza de vida observada",
y = "Esperanza de vida predicha",
title = "Predicho vs observado en el conjunto de prueba",
subtitle = "Banda sombreada: IC 95% del ajuste lineal predicho vs observado") +
theme_minimal() +
theme(legend.position = "none")7 Discusión
A partir de las métricas fuera de muestra se discuten las preguntas guía:
- ¿Cuál modelo predijo mejor en los datos de prueba? El modelo k-NN obtuvo mejor desempeño predictivo que la regresión lineal en ambas métricas: RMSE de 2.69 frente a 3.02 (≈11% más bajo) y MAE de 2.09 frente a 2.13. La diferencia es mayor en RMSE que en MAE, lo que sugiere que k-NN reduce especialmente los errores grandes en algunos países. Esto indica que existen relaciones no estrictamente lineales entre los predictores de salud materno-infantil y la esperanza de vida, que k-NN logra aprovechar al apoyarse en los vecinos más cercanos en el espacio estandarizado de variables.
- ¿El mejor modelo fue también el más interpretable? No. Aquí aparece un trade-off clásico entre capacidad predictiva e interpretabilidad: k-NN predice mejor pero no entrega coeficientes ni efectos marginales, mientras que la regresión lineal —aunque con mayor error— permite cuantificar el efecto de cada predictor sobre la esperanza de vida y realizar inferencia clásica.
- ¿Cambian las conclusiones del Taller 2? Parcialmente. Las conclusiones explicativas del Taller 2 siguen siendo válidas: el modelo lineal identifica qué variables están asociadas con la esperanza de vida y en qué magnitud. Sin embargo, si el objetivo es predecir en nuevos países, k-NN resulta más adecuado, lo que muestra que “explicar bien” y “predecir bien” no siempre coinciden.
- Ventajas y limitaciones:
- Regresión lineal: alta interpretabilidad, inferencia clásica (IC, pruebas t/F), estable con pocas observaciones. Limitación: asume linealidad y puede perder patrones no lineales.
- k-NN: flexible y no paramétrico, capta relaciones no
lineales e interacciones sin especificarlas. Limitaciones: no entrega
coeficientes interpretables, es sensible a la escala (por eso fue
necesario estandarizar), requiere elegir k por validación
cruzada, y con
n = 53su desempeño puede ser inestable frente a cambios en la partición.
8 Conclusiones
En este conjunto de datos, el modelo de k-NN de regresión logró un menor RMSE en el conjunto de prueba que la regresión lineal múltiple, lo que indica que captura relaciones no lineales entre las variables de salud materno-infantil y la esperanza de vida al nacer. La respuesta a la pregunta orientadora es negativa: el modelo que mejor explicaba el fenómeno en el Taller 2 (regresión lineal) no es el que mejor predice en datos nuevos.
No obstante, la elección del modelo depende del objetivo: si se busca interpretación y comunicación de efectos, la regresión lineal sigue siendo la herramienta adecuada; si se busca máxima capacidad predictiva, k-NN es preferible en este caso. Este taller ilustra claramente el trade-off entre interpretabilidad y capacidad predictiva, uno de los temas centrales del aprendizaje supervisado.
9 Bibliografía
- James, G., Witten, D., Hastie, T., & Tibshirani, R. (2021). An Introduction to Statistical Learning with Applications in R (2nd ed.). Springer.
- Kuhn, M. (2008). Building Predictive Models in R Using the caret Package. Journal of Statistical Software, 28(5).
- Banco Mundial. World Development Indicators. https://databank.worldbank.org/