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.
# 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)
# file.choose()
df <- read_excel("heart.xlsx", sheet="heart")
df <- data.frame(df)
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
# 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, ]
Los métodos más utilizados para modelar aprendizaje automático son:
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
##
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
##
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
##
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
##
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
##
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
##
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
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.