Apellidos | Nombres | Código |
---|---|---|
Colca Balbin | Josue Jeremías | 20220761 |
Jesús Mamani | Angelo Miguel | 20220767 |
Landa Cordova | Valeria Estefany | 20220768 |
Ramos Orue | Selene Milagros | 20220777 |
Sanchez Perez | Omar Zenon | 20211938 |
Sandoval Hurtado | Nagiely | 20220780 |
Los métodos basados en árboles son modelos no paramétricos que usan reglas de decisión para predecir una respuesta a partir de variables predictoras. En concreto, permiten resolver problemas tanto de clasificación (respuesta categórica, por ejemplo “desarrollará enfermedad: sí/no”) como de regresión (respuesta numérica, por ejemplo nivel de glucosa). Un árbol de decisión inicia en un nodo raíz con todo el conjunto de datos de entrenamiento y lo divide recursivamente en ramas según condiciones como “\(¿x_k ≤ c?\)” para variables continuas o “¿\(x_k = nivel_j\)?” para variables categóricas. Cada división busca crear subgrupos homogéneos respecto a la respuesta. El proceso de división continúa hasta un criterio de parada (por ejemplo, un número mínimo de observaciones en un nodo o una profundidad máxima). Al final, cada hoja del árbol realiza la predicción: en un árbol de regresión predice la media de los valores de la respuesta en ese subgrupo; en un árbol de clasificación asigna la clase mayoritaria del subgrupo (y suele estimar la probabilidad de cada clase). En el contexto de salud binaria, por ejemplo, un árbol de clasificación podría predecir “enfermedad sí/no” y proporcionar la probabilidad de enfermedad en cada hoja.
Los árboles de decisión construyen particiones del espacio predictor basadas en preguntas binarias iterativas. Cada nodo interno corresponde a una condición del tipo “\(¿x_j ≤ c?\)” (para una variable cuantitativa) o “¿\(x_j = nivel_k\)?” (para una cualitativa). La elección de la variable y el umbral se hace buscando maximizar la pureza de los subgrupos resultantes. En árboles de regresión, la pureza se mide típicamente minimizando el error cuadrático: se selecciona la partición que minimiza la suma de los residuos cuadrados en los nodos hijos. En árboles de clasificación, se minimiza la impureza de clase; un criterio común es el índice de Gini. Si en un nodo dado la variable respuesta tiene \(\kappa\) clases y \(p_i\) es la proporción de la clase \(i\) en el nodo, el índice de Gini se define por:
y para una partición en dos subnodos \(X_1,X_2\) de tamaños \(n_1,n_2\) sobre un total \(n=n_1+n_2\), la impureza ponderada es
En árboles binarios (respuesta \(\kappa=2\)), esto coincide con maximizar la ganancia de información (reducción de entropía). El algoritmo CART (Classification and Regression Trees) prefiere la variable de entrada que produce la menor impureza ponderada tras la división.
En el contexto de salud, un árbol de regresión podría predecir, por ejemplo, el nivel continuo de presión arterial de un paciente a partir de edad, índice de masa corporal, hábitos de vida, etc. Un árbol de clasificación podría predecir si un paciente desarrollará o no desarrollará una enfermedad, asignando “sí” o “no” según la mayoría de casos en cada hoja y proporcionando una probabilidad estimada de enfermedad.
Un árbol de regresión tiene una variable respuesta continua. En cada nodo se busca la partición (variable predictora \(X_j\) y corte \(c\)) que minimice la suma de cuadrados de los residuos (RSS) en los nodos hijos. Formalmente, si un nodo \(R\) con observaciones \({(x_i,y_i)}\) se divide en \(R_1\) y \(R_2\), se elige el par \((j,c)\) que minimiza
donde \(\bar y_{R_k}\) es la media de \(y_i\) en el subgrupo \(R_k\). Equivalente, se minimiza la RSS total \(\sum (y_i - \hat y_i)^2\) en el nodo. Este proceso crea regiones de predicción aproximadas por constantes (la predicción en cada hoja es la media de \(y\) en esa hoja). Por ejemplo, al predecir la glucemia en sangre de un paciente, el árbol podría dividir primero por edad, luego por IMC, etc., y en cada hoja devolver la glucosa promedio observada de pacientes con condiciones similares.
En un árbol de clasificación la respuesta \(Y\) es cualitativa (por ejemplo, “tiene la enfermedad” vs “no la tiene”). Cada nodo se divide usando una medida de impureza de clases. El criterio más común es el índice de Gini (definido arriba) o la entropía de Shannon. El algoritmo busca la partición que maximice la pureza de las clases en los hijos. Por ejemplo, un nodo con 30% casos de enfermos y 70% sanos tiene \(Gini =1 - (0.3^2+0.7^2)\), y una partición se elige para minimizar la Gini ponderada tras la división. Al final, cada hoja asigna la clase mayoritária de los pacientes en ella como predicción. Además, puede reportarse la probabilidad estimada de enfermedad en esa hoja (porcentaje de casos positivos). En salud, un árbol de clasificación podría, por ejemplo, predecir “diabetes sí/no”: cada hoja contendría un número de pacientes diabéticos vs no diabéticos, y el árbol asigna la clase que predomina (por ejemplo, “sí”) y la probabilidad correspondiente.
A diferencia de los modelos lineales (regresión o clasificación lineal), los árboles no asumen una relación lineal entre predictores y respuesta. Pueden capturar relaciones muy complejas y no lineales porque particionan el espacio de entrada en regiones arbitrarias. Por ejemplo, mientras la regresión lineal modela \(Y=\beta_0+\sum \beta_j X_j\), un árbol de decisión puede segmentar los datos primero por edad, luego por IMC, etc., implicitando interacciones sin necesidad de especificarlas previamente. Esto les permite adaptarse bien cuando hay curvas o umbrales en el efecto de los predictores.
Sin embargo, los árboles pueden sobreajustar fácilmente si no se controlan: tienden a crear particiones muy específicas al entrenamiento y luego generalizan mal a datos nuevos. Por el contrario, un modelo lineal sencillo suele ser más robusto al sobreajuste (aunque puede quedar corto si los datos tienen patrones no lineales). Además, la interpretabilidad contrasta: los coeficientes de la regresión lineal ofrecen una ecuación explícita fácil de interpretar, mientras que un árbol profundo puede ser difícil de analizar de un vistazo, aunque su representación en forma de diagrama es intuitiva. En resumen, un árbol de decisión es preferible cuando sospechamos efectos no lineales o interacciones fuertes entre variables, mientras que un modelo lineal es mejor cuando la relación es aproximadamente lineal y simple.
Ventajas: Los árboles de decisión son muy fáciles de entender y visualizar: las reglas de “si-entonces” resultantes suelen ser intuitivas, algo valioso en medicina para explicar decisiones. No requieren normalizar ni estandarizar las variables, y manejan directamente tanto variables cuantitativas como cualitativas (incluyendo variables binarias). Además, capturan automáticamente efectos no lineales e interacciones sin necesidad de especificarlas. Son métodos no paramétricos, es decir, no hacen suposiciones fuertes sobre la distribución de los datos. Su entrenamiento suele ser rápido (cada árbol se construye con complejidad relativamente baja) y manejan bien datos con mucha dimensionalidad (muchos predictores) si se podan adecuadamente.
Desventajas: Los árboles son muy sensibles al ruido y a pequeñas perturbaciones en los datos: una leve variación en las muestras de entrenamiento puede cambiar radicalmente la estructura del árbol. Esto los hace inestables y con alta varianza. Si no se podan o regularizan, tienden a sobreajustar los datos de entrenamiento. En problemas de clasificación con clases muy desbalanceadas pueden sesgarse hacia la clase mayoritaria. Además, los árboles profundos pueden ser complejos de interpretar en conjunto (aunque cada regla individual es clara). Estos inconvenientes explican por qué en la práctica a menudo se usan métodos de ensamble basados en árboles (bagging, random forest, boosting) para mejorar la precisión.
Además de los árboles individuales, existen técnicas de aprendizaje por ensamblado que combinan múltiples árboles débiles para mejorar la predicción. En el contexto de salud, estos métodos suelen dar modelos más precisos y estables. En general, un árbol aislado se combina con otros para reducir el sobreajuste y la varianza. Los más importantes son bagging, random forests y boosting.
Bagging (Bootstrap Aggregation) es una técnica para reducir la varianza de un modelo de alta varianza como el árbol. La idea es generar \(B\) conjuntos de entrenamiento bootstrap (muestras con reemplazo del conjunto original), ajustar en cada uno un árbol de regresión o clasificación completo (sin poda), y luego combinar las predicciones de estos \(B\) árboles. Para regresión se promedian sus predicciones, y para clasificación se toma votación mayoritaria. Al entrenar cada árbol sobre una muestra distinta, se obtiene un conjunto de árboles distintos. El error global del ensamble suele ser menor que el de un solo árbol porque los errores aleatorios se promedian. Por ejemplo, para predecir enfermedad cardiovascular, podríamos generar 100 árboles con diferentes muestras bootstrap y cada uno daría su predicción; el resultado final sería el promedio o el voto mayoritario de esas predicciones. Bagging no altera el sesgo de los árboles (cada árbol sigue siendo un modelo complejo), pero reduce mucho la varianza al promediar. También permite estimar un error de predicción interno: al hacer bootstrap, cerca de 1/3 de las observaciones originales quedan “fuera de bolsa” (out-of-bag) en cada muestra y se pueden usar para validar el árbol correspondiente. En problemas de clasificación binaria, bagging suele mejorar notablemente la estabilidad del predictor y la precisión, comparado con un árbol único.
Esquema ilustrativo de un Random Forest con tres árboles débiles. Cada árbol vota “ACEPTA” o “RECHAZA” y la predicción final se decide por votación mayoritaria.
Random Forest extiende la idea de bagging añadiendo aleatoriedad extra: al crecer cada árbol, en cada división se elige no entre todas las variables, sino entre un subconjunto aleatorio de ellas. Esto evita que todos los árboles elijan las mismas variables dominantes (como suele ocurrir en bagging) y reduce la correlación entre árboles. El procedimiento es: para cada árbol, se extrae un bootstrap del entrenamiento; al momento de cada partición, en lugar de buscar entre las \(p\) variables la mejor división, el árbol elige la mejor partición solo dentro de un subconjunto aleatorio de tamaño \(m_\text{try}\). Por defecto en clasificación se toma \(m_\text{try}=\sqrt{p}\) (y en regresión \(m_\text{try}=p/3\)). Esta aleatorización adicional da árboles más diversos y mejora la generalización. Los árboles del bosque crecen muy profundos y no se podan, lo que hace al conjunto robusto. En la Figura de arriba se muestra un ejemplo simplificado: cada árbol (1,2,3) emite “ACEPTA” o “RECHAZA” para un paciente, y el bosque predice la respuesta más frecuente (en el dibujo “ACEPTA” con 2 de 3 votos). En general, un random forest requiere muchos árboles (decenas o cientos) para estabilizar la predicción. Su principal ventaja práctica es que funciona muy bien “out-of-the-box” con valores por defecto de hiperparámetros: suele dar alta precisión sin mucho ajuste. Es rápido de entrenar en paralelo y maneja bien tanto problemas de clasificación como de regresión. Sin embargo, como cualquier método de ensamble, sacrifica algo de interpretabilidad: el modelo final es una caja negra cuya “regla de decisión” agregada no se expresa fácilmente en forma de reglas sencillas.
Ejemplo esquemático de Gradient Boosting: cada árbol sucesivo corrige los errores del modelo acumulado, y la predicción final se obtiene como una combinación ponderada de los árboles débiles.
Boosting es un enfoque de ensamblado diferente. En lugar de entrenar árboles en paralelo con bootstrap, boosting entrena secuencialmente árboles “débilmente” correlacionados, de modo que cada nuevo árbol se centra en corregir los errores de los anteriores. En otras palabras, el primer árbol se ajusta al conjunto original; luego se construye un segundo árbol que trata de predecir los residuos (o las observaciones mal clasificadas) del primero, y así sucesivamente. Al final se combina la predicción de todos los árboles mediante una votación o suma ponderada. Una forma intuitiva de ver la diferencia con bagging es la siguiente: en bagging se combinan muchos árboles aprendiendo de datos bootstrap de forma independiente (“muchos amigos dando ideas al mismo tiempo”), mientras que en boosting los árboles se agregan uno tras otro, cada uno enfocándose en los casos difíciles que no acertó el anterior (“un amigo tras otro, cada uno corrigiendo al anterior”. Los algoritmos clásicos de boosting incluyen AdaBoost (Adaptive Boosting) y Gradient Boosting. AdaBoost ajusta un árbol tras otro asignando más peso a los casos mal clasificados previamente; Gradient Boosting construye árboles optimizando gradualmente una función de pérdida (por ejemplo, log-verosimilitud para clasificación binaria). En boosting las predicciones se combinan ponderadamente: en clasificación por votación ponderada y en regresión por suma ponderada. Por ejemplo, en clasificación binaria se puede definir un modelo final \(f(x)=\sum_{k=1}^K f_k(x)\), donde cada \(f_k\) es un árbol débil. Entonces la probabilidad estimada de clase “1” puede definirse usando la función logística:
de manera que ajustar el boosting equivale a encontrar \(f\) que maximice la verosimilitud de los datos. En cada iteración se añade un árbol \(f_k\) al modelo considerando la derivada del log-loss (residuales “pseudo” de la iteración previa). En la práctica se incluyen hiperparámetros como la tasa de aprendizaje \(\alpha\) (peso con el que cada árbol nuevo contribuye) y la profundidad máxima de cada árbol (control de complejidad) para evitar sobreajuste.
Ventajas del boosting: suele obtener modelos muy precisos, pues reduce tanto sesgo como varianza al enfocarse en errores previos. Frecuentemente supera en precisión a métodos más simples. No requiere preprocesamiento especial de variables (maneja datos faltantes y variables categóricas). Cada árbol nuevo “aprende de sus errores” para mejorar la predicción. Los árboles sucesivos refuerzan las regiones donde hay errores y aportan flexibilidad al modelo final. Desventajas: Como los árboles se entrenan secuencialmente, boosting es más lento y difícil de paralelizar que bagging o random forest. Al añadir árboles de forma indefinida puede sobreajustar los datos, sobre todo si la tasa de aprendizaje es alta. Hay que ajustar cuidadosamente el número de árboles, la tasa de aprendizaje y la complejidad de cada árbol para evitar un modelo excesivamente complejo. Además, al combinar muchos árboles el modelo final es complejo y suele considerarse de “caja negra”: resulta difícil de interpretar directamente, al igual que otros métodos de ensamblado. Por estas razones, en la práctica se suelen usar variantes optimizadas (por ejemplo, XGBoost o LightGBM) y validación cruzada para afinar los hiperparámetros del boosting.
A continuación se explicara de manera conceptual cómo se ajustan y aplican los métodos basados en árboles en un contexto de salud (p.ej. predicción de una enfermedad).
Para ajustar un árbol de clasificación se procede así:
Se divide el conjunto de entrenamiento recursivamente. En cada paso el algoritmo escoge el mejor predictor \(X_j\) y valor de corte \(c\) que maximizan la pureza de clase (p.ej. minimizan el índice de Gini o maximizan la ganancia de información) en los hijos. Esto produce una partíción del espacio en regiones con pacientes similares.
Se continúa hasta cumplir criterios de parada (por ejemplo, profundidad máxima o número mínimo de pacientes por hoja).
Se asigna a cada hoja la clase más frecuente.
Para evitar sobreajuste es común podar el árbol: se ajusta un árbol muy profundo y luego se aplica poda de complejidad (cost-complexity pruning). Esto implica seleccionar el árbol \(\hat T\) que minimice un criterio como \(R_\alpha(T) = R(T) + \alpha |T|\), donde \(R(T)\) es el error de clasificación en entrenamiento y \(|T|\) el número de hojas; \(\alpha\) es un parámetro que controla la penalización por complejidad. En la práctica se usa validación cruzada para elegir \(\alpha\) óptimo y así el árbol podado final.
Ejemplo ilustrativo: Supongamos un dataset médico para predecir diabetes (variable binaria 0/1) a partir de edad, nivel de insulina, BMI y factores de riesgo familiares. El algoritmo CART podría descubrir primero un nodo “edad ≥ 50 años”, separando pacientes mayores y menores de 50. Luego en cada rama subdivide por otra variable (p.ej. índice de masa corporal alto vs bajo, o nivel de glucosa en sangre mayor vs menor). Cada hoja final predice diabetes “sí” o “no” según la mayoría de pacientes en ella. Se evaluaría el rendimiento con métricas como precisión, sensibilidad y especificidad sobre datos de validación o test.
Aunque el enfoque está en clasificación binaria, también cabe un árbol de regresión en salud (por ejemplo, predecir la edad de aparición de una enfermedad o el nivel de presión arterial futuro). El ajuste es análogo: en cada nodo se busca la partición que minimice la suma de cuadrados (RSS) en los hijos. El árbol resultante predice en cada hoja la media de \(Y\) en esa región. Al igual que en clasificación, se suele podar el árbol para equilibrar sesgo y varianza.
Ejemplo: Podríamos usar un árbol de regresión para estimar el riesgo continuo de enfermedad cardiovascular (escala 0-1). El árbol segmentaría el espacio por variables de riesgo (colesterol, tabaco, actividad física, etc.) minimizando el error cuadrático. Cada hoja daría el riesgo promedio observado de los pacientes de entrenamiento en esa región. Luego se validaría el árbol con el error cuadrático medio (RMSE) en nuevos datos.
Para aplicar bagging, se generan múltiples árboles como en la teoría:
a cada árbol se le entrena con una muestra bootstrap distinta. En
clasificación binaria, cada árbol vota por “enfermedad sí/no” y la
predicción final del ensamble es el voto mayoritario. En regresión se
promedian las predicciones de los árboles. En R se puede usar la función
randomForest()
con mtry=p
(todas las
variables) para simular bagging. Un dato adicional es que out-of-bag
(OOB) puede usarse para estimar el error sin validación cruzada: en cada
árbol, las observaciones no seleccionadas para ese bootstrap se usan
como test interno.
Para random forests, el procedimiento es similar pero en cada división interna sólo se elige entre un subconjunto aleatorio de predictores. Esto suele mejorar la precisión respecto al bagging normal y a un solo árbol. En salud, random forests se aplican frecuentemente por su alta eficacia. Por ejemplo, para predecir diabetes se podría entrenar un random forest con 500 árboles, donde en cada división se prueban sólo \(\sqrt{p}\) variables al azar. El modelo resultante suele tener alta precisión y permite calcular importancias de variable, lo que ayuda a identificar factores de riesgo más relevantes (aunque el bosque completo sea menos interpretable que un solo árbol).
En boosting se entrena un árbol tras otro. Cada árbol nuevo intenta
corregir los errores de los anteriores, ajustando más los casos que
fueron mal predichos. Un algoritmo común para clasificación binaria es
AdaBoost, que repondera iterativamente los casos difíciles. Otro muy
usado es Gradient Boosting: se añade un árbol por iteración ajustándose
al residuo logístico de la iteración previa. En la práctica en R/Python
existen implementaciones como xgboost
o gbm
que optimizan muchos detalles.
Al igual que en caso teórico, en boosting se combinan las predicciones de todos los árboles. En clasificación se suele usar votación ponderada: árboles con mejor desempeño tienen mayor peso. En regresión, suma ponderada. Es importante regularizar ajustando la tasa de aprendizaje y limitando la profundidad de los árboles.
Ejemplo: Para predecir la probabilidad de infarto (sí/no), se podría usar gradient boosting. El primer árbol produce una predicción inicial; luego cada nuevo árbol modela la diferencia entre la etiqueta real y la predicción actual (p. ej. usando residuos de la verosimilitud logística . Se acumulan, dando la función \(f(x)=\sum_k f_k(x)\). Finalmente, la probabilidad de infarto se calcula como \(\sigma(f(x))=1/(1+e^{-f(x)})\). Con suficientes árboles (y una tasa de aprendizaje pequeña), el modelo suele conseguir alta precisión. Sin embargo, hay que detenerse cuando el error en validación comienza a aumentar para evitar sobreajuste.
En resumen, los métodos basados en árboles ofrecen una rica caja de herramientas para predicción en salud. Los árboles de decisión simples son transparentes y útiles para exploración de relaciones complejas, pero su limitación de varianza se supera con ensambles como bagging, random forests y boosting. Cada técnica tiene sus ventajas: los bosques aleatorios son un buen punto de partida robusto, mientras que boosting (especialmente Gradient Boosting o XGBoost) suele alcanzar las mejores precisiones cuando se calibra bien.
James, G., Witten, D., Hastie, T., & Tibshirani, R. (2017). An Introduction to Statistical Learning with Applications in R (2ª ed.). Springer. Capítulo 8.
Carrasco, R. A., Bueno, I., & Montero, J. M. (2018). Fundamentos de Ciencia de Datos con R. Capítulos 24, 28, 29.
Hernández G., F. (s.f.). Modelos predictivos. Sección “Árboles de clasificación” (Ejemplo de minimización RSS)
Gil, J. (2020). Regresión lineal vs. Árboles de decisión: Elección para datos continuos.
DataCamp (2024). ¿Qué es el refuerzo en el aprendizaje automático?
Mediani, S. (2020). Árboles de decisiones — Introducción a la
ciencia de datos.
En este estudio se aplica un modelo de árboles de decisión para predecir la probabilidad de supervivencia de los pasajeros del Titanic, a partir de variables demográficas y socioeconómicas extraídas del conjunto de datos histórico proporcionado por Kaggle.
El objetivo es construir un modelo interpretable, que permita identificar los factores más relevantes asociados a la supervivencia, evaluando el desempeño del clasificador y su capacidad para generalizar a nuevos datos.
library(titanic)
datos_train <- titanic_train
# Realizando una limpieza y re-codificando la variable respuesta ----
datos_train <- na.omit(titanic_train)
datos_train$Survived <- factor(
datos_train$Survived,
levels = c(0, 1),
labels = c("No", "Sí")
)
datos_train$Survived <- relevel(datos_train$Survived, ref = "Sí")
head(datos_train)
Variable | Definición | Codificación / Ejemplo |
---|---|---|
PassengerId |
Identificador único del pasajero | 1, 2, 3, … |
Survived |
Supervivencia | 0 = No, 1 = Sí |
Pclass |
Clase de boleto del pasajero | 1 = 1ra, 2 = 2da, 3 = 3ra |
Name |
Nombre completo del pasajero | “Allen, Miss. Elisabeth Walton” |
Sex |
Sexo del pasajero | “male”, “female” |
Age |
Edad en años | Valores numéricos |
SibSp |
Número de hermanos o esposos a bordo | 0, 1, 2, … |
Parch |
Número de padres o hijos a bordo | 0, 1, 2, … |
Ticket |
Número del boleto | “A/5 21171”, “PC 17599” |
Fare |
Tarifa pagada por el pasajero | Valores numéricos (ej. 7.25, 71.28…) |
Cabin |
Número de cabina | Ejemplo: “C85”, “E46”, puede haber valores NA |
Embarked |
Puerto de embarque | C = Cherbourg, Q = Queenstown, S = Southampton |
####Resumen general de los datos
summary(datos_train)
## PassengerId Survived Pclass Name Sex
## Min. : 1.0 Sí:290 Min. :1.000 Length:714 Length:714
## 1st Qu.:222.2 No:424 1st Qu.:1.000 Class :character Class :character
## Median :445.0 Median :2.000 Mode :character Mode :character
## Mean :448.6 Mean :2.237
## 3rd Qu.:677.8 3rd Qu.:3.000
## Max. :891.0 Max. :3.000
## Age SibSp Parch Ticket
## Min. : 0.42 Min. :0.0000 Min. :0.0000 Length:714
## 1st Qu.:20.12 1st Qu.:0.0000 1st Qu.:0.0000 Class :character
## Median :28.00 Median :0.0000 Median :0.0000 Mode :character
## Mean :29.70 Mean :0.5126 Mean :0.4314
## 3rd Qu.:38.00 3rd Qu.:1.0000 3rd Qu.:1.0000
## Max. :80.00 Max. :5.0000 Max. :6.0000
## Fare Cabin Embarked
## Min. : 0.00 Length:714 Length:714
## 1st Qu.: 8.05 Class :character Class :character
## Median : 15.74 Mode :character Mode :character
## Mean : 34.69
## 3rd Qu.: 33.38
## Max. :512.33
Antes de continuar el análisis exploratorio de los datos, se consideró necesario realizar una depuración inicial del conjunto de datos original, con el fin de enfocar los análisis únicamente en aquellas variables con relevancia potencial para el modelo de clasificación.
## Usando el criterio de reducción del índice de Gini calculado por el modelo rpart
library(rpart)
library(rpart.plot)
var_sig <- rpart(Survived ~ ., data = titanic_train, method = "class")
var_sig$variable.importance
## Name Ticket Sex Cabin Fare Pclass
## 421.45455 357.37374 187.31313 145.41414 72.70707 69.01010
Aunque el modelo rpart permite estimar la importancia de las variables mediante la reducción del índice de Gini, se observa que algunas variables como Name, Ticket y Cabin aparecen con alta importancia relativa, a pesar de no tener un significado predictivo interpretable o ser de carácter identificador.
Por esta razón, se opta por buscar métodos alternativos de selección de variables que consideren tanto el poder predictivo como la relevancia contextual y la interpretabilidad del modelo.
## Usando la libreria Boruta
library(Boruta)
set.seed(123)
boruta_output <- Boruta(Survived ~ ., data = titanic_train, doTrace = 1)
# Ver variables confirmadas, rechazadas o dudosas
print(boruta_output)
## Boruta performed 99 iterations in 51.80145 secs.
## 7 attributes confirmed important: Age, Cabin, Fare, Parch, Pclass and
## 2 more;
## 2 attributes confirmed unimportant: Embarked, PassengerId;
## 2 tentative attributes left: Name, SibSp;
plot(boruta_output)
Para realizar una selección más robusta y objetiva de variables, se aplicó el algoritmo Boruta, el cual evalúa la importancia de cada variable comparándola contra versiones aleatorias (shadow attributes) utilizando un clasificador basado en Random Forest.
En este caso, Boruta confirmó como importantes variables como
Age
, Fare
, Pclass
y
Sex
, mientras que descartó otras como
PassengerId
y Embarked
, y dejó en estado
tentativo a Name
y SibSp
.
Guiándonos por el gráfico generado y priorizando aquellas variables con clara interpretación y bajo nivel de valores perdidos, se decidió conservar las variables:
Sex
Pclass
Fare
Age
#Seleccionando solo las 4 más variables significativas según el criterio de Boruta
datos_train <- datos_train[,-c(1,4,7,8,9,11,12)]
head(datos_train)
A partir de este punto, se continuara con el análisis exploratorio de los datos, enfocado en las variables seleccionadas previamente por su relevancia predictiva.
library(ggplot2)
ggplot(datos_train, aes(x = Sex, fill = Survived)) +
geom_bar(position = "fill") + ylab("Proporción")
El gráfico muestra la proporción de pasajeros que sobrevivieron
(Sí
) y no sobrevivieron (No
) según el
sexo.
Se observa una diferencia marcada: la mayoría de mujeres sobrevivieron, mientras que en el caso de los hombres, la mayoría no lo hizo.
Esto nos da indicios de que la variable Sex
pueda tener
un fuerte poder discriminante y posiblemente estuvo asociada a
decisiones de evacuación durante el hundimiento, como la prioridad dada
a mujeres y niños.
# Boxplots por grupo:
ggplot(datos_train, aes(x = Survived, y = Age, fill = Survived)) +
geom_boxplot()
El gráfico compara la distribución de las edades entre los pasajeros que sobrevivieron (Sí) y los que no (No).
Se observa que la edad mediana es similar en ambos grupos, aunque los pasajeros que no sobrevivieron presentan una mayor dispersión, con algunos valores atípicos más altos.
Si bien no hay una diferencia drástica en la mediana, se aprecia que la edad por sí sola no es un factor claramente determinante, aunque podría estar correlacionada con otras variables como el sexo o la clase del pasaje.
Este comportamiento sugiere que la variable Age
podría
aportar valor al modelo en combinación con otros predictores, aunque no
tiene por sí sola un poder discriminante tan fuerte como el sexo.
# Correlación entre variables numéricas
numericas <- datos_train[sapply(datos_train, is.numeric)]
cor(numericas, use = "complete.obs")
## Pclass Age Fare
## Pclass 1.0000000 -0.36922602 -0.55418247
## Age -0.3692260 1.00000000 0.09606669
## Fare -0.5541825 0.09606669 1.00000000
corrplot::corrplot(cor(numericas, use = "complete.obs"), method = "circle")
El gráfico muestra las correlaciones entre las variables numéricas
seleccionadas (Pclass
, Age
y
Fare
) mediante círculos cuyo tamaño y color representan la
magnitud y dirección de la correlación.
Se observa una correlación negativa moderada entre
Pclass
y Fare
, lo cual indica que los
pasajeros de clases más altas (menor valor en Pclass
)
pagaron tarifas más altas.
Las correlaciones entre Age
y las otras variables
(Pclass
, Fare
) son bajas, lo que sugiere que
la edad varía de forma más independiente respecto a la clase y la
tarifa.
Con el fin de analizar el poder discriminante de cada variable de
forma individual, se ajustaron modelos de árbol de decisión utilizando
una sola variable predictora en cada caso.
Esta estrategia permite visualizar cómo cada variable contribuye a la
clasificación de los pasajeros según su probabilidad de
supervivencia.
Los árboles resultantes muestran la capacidad de segmentación de
Age
, Pclass
, Sex
y
Fare
respecto a la variable respuesta, y permiten
identificar posibles puntos de corte relevantes o relaciones no
lineales.
modelo_1 <- rpart(Survived ~ Age, data = datos_train, method = "class")
summary(modelo_1)
## Call:
## rpart(formula = Survived ~ Age, data = datos_train, method = "class")
## n= 714
##
## CP nsplit rel error xerror xstd
## 1 0.06551724 0 1.0000000 1.0000000 0.04525169
## 2 0.01000000 1 0.9344828 0.9655172 0.04498594
##
## Variable importance
## Age
## 100
##
## Node number 1: 714 observations, complexity param=0.06551724
## predicted class=No expected loss=0.4061625 P(node) =1
## class counts: 290 424
## probabilities: 0.406 0.594
## left son=2 (47 obs) right son=3 (667 obs)
## Primary splits:
## Age < 6.5 to the left, improve=8.814172, (0 missing)
##
## Node number 2: 47 observations
## predicted class=Sí expected loss=0.2978723 P(node) =0.06582633
## class counts: 33 14
## probabilities: 0.702 0.298
##
## Node number 3: 667 observations
## predicted class=No expected loss=0.3853073 P(node) =0.9341737
## class counts: 257 410
## probabilities: 0.385 0.615
Este modelo se construyó usando únicamente la variable
Age
para predecir la supervivencia de los
pasajeros (Survived
).
Importancia de la variable:
La salida indica que Age
tiene un 100% de importancia
relativa en el modelo, lo cual es esperado dado que es la única variable
incluida.
Complejidad del árbol (CP
):
El árbol presenta 1 división (nsplit = 1
), lo que
indica una única partición del conjunto de datos con base en la
edad.
El error relativo inicial es 1.00
, lo que significa
que antes de realizar divisiones, el árbol no tenía poder
predictivo.
Luego de una división, el error relativo disminuye a 0.934, lo que muestra una mejora leve.
El xerror (error de validación cruzada) también se mantiene alto
(0.965
), indicando que Age
por sí sola no
tiene un gran poder de clasificación.
Aunque Age
presenta cierta capacidad para segmentar la
variable respuesta (survival), el modelo resultante es simple y con alta
tasa de error, lo que sugiere que no es suficiente por sí sola para
predecir adecuadamente la supervivencia.
rpart.plot(modelo_1)
Nodo Raíz (arriba): Indica la clase mayoritaria inicial (“No”) y la impureza (0.41) antes de cualquier división, representando el 100% de los datos.
Decisión (centro): La regla de división es “Edad >= 6.5”. Divide los datos en dos grupos según si la edad es mayor o igual a 6.5.
Hoja Izquierda (Edad >= 6.5): Predice “No”. Este grupo es más puro (0.39 de impureza) y contiene el 93% de los datos que cumplen la condición.
Hoja Derecha (Edad < 6.5): Predice “Si”. Este grupo es más heterogéneo (0.70 de impureza) y solo representa el 7% de los datos.
En resumen, el árbol muestra que la “Edad” es un factor clave: la mayoría de las personas de 6.5 años o más se clasifican como “No”, mientras que un grupo más pequeño de menores de 6.5 se clasifica como “Si”.
modelo_2 <- rpart(Survived ~ Pclass, data = datos_train, method = "class")
summary(modelo_2)
## Call:
## rpart(formula = Survived ~ Pclass, data = datos_train, method = "class")
## n= 714
##
## CP nsplit rel error xerror xstd
## 1 0.17586207 0 1.0000000 1.0000000 0.04525169
## 2 0.02413793 1 0.8241379 0.8241379 0.04348091
## 3 0.01000000 2 0.8000000 0.8482759 0.04378682
##
## Variable importance
## Pclass
## 100
##
## Node number 1: 714 observations, complexity param=0.1758621
## predicted class=No expected loss=0.4061625 P(node) =1
## class counts: 290 424
## probabilities: 0.406 0.594
## left son=2 (359 obs) right son=3 (355 obs)
## Primary splits:
## Pclass < 2.5 to the left, improve=39.25256, (0 missing)
##
## Node number 2: 359 observations, complexity param=0.02413793
## predicted class=Sí expected loss=0.4289694 P(node) =0.5028011
## class counts: 205 154
## probabilities: 0.571 0.429
## left son=4 (186 obs) right son=5 (173 obs)
## Primary splits:
## Pclass < 1.5 to the left, improve=5.562067, (0 missing)
##
## Node number 3: 355 observations
## predicted class=No expected loss=0.2394366 P(node) =0.4971989
## class counts: 85 270
## probabilities: 0.239 0.761
##
## Node number 4: 186 observations
## predicted class=Sí expected loss=0.344086 P(node) =0.2605042
## class counts: 122 64
## probabilities: 0.656 0.344
##
## Node number 5: 173 observations
## predicted class=No expected loss=0.4797688 P(node) =0.2422969
## class counts: 83 90
## probabilities: 0.480 0.520
Este modelo evalúa la capacidad de la clase del boleto
(Pclass
) para predecir la supervivencia de los pasajeros
(Survived
).
nsplit
):Pclass
.Error relativo inicial = 1.000
Corresponde al error sin ninguna división del árbol (modelo sin
segmentación).
Error relativo tras 1 split = 0.824
La primera división reduce el error en aproximadamente un 17.6%, lo cual
sugiere que Pclass
tiene alguna capacidad
discriminante.
Error relativo final con 2 splits = 0.800
Mejora marginal adicional, lo que indica que el poder predictivo
adicional al seguir dividiendo es limitado.
Error de validación cruzada (xerror
) =
0.848
Relativamente alto, lo que sugiere que el modelo no generaliza bien
usando solo Pclass
, aunque algo mejor que
Age
.
El modelo basado en Pclass
mejora ligeramente el poder
de clasificación respecto a Age
, realizando dos divisiones
que capturan diferencias en supervivencia entre clases.
Sin embargo, el error sigue siendo elevado, lo que sugiere que
Pclass
por sí sola no es suficiente para un modelo preciso,
aunque sí aporta una estructura básica útil.
rpart.plot(modelo_2)
Este árbol muestra cómo se puede predecir si un pasajero sobrevivió o no en función de su clase (Pclass), que toma valores 1 (primera clase), 2 (segunda) y 3 (tercera).
Este árbol evidencia que la clase del pasajero (Pclass) está asociada con la probabilidad de supervivencia. En general, los pasajeros de clases más altas (1.ª o 2.ª clase) tuvieron mayores probabilidades de sobrevivir que los de tercera clase. El modelo logra identificar esas diferencias a través de divisiones simples basadas en valores de Pclass.
modelo_3 <- rpart(Survived ~ Sex, data = datos_train, method = "class")
summary(modelo_3)
## Call:
## rpart(formula = Survived ~ Sex, data = datos_train, method = "class")
## n= 714
##
## CP nsplit rel error xerror xstd
## 1 0.4586207 0 1.0000000 1.0000000 0.04525169
## 2 0.0100000 1 0.5413793 0.5413793 0.03816193
##
## Variable importance
## Sex
## 100
##
## Node number 1: 714 observations, complexity param=0.4586207
## predicted class=No expected loss=0.4061625 P(node) =1
## class counts: 290 424
## probabilities: 0.406 0.594
## left son=2 (261 obs) right son=3 (453 obs)
## Primary splits:
## Sex splits as LR, improve=99.99817, (0 missing)
##
## Node number 2: 261 observations
## predicted class=Sí expected loss=0.2452107 P(node) =0.3655462
## class counts: 197 64
## probabilities: 0.755 0.245
##
## Node number 3: 453 observations
## predicted class=No expected loss=0.205298 P(node) =0.6344538
## class counts: 93 360
## probabilities: 0.205 0.795
Este modelo evalúa el poder discriminante del sexo del
pasajero (Sex
) para predecir su supervivencia
(Survived
).
Error relativo inicial = 1.000
Corresponde al error de clasificación antes de realizar cualquier
división (modelo sin información).
Error relativo tras 1 split = 0.541
La división reduce el error en casi un 46%, lo que indica que
Sex
tiene alta capacidad para separar las clases
(No/Sí).
Error de validación cruzada (xerror
) =
0.541
Valor relativamente bajo, el mejor entre los modelos individuales vistos
hasta ahora, y muy cercano al error en el conjunto de entrenamiento, lo
que sugiere buena generalización incluso con una sola división.
Sex
es la variable más poderosa individualmente para
predecir la supervivencia. Con solo una división, el modelo logra
reducir significativamente el error, lo cual confirma que el sexo del
pasajero fue un factor clave durante el evento (por ejemplo, al
priorizar mujeres en el rescate).
rpart.plot(modelo_3)
Este árbol muestra que el sexo fue una variable muy influyente en la probabilidad de supervivencia en el Titanic. De forma clara, se observa que las mujeres tuvieron muchas más probabilidades de sobrevivir que los hombres. El modelo, aunque simple, logra capturar una regla muy poderosa con solo una división.
modelo_4 <- rpart(Survived ~ Fare, data = datos_train, method = "class")
summary(modelo_4)
## Call:
## rpart(formula = Survived ~ Fare, data = datos_train, method = "class")
## n= 714
##
## CP nsplit rel error xerror xstd
## 1 0.2068966 0 1.0000000 1.0000000 0.04525169
## 2 0.0100000 1 0.7931034 0.8068966 0.04324954
##
## Variable importance
## Fare
## 100
##
## Node number 1: 714 observations, complexity param=0.2068966
## predicted class=No expected loss=0.4061625 P(node) =1
## class counts: 290 424
## probabilities: 0.406 0.594
## left son=2 (130 obs) right son=3 (584 obs)
## Primary splits:
## Fare < 52.2771 to the right, improve=33.49453, (0 missing)
##
## Node number 2: 130 observations
## predicted class=Sí expected loss=0.2692308 P(node) =0.1820728
## class counts: 95 35
## probabilities: 0.731 0.269
##
## Node number 3: 584 observations
## predicted class=No expected loss=0.3339041 P(node) =0.8179272
## class counts: 195 389
## probabilities: 0.334 0.666
Este modelo analiza si la tarifa pagada por el pasaje
(Fare
) tiene capacidad para predecir la supervivencia del
pasajero (Survived
).
Error relativo inicial = 1.000
Sin divisiones, el modelo no tiene capacidad predictiva.
Error relativo tras 1 split = 0.793
Se reduce el error en un 20.7%, una mejora moderada, inferior a la
obtenida con Sex
, pero mejor que Age
.
Error de validación cruzada (xerror
) =
0.814
Similar al error en el conjunto de entrenamiento, lo cual indica
consistencia, aunque la capacidad predictiva es limitada.
Fare
muestra cierta capacidad para distinguir entre
pasajeros que sobrevivieron y los que no, lo cual puede estar
relacionado con la clase socioeconómica (quienes pagaron más
posiblemente accedieron a mejores condiciones de evacuación).
No obstante, su capacidad predictiva individual es limitada comparada
con variables como Sex
. Por tanto, Fare
podría
ser útil en modelos multivariados, pero no resulta suficientemente
fuerte por sí sola.
rpart.plot(modelo_4)
Este árbol muestra cómo la probabilidad de supervivencia varía según el monto pagado por el pasajero:
El árbol parte de la condición Fare < 52:
Si sí (es decir, la tarifa fue menor a 52 unidades monetarias), el modelo predice que no sobrevivió, con una probabilidad estimada de 0.33, y este grupo representa el 82% de los datos.
Si no (es decir, pagó 52 o más), el modelo predice que sí sobrevivió, con una probabilidad estimada de 0.73, y este grupo representa el 18% restante.
Este modelo sugiere que la tarifa pagada fue un factor asociado a la probabilidad de supervivencia: Pasajeros que pagaron tarifas más altas (al menos 52) tuvieron más probabilidades de sobrevivir que quienes pagaron menos. Esto podría estar reflejando diferencias de acceso a botes salvavidas o ubicación en el barco, ya que la tarifa está relacionada con la clase y el tipo de cabina.
Este modelo se ajustó utilizando conjuntamente las variables más
relevantes (Sex
, Pclass
, Fare
,
Age
) para predecir la variable respuesta
Survived
.
nsplit
):El árbol realizó 5 divisiones, lo que indica un mayor nivel de segmentación comparado con los modelos univariantes.
Esto permite capturar interacciones y combinaciones entre variables, mejorando la capacidad predictiva.
Split | Rel. Error | Xerror (validación cruzada) | Interpretación |
---|---|---|---|
0 | 1.000 | 1.000 | Sin divisiones, sin poder predictivo. |
1 | 0.541 | 0.541 | Reducción significativa tras primera división (influencia de
Sex ). |
3 | 0.483 | 0.583 | Se incorporan otras variables, leve mejora. |
4 | 0.455 | 0.514 | Error continúa bajando. |
5 | 0.445 | 0.531 | Mejora moderada, buen equilibrio entre complejidad y error. |
Variable | Importancia relativa (%) | Interpretación |
---|---|---|
Sex |
56 | Principal variable del modelo, con alta capacidad discriminante. |
Pclass |
16 | Aporta segmentación adicional, especialmente en combinación con
Sex . |
Fare |
16 | Se relaciona indirectamente con Pclass y mejora la
predicción. |
Age |
11 | Su influencia es menor, pero complementa las decisiones del modelo. |
El modelo final muestra una mejor capacidad predictiva que cualquier modelo univariable, gracias a la combinación de las variables más relevantes.
La variable Sex
sigue siendo el factor principal, pero
el uso conjunto con Pclass
, Fare
y
Age
permite capturar interacciones que mejoran el
rendimiento general.
El modelo logra un equilibrio entre simplicidad y precisión, con errores relativamente bajos y estructura interpretable.
rpart.plot(modelo_final)
El árbol de decisión muestra cómo ciertas variables como el sexo, la edad, la clase del pasaje (Pclass) y la tarifa pagada (Fare) influyeron en la probabilidad de supervivencia de los pasajeros del Titanic.
Si el pasajero era hombre, la mayoría no sobrevivió.
Si era mujer, la mayoría sí sobrevivió.
Los niños muy pequeños (menores de 6.5 años) tuvieron mayor probabilidad de sobrevivir.
Los hombres mayores, en general, no sobrevivieron.
Las mujeres en tercera clase (Pclass = 3) tuvieron una alta tasa de supervivencia.
En clases más altas, la supervivencia dependió del precio del boleto y la edad:
Las mujeres que pagaron poco y eran mayores de edad sobrevivieron más.
Las que pagaron mucho tuvieron menor probabilidad de sobrevivir, aunque este grupo fue pequeño.
El modelo refleja el famoso patrón del Titanic:
“Mujeres y niños primero”.
Se ajustó un nuevo árbol de decisión utilizando los mismos predictores seleccionados, pero incorporando hiperparámetros para mejorar el control sobre la complejidad del modelo y evitar sobreajuste.
modelo_final1 <- rpart(Survived ~ ., data = datos_train, method = "class",
cp = 0.005,
maxdepth = 5,
minbucket = 10)
cp = 0.005
permite considerar divisiones
con mejoras muy pequeñas en el error, promoviendo árboles más
detallados.maxdepth = 5
restringe la profundidad máxima del árbol,
lo que impide estructuras excesivamente ramificadas que podrían
sobreajustar a los datos de entrenamiento.minbucket = 10
asegura que cada nodo terminal tenga al
menos 10 observaciones, aportando estabilidad a las particiones y
evitando nodos con casos aislados o poco representativos.En conjunto, estos ajustes permiten explorar árboles más desarrollados, pero con restricciones estructurales que buscan mantener un buen balance entre ajuste y generalización.
División (nsplit ) |
Error relativo (rel error ) |
Error cruzado (xerror ) |
Std. error (xstd ) |
Interpretación |
---|---|---|---|---|
0 | 1.000 | 1.000 | 0.0453 | Sin divisiones, sin poder predictivo. |
1 | 0.541 | 0.541 | 0.0382 | Primera división mejora fuertemente el modelo (Sex probablemente). |
3 | 0.483 | 0.548 | 0.0383 | Mejora leve en entrenamiento, pero xerror se mantiene
estable. |
4 | 0.455 | 0.534 | 0.0380 | Punto óptimo aparente: menor error de validación cruzada. |
6 | 0.434 | 0.562 | 0.0387 | Más complejidad sin ganancia; comienza a sugerirse sobreajuste. |
El modelo alcanza su mejor capacidad de generalización
con 4 divisiones, donde el error de validación cruzada
(xerror
) es mínimo (0.534).
La inclusión de restricciones mediante hiperparámetros
(cp = 0.005
, maxdepth = 5
,
minbucket = 10
) permitió construir un árbol más
regulado y estable, evitando divisiones poco representativas o
nodos con muy pocos casos.
A pesar de permitir hasta 5 niveles de profundidad, el árbol se detuvo tras 6 divisiones, lo que sugiere que las condiciones del modelo equilibran bien ajuste y simplicidad.
Este modelo representa una solución robusta y bien regulada, con un
desempeño sólido en términos de error de validación cruzada. La
estructura del árbol sigue siendo interpretable, y se apoya
principalmente en Sex
, mientras que Fare
,
Pclass
y Age
complementan el análisis.
# Predicción de clases
pred_clase_train <- predict(modelo_final1, newdata = datos_train, type = "class")
# Predicción de probabilidades
pred_prob_train <- predict(modelo_final1, newdata = datos_train, type = "prob")
datos_train$clase_pred <- pred_clase_train
datos_train$clase_prob <- pred_prob_train[, "Sí"]
head(datos_train)
niveles <- c("Sí", "No")
datos_train$Survived <- factor(datos_train$Survived, levels = niveles)
datos_train$clase_pred <- factor(datos_train$clase_pred, levels = niveles)
library(caret)
confusionMatrix(data = datos_train$clase_pred, reference = datos_train$Survived)
## Confusion Matrix and Statistics
##
## Reference
## Prediction Sí No
## Sí 202 38
## No 88 386
##
## Accuracy : 0.8235
## 95% CI : (0.7935, 0.8508)
## No Information Rate : 0.5938
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.6239
##
## Mcnemar's Test P-Value : 1.27e-05
##
## Sensitivity : 0.6966
## Specificity : 0.9104
## Pos Pred Value : 0.8417
## Neg Pred Value : 0.8143
## Prevalence : 0.4062
## Detection Rate : 0.2829
## Detection Prevalence : 0.3361
## Balanced Accuracy : 0.8035
##
## 'Positive' Class : Sí
##
Métrica | Fórmula | Interpretación en este contexto |
---|---|---|
Accuracy | (TP + TN) / (TP + TN + FP + FN) | Proporción total de predicciones correctas (82.35%). Es decir, el modelo acierta en 8 de cada 10 casos. |
Sensitivity (Recall, TPR) | TP / (TP + FN) | De los que sí sobrevivieron, el modelo identificó correctamente el 69.66%. |
Specificity | TN / (TN + FP) | De los que no sobrevivieron, el modelo acertó el 91.04%. |
Pos Pred Value (Precision) | TP / (TP + FP) | De todos los predichos como “Sí sobrevivió”, el 84.17% realmente sobrevivió. |
Neg Pred Value | TN / (TN + FN) | De todos los predichos como “No sobrevivió”, el 81.43% realmente no sobrevivió. |
Balanced Accuracy | (Sensitivity + Specificity) / 2 | Promedio entre Sensibilidad y Especificidad (80.35%), útil en clases desbalanceadas. |
Detection Rate | TP / Total | Porcentaje total correctamente clasificados como “Sí sobrevivió” (28.29%). |
Detection Prevalence | (TP + FP) / Total | Proporción predicha como “Sí sobrevivió” (33.61%). |
No Information Rate | Max(Proporción clase mayoritaria) | Si siempre predijéramos la clase mayoritaria (“No”), acertaríamos 59.38%. |
Valor de Kappa | Interpretación |
---|---|
< 0.00 | Sin acuerdo (peor que el azar) |
0.00–0.20 | Acuerdo leve |
0.21–0.40 | Acuerdo aceptable |
0.41–0.60 | Acuerdo moderado |
0.61–0.80 | Acuerdo sustancial |
0.81–1.00 | Acuerdo casi perfecto |
Kappa = 0.62 indica un acuerdo sustancial, lo que sugiere que el modelo tiene un rendimiento mucho mejor que el azar.
Como el p-valor es menor a 0.05(p-value = 1.27e-05), se rechaza H₀, concluyendo que el modelo tiene desequilibrio en los errores (posiblemente clasifica mejor una clase que la otra).
library(ROSE)
# Graficar la curva ROC
roc.curve(datos_train$Survived, datos_train$clase_prob,
lty = 2, lwd = 1.8, col = "blue",
main = "Curva ROC - Árbol de Decisión")
## Area under the curve (AUC): 0.830
library(caTools)
datos_train$Survived_num <- ifelse(datos_train$Survived == "Sí", 1, 0)
# Curva ROC y AUC
colAUC(datos_train$clase_prob, datos_train$Survived_num, plotROC = TRUE)
## [,1]
## 0 vs. 1 0.8302619
abline(0, 1, col = "gold", lty = 7)
El área bajo la curva (AUC = 0.83) obtenida tanto con la función
roc.curve()
como con colAUC()
confirma que el
modelo de árbol de decisión presenta una capacidad discriminativa
adecuada para diferenciar entre pasajeros que sobrevivieron y los que
no. Este valor sugiere un rendimiento significativamente superior al
azar y, por tanto, valida el uso de este modelo en el contexto del
problema.
datos_test <- titanic_test
datos_test <- na.omit(titanic_test)
datos_test <- datos_test[,-c(1,3,6,7,8,10,11)]
head(datos_test)
# Predicción de clase (Sí / No)
datos_test$clase_pred <- predict(modelo_final1, newdata = datos_test, type = "class")
# Predicción de probabilidad (probabilidad de clase "Sí")
datos_test$clase_prob <- predict(modelo_final1, newdata = datos_test, type = "prob")[, "Sí"]
head(datos_test[, c("clase_pred", "clase_prob")])
"No"
."Sí"
, es decir, el modelo cree que
esos pasajeros probablemente sobrevivieron.Factores determinantes de supervivencia
El sexo del pasajero es el predictor más influyente, reflejando la prioridad histórica de mujeres y niños en el rescate.
Aspectos socioeconómicos: representados por la clase del pasaje
(Pclass
) y la tarifa pagada (Fare
) aportan
información relevante, aunque en menor medida.
La edad juega un papel secundario, útil en situaciones específicas pero insuficiente por sí sola.
Desempeño predictivo
El modelo alcanzó una precisión global (accuracy) de más del 82 % y un AUC ≃ 0.83, lo que indica una buena capacidad de discriminación entre quienes sobrevivieron y quienes no.
La sensibilidad alrededor del 70 % y la especificidad superior al 90 % muestran que el clasificador identifica correctamente a la mayoría de no supervivientes y captura bien gran parte de los supervivientes.
Equilibrio y robustez
El coeficiente de Kappa ≃ 0.62 confirma un acuerdo sustancial con respecto al azar.
La curva ROC, coherente en distintos métodos de cálculo, y las métricas de validación interna reflejan un modelo estable que, aun limitado a los datos de entrenamiento, sugiere un buen grado de generalización.
El presente apartado desarrolla el punto 2 del trabajo final de Técnicas Multivariadas: el clasificador Random Forest. Este método de aprendizaje supervisado se aplica comúnmente a problemas de clasificación, y es especialmente útil cuando se trabaja con variables predictoras tanto cualitativas como cuantitativas.
Se incluye una revisión teórica del algoritmo, la simulación de una base de datos adecuada para su aplicación, el entrenamiento del modelo, y la evaluación de su rendimiento mediante métricas de clasificación y curva ROC. Esta sección también servirá como base para la posterior comparación con los clasificadores desarrollados en otros puntos del informe.
Random Forest es un algoritmo de aprendizaje supervisado propuesto por Breiman [@breiman2001random], basado en el principio de ensamblado de múltiples árboles de decisión. La idea principal es que un conjunto de clasificadores débiles (árboles individuales) puede combinarse para formar un clasificador más robusto y preciso.
El algoritmo construye cada árbol usando una muestra aleatoria con reemplazo del conjunto de entrenamiento (bootstrap), y en cada nodo de división selecciona aleatoriamente un subconjunto de las variables predictoras disponibles [@james2021isl]. Esta aleatoriedad ayuda a reducir la varianza del modelo final y mitiga el sobreajuste.
Cada árbol predice una clase, y la clase final es determinada por votación mayoritaria entre todos los árboles [@liaw2002classification]. En problemas de regresión, se utiliza el promedio de las predicciones individuales.
ntree
y
mtry
[@james2021isl].Random Forest es considerado uno de los métodos más eficaces y versátiles dentro del aprendizaje automático supervisado.
Para aplicar el clasificador Random Forest se simuló una base de datos con 300 observaciones y las siguientes variables:
Variable | Tipo | Descripción |
---|---|---|
edad | Cuantitativa | Edad del individuo (en años) |
ingresos | Cuantitativa | Ingreso mensual en dólares |
sexo | Cualitativa | Género del individuo: Hombre / Mujer |
educacion | Cualitativa | Nivel educativo: Secundaria, Superior, Posgrado |
compra | Categórica | Variable respuesta: “Sí” o “No” (si compró o no) |
La variable compra
fue generada de forma probabilística,
condicionada a las otras variables. Se asumió que personas con ingresos
más altos, menor edad y mayor nivel educativo tienen más probabilidad de
comprar.
Se dividió la base de datos simulada en dos subconjuntos: -
70% para entrenamiento del modelo
(train_rf
) - 30% para prueba del modelo
(test_rf
)
Esta partición se realizó de manera estratificada utilizando la
función createDataPartition()
del paquete
caret
, garantizando que ambas clases (“Sí” y “No”) estén
representadas proporcionalmente en ambos subconjuntos.
set.seed(456) # Semilla para reproducibilidad
# División 70% entrenamiento, 30% prueba
index <- createDataPartition(datos_rf$compra, p = 0.7, list = FALSE)
train_rf <- datos_rf[index, ]
test_rf <- datos_rf[-index, ]
Se entrenó un modelo de clasificación utilizando el algoritmo Random
Forest mediante la función randomForest()
del paquete
randomForest
. El modelo se ajustó para predecir la variable
compra
a partir de las variables predictoras simuladas.
Se construyeron 100 árboles (ntree = 100
) y se activó el
cálculo de la importancia de variables
(importance = TRUE
).
# Fijar semilla para reproducibilidad
set.seed(1111)
# Entrenamiento del modelo Random Forest
modelo_rf <- randomForest(
compra ~ .,
data = train_rf,
ntree = 100,
importance = TRUE
)
# Mostrar resumen del modelo
print(modelo_rf)
##
## Call:
## randomForest(formula = compra ~ ., data = train_rf, ntree = 100, importance = TRUE)
## Type of random forest: classification
## Number of trees: 100
## No. of variables tried at each split: 2
##
## OOB estimate of error rate: 41.71%
## Confusion matrix:
## No Sí class.error
## No 53 43 0.4479167
## Sí 45 70 0.3913043
El modelo entrenado con 100 árboles mostró un error OOB (out-of-bag) de aproximadamente 41.2%, lo cual indica que el modelo tiene dificultades para generalizar. La matriz de confusión del conjunto de entrenamiento también muestra cierto grado de desbalance en las predicciones. Esto puede estar relacionado con la naturaleza simulada de los datos o con la complejidad de la relación entre variables predictoras y la respuesta.
Una vez entrenado el modelo de Random Forest, se procedió a evaluar
su desempeño sobre el conjunto de prueba (test_rf
). Para
ello, se generaron predicciones y se construyó una matriz de confusión,
a partir de la cual se calcularon métricas de validación como:
Estas métricas permiten evaluar si el modelo generaliza bien a datos nuevos.
# Predicción sobre el conjunto de prueba
pred_rf <- predict(modelo_rf, newdata = test_rf)
# Matriz de confusión
confusionMatrix(pred_rf, test_rf$compra)
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Sí
## No 23 19
## Sí 17 30
##
## Accuracy : 0.5955
## 95% CI : (0.4862, 0.6983)
## No Information Rate : 0.5506
## P-Value [Acc > NIR] : 0.2285
##
## Kappa : 0.1864
##
## Mcnemar's Test P-Value : 0.8676
##
## Sensitivity : 0.5750
## Specificity : 0.6122
## Pos Pred Value : 0.5476
## Neg Pred Value : 0.6383
## Prevalence : 0.4494
## Detection Rate : 0.2584
## Detection Prevalence : 0.4719
## Balanced Accuracy : 0.5936
##
## 'Positive' Class : No
##
# Probabilidades para la clase "Sí"
prob_rf <- predict(modelo_rf, newdata = test_rf, type = "prob")[, "Sí"]
# Curva ROC
roc_rf <- roc(test_rf$compra, prob_rf)
# Gráfico de la curva ROC
plot(roc_rf, col = "blue", main = "Curva ROC - Random Forest")
# AUC
auc(roc_rf)
## Area under the curve: 0.6112
El modelo Random Forest, entrenado con 100 árboles y validado sobre un conjunto de prueba, obtuvo una precisión del 58.43%, con valores de sensibilidad y especificidad moderadamente equilibrados (57.50% y 59.18%, respectivamente). El índice Kappa fue bajo (0.1657), lo que sugiere que el acuerdo entre las predicciones y los valores reales no es alto.
En cuanto a la capacidad discriminativa del modelo, el valor del área bajo la curva (AUC) fue de 0.6112. Esto indica un desempeño por encima del azar, aunque no especialmente alto.
Estos resultados permiten observar que el modelo logra cierta capacidad de clasificación, aunque aún existe margen de mejora. Más adelante se discutirán posibles razones y recomendaciones a partir de estos hallazgos.
El clasificador Random Forest demostró ser capaz de trabajar eficientemente con variables predictoras tanto cuantitativas como cualitativas, como lo exige la pregunta.
A través de la simulación de una base de datos con características realistas, se logró entrenar y evaluar un modelo de clasificación binaria (compra: Sí/No).
Los resultados obtenidos mostraron una precisión del 58.43%, una AUC de 0.6112, y valores moderados de sensibilidad y especificidad, lo que indica un rendimiento aceptable pero mejorable.
La baja puntuación del índice Kappa sugiere que las predicciones del modelo aún no logran superar con claridad el desempeño por azar, lo cual puede deberse a la naturaleza simulada y limitada del conjunto de datos.
A pesar de estas limitaciones, el modelo cumple con su función básica de clasificación, y puede servir como punto de partida para futuras mejoras o comparaciones con otros clasificadores como árboles de decisión o redes neuronales.
Las referencias utilizadas fueron citadas automáticamente mediante el archivo referencias.bib y el estilo apa.csl.
Las redes neuronales artificiales (ANN) son modelos computacionales inspirados en el funcionamiento del cerebro humano, capaces de aprender patrones complejos a partir de datos. Son particularmente útiles cuando:
Las relaciones entre variables son no lineales
Hay interacciones complejas entre predictores
Se trabaja con datos de alta dimensionalidad
Estructura básica:
Capa de entrada: Recibe las variables predictoras (tanto cualitativas como cuantitativas)
Capas ocultas: Realizan transformaciones no lineales mediante funciones de activación
Capa de salida: Produce las predicciones (probabilidades de clase en clasificación)
Funcionamiento:
Propagación hacia adelante: Los datos fluyen desde la entrada hasta la salida
Cálculo del error: Se compara la salida con el valor real
Retropropagación: Se ajustan los pesos para minimizar el error
#----------------------------------------------
library(mlbench)
library(tidyr)
data(BreastCancer, package = "mlbench")
# Procesamiento
df <- BreastCancer %>%
# Elimina columna ID (no es predictora)
select(-Id) %>%
# Convierte todas las columnas (excepto Class) a numéricas
mutate(across(-Class, as.numeric)) %>%
# Elimina filas con valores faltantes (solo 16 en este dataset)
drop_na()
# Inspección de estructura
glimpse(df)
## Rows: 683
## Columns: 10
## $ Cl.thickness <dbl> 5, 5, 3, 6, 4, 8, 1, 2, 2, 4, 1, 2, 5, 1, 8, 7, 4, 4, …
## $ Cell.size <dbl> 1, 4, 1, 8, 1, 10, 1, 1, 1, 2, 1, 1, 3, 1, 7, 4, 1, 1,…
## $ Cell.shape <dbl> 1, 4, 1, 8, 1, 10, 1, 2, 1, 1, 1, 1, 3, 1, 5, 6, 1, 1,…
## $ Marg.adhesion <dbl> 1, 5, 1, 1, 3, 8, 1, 1, 1, 1, 1, 1, 3, 1, 10, 4, 1, 1,…
## $ Epith.c.size <dbl> 2, 7, 2, 3, 2, 7, 2, 2, 2, 2, 1, 2, 2, 2, 7, 6, 2, 2, …
## $ Bare.nuclei <dbl> 1, 10, 2, 4, 1, 10, 10, 1, 1, 1, 1, 1, 3, 3, 9, 1, 1, …
## $ Bl.cromatin <dbl> 3, 3, 3, 3, 3, 9, 3, 3, 1, 2, 3, 2, 4, 3, 5, 4, 2, 3, …
## $ Normal.nucleoli <dbl> 1, 2, 1, 7, 1, 7, 1, 1, 1, 1, 1, 1, 4, 1, 5, 3, 1, 1, …
## $ Mitoses <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 4, 1, 1, 1, …
## $ Class <fct> benign, benign, benign, benign, benign, malignant, ben…
Se utilizara una Red Neuronal Artificial (RNA) con 2 capas ocultas con el objetivo de predecir si un tumor es benigno (0) o maligno (1) basado en características celulares
Caracteristicas Celulares:
Clump Thickness: Grosor del agrupamiento celular (1-10).
Uniformity of Cell Size: Uniformidad del tamaño celular (1-10).
Uniformity of Cell Shape: Uniformidad de la forma celular (1-10).
Marginal Adhesion: Adhesión marginal (1-10).
Single Epithelial Cell Size: Tamaño de células epiteliales individuales (1-10).
Bare Nuclei: Núcleos desnudos (valores enteros 1-10, únicos con NAs).
Bland Chromatin: Cromatina suave (1-10).
Normal Nucleoli: Nucléolos normales (1-10).
Mitoses: Mitosis (1-10).
#----------------------------------------------------------
# Convertir variable objetivo a binaria (0: benigno, 1: maligno)
df$Class <- ifelse(df$Class == "malignant", 1, 0)
# Semilla
set.seed(42)
# División estratificada
trainIndex <- createDataPartition(
df$Class,
p = 0.7,
list = FALSE
)
# Crear conjuntos de datos
trainData <- df[trainIndex, ] # Datos de entrenamiento
testData <- df[-trainIndex, ] # Datos de prueba
# Estandarización (es importante para redes neuronales)
preProc <- preProcess(trainData[, -10], method = c("center", "scale"))
trainData[, -10] <- predict(preProc, trainData[, -10])
testData[, -10] <- predict(preProc, testData[, -10])
Partición: 70% entrenamiento (478 filas), 30% prueba (205 filas)
Estandarización: Se escalaron las variables predictoras (media = 0, desviación = 1) para que todas contribuyan equitativamente al modelo.
library(neuralnet)
#-------------------------------------------------
# Crear fórmula dinámica (Class en función de todas las demás variables)
nombres_vars <- names(trainData[, -10])
formula <- as.formula(paste("Class ~", paste(nombres_vars, collapse = " + ")))
# Entrenamiento del modelo
set.seed(42)
modelo_nnet <- neuralnet(
formula, # Fórmula del modelo
data = trainData, # Datos de entrenamiento
hidden = c(5, 3), # Arquitectura: 2 capas ocultas (5 y 3 neuronas)
act.fct = "logistic", # Función de activación sigmoide (para no linealidad)
linear.output = FALSE, # FALSE para clasificación (TRUE para regresión)
lifesign = "full", # Muestra progreso durante entrenamiento
stepmax = 1e6 # Máximo de iteraciones
)
# Visualización de la red
plot(modelo_nnet, rep = "best")
Error: 3.401674 → Error de la red durante el entrenamiento (pérdida).
Steps: 34 → Iteraciones realizadas hasta ese punto.
#----------------------------------------------------
# Predicciones en datos de prueba
predicciones <- predict(modelo_nnet, testData[, -10])
# Convertir probabilidades a clases
clases_predichas <- ifelse(predicciones > 0.5, 1, 0)
cm = table(clases_predichas, testData$Class)
# Matriz de confusión
conf_matrix <- confusionMatrix(
factor(clases_predichas), # Predicciones
factor(testData$Class), # Valores reales
positive = "1" # Clase de interés (maligno)
)
# Impresión de métricas
print(conf_matrix)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 129 2
## 1 5 68
##
## Accuracy : 0.9657
## 95% CI : (0.9306, 0.9861)
## No Information Rate : 0.6569
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.9247
##
## Mcnemar's Test P-Value : 0.4497
##
## Sensitivity : 0.9714
## Specificity : 0.9627
## Pos Pred Value : 0.9315
## Neg Pred Value : 0.9847
## Prevalence : 0.3431
## Detection Rate : 0.3333
## Detection Prevalence : 0.3578
## Balanced Accuracy : 0.9671
##
## 'Positive' Class : 1
##
# Curva ROC y AUC
roc_obj <- roc(
response = testData$Class, # Valores reales
predictor = predicciones, # Probabilidades predichas
levels = c(0, 1) # Niveles de las clases
)
# Gráfico de la curva ROC
plot(
roc_obj,
main = "Curva ROC - Clasificador de Red Neuronal",
col = "#1c61b6",
lwd = 2,
print.auc = TRUE,
auc.polygon = TRUE
)
# Cálculo del AUC
auc_value <- auc(roc_obj)
cat("\nAUC:", auc_value, "\n")
##
## AUC: 0.9902985
Accuracy: 96.6% de todas las predicciones son correctas.
Sensitivity: Detecta el 97.1% de los tumores malignos (muy importante en diagnóstico médico).
Specificity: Identifica correctamente el 96.3% de los benignos.
AUC: Excelente discriminación entre clases (casi perfecta).
Test de Mcnemar: p-value = 0.4497 (>0.05) → No hay diferencia significativa entre los valores predichos y los reales.
En esta sección se presenta una comparación de desempeño entre tres modelos de clasificación: Árbol de Decisión, Random Forest y Red Neuronal. Para evaluar su rendimiento, se utilizan las métricas estándar de clasificación:
Accuracy: Proporción de aciertos sobre el total.
Precision: Evalúa cuántas de las predicciones positivas fueron realmente positivas.
Sensibilidad/Recall(TPR): Indica cuántas de las instancias positivas reales fueron correctamente detectadas.
Especificidad(TNR): Indica cuántas de las instancias negativas reales fueron correctamente detectadas.
F1-Score: Representa una media armónica entre precisión y recall, útil cuando hay desequilibrio entre clases.
A continuación, se muestran gráficas que facilitan la comparación entre modelos.
# Función para extraer métricas
extraer_metricas <- function(conf_mat, auc_val, modelo) {
acc <- conf_mat$overall["Accuracy"]
prec <- conf_mat$byClass["Precision"]
rec <- conf_mat$byClass["Recall"]
esp <- conf_mat$byClass["Specificity"]
f1 <- conf_mat$byClass["F1"]
data.frame(Modelo = modelo,
Accuracy = round(acc, 3),
Precision = round(prec, 3),
Recall = round(rec, 3),
Especificidad = round(esp, 3),
F1 = round(f1, 3),
AUC = round(auc_val, 3))
}
library(caret)
conf_arbol <- confusionMatrix(datos_train$clase_pred, datos_train$Survived)
auc_arbol <- colAUC(datos_train$clase_prob, datos_train$Survived_num)[1]
m_arbol <- extraer_metricas(conf_arbol, auc_arbol, "Árboles de decisión")
conf_rf <- confusionMatrix(pred_rf, test_rf$compra)
auc_rf <- auc(roc_rf)
m_rf <- extraer_metricas(conf_rf, auc_rf, "Random Forest")
conf_nn <- confusionMatrix(factor(clases_predichas), factor(testData$Class), positive = "1")
auc_nn <- auc(roc_obj)
m_nn <- extraer_metricas(conf_nn, auc_nn, "Red Neuronal")
# Unir métricas de los tres modelos
metricas_totales <- rbind(m_arbol, m_rf, m_nn)
# Ver tabla en consola
print(metricas_totales)
## Modelo Accuracy Precision Recall Especificidad F1
## Accuracy Árboles de decisión 0.824 0.842 0.697 0.910 0.762
## Accuracy1 Random Forest 0.596 0.548 0.575 0.612 0.561
## Accuracy2 Red Neuronal 0.966 0.932 0.971 0.963 0.951
## AUC
## Accuracy 0.830
## Accuracy1 0.611
## Accuracy2 0.990
library(tidyr)
library(ggplot2)
# Transformar para gráfico
metricas_long <- pivot_longer(metricas_totales,
cols = -Modelo,
names_to = "Medida",
values_to = "Valor")
# Gráfico de barras comparativo
ggplot(metricas_long, aes(x = Medida, y = Valor, fill = Modelo)) +
geom_bar(stat = "identity", position = position_dodge()) +
labs(title = "Comparación de Medidas de Clasificación",
x = "Medida",
y = "Valor") +
theme_minimal() +
scale_fill_brewer(palette = "Dark2")
🟣 La Red Neuronal se posiciona consistentemente como el mejor modelo, superando a los otros en todas las métricas. Sus barras están muy próximas al valor máximo de 1.0, lo que indica un rendimiento casi perfecto.
🟢 El Árbol de Decisión muestra un desempeño intermedio. Aunque sus resultados son aceptables y uniformes, es notable que su Recall (capacidad de identificar los positivos reales) es más baja que su precisión, lo que sugiere que tiende a dejar pasar verdaderos positivos.
🟠 Random Forest tiene el rendimiento más bajo en todas las métricas. Sus barras se sitúan por debajo de 0.6 en la mayoría de las categorías, lo que indica un modelo poco confiable en este contexto.
# Función para graficar matriz de confusión como heatmap
plot_cm_heatmap <- function(cm, titulo){
cm_table <- as.data.frame(cm$table)
ggplot(cm_table, aes(Prediction, Reference, fill = Freq)) +
geom_tile() +
geom_text(aes(label = Freq), color = "white", size = 5) +
scale_fill_gradient(low = "steelblue", high = "darkred") +
labs(title = titulo, x = "Predicción", y = "Real") +
theme_minimal()
}
library(patchwork)
g1 <- plot_cm_heatmap(conf_arbol, "Árbol de Decisión")
g2 <- plot_cm_heatmap(conf_rf, "Random Forest")
g3 <-plot_cm_heatmap(conf_nn, "Red Neuronal")
g1 + g2 + g3 + plot_layout(nrow = 1) + plot_annotation(title = "Matrices de Confusión")
Además de las métricas puntuales, la calidad de los modelos de clasificación se evalúa mediante la curva ROC (Receiver Operating Characteristic) y el AUC (Área Bajo la Curva).
La curva ROC muestra la relación entre la tasa de verdaderos positivos (TPR) y la tasa de falsos positivos (FPR), proporcionando una visión completa de la capacidad del modelo para discriminar entre clases.
El AUC cuantifica esta capacidad: un valor de AUC cercano a 1 indica excelente discriminación; un valor cerca de 0.5 sugiere que el modelo no discrimina mejor que el azar.
Estas herramientas son útiles especialmente cuando se trabaja con clases desbalanceadas o cuando se quiere entender el comportamiento del modelo más allá de una única predicción.
# ROC para el clasificador arboles de decision
roc_arbol <- roc(response = datos_train$Survived_num,
predictor = datos_train$clase_prob)
# Gráfico comparativo de las curvas ROC
plot(roc_arbol, col = "blue", main = "Curvas ROC - Comparación de Modelos")
lines(roc_rf, col = "forestgreen")
lines(roc_obj, col = "red")
legend("bottomright",
legend = c(
paste("Árboles de decisión (AUC =", round(auc(roc_arbol), 3), ")"),
paste("Random Forest (AUC =", round(auc(roc_rf), 3), ")"),
paste("Red Neuronal (AUC =", round(auc(roc_obj), 3), ")")
),
col = c("blue", "forestgreen", "red"),
lwd = 2)
📌 1. Comparación general de desempeño (AUC):
Red Neuronal (rojo) muestra el mejor desempeño con un AUC = 0.99, lo que indica una capacidad casi perfecta para discriminar entre clases positivas y negativas.
Árbol de Decisión (azul) tiene un AUC = 0.83, lo que representa un rendimiento bueno, aunque no excelente.
Random Forest (verde) tiene un AUC = 0.611, apenas por encima del azar (AUC = 0.5), lo que sugiere un desempeño débil en este caso particular.
📌 2. Forma de las curvas:
La curva de la Red Neuronal se aproxima mucho a la esquina superior izquierda (alta sensibilidad con baja tasa de falsos positivos), lo que visualmente respalda su alto AUC.
La curva del Árbol de Decisión también se curva hacia arriba, aunque menos marcada.
La curva del Random Forest se muestra irregular y más cercana a la diagonal, lo cual indica una capacidad de clasificación poco confiable bajo distintas probabilidades de corte.
📌 3. Tasa de falsos positivos (FPR) y sensibilidad (TPR)
Los modelos con curvas más a la izquierda y arriba (Red Neuronal, Árbol de Decisión) tienen baja tasa de falsos positivos y alta tasa de verdaderos positivos, lo que los hace más robustos.
Random Forest, en cambio, muestra mayor área bajo la diagonal, indicando más errores de clasificación, especialmente falsos positivos.
library(fmsb)
# Preparar datos
df_radar <- as.data.frame(rbind(
max = rep(1, 4),
min = rep(0, 4),
as.numeric(as.character(t(metricas_long[1:4, 3]))), # Árbol
as.numeric(as.character(t(metricas_long[7:10, 3]))), # RF
as.numeric(as.character(t(metricas_long[13:16, 3]))) # NN
))
rownames(df_radar) <- c("Max", "Min", "Árboles de decisión", "Random Forest", "Red Neuronal")
colnames(df_radar) <- c("Accuracy", "Precision", "Recall", "Especificidad")
# Graficar
radarchart(df_radar,
axistype = 1,
pcol = c("blue", "forestgreen", "red"),
pfcol = c(rgb(0,0,1,0.2), rgb(0,1,0,0.2), rgb(1,0,0,0.2)),
plwd = 2,
cglcol = "grey", cglty = 1,
axislabcol = "grey",
vlcex = 0.8,
title = "Comparación de Métricas - Gráfico Radar")
legend("topright", legend = c("Árboles de decisión", "Random Forest", "Red Neuronal"),
col = c("blue", "forestgreen", "red"), lwd = 2, bty = "n")
🔵 Árbol de decisión
Tiene un desempeño equilibrado en todas las métricas, con valores moderadamente altos, aunque su Recall es menor que su Precision, lo que sugiere que detecta menos positivos reales que los que predice correctamente.
🟢 Random Forest
Se muestra claramente como el modelo más débil: sus valores son visiblemente más bajos en las cuatro métricas. Especialmente llama la atención su bajo Recall, lo que indica que muchos positivos reales no están siendo detectados.
🔴 Red Neuronal
Es el modelo con mejor rendimiento. Su figura se extiende hasta el límite exterior del gráfico en todas las métricas, lo que indica que es el más preciso, sensible y equilibrado de los tres. Es decir, clasifica correctamente la mayoría de los casos positivos y negativos.
El análisis jerárquico de clúster es una técnica de machine learning no supervisada utilizada para agrupar objetos similares en una estructura de árbol, denominada dendrograma, que representa las relaciones de distancia o similitud entre los objetos o grupos de objetos. Es ampliamente utilizado en diversas disciplinas, como biología, marketing, análisis de imágenes y ciencias sociales, para descubrir patrones, asociaciones y estructuras que no son evidentes a simple vista.
Existen dos enfoques principales en el análisis jerárquico de cluster:
Aglomerativo (ascendente): Cada objeto comienzaa en su propio cluster y, en cada paso, los dos clústeresmas similares se fusionan. Este proceso continúa hasta que todos los objetos forman un único cluster.
Divisivo (descendente): Todos los objetos comienzaan en un único cluster y, en cada paso, el cluster se divide en dos, continuando hasta que cada objeto esté en su propio clúster.
Ambos enfoques utilizan algoritmos “codisiosos” que toman decisiones óptimas localmente en cada etapa del proceso.
Característica | Métodos Aglomerativos (Ascendentes) | Métodos Divisivos (Descendentes) |
---|---|---|
Punto de partida | Cada elemento es un clúster individual. | Todos los elementos forman un único clúster inicial. |
Proceso | Fusionan sucesivamente los clústeres más similares hasta formar uno solo. | Dividen sucesivamente el clúster más heterogéneo hasta obtener clústeres individuales. |
Dirección | De lo particular a lo general (de muchos clústeres a uno). | De lo general a lo particular (de un clúster a muchos). |
Complejidad computacional | Generalmente menor (del orden de n³). | Generalmente mayor (del orden de 2ⁿ), aunque existen optimizaciones. |
Visualización | El dendrograma se construye de abajo hacia arriba. | El dendrograma se construye de arriba hacia abajo. |
Uso común | Más utilizados en la práctica y en la mayoría de programas estadísticos. | Menos utilizados debido a su mayor complejidad computacional. |
Ventaja principal | Simplicidad y disponibilidad de múltiples criterios de fusión. | Permite mayor flexibilidad en la estructura del árbol y el equilibrio de los clústeres. |
Desventaja principal | Puede ser más lento en grandes conjuntos de datos y susceptible al encadenamiento. | Algoritmos más complejos y menos eficientes para grandes volúmenes de datos. |
El resultado del análisis jerárquico se representa mediante un dendrograma, un diagrama en forma de árbol que muestra cómo y en qué orden se agrupan o dividen los objetos. Este gráfico facilita la interpretación de las relaciones entre los clústeres y permite decidir el número óptimo de grupos cortando el dendrograma en un determinado nivel.
La base del agrupamiento jerárquico es la matriz de distancias o disimilitudes entre los objetos. Existen diferentes métodos para calcular la distancia entre clústeres, conocidos como métodos de vinculación.
Distancia Euclidiana: \[ d(i, j) = \sqrt{\sum_{k=1}^{p} (x_{ik} - x_{jk})^2} \]
Distancia Manhattan: \[ d(i, j) = \sum_{k=1}^{p} \left| x_{ik} - x_{jk} \right| \]
Distancia de Mahalanobis: \[ d(i, j) = \sqrt{ (\mathbf{x}_i - \mathbf{x}_j)^T \mathbf{S}^{-1} (\mathbf{x}_i - \mathbf{x}_j) } \]
Enlace simple (vecino más próximo): Usa la distancia mínima entre elementos de dos clústeres. \[ D(A, B) = \min \{ d(x_i, x_j) : x_i \in A,\, x_j \in B \} \]
Enlace completo (vecino más lejano): Usa la distancia máxima entre elementos de dos clústeres. \[ D(A, B) = \max \{ d(x_i, x_j) : x_i \in A,\, x_j \in B \} \]
Vinculación promedio: Usa el promedio de todas las distancias entre pares de elementos de los dos clústeres. D(A,B) = promedio de todas las distancias
Método de Ward: Minimiza la varianza total dentro de los clústeres.
Centroide y mediana: Basados en la distancia entre los centroides o medianas de los clústeres.
La elección del método de vinculación puede influir en la forma y composición de los clústeres resultantes.
Formación y tamaño de los clústeres: Dependiendo del criterio de distancia, los clústeres pueden ser más compactos, alargados o incluso poco interpretables. Por ejemplo, el método de enlace simple (single linkage) tiende a crear clústeres alargados y puede unir puntos a través de cadenas, lo que puede resultar en clústeres poco cohesionados (efecto de encadenamiento).
Sensibilidad a outliers: Algunos métodos, como el enlace simple, son sensibles a valores atípicos y ruido, ya que un solo punto puede conectar dos clústeres distintos. El enlace completo (complete linkage), en cambio, tiende a formar clústeres más compactos y es menos sensible a outliers, pero puede dividir grupos naturales si hay puntos alejados dentro del mismo grupo
Distorsión de la métrica: Métodos como el de la media (average linkage) conservan mejor la métrica original y suelen producir clústeres más equilibrados, mientras que otros pueden contraer o expandir artificialmente las distancias entre grupos.
Estructura del dendrograma: El criterio de distancia afecta directamente la estructura del dendrograma, ya que determina en qué orden y a qué distancia se fusionan o dividen los clústeres, lo que puede cambiar la interpretación final del agrupamiento
Ventajas:
Limitaciones:
En el presente análisis se busca agrupar 20 ciudades ficticias de un país en función de tres indicadores socioeconómicos:
Ingreso per cápita (USD),
Tasa de desempleo (%),
Nivel educativo promedio (años).
Este tipo de análisis es útil para la planificación de políticas públicas, ya que permite identificar grupos de ciudades con características similares, y enfocar estrategias específicas para cada grupo.
## Ingreso_PC Desempleo Educacion
## Min. :12134 Min. : 4.600 Min. : 7.90
## 1st Qu.:18026 1st Qu.: 6.650 1st Qu.:10.18
## Median :20480 Median : 7.750 Median :10.90
## Mean :20567 Mean : 7.895 Mean :11.21
## 3rd Qu.:22195 3rd Qu.: 9.450 3rd Qu.:12.30
## Max. :27148 Max. :10.500 Max. :15.30
Interpretación:
Ingreso per cápita (Ingreso_PC): El ingreso promedio per cápita es de aproximadamente 20,567 unidades monetarias. El valor mínimo es 12,134, mientras que el máximo es 27,148, lo que indica una alta dispersión entre ciudades. El 25% de las ciudades tiene ingresos menores a 18,026, mientras que el 75% tiene ingresos menores a 22,195.
Desempleo: El desempleo varía entre 4.6% y 10.5%, con una media cercana al 7.9%. La mediana es 7.75%, lo que indica que la mitad de las ciudades tiene tasas de desempleo por debajo de ese valor. Este rango sugiere una moderada variabilidad en la tasa de desempleo entre ciudades.
Educación: Esta variable (posiblemente porcentaje de población con educación superior o años promedio) tiene una media de 11.21 y una mediana de 10.90. El valor mínimo es 7.90 y el máximo 15.30, lo que refleja diferencias significativas en los niveles educativos entre ciudades.
Conclusión:El análisis descriptivo muestra una dispersión considerable entre ciudades en cuanto a ingreso, desempleo y nivel educativo. Las ciudades con mayores ingresos tienden a presentar también niveles educativos más altos. Este tipo de análisis puede ser útil para identificar brechas socioeconómicas y orientar políticas públicas focalizadas.
Los datos fueron estandarizados (media = 0, desviación estándar = 1) para eliminar el efecto de las diferentes escalas de las variables:
## Ingreso_PC Desempleo Educacion
## Ingreso_PC 1.0000000 -0.09127040 -0.12740892
## Desempleo -0.0912704 1.00000000 0.09099118
## Educacion -0.1274089 0.09099118 1.00000000
Interpretación
Ingreso_PC y Desempleo (-0.09): Existe una correlación negativa muy débil entre el ingreso per cápita y el desempleo. Esto sugiere que, a medida que el ingreso aumenta, el desempleo tiende a disminuir ligeramente, aunque la relación es casi inexistente.
Ingreso_PC y Educación (-0.13): También hay una correlación negativa débil entre el ingreso y el nivel educativo. Este resultado es un poco inesperado, ya que usualmente se espera una relación positiva. Podría deberse a características específicas de las ciudades analizadas o a que la educación medida no refleja necesariamente calidad o aplicabilidad al mercado laboral.
Desempleo y Educación (0.09): Hay una correlación positiva muy débil, indicando que, en esta muestra, a mayor nivel educativo podría haber una ligera tendencia a mayor desempleo, aunque esta relación también es muy débil y no debe sobreinterpretarse.
###
6.3 Normalización o Estandarización de Varables En los
análisis multivariados, como el análisis de clúster o análisis de
componentes principales, es importante que todas las variables estén en
la misma escala para que ninguna domine sobre las demás debido a sus
unidades o magnitudes. Si no se normaliza:
## Ingreso_PC Desempleo Educacion
## [1,] -0.72187637 -1.192582446 -0.843879127
## [2,] -0.38233616 -0.176346778 -0.318097740
## [3,] 1.45698993 -1.192582446 -1.422238653
## [4,] -0.07312581 -0.833911033 2.153074782
## [5,] -0.01272312 -0.714353896 1.154090146
## [6,] 1.61763537 -1.969703839 -1.264504237
## [7,] 0.32835929 1.079003165 -0.528410295
## [8,] -1.44619455 0.242103203 -0.580988433
## [9,] -0.85167789 -1.312139583 0.733465036
## [10,] -0.60389836 1.557231715 -0.212941462
## [11,] 1.11282312 0.600774615 0.155105509
## [12,] 0.22426104 -0.295903915 -0.160363323
## [13,] 0.26641441 1.138781734 -0.160363323
## [14,] -0.03174354 1.138781734 1.311824562
## [15,] -0.71699275 1.019224596 -0.370675878
## [16,] 1.69166079 0.899667459 1.469558978
## [17,] 0.36614310 0.720331753 -1.737707486
## [18,] -2.16742834 0.002988928 0.523152481
## [19,] 0.57536772 -0.295903915 -0.002628907
## [20,] -0.63165789 -0.415461052 0.102527371
## attr(,"scaled:center")
## Ingreso_PC Desempleo Educacion
## 20566.500 7.895 11.205
## attr(,"scaled:scale")
## Ingreso_PC Desempleo Educacion
## 3890.555386 1.672840 1.901931
Conclusión sobre la estandarización
Se aplicó una transformación Z-score a las variables cuantitativas para llevarlas a una escala comparable, con media 0 y desviación estándar 1. Esta normalización permite que variables con distintas unidades puedan ser analizadas simultáneamente en técnicas multivariadas, como el análisis de clúster o de componentes principales, sin que una variable domine a las demás por su escala. A partir de la matriz estandarizada, se observa que algunas observaciones presentan valores significativamente alejados de la media, lo cual será relevante en los análisis posteriores.
El dendrograma muestra los resultados del clustering jerárquico utilizando la distancia euclidiana y el método de enlace completo (complete), aplicado a los datos normalizados de las ciudades.
Cada línea horizontal indica un agrupamiento (fusión) entre ciudades o grupos de ciudades.
El eje vertical (Height) representa la distancia o disimilitud entre los elementos al momento de agruparse. Cuanto mayor la altura, mayor la diferencia entre los grupos que se están uniendo.
Se ha cortado el dendrograma en 3 grupos (coloreados en rojo, verde y azul), lo cual divide a las 20 ciudades en tres conglomerados principales.
Interpretación
Grupo 1 (rojo): incluye las ciudades 14, 16, 10, 15, 17, 11, 7 y 13. Estas ciudades se agrupan a una altura baja, lo que indica que son muy similares entre sí en términos de ingreso per cápita, desempleo y educación. Es el grupo más homogéneo del análisis.
Grupo 2 (verde):contiene únicamente a las ciudades 3 y 9. Se agrupan entre ellas a una altura muy baja (alta similitud), pero se fusionan con el resto a una altura considerable, lo que sugiere que son distintas de los otros grupos. Es decir, aunque estas dos ciudades son muy parecidas entre sí, difieren bastante del resto.
Grupo 3 (azul): abarca las ciudades 6, 4, 5, 8, 1, 18, 12, 2 y 20. Se observa más dispersión interna, ya que las fusiones entre ellas ocurren a mayores alturas que en el grupo rojo. Esto indica que este grupo presenta más diversidad socioeconómica.
## Ciudad Ingreso_PC Desempleo Educacion Grupo
## 1 Lima 17758 5.9 9.6 1
## 2 Arequipa 19079 7.6 10.6 1
## 3 Trujillo 26235 5.9 8.5 2
## 4 Chiclayo 20282 6.5 15.3 1
## 5 Piura 20517 6.7 13.4 1
## 6 Cusco 26860 4.6 8.8 2
## 7 Iquitos 21844 9.7 10.2 3
## 8 Huancayo 14940 8.3 10.1 1
## 9 Tacna 17253 5.7 12.6 1
## 10 Pucallpa 18217 10.5 10.8 3
## 11 Ica 24896 8.9 11.5 3
## 12 Ayacucho 21439 7.4 10.9 1
## 13 Cajamarca 21603 9.8 10.9 3
## 14 Tarapoto 20443 9.8 13.7 3
## 15 Chimbote 17777 9.6 10.5 3
## 16 Juliaca 27148 9.4 14.0 3
## 17 Moquegua 21991 9.1 7.9 3
## 18 Tumbes 12134 7.9 12.2 1
## 19 Puerto Maldonado 22805 7.4 11.2 1
## 20 Huaraz 18109 7.2 11.4 1
El dendrograma obtenido mediante el método de enlace completo y la distancia euclidiana permite observar la agrupación jerárquica de las ciudades del Perú en función de sus características socioeconómicas (Ingreso per cápita, Tasa de Desempleo y Nivel Educativo).
Grupo 1: Este grupo incluye ciudades como Lima, Arequipa, Iquitos, Huancayo, Tacna y Pucallpa. Aunque presentan algunas diferencias, tienden a estar agrupadas por tener niveles de ingreso moderados y valores de educación y desempleo variables. Lima y Arequipa, a pesar de tener altos ingresos, están agrupadas con ciudades de ingresos más bajos debido probablemente a similitudes en el desempleo o la educación.
Grupo 2: Incluye a Trujillo y Cusco, que se distinguen por tener los ingresos per cápita más altos del conjunto de datos. Además, mantienen niveles de desempleo y educación más balanceados, lo que podría explicar su cercanía dentro del mismo grupo.
Grupo 3: Compuesto por Chiclayo y Piura, este grupo parece diferenciarse por tener niveles más altos de educación en comparación con otras ciudades, así como un desempleo medio-alto. Esto puede indicar una particularidad en el perfil educativo de estas ciudades.
El análisis de clúster jerárquico permitió segmentar las ciudades peruanas en tres grupos distintos según variables económicas y sociales. Este tipo de análisis es útil para identificar patrones regionales y diseñar políticas públicas más focalizadas, considerando que algunas ciudades comparten características que podrían beneficiarse de estrategias comunes en educación, empleo o desarrollo económico.
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
El gráfico muestra la representación bidimensional de los tres clústeres obtenidos tras aplicar un método de agrupamiento (probablemente k-means o HCPC). Las dimensiones Dim1 (40.2%) y Dim2 (30.7%) explican en conjunto el 70.9% de la variabilidad total de los datos.
Clúster 1 (círculos azules): Es el grupo más numeroso y presenta una alta dispersión. Se concentra alrededor del origen del gráfico, lo que sugiere que sus individuos tienen características promedio respecto a las variables originales.
Clúster 2 (triángulos amarillos): Está claramente separado de los otros dos clústeres en el espacio bidimensional, con coordenadas en valores más altos de Dim1 y Dim2. Este grupo contiene pocos individuos y muestra características particulares o extremas.
Clúster 3 (cuadrados grises): Es un grupo intermedio en cuanto a ubicación y tamaño. Se ubica entre los clústeres 1 y 2, con una leve inclinación hacia valores negativos de Dim1. Presenta menor dispersión que el clúster 1.
El análisis de clúster permitió identificar tres grupos bien diferenciados en el conjunto de datos. El clúster 2 está claramente separado, lo que indica que sus individuos tienen un perfil distinto al de los otros grupos. Por otro lado, el clúster 1 agrupa a la mayoría de los individuos, posiblemente con valores promedio o comunes. Estos resultados pueden ser útiles para la segmentación, la toma de decisiones o el análisis más profundo de los perfiles representados por cada grupo.
A continuación, se presentan las interpretaciones de las variables socioeconómicas según los grupos identificados:
Los tres grupos muestran diferentes perfiles socioeconómicos. El Grupo 2 resalta por su alto ingreso y bajo desempleo, aunque con menor educación formal, posiblemente asociado a sectores productivos intensivos. El Grupo 3 destaca por su alto nivel educativo, aunque presenta un desempleo más elevado. Por otro lado, el Grupo 1 parece ocupar una posición intermedia en todas las variables. Estos hallazgos sugieren que las estrategias de desarrollo económico y social deben adaptarse a las particularidades de cada grupo para ser más efectivas.
El análisis de clúster, también conocido como análisis de conglomerado, es una técnica estadística multivariante que busca agrupar elementos (o variables) tratando de lograr la máxima homogeneidad en cada grupo y la mayor diferencia entre los grupos.
El objetivo principal del análisis de conglomerados es la identificación de grupos de manera que la variabilidad intraclase sea inferior a la variabilidad entreclases.
Existen dos tipos de análisis de clúster: Jerárquicos y no Jerárquicos, en esta ocasión nos centraremos en la análisis clúster no jerárquico.
Mejor conocido como métodos de optimización. Estos métodos si permiten una reasignación en los grupos, aunque se vuelve necesario fijar de antemano el número de cluster deseado.
Ventajas:
Los métodos de reasignación permiten reasignar objetos a distintos conglomerados en cada fase.
Los métodos de búsqueda de densidad se agrupan mediante la búsqueda de altas densidades (modas).
Los métodos directos permiten clasificar de forma simultánea individuos y variables.
Desventajas:
Se debe especificar con anticipación el número de clústers.
Asume que se tiene conocimiento de la data (K-means)
Los resultados finales son sensibles a la selección aleatoria de clusters centers. (K-means)
Si se ordena nuevamente la data es muy posible que se obtengan salidas diferentes cada vez que la data se reordene (K-means)
Es muy sensible a los datos atípicos (K-means)
La presente base de datos contiene información sobre la evaluación de la calidad de atención brindada por asesores comerciales a los clientes, posterior a la prestación del servicio. Cada registro corresponde a un asesor, identificado mediante un código único, y evalúa distintos aspectos percibidos de la atención al cliente. Estas evaluaciones se expresan como puntajes en una escala que varía de 0 a 10, donde valores mayores indican un mejor desempeño en el criterio correspondiente.
El propósito de este análisis es identificar grupos (clusters) de asesores con perfiles de calidad de atención similares mediante un método de clusterización no jerárquico (por ejemplo, k-means), lo que permitirá caracterizar patrones de desempeño y proponer estrategias de mejora orientadas a cada segmento.
Variable | Descripción |
---|---|
ID | Código único que identifica a cada asesor comercial evaluado. |
Amab | Puntaje que refleja el nivel de amabilidad percibido durante la interacción con el cliente. |
Interes | Grado de interés mostrado por el asesor respecto a la situación o problema expuesto. |
Capa | Habilidad demostrada por el asesor para dar solución efectiva al requerimiento planteado. |
Clari | Claridad y precisión con la que el asesor brindó información al cliente. |
Tiemp | Puntaje asignado al tiempo total empleado en la atención, considerando oportunidad y agilidad. |
Soluc | Evaluación del resultado final en cuanto a si el problema del cliente fue resuelto satisfactoriamente. |
La mayoría de las variables presentan asimetría negativa. Para corregirla, se aplicará una transformación mediante la elevación al cuadrado de la variable Cal.
Como se puede ver, en la figura la asimetría negativa y los datos atípicos ya desaparecieron.
Eligiendo el número de Cluster:
WSS: Within Sum of Squares (Suma de cuadrados Intra clusters ) Calcula la inercia dentro de cada cluster y grafica cómo disminuye a medida que aumentas el número de clusters.
EL metodo del Codo: Intenta encontrar el número de clusters donde la mejora de la WSS (reducción de inercia) se estabiliza.
El método codo sugiere que se debe agrupar en 3 grupos; ya que en k = 3 se forma el codo la pendiente de la curva comienza a disminuir.
Determina el número óptimo de clusters y presenta los resultados de manera visual. El coef mide qué tan bien se asigna un punto a su cluster:
Un alto ancho de silueta promedio indica un buen agrupamiento. En el ejemplo, el punto más alto es en k = 2. Por lo que método Silhouette recomienda agrupar en dos grupos a los asesores comerciales.
Este método compara la variación dentro de los clusters en los datos originales con los datos generados aleatoriamente (sin estructura de clustering). Este método evalúa qué tan diferente es la variación dentro de los clusters en los datos reales comparado con datos aleatorios
Con el Método Gap statistic la estimaciónde los clústeres óptimos será con un valor que maximice la estadística de Gap. En este ejemplo, este método recomienda agrupar a los asesores comerciales en 3 grupos.
El método de BSS es similar al método del codo, pero se enfoca solo en la variabilidad explicada entre clusters.
No hay una función en R para este método, por lo que se usa la siguiente función llamado Niveles.
## NULL
## [1] 2.273737e-13 2.707223e+02 3.525805e+02 3.876181e+02 4.114582e+02
## [6] 4.287358e+02 4.449176e+02 4.559949e+02
Segun este método se observa que en k = 3 la curva cambia de pendiente. Por que este método también sugiere agrupar los asesores comerciales en tres grupos. (En la función Niveles v = 3 es para que en la gráfica aparezca la linea entrecortada vertical).
En esta parte se visualizara los puntos de datos del dataframe coloreados según el cluster al que pertenecen, incluyendo los centroides de cada cluster. También se Trazara elipses que indican la concentración de los puntos dentro de cada cluster, ayudando a interpretar visualmente la separación y compacidad de los clusters.
Como la mayoría de los métodos recomiendan agrupar a los asesores comerciales en tres grupos, entonces le vamos a pedir que nos visualice que nos visualice en tres grupos.
Los colores denotan el cluster al que pertenece cada punto:
Separación entre clusters:
Los clusters muestran una buena separación general, sobre todo el Cluster 1 (azul), que se encuentra claramente diferenciado hacia la derecha del gráfico.
El Cluster 2 (amarillo) está localizado en la parte izquierda, bien definido y compacto, con poca dispersión de sus observaciones.
El Cluster 3 (gris) ocupa una posición intermedia entre los otros dos clusters y presenta cierta superposición con el Cluster 2 (amarillo). Este solapamiento indica que algunos individuos podrían compartir características de ambos grupos.
La forma convexa de las envolventes permite visualizar el alcance y la densidad de cada cluster. El polígono del Cluster 3 es más amplio, sugiriendo mayor heterogeneidad interna en comparación con el Cluster 2.
Vamos a cortar en 3 cluster
En esta salida, el asesor comercial 1 pertenece al clúster 3, el asesor comercial 6 al clúster 1, el asesor comercial 15 al clúster 2, y así sucesivamente.
## grp3
## 1 2 3
## 18 43 43
En la tabla se observa la distribución de los asesores comerciales en los diferentes clústeres identificados. El clúster 1 agrupa a 18 asesores, mientras que el clúster 2 concentra a 43 asesores y el clúster 3 incluye a 43. Esta agrupación permite identificar patrones de comportamiento o desempeño comunes dentro de cada clúster, lo que facilitará el diseño de estrategias específicas para cada grupo.
El Cluster 2 se caracteriza por altos puntajes en las siguientes variables: amabilidad de atención, interés en el problema, capacidad para resolver el problema, claridad de la información, tiempo de atención y solución del problema.
Por otro lado, el Cluster 1 se distingue por tener bajos puntajes en todas estas variables. Finalmente, el Cluster 3 presenta puntajes promedio en todas las variables, es decir, no se destacan por ser ni bajos ni altos.
La descripción de cada clúster también se puede realizar mediante diagramas de caracterización. Para ello, primero se debe ejecutar la función: Caract1
En la figura, se puede observar que los asesores comerciales pertenecientes al clúster 2 tienen altos puntajes en todas las variables. Por el contrario, aquel los del clúster 1 muestran bajos puntajes en todas las variables, mientras que los asesores del clúster 3 tienen puntajes por debajo del promedio.
De manera similar se puede hacer con el algoritmo PAM, este algoritmo es similar a K-Means, pero usa medoides (los puntos reales más centrales del cluster) en lugar de centroides, lo que lo hace más robusto frente a valores atípicos.
Eligiendo el número de Cluster:
El método de silueta evalúa la calidad del clustering en función de:
Separación: Qué tan lejos están los puntos de un cluster de los puntos de otros clusters.
Cohesión: Qué tan cerca están los puntos dentro de un mismo cluster.
La estadística de brecha mide cuánto mejor se agrupan los datos reales en comparación con datos generados aleatoriamente (sin estructura) y que el número óptimo de clusters (k) se encuentra en el punto donde el valor de la brecha alcanza su máximo.
Con k=3 clusters usando elipses: euclídea y convexa:
## 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
## 1 1 1 2 2 3 2 2 1 1 2 1 1 3 2 1 3 1 2 1
## 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
## 2 1 1 2 3 2 2 2 1 1 2 2 2 1 1 3 2 2 2 1
## 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
## 1 2 1 3 2 3 1 1 2 1 2 1 2 2 2 1 1 1 1 3
## 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
## 1 3 1 3 1 2 2 3 3 1 3 2 2 2 2 2 1 1 2 2
## 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
## 2 1 1 1 3 1 2 1 1 1 2 3 1 1 2 2 2 2 3 3
## 101 102 103 104
## 2 1 2 3
## grp5
## 1 2 3
## 43 43 18
Esta diseñado para datasets grandes. Selecciona una muestra representativa del dataset para aplicar PAM, reduciendo el tiempo de cálculo. Es útil cuando trabajar con todo el dataset es computacionalmente costoso.
Eligiendo el número de Cluster:
Con k=3 clusters usando elipses: euclídea y convexa:
## 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
## 1 1 1 2 1 3 2 1 1 1 1 3 1 3 2 3 3 1 1 1
## 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
## 2 1 1 1 3 2 2 2 1 1 2 1 2 1 1 3 2 2 2 1
## 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
## 3 2 1 3 2 3 3 1 2 1 2 1 2 2 2 1 1 1 1 3
## 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
## 1 3 1 3 1 2 2 3 3 1 3 2 2 2 2 2 1 1 2 2
## 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
## 2 1 1 1 3 1 2 3 1 1 2 3 1 1 2 1 2 2 3 3
## 101 102 103 104
## 1 1 2 3
## grp6
## 1 2 3
## 46 35 23
Se compararon tres métodos de clustering no jerárquico: K-means, PAM y CLARA, evaluando su desempeño con métricas internas y de estabilidad. Las principales medidas consideradas fueron:
APN (Average Proportion of Non-overlap): Mide la estabilidad del clustering; valores más bajos indican mayor estabilidad.
AD (Average Distance): Evaluación de la estabilidad; valores más bajos son preferibles.
ADM (Average Distance Between Means): Estabilidad; valores más bajos indican mayor consistencia.
FOM (Figure of Merit): Métrica de error interno; valores más bajos son mejores.
Connectivity: Mide qué tan bien conectados están los puntos dentro de cada cluster; valores más bajos son mejores.
Dunn index: Evalúa la compacidad y separación entre clusters; valores más altos son mejores.
Silhouette width: Evalúa la calidad del clustering; valores más altos son mejores.
##
## Clustering Methods:
## kmeans pam clara
##
## Cluster sizes:
## 3
##
## Validation Measures:
## 3
##
## kmeans APN 0.1389
## AD 2.0741
## ADM 0.3807
## FOM 0.7656
## Connectivity 36.6909
## Dunn 0.0671
## Silhouette 0.3446
## pam APN 0.1297
## AD 2.0568
## ADM 0.3343
## FOM 0.7666
## Connectivity 34.7294
## Dunn 0.0793
## Silhouette 0.3251
## clara APN 0.1091
## AD 2.0433
## ADM 0.3126
## FOM 0.7499
## Connectivity 25.3167
## Dunn 0.1431
## Silhouette 0.3300
##
## Optimal Scores:
##
## Score Method Clusters
## APN 0.1091 clara 3
## AD 2.0433 clara 3
## ADM 0.3126 clara 3
## FOM 0.7499 clara 3
## Connectivity 25.3167 clara 3
## Dunn 0.1431 clara 3
## Silhouette 0.3446 kmeans 3
APN: 0.1091 (más bajo = mejor estabilidad).
AD: 2.0433 (más bajo).
ADM: 0.3126 (más bajo).
FOM: 0.7499 (más bajo).
Connectivity: 25.3167 (más bajo).
Dunn index: 0.1431 (más alto, lo que indica mejor separación relativa).
Estos resultados indican que CLARA ofrece una solución más estable y con mejor compacidad y separación entre clusters en comparación con K-means y PAM.
K-means tuvo el Silhouette más alto (0.3446), aunque solo ligeramente superior al de CLARA (0.3300), sugiriendo que su agrupamiento también es aceptable en términos de calidad, pero con menor estabilidad y separación según las otras métricas.
PAM mostró un rendimiento intermedio, sin sobresalir en ninguna métrica.
En resumen, el algoritmo Clara es el mejor para el análisis.
De acuerdo con estas métricas, CLARA fue el método más adecuado para agrupar los datos en 3 clusters, ya que obtuvo las puntuaciones óptimas en casi todos los criterios de validación interna y de estabilidad. Si el objetivo es maximizar la consistencia y la separación entre grupos, CLARA es la opción recomendada.
El análisis permitió segmentar a los asesores comerciales en grupos con perfiles diferenciados de calidad de atención al cliente.
La mayoría de los métodos para determinar el número óptimo de clusters (Elbow, Gap Statistic, BSS) coincidieron en que 3 clusters era la solución más adecuada.
El algoritmo CLARA presentó el mejor desempeño en las métricas de validación interna y estabilidad, por lo que se considera la técnica más recomendable para este análisis.
Los clusters identificados se caracterizaron de la siguiente manera:
Cluster 1: Bajo desempeño en todas las variables evaluadas.
Cluster 2: Alto desempeño en todas las dimensiones de atención.
Cluster 3: Desempeño intermedio o promedio.
Las visualizaciones mostraron que existe una separación razonable entre los clusters, destacando especialmente la diferenciación del grupo de alto desempeño, aunque con cierto solapamiento entre los grupos intermedio y bajo.
Estos hallazgos permiten diseñar estrategias de mejora específicas, como programas de capacitación para los asesores de bajo desempeño, acciones de refuerzo para el grupo intermedio y reconocimiento a los asesores con resultados sobresalientes.