Teoría

El paquete CARET (Classification And Regression Training) es un paquete que permite utilizar distintos algoritmos de aprendizaje automático y comparar sus resultados.

En este ejercicio se utilizará una base de datos de pacientes para tratar de predecir la presencia o ausencia de enfermedad cardiaca.

Instalar paquetes y llamar librerías

# install.packages("caret") # Algoritmos de aprendizaje automático
library(caret)
# install.packages("ggplot2") # Gráficas
library(ggplot2)
# install.packages("lattice") # Crear gráficos
library(lattice)
# install.packages("DataExplorer") # Análisis Descriptivo
library(DataExplorer)
# install.packages("kernlab")
library(kernlab)
# install.packages("randomForest")
library(randomForest)
# install.packages("readxl")
library(readxl)

Importar base de datos

# file.choose()
df <- read_excel("heart.xlsx", sheet="heart")
df <- data.frame(df)

Entender la base de datos

summary(df)
##       age             sex               cp            trestbps    
##  Min.   :29.00   Min.   :0.0000   Min.   :0.0000   Min.   : 94.0  
##  1st Qu.:48.00   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:120.0  
##  Median :56.00   Median :1.0000   Median :1.0000   Median :130.0  
##  Mean   :54.43   Mean   :0.6956   Mean   :0.9424   Mean   :131.6  
##  3rd Qu.:61.00   3rd Qu.:1.0000   3rd Qu.:2.0000   3rd Qu.:140.0  
##  Max.   :77.00   Max.   :1.0000   Max.   :3.0000   Max.   :200.0  
##       chol          fbs            restecg          thalach     
##  Min.   :126   Min.   :0.0000   Min.   :0.0000   Min.   : 71.0  
##  1st Qu.:211   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:132.0  
##  Median :240   Median :0.0000   Median :1.0000   Median :152.0  
##  Mean   :246   Mean   :0.1493   Mean   :0.5298   Mean   :149.1  
##  3rd Qu.:275   3rd Qu.:0.0000   3rd Qu.:1.0000   3rd Qu.:166.0  
##  Max.   :564   Max.   :1.0000   Max.   :2.0000   Max.   :202.0  
##      exang           oldpeak          slope             ca        
##  Min.   :0.0000   Min.   :0.000   Min.   :0.000   Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:0.000   1st Qu.:1.000   1st Qu.:0.0000  
##  Median :0.0000   Median :0.800   Median :1.000   Median :0.0000  
##  Mean   :0.3366   Mean   :1.072   Mean   :1.385   Mean   :0.7541  
##  3rd Qu.:1.0000   3rd Qu.:1.800   3rd Qu.:2.000   3rd Qu.:1.0000  
##  Max.   :1.0000   Max.   :6.200   Max.   :2.000   Max.   :4.0000  
##       thal           target      
##  Min.   :0.000   Min.   :0.0000  
##  1st Qu.:2.000   1st Qu.:0.0000  
##  Median :2.000   Median :1.0000  
##  Mean   :2.324   Mean   :0.5132  
##  3rd Qu.:3.000   3rd Qu.:1.0000  
##  Max.   :3.000   Max.   :1.0000
str(df)
## 'data.frame':    1025 obs. of  14 variables:
##  $ age     : num  52 53 70 61 62 58 58 55 46 54 ...
##  $ sex     : num  1 1 1 1 0 0 1 1 1 1 ...
##  $ cp      : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ trestbps: num  125 140 145 148 138 100 114 160 120 122 ...
##  $ chol    : num  212 203 174 203 294 248 318 289 249 286 ...
##  $ fbs     : num  0 1 0 0 1 0 0 0 0 0 ...
##  $ restecg : num  1 0 1 1 1 0 2 0 0 0 ...
##  $ thalach : num  168 155 125 161 106 122 140 145 144 116 ...
##  $ exang   : num  0 1 1 0 0 0 0 1 0 1 ...
##  $ oldpeak : num  1 3.1 2.6 0 1.9 1 4.4 0.8 0.8 3.2 ...
##  $ slope   : num  2 0 0 2 1 1 0 1 2 1 ...
##  $ ca      : num  2 0 0 1 3 0 3 1 0 2 ...
##  $ thal    : num  3 3 3 3 2 2 1 3 3 2 ...
##  $ target  : num  0 0 0 0 0 1 0 0 0 0 ...
# create_report(df) # DataExplorer
plot_missing(df)

plot_histogram(df)

plot_correlation(df)

NOTA: En modelos de clasificación, la variable que queremos predecir debe tener formato de FACTOR

df$target <- as.factor(ifelse(df$target==1, "Si", "No"))

str(df)
## 'data.frame':    1025 obs. of  14 variables:
##  $ age     : num  52 53 70 61 62 58 58 55 46 54 ...
##  $ sex     : num  1 1 1 1 0 0 1 1 1 1 ...
##  $ cp      : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ trestbps: num  125 140 145 148 138 100 114 160 120 122 ...
##  $ chol    : num  212 203 174 203 294 248 318 289 249 286 ...
##  $ fbs     : num  0 1 0 0 1 0 0 0 0 0 ...
##  $ restecg : num  1 0 1 1 1 0 2 0 0 0 ...
##  $ thalach : num  168 155 125 161 106 122 140 145 144 116 ...
##  $ exang   : num  0 1 1 0 0 0 0 1 0 1 ...
##  $ oldpeak : num  1 3.1 2.6 0 1.9 1 4.4 0.8 0.8 3.2 ...
##  $ slope   : num  2 0 0 2 1 1 0 1 2 1 ...
##  $ ca      : num  2 0 0 1 3 0 3 1 0 2 ...
##  $ thal    : num  3 3 3 3 2 2 1 3 3 2 ...
##  $ target  : Factor w/ 2 levels "No","Si": 1 1 1 1 1 2 1 1 1 1 ...
table(df$target)
## 
##  No  Si 
## 499 526

Partir la base de datos

# Normalmente 80-20 o 70-30
set.seed(123) # Números aleatorios

renglones_entrenamiento <- createDataPartition(df$target, p=0.8, list=FALSE)

entrenamiento <- df[renglones_entrenamiento, ]
prueba <- df[-renglones_entrenamiento, ]

Distintos tipos de Métodos para Modelar

Los métodos más utilizados para modelar aprendizaje automático son:

Modelo 1: SVM Lineal

modelo1 <- train(target ~., data=entrenamiento, 
                 method="svmLinear",
                 preProcess = c("scale", "center"),
                 trControl = trainControl(method = "cv", number = 10),
                 tuneGrid = data.frame(C=1)
                 )

resultado_entrenamiento1 <- predict(modelo1,entrenamiento)
resultado_prueba1 <- predict(modelo1,prueba)

# Matriz de Confusión
# Es una tabla de evaluación que desglosa el rendimiento del modelo de clasificación

# Matriz de Confusión del Resultado de Entrenamiento
mcre1 <- confusionMatrix(resultado_entrenamiento1, entrenamiento$target)
mcre1
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  No  Si
##         No 301  37
##         Si  99 384
##                                           
##                Accuracy : 0.8343          
##                  95% CI : (0.8071, 0.8592)
##     No Information Rate : 0.5128          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.6672          
##                                           
##  Mcnemar's Test P-Value : 1.689e-07       
##                                           
##             Sensitivity : 0.7525          
##             Specificity : 0.9121          
##          Pos Pred Value : 0.8905          
##          Neg Pred Value : 0.7950          
##              Prevalence : 0.4872          
##          Detection Rate : 0.3666          
##    Detection Prevalence : 0.4117          
##       Balanced Accuracy : 0.8323          
##                                           
##        'Positive' Class : No              
## 
# Matriz de Confusión del Resultado de la Prueba
mcrp1 <- confusionMatrix(resultado_prueba1, prueba$target)
mcrp1
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction No Si
##         No 78 10
##         Si 21 95
##                                           
##                Accuracy : 0.848           
##                  95% CI : (0.7913, 0.8944)
##     No Information Rate : 0.5147          
##     P-Value [Acc > NIR] : < 2e-16         
##                                           
##                   Kappa : 0.6948          
##                                           
##  Mcnemar's Test P-Value : 0.07249         
##                                           
##             Sensitivity : 0.7879          
##             Specificity : 0.9048          
##          Pos Pred Value : 0.8864          
##          Neg Pred Value : 0.8190          
##              Prevalence : 0.4853          
##          Detection Rate : 0.3824          
##    Detection Prevalence : 0.4314          
##       Balanced Accuracy : 0.8463          
##                                           
##        'Positive' Class : No              
## 

Modelo 2: SVM Radial

modelo2 <- train(target ~., data=entrenamiento, 
                 method="svmRadial",
                 preProcess = c("scale", "center"),
                 trControl = trainControl(method = "cv", number = 10),
                 tuneGrid = data.frame(sigma=0.1, C=1)
                 )

resultado_entrenamiento2 <- predict(modelo2,entrenamiento)
resultado_prueba2 <- predict(modelo2,prueba)

# Matriz de Confusión
# Es una tabla de evaluación que desglosa el rendimiento del modelo de clasificación

# Matriz de Confusión del Resultado de Entrenamiento
mcre2 <- confusionMatrix(resultado_entrenamiento2, entrenamiento$target)
mcre2
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  No  Si
##         No 385   7
##         Si  15 414
##                                           
##                Accuracy : 0.9732          
##                  95% CI : (0.9597, 0.9831)
##     No Information Rate : 0.5128          
##     P-Value [Acc > NIR] : <2e-16          
##                                           
##                   Kappa : 0.9463          
##                                           
##  Mcnemar's Test P-Value : 0.1356          
##                                           
##             Sensitivity : 0.9625          
##             Specificity : 0.9834          
##          Pos Pred Value : 0.9821          
##          Neg Pred Value : 0.9650          
##              Prevalence : 0.4872          
##          Detection Rate : 0.4689          
##    Detection Prevalence : 0.4775          
##       Balanced Accuracy : 0.9729          
##                                           
##        'Positive' Class : No              
## 
# Matriz de Confusión del Resultado de la Prueba
mcrp2 <- confusionMatrix(resultado_prueba2, prueba$target)
mcrp2
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  No  Si
##         No  95   5
##         Si   4 100
##                                           
##                Accuracy : 0.9559          
##                  95% CI : (0.9179, 0.9796)
##     No Information Rate : 0.5147          
##     P-Value [Acc > NIR] : <2e-16          
##                                           
##                   Kappa : 0.9117          
##                                           
##  Mcnemar's Test P-Value : 1               
##                                           
##             Sensitivity : 0.9596          
##             Specificity : 0.9524          
##          Pos Pred Value : 0.9500          
##          Neg Pred Value : 0.9615          
##              Prevalence : 0.4853          
##          Detection Rate : 0.4657          
##    Detection Prevalence : 0.4902          
##       Balanced Accuracy : 0.9560          
##                                           
##        'Positive' Class : No              
## 

Modelo 3: SVM Polinómico

modelo3 <- train(target ~., data=entrenamiento, 
                 method="svmPoly",
                 preProcess = c("scale", "center"),
                 trControl = trainControl(method = "cv", number = 10),
                 tuneGrid = data.frame(degree=1, scale=1, C=1)
                 )

resultado_entrenamiento3 <- predict(modelo3,entrenamiento)
resultado_prueba3 <- predict(modelo3,prueba)

# Matriz de Confusión
# Es una tabla de evaluación que desglosa el rendimiento del modelo de clasificación

# Matriz de Confusión del Resultado de Entrenamiento
mcre3 <- confusionMatrix(resultado_entrenamiento3, entrenamiento$target)
mcre3
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  No  Si
##         No 301  37
##         Si  99 384
##                                           
##                Accuracy : 0.8343          
##                  95% CI : (0.8071, 0.8592)
##     No Information Rate : 0.5128          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.6672          
##                                           
##  Mcnemar's Test P-Value : 1.689e-07       
##                                           
##             Sensitivity : 0.7525          
##             Specificity : 0.9121          
##          Pos Pred Value : 0.8905          
##          Neg Pred Value : 0.7950          
##              Prevalence : 0.4872          
##          Detection Rate : 0.3666          
##    Detection Prevalence : 0.4117          
##       Balanced Accuracy : 0.8323          
##                                           
##        'Positive' Class : No              
## 
# Matriz de Confusión del Resultado de la Prueba
mcrp3 <- confusionMatrix(resultado_prueba3, prueba$target)
mcrp3
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction No Si
##         No 78 10
##         Si 21 95
##                                           
##                Accuracy : 0.848           
##                  95% CI : (0.7913, 0.8944)
##     No Information Rate : 0.5147          
##     P-Value [Acc > NIR] : < 2e-16         
##                                           
##                   Kappa : 0.6948          
##                                           
##  Mcnemar's Test P-Value : 0.07249         
##                                           
##             Sensitivity : 0.7879          
##             Specificity : 0.9048          
##          Pos Pred Value : 0.8864          
##          Neg Pred Value : 0.8190          
##              Prevalence : 0.4853          
##          Detection Rate : 0.3824          
##    Detection Prevalence : 0.4314          
##       Balanced Accuracy : 0.8463          
##                                           
##        'Positive' Class : No              
## 

Modelo 4: Árbol de Decisión

modelo4 <- train(target ~., data=entrenamiento, 
                 method="rpart",
                 preProcess = c("scale", "center"),
                 trControl = trainControl(method = "cv", number = 10),
                 tuneLength = 10
                 )

resultado_entrenamiento4 <- predict(modelo4,entrenamiento)
resultado_prueba4 <- predict(modelo4,prueba)

# Matriz de Confusión
# Es una tabla de evaluación que desglosa el rendimiento del modelo de clasificación

# Matriz de Confusión del Resultado de Entrenamiento
mcre4 <- confusionMatrix(resultado_entrenamiento4, entrenamiento$target)
mcre4
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  No  Si
##         No 360  29
##         Si  40 392
##                                          
##                Accuracy : 0.916          
##                  95% CI : (0.8948, 0.934)
##     No Information Rate : 0.5128         
##     P-Value [Acc > NIR] : <2e-16         
##                                          
##                   Kappa : 0.8317         
##                                          
##  Mcnemar's Test P-Value : 0.2286         
##                                          
##             Sensitivity : 0.9000         
##             Specificity : 0.9311         
##          Pos Pred Value : 0.9254         
##          Neg Pred Value : 0.9074         
##              Prevalence : 0.4872         
##          Detection Rate : 0.4385         
##    Detection Prevalence : 0.4738         
##       Balanced Accuracy : 0.9156         
##                                          
##        'Positive' Class : No             
## 
# Matriz de Confusión del Resultado de la Prueba
mcrp4 <- confusionMatrix(resultado_prueba4, prueba$target)
mcrp4
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction No Si
##         No 81  7
##         Si 18 98
##                                           
##                Accuracy : 0.8775          
##                  95% CI : (0.8244, 0.9191)
##     No Information Rate : 0.5147          
##     P-Value [Acc > NIR] : <2e-16          
##                                           
##                   Kappa : 0.7539          
##                                           
##  Mcnemar's Test P-Value : 0.0455          
##                                           
##             Sensitivity : 0.8182          
##             Specificity : 0.9333          
##          Pos Pred Value : 0.9205          
##          Neg Pred Value : 0.8448          
##              Prevalence : 0.4853          
##          Detection Rate : 0.3971          
##    Detection Prevalence : 0.4314          
##       Balanced Accuracy : 0.8758          
##                                           
##        'Positive' Class : No              
## 

Modelo 5: Bosques Aleatorios

modelo5 <- train(target ~., data=entrenamiento, 
                 method="rf",
                 preProcess = c("scale", "center"),
                 trControl = trainControl(method = "cv", number = 10),
                 tuneGrid = expand.grid(mtry=c(2,4,6))
                 )

resultado_entrenamiento5 <- predict(modelo5,entrenamiento)
resultado_prueba5 <- predict(modelo5,prueba)

# Matriz de Confusión
# Es una tabla de evaluación que desglosa el rendimiento del modelo de clasificación

# Matriz de Confusión del Resultado de Entrenamiento
mcre5 <- confusionMatrix(resultado_entrenamiento5, entrenamiento$target)
mcre5
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  No  Si
##         No 400   0
##         Si   0 421
##                                      
##                Accuracy : 1          
##                  95% CI : (0.9955, 1)
##     No Information Rate : 0.5128     
##     P-Value [Acc > NIR] : < 2.2e-16  
##                                      
##                   Kappa : 1          
##                                      
##  Mcnemar's Test P-Value : NA         
##                                      
##             Sensitivity : 1.0000     
##             Specificity : 1.0000     
##          Pos Pred Value : 1.0000     
##          Neg Pred Value : 1.0000     
##              Prevalence : 0.4872     
##          Detection Rate : 0.4872     
##    Detection Prevalence : 0.4872     
##       Balanced Accuracy : 1.0000     
##                                      
##        'Positive' Class : No         
## 
# Matriz de Confusión del Resultado de la Prueba
mcrp5 <- confusionMatrix(resultado_prueba5, prueba$target)
mcrp5
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  No  Si
##         No  99   0
##         Si   0 105
##                                      
##                Accuracy : 1          
##                  95% CI : (0.9821, 1)
##     No Information Rate : 0.5147     
##     P-Value [Acc > NIR] : < 2.2e-16  
##                                      
##                   Kappa : 1          
##                                      
##  Mcnemar's Test P-Value : NA         
##                                      
##             Sensitivity : 1.0000     
##             Specificity : 1.0000     
##          Pos Pred Value : 1.0000     
##          Neg Pred Value : 1.0000     
##              Prevalence : 0.4853     
##          Detection Rate : 0.4853     
##    Detection Prevalence : 0.4853     
##       Balanced Accuracy : 1.0000     
##                                      
##        'Positive' Class : No         
## 

Modelo 6: Redes Neuronales

modelo6 <- train(target ~., data=entrenamiento, 
                 method="nnet",
                 preProcess = c("scale", "center"),
                 trControl = trainControl(method = "cv", number = 10),
                 trace=FALSE
                 )

resultado_entrenamiento6 <- predict(modelo6,entrenamiento)
resultado_prueba6 <- predict(modelo6,prueba)

# Matriz de Confusión
# Es una tabla de evaluación que desglosa el rendimiento del modelo de clasificación

# Matriz de Confusión del Resultado de Entrenamiento
mcre6 <- confusionMatrix(resultado_entrenamiento6, entrenamiento$target)
mcre6
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  No  Si
##         No 391  10
##         Si   9 411
##                                          
##                Accuracy : 0.9769         
##                  95% CI : (0.9641, 0.986)
##     No Information Rate : 0.5128         
##     P-Value [Acc > NIR] : <2e-16         
##                                          
##                   Kappa : 0.9537         
##                                          
##  Mcnemar's Test P-Value : 1              
##                                          
##             Sensitivity : 0.9775         
##             Specificity : 0.9762         
##          Pos Pred Value : 0.9751         
##          Neg Pred Value : 0.9786         
##              Prevalence : 0.4872         
##          Detection Rate : 0.4762         
##    Detection Prevalence : 0.4884         
##       Balanced Accuracy : 0.9769         
##                                          
##        'Positive' Class : No             
## 
# Matriz de Confusión del Resultado de la Prueba
mcrp6 <- confusionMatrix(resultado_prueba6, prueba$target)
mcrp6
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction No Si
##         No 97  6
##         Si  2 99
##                                           
##                Accuracy : 0.9608          
##                  95% CI : (0.9242, 0.9829)
##     No Information Rate : 0.5147          
##     P-Value [Acc > NIR] : <2e-16          
##                                           
##                   Kappa : 0.9216          
##                                           
##  Mcnemar's Test P-Value : 0.2888          
##                                           
##             Sensitivity : 0.9798          
##             Specificity : 0.9429          
##          Pos Pred Value : 0.9417          
##          Neg Pred Value : 0.9802          
##              Prevalence : 0.4853          
##          Detection Rate : 0.4755          
##    Detection Prevalence : 0.5049          
##       Balanced Accuracy : 0.9613          
##                                           
##        'Positive' Class : No              
## 

Tabla de Resultados

resultados <- data.frame(
  "SVM Lineal" = c(mcre1$overall["Accuracy"], mcrp1$overall["Accuracy"]),
  "SVM Radial" = c(mcre2$overall["Accuracy"], mcrp2$overall["Accuracy"]),
  "SVM Polinomico" = c(mcre3$overall["Accuracy"], mcrp3$overall["Accuracy"]),
  "Arbol de Decision" = c(mcre4$overall["Accuracy"], mcrp4$overall["Accuracy"]),
  "Random Forest" = c(mcre5$overall["Accuracy"], mcrp5$overall["Accuracy"]),
  "Redes Neuronales" = c(mcre6$overall["Accuracy"], mcrp6$overall["Accuracy"])
)

rownames(resultados) <- c("Exactitud del Entrenamiento", "Exactitud de la Prueba")

resultados
##                             SVM.Lineal SVM.Radial SVM.Polinomico
## Exactitud del Entrenamiento  0.8343484  0.9732034      0.8343484
## Exactitud de la Prueba       0.8480392  0.9558824      0.8480392
##                             Arbol.de.Decision Random.Forest Redes.Neuronales
## Exactitud del Entrenamiento         0.9159562             1        0.9768575
## Exactitud de la Prueba              0.8774510             1        0.9607843

Conclusión

En conclusión, se compararon seis modelos diferentes para clasificar si un paciente presenta o no enfermedad cardiaca. Para escoger el mejor modelo se debe revisar principalmente la exactitud obtenida con la base de prueba, ya que esta nos ayuda a ver qué tan bien funciona el modelo con datos que no utilizó para entrenarse.