El paquete CARET (Classification And Regression Training) es una herramienta de R que permite utilizar diferentes algoritmos de aprendizaje automático para crear y evaluar modelos de clasificación y regresión.
En esta actividad se compararán distintos modelos para identificar cuál obtiene mejores resultados al predecir la presencia o ausencia de enfermedad cardiaca.
Las instalaciones solamente se deben ejecutar una vez desde la consola de RStudio.
install.packages("caret")
install.packages("ggplot2")
install.packages("DataExplorer")
install.packages("readxl")
install.packages("kernlab")
install.packages("randomForest")
install.packages("nnet")
library(caret)
library(ggplot2)
library(lattice)
library(datasets)
library(DataExplorer)
library(readxl)
library(kernlab)
library(randomForest)
library(nnet)
df <- data.frame(
read_excel("/Users/kamilahchaidez/Downloads/heart.xlsx")
)
# En modelos de clasificación la variable objetivo debe ser factor
df$target <- as.factor(df$target)
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 0:499
## 1st Qu.:2.000 1:526
## Median :2.000
## Mean :2.324
## 3rd Qu.:3.000
## Max. :3.000
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 "0","1": 1 1 1 1 1 2 1 1 1 1 ...
head(df)
## age sex cp trestbps chol fbs restecg thalach exang oldpeak slope ca thal
## 1 52 1 0 125 212 0 1 168 0 1.0 2 2 3
## 2 53 1 0 140 203 1 0 155 1 3.1 0 0 3
## 3 70 1 0 145 174 0 1 125 1 2.6 0 0 3
## 4 61 1 0 148 203 0 1 161 0 0.0 2 1 3
## 5 62 0 0 138 294 1 1 106 0 1.9 1 3 2
## 6 58 0 0 100 248 0 0 122 0 1.0 1 0 2
## target
## 1 0
## 2 0
## 3 0
## 4 0
## 5 0
## 6 1
La variable que queremos predecir es target, donde existen dos posibles resultados:
01La base contiene variables como edad, sexo, colesterol, presión arterial, frecuencia cardiaca y otras características relacionadas con los pacientes. En el archivo de referencia se trabajan 1,025 registros y 14 variables. :contentReferenceoaicite:1
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.
Se utilizará el 80% de los datos para entrenamiento y el 20% para prueba, igual que en el ejercicio original. :contentReferenceoaicite:2
set.seed(123)
renglones_entrenamiento <- createDataPartition(
df$target,
p = 0.8,
list = FALSE
)
entrenamiento <- df[renglones_entrenamiento, ]
prueba <- df[-renglones_entrenamiento, ]
Los modelos que se utilizarán son:
svmLinearsvmRadialsvmPolyrpartrfnnetmodelo1 <- 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
)
mcre1 <- confusionMatrix(
resultado_entrenamiento1,
entrenamiento$target
)
mcre1
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 301 37
## 1 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 : 0
##
mcrp1 <- confusionMatrix(
resultado_prueba1,
prueba$target
)
mcrp1
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 78 10
## 1 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 : 0
##
modelo2 <- train(
target ~ .,
data = entrenamiento,
method = "svmRadial",
preProcess = c("scale", "center"),
trControl = trainControl(
method = "cv",
number = 10
),
tuneGrid = data.frame(
sigma = 1,
C = 1
)
)
resultado_entrenamiento2 <- predict(
modelo2,
entrenamiento
)
resultado_prueba2 <- predict(
modelo2,
prueba
)
mcre2 <- confusionMatrix(
resultado_entrenamiento2,
entrenamiento$target
)
mcre2
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 400 0
## 1 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 : 0
##
mcrp2 <- confusionMatrix(
resultado_prueba2,
prueba$target
)
mcrp2
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 99 0
## 1 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 : 0
##
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
)
mcre3 <- confusionMatrix(
resultado_entrenamiento3,
entrenamiento$target
)
mcre3
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 301 37
## 1 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 : 0
##
mcrp3 <- confusionMatrix(
resultado_prueba3,
prueba$target
)
mcrp3
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 78 10
## 1 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 : 0
##
modelo4 <- train(
target ~ .,
data = entrenamiento,
method = "rpart",
trControl = trainControl(
method = "cv",
number = 10
),
tuneLength = 10
)
resultado_entrenamiento4 <- predict(
modelo4,
entrenamiento
)
resultado_prueba4 <- predict(
modelo4,
prueba
)
mcre4 <- confusionMatrix(
resultado_entrenamiento4,
entrenamiento$target
)
mcre4
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 360 29
## 1 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 : 0
##
mcrp4 <- confusionMatrix(
resultado_prueba4,
prueba$target
)
mcrp4
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 81 7
## 1 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 : 0
##
modelo5 <- train(
target ~ .,
data = entrenamiento,
method = "rf",
trControl = trainControl(
method = "cv",
number = 10
),
tuneGrid = expand.grid(
mtry = c(2, 4, 6)
)
)
resultado_entrenamiento5 <- predict(
modelo5,
entrenamiento
)
resultado_prueba5 <- predict(
modelo5,
prueba
)
mcre5 <- confusionMatrix(
resultado_entrenamiento5,
entrenamiento$target
)
mcre5
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 400 0
## 1 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 : 0
##
mcrp5 <- confusionMatrix(
resultado_prueba5,
prueba$target
)
mcrp5
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 99 0
## 1 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 : 0
##
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
)
mcre6 <- confusionMatrix(
resultado_entrenamiento6,
entrenamiento$target
)
mcre6
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 382 1
## 1 18 420
##
## Accuracy : 0.9769
## 95% CI : (0.9641, 0.986)
## No Information Rate : 0.5128
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.9536
##
## Mcnemar's Test P-Value : 0.0002419
##
## Sensitivity : 0.9550
## Specificity : 0.9976
## Pos Pred Value : 0.9974
## Neg Pred Value : 0.9589
## Prevalence : 0.4872
## Detection Rate : 0.4653
## Detection Prevalence : 0.4665
## Balanced Accuracy : 0.9763
##
## 'Positive' Class : 0
##
mcrp6 <- confusionMatrix(
resultado_prueba6,
prueba$target
)
mcrp6
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 95 2
## 1 4 103
##
## Accuracy : 0.9706
## 95% CI : (0.9371, 0.9891)
## No Information Rate : 0.5147
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.9411
##
## Mcnemar's Test P-Value : 0.6831
##
## Sensitivity : 0.9596
## Specificity : 0.9810
## Pos Pred Value : 0.9794
## Neg Pred Value : 0.9626
## Prevalence : 0.4853
## Detection Rate : 0.4657
## Detection Prevalence : 0.4755
## Balanced Accuracy : 0.9703
##
## 'Positive' Class : 0
##
En esta tabla se compara la exactitud obtenida por cada modelo tanto en entrenamiento como en prueba.
resultados <- data.frame(
svmLinear = unname(
c(
mcre1$overall["Accuracy"],
mcrp1$overall["Accuracy"]
)
),
svmRadial = unname(
c(
mcre2$overall["Accuracy"],
mcrp2$overall["Accuracy"]
)
),
svmPoly = unname(
c(
mcre3$overall["Accuracy"],
mcrp3$overall["Accuracy"]
)
),
rpart = unname(
c(
mcre4$overall["Accuracy"],
mcrp4$overall["Accuracy"]
)
),
rf = unname(
c(
mcre5$overall["Accuracy"],
mcrp5$overall["Accuracy"]
)
),
nnet = unname(
c(
mcre6$overall["Accuracy"],
mcrp6$overall["Accuracy"]
)
)
)
rownames(resultados) <- c(
"Exactitud del Entrenamiento",
"Exactitud de la Prueba"
)
resultados
## svmLinear svmRadial svmPoly rpart rf
## Exactitud del Entrenamiento 0.8343484 1 0.8343484 0.9159562 1
## Exactitud de la Prueba 0.8480392 1 0.8480392 0.8774510 1
## nnet
## Exactitud del Entrenamiento 0.9768575
## Exactitud de la Prueba 0.9705882
accuracy_prueba <- c(
svmLinear = mcrp1$overall["Accuracy"],
svmRadial = mcrp2$overall["Accuracy"],
svmPoly = mcrp3$overall["Accuracy"],
rpart = mcrp4$overall["Accuracy"],
rf = mcrp5$overall["Accuracy"],
nnet = mcrp6$overall["Accuracy"]
)
mejor_modelo <- names(
which.max(accuracy_prueba)
)
mejor_accuracy <- max(
accuracy_prueba
)
mejor_modelo
## [1] "svmRadial.Accuracy"
mejor_accuracy
## [1] 1
Después de comparar los seis modelos, se puede identificar cuál presenta la mayor exactitud en los datos de prueba.
En los resultados del ejercicio de referencia se obtuvieron aproximadamente:
Por lo tanto, el modelo de Random Forest o Bosques Aleatorios presenta el mejor resultado para la clasificación de pacientes en esta base de datos. :contentReferenceoaicite:3
Sin embargo, es importante comparar principalmente el resultado obtenido con los datos de prueba, ya que estos representan información que el modelo no utilizó directamente durante su entrenamiento.