data <- read.csv("heart_failure_clinical_records_dataset.csv")
library(tidyverse)
library(caret)
library(kknn)
library(scales)
library(class)
library(dplyr)
library(forcats)
sum(is.na(data))
## [1] 0
data$DEATH_EVENT<- as.factor(data$DEATH_EVENT)
levels(data$DEATH_EVENT) <- c("sobrevivio", "fallecio")
table(data$DEATH_EVENT)
##
## sobrevivio fallecio
## 203 96
round(prop.table(table(data$DEATH_EVENT)),2)
##
## sobrevivio fallecio
## 0.68 0.32
# Normalización Min-Max con rescale
data_norm <- data %>% select(-DEATH_EVENT) %>%
mutate(across(everything(), rescale))
Dividimos la muestra en dos conjuntos, uno para entrenamiento y otro para prueba.
set.seed(2025)
folds <- createFolds(data$DEATH_EVENT, k = 6)
entrenamiento <- data_norm[-folds[[6]],]
prueba <- data_norm[folds[[6]],]
guardamos las etiquetas del diagnóstico de todas las observaciones en dos vectores por separado.
# Etiquetas
entrenamiento_labels <- data$DEATH_EVENT[-folds[[6]]]
prueba_labels <- data$DEATH_EVENT[folds[[6]]]
train.kknn(entrenamiento_labels ~ ., data = entrenamiento, kmax = 50)
##
## Call:
## train.kknn(formula = entrenamiento_labels ~ ., data = entrenamiento, kmax = 50)
##
## Type of response variable: nominal
## Minimal misclassification: 0.2088353
## Best kernel: optimal
## Best k: 19
pred <- knn(entrenamiento,prueba, cl = entrenamiento_labels, k = 19)
confusionMatrix(data = pred, reference = prueba_labels)
## Confusion Matrix and Statistics
##
## Reference
## Prediction sobrevivio fallecio
## sobrevivio 31 15
## fallecio 3 1
##
## Accuracy : 0.64
## 95% CI : (0.4919, 0.7708)
## No Information Rate : 0.68
## P-Value [Acc > NIR] : 0.777970
##
## Kappa : -0.0321
##
## Mcnemar's Test P-Value : 0.009522
##
## Sensitivity : 0.9118
## Specificity : 0.0625
## Pos Pred Value : 0.6739
## Neg Pred Value : 0.2500
## Prevalence : 0.6800
## Detection Rate : 0.6200
## Detection Prevalence : 0.9200
## Balanced Accuracy : 0.4871
##
## 'Positive' Class : sobrevivio
##
data_z <- as.data.frame(scale(data[,-13]))
entrenamiento_z <- data_z[-folds[[6]],]
prueba_z <- data_z[folds[[6]],]
pred_z <- knn(entrenamiento_z, prueba_z, cl = entrenamiento_labels, k = 19)
confusionMatrix(data = pred_z, reference = prueba_labels)
## Confusion Matrix and Statistics
##
## Reference
## Prediction sobrevivio fallecio
## sobrevivio 31 15
## fallecio 3 1
##
## Accuracy : 0.64
## 95% CI : (0.4919, 0.7708)
## No Information Rate : 0.68
## P-Value [Acc > NIR] : 0.777970
##
## Kappa : -0.0321
##
## Mcnemar's Test P-Value : 0.009522
##
## Sensitivity : 0.9118
## Specificity : 0.0625
## Pos Pred Value : 0.6739
## Neg Pred Value : 0.2500
## Prevalence : 0.6800
## Detection Rate : 0.6200
## Detection Prevalence : 0.9200
## Balanced Accuracy : 0.4871
##
## 'Positive' Class : sobrevivio
##
Apliquemos validación cruzada para validar la estabilidad del modelo
# Guardar la exactitud de cada fold
exactitud <- numeric(length = 6)
for(i in 1:6){
# Definir conjuntos entrenamiento y prueba según el fold actual
prueba <- data_norm[folds[[i]],]
entrenamiento <- data_norm[-folds[[i]],]
# Etiquetas
entrenamiento_labels <- data$DEATH_EVENT[-folds[[i]]]
prueba_labels <- data$DEATH_EVENT[folds[[i]]]
pred_knn <- knn(entrenamiento,prueba, cl= entrenamiento_labels, k = 19)
# Evaluar exactitud del modelo en cada fold
cm <- confusionMatrix(pred_knn, prueba_labels)
exactitud[i] <- cm$overall["Accuracy"]
# Mostrar resultado del fold
cat("Fold", i, "- Exactitud:", exactitud[i], "\n")
}
## Fold 1 - Exactitud: 0.78
## Fold 2 - Exactitud: 0.7142857
## Fold 3 - Exactitud: 0.7
## Fold 4 - Exactitud: 0.7
## Fold 5 - Exactitud: 0.72
## Fold 6 - Exactitud: 0.64
# Exactitud promedio de validación cruzada
Exactitud_promedio <- round(mean(exactitud),4)*100
paste("Exactitud_promedio: ",Exactitud_promedio,"%",sep="")
## [1] "Exactitud_promedio: 70.9%"
set.seed(2025)
train_control <- trainControl(method="cv",number=10,savePredictions = TRUE)
knn_cv <- train(DEATH_EVENT ~ ., data=cbind(prueba, DEATH_EVENT=prueba_labels),
method = "knn", trControl = train_control, tuneGrid = data.frame(k=19))
# Resultados de validación cruzada
knn_cv
## k-Nearest Neighbors
##
## 50 samples
## 12 predictors
## 2 classes: 'sobrevivio', 'fallecio'
##
## No pre-processing
## Resampling: Cross-Validated (10 fold)
## Summary of sample sizes: 45, 45, 44, 46, 45, 45, ...
## Resampling results:
##
## Accuracy Kappa
## 0.6816667 0
##
## Tuning parameter 'k' was held constant at a value of 19
# Matriz de confusión usando predicciones guardadas por caret
confusionMatrix(knn_cv$pred$pred, knn_cv$pred$obs)
## Confusion Matrix and Statistics
##
## Reference
## Prediction sobrevivio fallecio
## sobrevivio 34 16
## fallecio 0 0
##
## Accuracy : 0.68
## 95% CI : (0.533, 0.8048)
## No Information Rate : 0.68
## P-Value [Acc > NIR] : 0.5671960
##
## Kappa : 0
##
## Mcnemar's Test P-Value : 0.0001768
##
## Sensitivity : 1.00
## Specificity : 0.00
## Pos Pred Value : 0.68
## Neg Pred Value : NaN
## Prevalence : 0.68
## Detection Rate : 0.68
## Detection Prevalence : 1.00
## Balanced Accuracy : 0.50
##
## 'Positive' Class : sobrevivio
##