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:

  1. Evaluación de Precisión (Accuracy):
    • Basándonos en los resultados obtenidos, el modelo CART muestra un mejor rendimiento general, con una media de precisión de 0.855 (85.5%) en comparación con C5.0 que alcanzó 0.817 (81.7%).
    • Los boxplots y dotplots revelan que CART mantiene una distribución más concentrada en valores altos, alcanzando máximos de 1.0 en varios pliegues.
    • Es notable que ambos modelos muestran cierta variabilidad, con mínimos cercanos a 0.6, pero CART demuestra una mayor consistencia en sus predicciones.
  2. Evaluación del Estadístico Kappa:
    • El coeficiente Kappa, que nos ayuda a entender la concordancia entre predicciones y valores reales más allá del azar, favorece al modelo CART.
    • CART alcanzó un Kappa medio de 0.617, superando al 0.471 de C5.0.
    • Las visualizaciones muestran que CART mantiene una mayor estabilidad en esta métrica a través de los diferentes folds de validación.

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.