Introducción

La elección de este tema surge del interés por explorar cómo técnicas de aprendizaje supervisado pueden contribuir al análisis y clasificación del desarrollo de los países, una variable de alta relevancia en estudios económicos y sociales. Ante la creciente disponibilidad de datos y la necesidad de métodos eficientes para su interpretación, aplicar modelos como K-Nearest Neighbors (KNN) y árboles de decisión permite evaluar no solo su rendimiento técnico, sino también su utilidad práctica en contextos reales.

Este informe tiene como propósito comparar la eficacia de estos dos algoritmos mediante un proceso de entrenamiento y prueba con datos del Banco Mundial. La variable objetivo corresponde a una clasificación binaria del Índice de Desarrollo Humano (IDH), considerado un indicador clave en la literatura para medir el progreso de los países. Para ello, se definieron dos categorías: nivel medio-bajo (IDH menor al 80%) y nivel alto (IDH igual o superior al 80%).

La motivación detrás de este enfoque radica en la posibilidad de automatizar, con base en datos objetivos, el diagnóstico del nivel de desarrollo de los países a partir de múltiples indicadores como los que veremos a continuación. Así, se busca no solo identificar qué modelo ofrece mejor desempeño, sino también reflexionar sobre la aplicabilidad de estas herramientas en el análisis socioeconómico desde una perspectiva computacional y cuantitativa.


library(ISLR)
library(readxl)
library(tidyverse)
library(skimr)
library(tree)
library(caret)
library(ROCR)
library(rpart)
library(rpart.plot)
library(ggplot2)
library(dplyr)
library(tidyr)
library(modeest)
library(tibble)
library(class)
library(car)
library(ggcorrplot)
library(plotly)
library(knitr)
library(yardstick)
library(gt)

Metodología

Para la construcción del modelo de clasificación binaria del nivel de desarrollo de los países, se seleccionaron nueve variables cuantitativas expresadas en forma de porcentaje, las cuales representan distintos aspectos del desarrollo socioeconómico. Estas variables fueron extraídas de fuentes oficiales como el Banco Mundial y normalizadas en su formato de porcentaje para asegurar comparabilidad entre países. A continuación, se describen brevemente:

  • IDH es una medida que resume el nivel de desarrollo de un país considerando salud, educación e ingresos. Su valor va de 0 a 1, donde valores más altos indican mayor desarrollo humano.

  • Acceso a electricidad (% de la población): indica el porcentaje de la población con acceso a fuentes modernas de electricidad, lo cual refleja el grado de infraestructura básica disponible en el país.

  • Gasto en salud (% del PIB): representa el porcentaje del Producto Interno Bruto destinado al sector salud, evidenciando el compromiso del país con el bienestar y la atención médica de su población.

  • Tasa de empleo (% de la población activa): mide el porcentaje de personas en edad laboral que se encuentran empleadas, reflejando la estabilidad y capacidad del mercado laboral.

  • Gasto en educación (% del PIB): muestra el porcentaje del PIB invertido en el sistema educativo, lo cual es un indicador clave del desarrollo del capital humano.

  • Uso de internet (% de la población): refiere al porcentaje de personas que utilizan internet, considerado un factor importante de inclusión digital y acceso a la información.

  • Servicio de saneamiento (% de la población): indica el porcentaje de la población con acceso a servicios de saneamiento mejorado, directamente relacionado con las condiciones de salud pública.

  • Uso de energía renovable (% del consumo total de energía): expresa la proporción del consumo energético proveniente de fuentes renovables, vinculada a políticas sostenibles y transición energética.

  • Educación terciaria (% de la población en edad): muestra el porcentaje de personas que acceden a estudios superiores, asociado al nivel de especialización y formación avanzada.

  • Tasa de desempleo (% de la población activa): mide el porcentaje de personas en edad laboral que no tienen empleo y lo están buscando, siendo un indicador inverso del dinamismo económico.

basee <- read_excel("basee.xlsx")
kable(head(basee), caption = "Base de Datos")
Base de Datos
Paises IDH Acceso_electricidad Gasto_salud Tasa_empleo Gasto_educacion Uso_internet Servicio_saneamiento Energia_renovable Educacion_terciaria Tasa_desempleo
Albania 79.7 100.0 6.668446 52.000 3.152945 65.4 98.97365 37.8 56.080299 12.304
Algeria 74.0 99.6 5.932386 37.137 5.812751 49.0 86.30309 0.2 53.163700 12.137
Angola 59.8 45.3 2.594822 62.818 2.183513 29.0 51.12074 52.5 9.352543 16.594
Armenia 78.1 99.9 10.005434 50.226 2.255868 68.2 93.69326 11.1 56.165050 18.966
Australia 94.1 100.0 10.051631 62.232 5.409676 90.0 99.99973 9.8 103.322090 5.300
Austria 91.7 100.0 10.348856 57.914 5.226550 87.5 99.97281 34.1 85.869888 4.933


Modelos de Aprendizaje Supervisado

El enfoque adoptado para la clasificación del nivel de desarrollo fue supervisado, utilizando dos algoritmos: K-Nearest Neighbors (KNN) y Árboles de decisión. En ambos casos, el modelo fue entrenado para predecir una variable binaria que clasifica a los países en dos grupos:

  1. Nivel de desarrollo alto (IDH ≥ 80%)

  2. Nivel de desarrollo medio o bajo (IDH < 80%)

El modelo KNN clasifica observaciones nuevas en función de la similitud con sus vecinos más cercanos, siendo útil cuando se espera que países con características similares compartan niveles de desarrollo. En contraste, los árboles de decisión construyen una estructura jerárquica basada en reglas lógicas que segmentan los datos, facilitando la interpretación de los factores más influyentes en la clasificación. Ambos modelos permiten evaluar no solo el rendimiento, sino también la capacidad explicativa del proceso de clasificación. Cada modelo se ajustó utilizando las nueve variables mencionadas, para determinar cuál de los dos algoritmos resultaba más efectivo en esta tarea de clasificación.


Resultados Descriptivos

A continuación, se presentan las estadísticas descriptivas de las variables numéricas y categóricas del estudio. Para las variables numéricas se calcularon medidas de tendencia central y dispersión (media, mediana, moda y desviación estándar), lo cual permite entender el comportamiento general de los datos.

variables <- c("IDH","Acceso_electricidad", "Gasto_salud", "Tasa_empleo", "Gasto_educacion", "Uso_internet", "Servicio_saneamiento","Energia_renovable","Educacion_terciaria","Tasa_desempleo")

tabla_resultados <- tibble(
  Variable = character(),
  Media = numeric(),
  Mediana = numeric(),
  Moda = numeric(),
  Desviacion = numeric()
)


for (var in variables) {
  valores <- basee[[var]]
  
  media <- mean(valores, na.rm = TRUE)
  mediana <- median(valores, na.rm = TRUE)
  moda <- mlv(valores, method = "mfv")[[1]]
  desviacion <- sd(valores, na.rm = TRUE)
  
  tabla_resultados <- add_row(
    tabla_resultados,
    Variable = var,
    Media = media,
    Mediana = mediana,
    Moda = moda,
    Desviacion = desviacion
  )
}

tabla_resultados


Gráfico de barras: Media por variable

El gráfico de barras presenta el promedio de un conjunto de variables seleccionadas, permitiendo visualizar comparaciones directas entre indicadores clave. Cada barra representa la magnitud media de una variable, como acceso a servicios básicos, gasto público en salud y educación, o tasas de empleo.

datos <- tibble::tibble(
  Variable = c("IDH", "Acceso_electricidad", "Gasto_salud", "Tasa_empleo",
               "Gasto_educacion", "Uso_internet", "Servicio_saneamiento",
               "Energia_renovable", "Educacion_terciaria", "Tasa_desempleo"),
  Media = c(76.6, 90.0, 6.68, 57.0, 4.42, 63.1, 83.2, 29.8, 49.7, 6.70),
  Mediana = c(79.2, 100, 6.66, 57.8, 4.34, 70.0, 95.6, 23.5, 52.5, 5.09),
  Moda = c(63.6, 100, 2.32, 21.7, 0.42, 64.8, 100, 0, 4.70, 4.34),
  Desviacion = c(14.6, 20.8, 2.66, 9.93, 1.48, 25.2, 23.2, 24.1, 29.6, 4.83)
)

# Gráfico de barras: Media por variable
p1 <- ggplot(datos, aes(x = reorder(Variable, Media), y = Media)) +
  geom_bar(stat = "identity", fill = "#0073C2FF") +
  coord_flip() +
  labs(title = "Media por Variable",
       x = "Variable",
       y = "Media") +
  theme_minimal()

ggplotly(p1)

Gráfico de lineas: Media, mediana y moda por variable

El gráfico de líneas compara tres medidas estadísticas fundamentales (media, mediana y moda) para cada variable analizada. Esta representación permite evaluar la distribución de los datos, identificando posibles sesgos o concentraciones en ciertos valores.

#Grafico de lineas: Media, mediana y moda por variable
datos_lineas <- datos %>%
  pivot_longer(cols = c(Media, Mediana, Moda),
               names_to = "Estadistico", values_to = "Valor")

p2 <- ggplot(datos_lineas, aes(x = Variable, y = Valor, color = Estadistico, group = Estadistico)) +
  geom_line(size = 1) +
  geom_point(size = 2) +
  theme_minimal() +
  labs(title = "Media, Mediana y Moda por Variable",
       x = "Variable", y = "Valor") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

ggplotly(p2)
set.seed(777)
basee$IDH_mediobajo <- ifelse(basee$IDH < 80, "Si", "No")
basee$IDH_mediobajo <- as.factor(basee$IDH_mediobajo)
basee$IDH <- NULL 
basee$Paises <- NULL

set.seed(777)
nuevo_entreno <- createDataPartition(y = basee$IDH_mediobajo, p = 0.6038, list = FALSE)

datos_train <- basee[nuevo_entreno,]
datos_test <- basee[-nuevo_entreno,]


Resultados del Modelo

Modelo KNN

set.seed(777)

SP_knnEntrenado <- train(IDH_mediobajo ~ ., 
                         data = datos_train, 
                         method = "knn",  
                         tuneLength = 20
)

plot(SP_knnEntrenado)

set.seed(777)

SP_knnEntrenado
## k-Nearest Neighbors 
## 
## 65 samples
##  9 predictor
##  2 classes: 'No', 'Si' 
## 
## No pre-processing
## Resampling: Bootstrapped (25 reps) 
## Summary of sample sizes: 65, 65, 65, 65, 65, 65, ... 
## Resampling results across tuning parameters:
## 
##   k   Accuracy   Kappa    
##    5  0.8740668  0.7484090
##    7  0.8613175  0.7251997
##    9  0.8633013  0.7285871
##   11  0.8657083  0.7352811
##   13  0.8527706  0.7087966
##   15  0.8597971  0.7230498
##   17  0.8572242  0.7182966
##   19  0.8605840  0.7250007
##   21  0.8567750  0.7177528
##   23  0.8459266  0.6967391
##   25  0.8318373  0.6702657
##   27  0.8279546  0.6632512
##   29  0.8197267  0.6474101
##   31  0.8200738  0.6487738
##   33  0.8215171  0.6514294
##   35  0.8161677  0.6426693
##   37  0.8030835  0.6173269
##   39  0.8094893  0.6301556
##   41  0.7911950  0.5953280
##   43  0.7913761  0.5968250
## 
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was k = 5.

Valor K-Óptimo

Al usar la librería Caret, no se usan múltiples lineas de código, por lo que no necesitamos generar un bucle de forma particular, sino que directamente, al ejecutar el modelo knn, este nos mostrará todos los valores de K escogidos, con su Accuracy y Kappa, y al final nos indicará el valor K óptimo. En este caso, fue el K=5.

Matriz de Confusión KNN

confusionMatrix(SP_knnPrediccion, datos_test$IDH_mediobajo)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction No Si
##         No 20  3
##         Si  0 18
##                                           
##                Accuracy : 0.9268          
##                  95% CI : (0.8008, 0.9846)
##     No Information Rate : 0.5122          
##     P-Value [Acc > NIR] : 1.22e-08        
##                                           
##                   Kappa : 0.8541          
##                                           
##  Mcnemar's Test P-Value : 0.2482          
##                                           
##             Sensitivity : 1.0000          
##             Specificity : 0.8571          
##          Pos Pred Value : 0.8696          
##          Neg Pred Value : 1.0000          
##              Prevalence : 0.4878          
##          Detection Rate : 0.4878          
##    Detection Prevalence : 0.5610          
##       Balanced Accuracy : 0.9286          
##                                           
##        'Positive' Class : No              
## 

El modelo presenta un desempeño sólido con una exactitud del 92.68% y un valor kappa de 0.8541, lo que indica una alta concordancia entre las predicciones y los valores reales, más allá del azar. La sensibilidad perfecta (1.000) muestra que el modelo identifica correctamente todos los casos reales de la clase “No”, mientras que la especificidad de 0.8571 refleja una buena capacidad para detectar los casos reales de la clase “Sí”. Además, el valor predictivo positivo de 0.8696 y el valor predictivo negativo de 1.000 confirman que las predicciones son fiables. El valor p extremadamente bajo (1.22e-08) indica que el modelo es significativamente mejor que una clasificación aleatoria. En conjunto, estas métricas evidencian que el modelo es preciso, equilibrado y estadísticamente robusto.


Curva ROC KNN

pred1 <- prediction(as.numeric(SP_knnPrediccion), as.numeric(datos_test$IDH_mediobajo))
perf1 <- performance(pred1, "tpr", "fpr")
plot(perf1)

Árbol de clasificación (tree)

arbol_clasificacion <- tree(
  formula = IDH_mediobajo ~ .,
  data    = datos_train,
  minsize = 0.0001
)


par(mar = c(4, 4, 2, 2))  # Ajusta según sea necesario
plot(x = arbol_clasificacion, type = "proportional")

text(x = arbol_clasificacion, splits = TRUE, pretty = 0.3, cex = 0.7, col = "firebrick")

predicciones <- predict(
  arbol_clasificacion,
  newdata = datos_test,
  type    = "class"
)

confusionMatrix(predicciones, datos_test$IDH_mediobajo)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction No Si
##         No 18  2
##         Si  2 19
##                                           
##                Accuracy : 0.9024          
##                  95% CI : (0.7687, 0.9728)
##     No Information Rate : 0.5122          
##     P-Value [Acc > NIR] : 1.14e-07        
##                                           
##                   Kappa : 0.8048          
##                                           
##  Mcnemar's Test P-Value : 1               
##                                           
##             Sensitivity : 0.9000          
##             Specificity : 0.9048          
##          Pos Pred Value : 0.9000          
##          Neg Pred Value : 0.9048          
##              Prevalence : 0.4878          
##          Detection Rate : 0.4390          
##    Detection Prevalence : 0.4878          
##       Balanced Accuracy : 0.9024          
##                                           
##        'Positive' Class : No              
## 

El modelo de clasificación Tree obtuvo una exactitud del 90.24%, lo que indica que acertó en poco más del 90% de las predicciones realizadas. El intervalo de confianza al 95% para esta métrica se sitúa entre 0.7687 y 0.9728, y el valor p asociado a la comparación con un modelo sin información (No Information Rate = 0.5122) fue de 1.14e-07, lo que demuestra que el modelo tiene un rendimiento significativamente superior al azar. El coeficiente Kappa fue de 0.8048, lo que refleja una buena concordancia entre las predicciones y los valores reales, más allá de lo que se esperaría por azar.

La matriz de confusión muestra 18 verdaderos negativos, 19 verdaderos positivos, 2 falsos negativos y 2 falsos positivos. Tanto la sensibilidad como la especificidad alcanzaron valores muy equilibrados, en torno al 90% (0.9000 y 0.9048, respectivamente), al igual que los valores predictivos positivo y negativo, que también fueron cercanos al 90%. La exactitud balanceada fue de 90.24%, lo cual refuerza que el modelo es consistente en ambas clases. Además, el valor p de la prueba de McNemar fue 1, lo que indica que no hay una diferencia estadísticamente significativa entre los errores de tipo I y tipo II. En conjunto, este modelo Tree ofrece un rendimiento sólido y equilibrado, tanto en términos de clasificación positiva como negativa.


Curva ROC TREE

pred1 <- prediction(as.numeric(predicciones), as.numeric(datos_test$IDH_mediobajo))
perf1 <- performance(pred1, "tpr", "fpr")
plot(perf1)


Árbol de clasificación (rpart)

modelo_rpart <- rpart(
  formula = IDH_mediobajo ~ .,
  data = datos_train,
  method = "class",
  control = rpart.control(cp = 0.0001)
)

#Visualización modelo árbol

rpart.plot(modelo_rpart, type = 4, extra = 104, under = TRUE, fallen.leaves = TRUE, main = "Árbol de Clasificación - IDH Medio/Bajo")

pred_rpart <- predict(modelo_rpart, newdata = datos_test, type = "class")


confusionMatrix(pred_rpart, datos_test$IDH_mediobajo)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction No Si
##         No 18  1
##         Si  2 20
##                                           
##                Accuracy : 0.9268          
##                  95% CI : (0.8008, 0.9846)
##     No Information Rate : 0.5122          
##     P-Value [Acc > NIR] : 1.22e-08        
##                                           
##                   Kappa : 0.8534          
##                                           
##  Mcnemar's Test P-Value : 1               
##                                           
##             Sensitivity : 0.9000          
##             Specificity : 0.9524          
##          Pos Pred Value : 0.9474          
##          Neg Pred Value : 0.9091          
##              Prevalence : 0.4878          
##          Detection Rate : 0.4390          
##    Detection Prevalence : 0.4634          
##       Balanced Accuracy : 0.9262          
##                                           
##        'Positive' Class : No              
## 

El modelo de clasificación basado en árbol de decisión (Tree) obtuvo una precisión del 92.68%, con un intervalo de confianza del 95% entre 0.8008 y 0.9846, lo que indica un alto nivel de acierto. La matriz de confusión muestra 18 verdaderos negativos, 20 verdaderos positivos, 1 falso positivo y 2 falsos negativos. El valor Kappa fue de 0.8534, lo cual refleja una alta concordancia entre las predicciones del modelo y los valores reales, incluso corrigiendo por el azar.

Además, el valor p de McNemar fue de 1, lo que sugiere que no hay una diferencia significativa entre los errores de tipo I y tipo II. En cuanto a las métricas específicas, el modelo alcanzó una sensibilidad del 90%, una especificidad del 95.24%, un valor predictivo positivo del 94.74% y un valor predictivo negativo del 90.91%. Finalmente, la exactitud balanceada fue de 92.62%, lo cual refuerza que el modelo tiene un rendimiento equilibrado aun cuando las clases tienen prevalencias similares.


Curva ROC RPART

predicciones2 <- predict(
  modelo_rpart,
  newdata = datos_test,
  type    = "class"
)

pred2 <- prediction(as.numeric(predicciones2), as.numeric(datos_test$IDH_mediobajo))
perf2 <- performance(pred2, "tpr", "fpr")
plot(perf2)


Gráfica ROC comparacion arboles de decision

La siguiente gráfica muestra la comparación de las curvas ROC de dos modelos de clasificación basados en árboles de decisión: rpart y tree. La curva ROCR permite evaluar la capacidad de discriminación de cada modelo, mostrando la relación entre la tasa de verdaderos positivos y la tasa de falsos positivos.Cuanto más se aproxime la curva a la esquina superior izquierda, mejor será el desempeño del modelo.

plot(perf2, col = "blue", lwd = 2, main = "Comparación Curvas ROC")
lines(unlist(perf1@x.values), unlist(perf1@y.values), col = "red", lwd = 2)
legend("bottomright", 
       legend = c("Modelo rpart", "Modelo tree"), 
       col = c("blue", "red"), 
       lwd = 2)


Conclusiones

  1. En este trabajo se logró el objetivo de explorar cómo modelos de aprendizaje supervisado pueden aplicarse al análisis del desarrollo de los países. Usando datos del Banco Mundial y técnicas como KNN y árboles de decisión, se logró clasificar el nivel de desarrollo de diferentes países. Más allá de los resultados, este enfoque mostró que es posible usar este tipo de herramientas para ayudar a entender mejor la realidad social y económica de forma más automatizada y clara.

  2. Al comparar los modelos KNN, RPART y TREE, se nota que tanto KNN como RPART obtuvieron los mejores resultados en precisión general (92.68%), apenas por encima del modelo TREE (90.24%). Si se considera el índice Kappa, que ajusta la concordancia esperada por azar, KNN y RPART también muestran un mejor desempeño que TREE.

    • KNN se destaca porque identificó correctamente todos los casos positivos (sensibilidad del 100%) y no tuvo ningún falso negativo. En cambio, RPART fue el mejor para evitar falsos positivos, ya que logró la mayor especificidad (95.24%) y el valor predictivo positivo más alto (94.74%).

    • El modelo TREE mostró resultados muy parejos en todas las métricas, rondando el 90%, aunque un poco por debajo de los otros dos. En cuanto a la precisión equilibrada entre clases, KNN volvió a liderar, seguido por RPART y luego TREE.

  3. Por último, el test de McNemar indicó que ninguno de los modelos tuvo diferencias importantes entre los errores que cometieron. En resumen, si lo más importante es no dejar pasar ningún caso positivo, conviene usar KNN. Si en cambio es clave evitar alarmas falsas, RPART sería la mejor opción. TREE también es una buena alternativa, aunque con un rendimiento general un poco menor.


Glosario

Matriz de confusión

  • Accuracy (Exactitud): Es la proporción de predicciones correctas (tanto verdaderos positivos como verdaderos negativos) entre el total de casos examinados. Proporciona una medida general de la calidad del modelo.

  • 95% CI (Intervalo de Confianza del 95%): Es un rango de valores, derivado de las estadísticas de la muestra, que probablemente contenga el valor real de una población. El 95% indica que hay un 95% de confianza de que el rango contiene dicho valor verdadero.

  • No Information Rate (Tasa de No Información): Es una tasa de precisión que se podría obtener al hacer predicciones usando la clase más frecuente sin tener en cuenta las características. Es una línea base con la que se compara la exactitud del modelo. Por tanto, el NIR proporciona un punto de referencia básico; cualquier modelo que desarrolles debería ser capaz de superar esta tasa de acierto para ser considerado útil.

  • P-Value [Acc > NIR] (P-Valor [Exactitud > Tasa de No Información]): Es el valor p que prueba la hipótesis nula de que la exactitud del modelo no es mejor que la tasa de no información. Un valor p bajo sugiere que el modelo tiene una precisión significativamente mejor que la tasa de no información.

  • Kappa: Es una medida de acuerdo que corrige el acuerdo que se podría esperar por casualidad en la clasificación categórica. El valor de Kappa puede ser interpretado como qué tan mejor es el acuerdo entre las predicciones y los valores verdaderos en comparación con el acuerdo que se esperaría al azar.

  • Mcnemar’s Test P-Value (Valor p del Test de McNemar): Es el valor p asociado con el Test de McNemar, que se utiliza para determinar si hay diferencias entre dos modelos de clasificación sobre los mismos casos.

  • Sensitivity (Sensibilidad): También conocida como el verdadero positivo, es la proporción de casos positivos reales que fueron identificados correctamente por el modelo.

  • Specificity (Especificidad): También conocida como el verdadero negativo, es la proporción de casos negativos reales que fueron identificados correctamente por el modelo.

  • Pos Pred Value (Valor Predictivo Positivo): Es la proporción de casos positivos predichos que son realmente positivos.

  • Neg Pred Value (Valor Predictivo Negativo): Es la proporción de casos negativos predichos que son realmente negativos.

  • Prevalence (Prevalencia): Es la proporción de casos positivos en el conjunto de datos.

  • Detection Rate (Tasa de Detección): Es la proporción de verdaderos positivos en el conjunto de datos.

  • Detection Prevalence (Prevalencia de Detección): Es la proporción de predicciones positivas en el conjunto de datos.

  • Balanced Accuracy (Exactitud Equilibrada): Es el promedio de la sensibilidad y la especificidad. Se utiliza cuando las clases están desbalanceadas, es decir, hay más casos en una clase que en la otra.

  • ‘positive’ class: evento de interés.


Bibliografía

Barandica, O. J. (s. f.). Orlando Joaqui Barandica. Orlando Joaqui Barandica. https://www.joaquibarandica.com/

DataBank | The World Bank. (n.d.). https://databank.worldbank.org/

Human Development Index. (2024, March 14). Our World in Data. https://ourworldindata.org/grapher/human-development-index?time=2018