PASO 1: Preparación inicial y limpieza de los datos:
library(caret)
## Loading required package: ggplot2
## Loading required package: lattice
library(rpart)
library(C50)
datos <- read.csv("https://archive.ics.uci.edu/ml/machine-learning-databases/00519/heart_failure_clinical_records_dataset.csv")
datos$DEATH_EVENT <- as.factor(datos$DEATH_EVENT)
# Verificar estructura de los datos
cat("Estructura del conjunto de datos:")
## Estructura del conjunto de datos:
str(datos)
## 'data.frame': 299 obs. of 13 variables:
## $ age : num 75 55 65 50 65 90 75 60 65 80 ...
## $ anaemia : int 0 0 0 1 1 1 1 1 0 1 ...
## $ creatinine_phosphokinase: int 582 7861 146 111 160 47 246 315 157 123 ...
## $ diabetes : int 0 0 0 0 1 0 0 1 0 0 ...
## $ ejection_fraction : int 20 38 20 20 20 40 15 60 65 35 ...
## $ high_blood_pressure : int 1 0 0 0 0 1 0 0 0 1 ...
## $ platelets : num 265000 263358 162000 210000 327000 ...
## $ serum_creatinine : num 1.9 1.1 1.3 1.9 2.7 2.1 1.2 1.1 1.5 9.4 ...
## $ serum_sodium : int 130 136 129 137 116 132 137 131 138 133 ...
## $ sex : int 1 1 1 1 0 1 1 1 0 1 ...
## $ smoking : int 0 0 1 0 0 1 0 1 0 1 ...
## $ time : int 4 6 7 7 8 8 10 10 10 10 ...
## $ DEATH_EVENT : Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ...
# Mostrar las primeras filas
cat("Primeras filas del conjunto de datos:")
## Primeras filas del conjunto de datos:
print(head(datos))
## age anaemia creatinine_phosphokinase diabetes ejection_fraction
## 1 75 0 582 0 20
## 2 55 0 7861 0 38
## 3 65 0 146 0 20
## 4 50 1 111 0 20
## 5 65 1 160 1 20
## 6 90 1 47 0 40
## high_blood_pressure platelets serum_creatinine serum_sodium sex smoking time
## 1 1 265000 1.9 130 1 0 4
## 2 0 263358 1.1 136 1 0 6
## 3 0 162000 1.3 129 1 1 7
## 4 0 210000 1.9 137 1 0 7
## 5 0 327000 2.7 116 0 0 8
## 6 1 204000 2.1 132 1 1 8
## DEATH_EVENT
## 1 1
## 2 1
## 3 1
## 4 1
## 5 1
## 6 1
PASO 2: Dividir los datos en conjunto de entrenamiento y prueba
set.seed(2025)
folds <- createFolds(datos$DEATH_EVENT, k = 7)
entrenamiento <- datos[-folds[[7]],]
prueba <- datos[folds[[7]],]
# Crear etiquetas
entrenamiento_labels <- datos$DEATH_EVENT[-folds[[7]]]
prueba_labels <- datos$DEATH_EVENT[folds[[7]]]
PASO 3: Construcción del árbol de decisión
library(rpart)
library(rpart.plot)
set.seed(2025)
arbol_1 <- rpart(DEATH_EVENT ~ ., data = entrenamiento)
# Graficar el árbol de decisión
rpart.plot(arbol_1)
PASO 4: Validar la estabilidad del modelo
library(caret)
library(C50)
set.seed(2025)
train_control <- trainControl(method="cv", number=10, savePredictions = TRUE)
arbol_cv <- train(DEATH_EVENT ~ .,
data=cbind(prueba, DEATH_EVENT=prueba_labels),
method = "C5.0",
trControl = train_control,
tuneLength = 10)
# Matriz de confusión usando predicciones guardadas por caret
confusionMatrix(arbol_cv$pred$pred, arbol_cv$pred$obs)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 1058 360
## 1 102 200
##
## Accuracy : 0.7314
## 95% CI : (0.7098, 0.7522)
## No Information Rate : 0.6744
## P-Value [Acc > NIR] : 1.709e-07
##
## Kappa : 0.3056
##
## Mcnemar's Test P-Value : < 2.2e-16
##
## Sensitivity : 0.9121
## Specificity : 0.3571
## Pos Pred Value : 0.7461
## Neg Pred Value : 0.6623
## Prevalence : 0.6744
## Detection Rate : 0.6151
## Detection Prevalence : 0.8244
## Balanced Accuracy : 0.6346
##
## 'Positive' Class : 0
##
PASO 5: Comparar desempeño de CART vs. C5.0
# Árbol CART
arbol_cart <- train(DEATH_EVENT ~ ., data=cbind(prueba, DEATH_EVENT=prueba_labels),
method = "rpart", trControl = train_control,
tuneLength = 10)
# Árbol C5.0
arbol_c50 <- train(DEATH_EVENT ~ ., data=cbind(prueba, DEATH_EVENT=prueba_labels),
method = "C5.0", trControl = train_control,
tuneLength = 10)
# Comparar modelos usando resamples()
comparacion <- resamples(list(CART = arbol_cart, C5.0 = arbol_c50))
# Resumen de métricas
summary(comparacion)
##
## Call:
## summary.resamples(object = comparacion)
##
## Models: CART, C5.0
## Number of resamples: 10
##
## Accuracy
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## CART 0.6 0.6375 1.0 0.8550000 1.00 1 0
## C5.0 0.6 0.7500 0.8 0.8166667 0.95 1 0
##
## Kappa
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## CART 0 0.04166667 1.0000000 0.6166667 1.0000000 1 0
## C5.0 0 0.00000000 0.5454545 0.4706294 0.9038462 1 0
# Boxplots de exactitud (u otras métricas)
bwplot(comparacion, metric = "Accuracy")
dotplot(comparacion, metric = "Accuracy")
bwplot(comparacion, metric = "Kappa")
Análisis comparativo de los modelos:
Conclusión final:
Después de analizar detalladamente los resultados de la validación
cruzada, podemos determinar que el modelo CART demuestra un desempeño
superior en este conjunto de datos específico. Su mayor precisión
promedio y mejor coeficiente Kappa sugieren que es más efectivo y
confiable para esta tarea de clasificación particular. La estabilidad
mostrada en las métricas a través de los diferentes folds refuerza su
robustez como herramienta de predicción para este caso.
Esta conclusión se basa en evidencia cuantitativa y proporciona una base sólida para preferir CART sobre C5.0 en este contexto específico de análisis de datos médicos.