Implementar el modelo de árbol de clasificación con datos relacionados a una condición de salud de las personas para predecir anomalías de corazón y evaluar la exactitud del modelo mediante la matriz de confusión.
Se cargan librerías y se descargan los datos: https://raw.githubusercontent.com/rpizarrog/Analisis-Inteligente-de-datos/main/datos/heart_2020_cleaned.csv
Los datos están relacionados con aspectos médicos y son valores numéricos de varias variables que caracterizan el estado de salud de 319,795 personas.
Se construye un modelo supervisado basado en el algoritmo de árbol de clasificación para resolver la tarea de clasificación binaria e identificar si una persona padece del corazón o no.
Se construyen datos de entrenamiento y validación al 80% y 20% cada uno.
Se desarrollan los modelos de:
Regresión Logística binaria
Árbol de Clasificación tipo class
K Means
SVM Lineal
SVM Polinomial
SVM Radial
Los modelo se aceptan si tienen un valor de exactitud por encima del 70%..
library(readr)
library(dplyr)
library(caret)
library(rpart)
library(rpart.plot)
library(knitr)
library(e1071) # Vectores de Soporte SVM
library(rpart) # Arboles de clasificación
Cargar datos de manera local.
# datos <- read.csv("https://raw.githubusercontent.com/rpizarrog/Machine-Learning-con-R/main/datos/heart_2020_cleaned.csv")
datos <- read.csv("../../datos/heart_2020_cleaned.csv", encoding = "UTF-8", stringsAsFactors = TRUE)
str(datos)
## 'data.frame': 319795 obs. of 18 variables:
## $ HeartDisease : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 2 1 1 1 1 ...
## $ BMI : num 16.6 20.3 26.6 24.2 23.7 ...
## $ Smoking : Factor w/ 2 levels "No","Yes": 2 1 2 1 1 2 1 2 1 1 ...
## $ AlcoholDrinking : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
## $ Stroke : Factor w/ 2 levels "No","Yes": 1 2 1 1 1 1 1 1 1 1 ...
## $ PhysicalHealth : num 3 0 20 0 28 6 15 5 0 0 ...
## $ MentalHealth : num 30 0 30 0 0 0 0 0 0 0 ...
## $ DiffWalking : Factor w/ 2 levels "No","Yes": 1 1 1 1 2 2 1 2 1 2 ...
## $ Sex : Factor w/ 2 levels "Female","Male": 1 1 2 1 1 1 1 1 1 2 ...
## $ AgeCategory : Factor w/ 13 levels "18-24","25-29",..: 8 13 10 12 5 12 11 13 13 10 ...
## $ Race : Factor w/ 6 levels "American Indian/Alaskan Native",..: 6 6 6 6 6 3 6 6 6 6 ...
## $ Diabetic : Factor w/ 4 levels "No","No, borderline diabetes",..: 3 1 3 1 1 1 1 3 2 1 ...
## $ PhysicalActivity: Factor w/ 2 levels "No","Yes": 2 2 2 1 2 1 2 1 1 2 ...
## $ GenHealth : Factor w/ 5 levels "Excellent","Fair",..: 5 5 2 3 5 2 2 3 2 3 ...
## $ SleepTime : num 5 7 8 6 8 12 4 9 5 10 ...
## $ Asthma : Factor w/ 2 levels "No","Yes": 2 1 2 1 1 1 2 2 1 1 ...
## $ KidneyDisease : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 2 1 ...
## $ SkinCancer : Factor w/ 2 levels "No","Yes": 2 1 1 2 1 1 2 1 1 1 ...
summary(datos)
## HeartDisease BMI Smoking AlcoholDrinking Stroke
## No :292422 Min. :12.02 No :187887 No :298018 No :307726
## Yes: 27373 1st Qu.:24.03 Yes:131908 Yes: 21777 Yes: 12069
## Median :27.34
## Mean :28.33
## 3rd Qu.:31.42
## Max. :94.85
##
## PhysicalHealth MentalHealth DiffWalking Sex
## Min. : 0.000 Min. : 0.000 No :275385 Female:167805
## 1st Qu.: 0.000 1st Qu.: 0.000 Yes: 44410 Male :151990
## Median : 0.000 Median : 0.000
## Mean : 3.372 Mean : 3.898
## 3rd Qu.: 2.000 3rd Qu.: 3.000
## Max. :30.000 Max. :30.000
##
## AgeCategory Race
## 65-69 : 34151 American Indian/Alaskan Native: 5202
## 60-64 : 33686 Asian : 8068
## 70-74 : 31065 Black : 22939
## 55-59 : 29757 Hispanic : 27446
## 50-54 : 25382 Other : 10928
## 80 or older: 24153 White :245212
## (Other) :141601
## Diabetic PhysicalActivity GenHealth
## No :269653 No : 71838 Excellent: 66842
## No, borderline diabetes: 6781 Yes:247957 Fair : 34677
## Yes : 40802 Good : 93129
## Yes (during pregnancy) : 2559 Poor : 11289
## Very good:113858
##
##
## SleepTime Asthma KidneyDisease SkinCancer
## Min. : 1.000 No :276923 No :308016 No :289976
## 1st Qu.: 6.000 Yes: 42872 Yes: 11779 Yes: 29819
## Median : 7.000
## Mean : 7.097
## 3rd Qu.: 8.000
## Max. :24.000
##
No es necesario alguna transformación
Todas las variables son de entrada o variables independientes:
“BMI”: Indice de masa corporal con valores entre 12.02 y 94.85.
“Smoking”: Si la persona es fumadora o no con valores categóritos de ‘Yes’ o ‘No’.
“AlcoholDrinking” : Si consume alcohol o no, con valores categóricos de ‘Yes’ o ‘No’.
“Stroke”: Si padece alguna anomalía cerebrovascular, apoplejia o algo similar, con valores categóricos de ‘Yes’ o ‘No’.
“PhysicalHealth” Estado físico en lo general con valores entre 0 y 30.
“MentalHealth”. Estado mental en lo general con valores entre 0 y 30.
“DiffWalking” . Que si se le dificulta caminar o tiene algún padecimiento al caminar, con valores categóritoc de ‘Yes’ o ‘No’.
“Sex”: Género de la persona, con valores de ‘Female’ y ‘Male’ para distinguir al género femenino y masculino respectivamente.
“AgeCategory”: Una clasificación de la edad de la persona de entre 18 y 80 años. La primera categoría con un rango de edad entre 18-24, a partir de 25 con rangos de 5 en 5 hasta la clase de 75-80 y una última categoría mayores de 80 años.
“Race”. Raza u origen de la persona con valores categóricos de ‘American Indian/Alaskan Native’, ’Asian’,’Black’, ’Hispanic’, ’Other’ y’White’.
“Diabetic”. Si padece o ha padecido de diabetes en cuatro condiciones siendo Yes y No para si o no: ‘No’, ‘borderline diabetes’ condición antes de detectarse diabetes tipo 2, ‘Yes’, y ‘Yes (during pregnancy)’ durante embarazo.
“PhysicalActivity” que si realiza actividad física, con valores categóricos de ‘Yes’ o ‘No’.
“GenHealth”: EStado general de salud de la persona con valores categóricos de ‘Excellent’, ‘Very good’, ’Good’, ’Fair’ y ’Poor’ con significado en español de excelente, muy buena, buena, regular y pobre o deficiente.
“SleepTime”: valor numérico de las horas de sueño u horas que duerme la persona con valores en un rango entre 1 y 24.
“Asthma”: si padece de asma o no, con valores categóricos de ‘Yes’ o ‘No’.
“KidneyDisease”: si tiene algún padecimiento en los riñones, con valores categóricos de ‘Yes’ o ‘No’.
“SkinCancer”: si padece algún tipo de cáncer de piel, con valores categóricos de ‘Yes’ o ‘No’.
La variable de interés como dependiente o variable de salida es la de daño al corazón (HeartDisease), con valores categóricos de ‘Yes’ o ‘No’.
Se parten los datos en en datos de entrenamiento con el 80% y datos de validación con el 20%.
set.seed(2022)
entrena <- createDataPartition(y = datos$HeartDisease,
p = 0.8,
list = FALSE,
times = 1)
# Datos entrenamiento
datos.entrenamiento <- datos[entrena, ] # [renglones, columna]
# Datos validación
datos.validacion <- datos[-entrena, ]
Se muestran los primeros 20 registros datos de entrenamiento
kable(head(datos.entrenamiento, 20), caption = "Primeros 20 registros de datos de entrenamiento")
| HeartDisease | BMI | Smoking | AlcoholDrinking | Stroke | PhysicalHealth | MentalHealth | DiffWalking | Sex | AgeCategory | Race | Diabetic | PhysicalActivity | GenHealth | SleepTime | Asthma | KidneyDisease | SkinCancer | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | No | 16.60 | Yes | No | No | 3 | 30 | No | Female | 55-59 | White | Yes | Yes | Very good | 5 | Yes | No | Yes |
| 2 | No | 20.34 | No | No | Yes | 0 | 0 | No | Female | 80 or older | White | No | Yes | Very good | 7 | No | No | No |
| 3 | No | 26.58 | Yes | No | No | 20 | 30 | No | Male | 65-69 | White | Yes | Yes | Fair | 8 | Yes | No | No |
| 4 | No | 24.21 | No | No | No | 0 | 0 | No | Female | 75-79 | White | No | No | Good | 6 | No | No | Yes |
| 5 | No | 23.71 | No | No | No | 28 | 0 | Yes | Female | 40-44 | White | No | Yes | Very good | 8 | No | No | No |
| 6 | Yes | 28.87 | Yes | No | No | 6 | 0 | Yes | Female | 75-79 | Black | No | No | Fair | 12 | No | No | No |
| 7 | No | 21.63 | No | No | No | 15 | 0 | No | Female | 70-74 | White | No | Yes | Fair | 4 | Yes | No | Yes |
| 8 | No | 31.64 | Yes | No | No | 5 | 0 | Yes | Female | 80 or older | White | Yes | No | Good | 9 | Yes | No | No |
| 9 | No | 26.45 | No | No | No | 0 | 0 | No | Female | 80 or older | White | No, borderline diabetes | No | Fair | 5 | No | Yes | No |
| 10 | No | 40.69 | No | No | No | 0 | 0 | Yes | Male | 65-69 | White | No | Yes | Good | 10 | No | No | No |
| 11 | Yes | 34.30 | Yes | No | No | 30 | 0 | Yes | Male | 60-64 | White | Yes | No | Poor | 15 | Yes | No | No |
| 12 | No | 28.71 | Yes | No | No | 0 | 0 | No | Female | 55-59 | White | No | Yes | Very good | 5 | No | No | No |
| 13 | No | 28.37 | Yes | No | No | 0 | 0 | Yes | Male | 75-79 | White | Yes | Yes | Very good | 8 | No | No | No |
| 14 | No | 28.15 | No | No | No | 7 | 0 | Yes | Female | 80 or older | White | No | No | Good | 7 | No | No | No |
| 15 | No | 29.29 | Yes | No | No | 0 | 30 | Yes | Female | 60-64 | White | No | No | Good | 5 | No | No | No |
| 16 | No | 29.18 | No | No | No | 1 | 0 | No | Female | 50-54 | White | No | Yes | Very good | 6 | No | No | No |
| 17 | No | 26.26 | No | No | No | 5 | 2 | No | Female | 70-74 | White | No | No | Very good | 10 | No | No | No |
| 18 | No | 22.59 | Yes | No | No | 0 | 30 | Yes | Male | 70-74 | White | No, borderline diabetes | Yes | Good | 8 | No | No | No |
| 20 | No | 18.13 | No | No | No | 0 | 0 | No | Male | 80 or older | White | No | Yes | Excellent | 8 | No | No | Yes |
| 21 | No | 21.16 | No | No | No | 0 | 0 | No | Female | 80 or older | Black | No, borderline diabetes | No | Good | 8 | No | No | No |
Se muestran los primeros 20 registros de datos de validación .
kable(head(datos.validacion, 20), caption = "Primeros 20 registros de datos de validación")
| HeartDisease | BMI | Smoking | AlcoholDrinking | Stroke | PhysicalHealth | MentalHealth | DiffWalking | Sex | AgeCategory | Race | Diabetic | PhysicalActivity | GenHealth | SleepTime | Asthma | KidneyDisease | SkinCancer | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 19 | No | 29.86 | Yes | No | No | 0 | 0 | Yes | Female | 75-79 | Black | Yes | No | Fair | 5 | No | Yes | No |
| 25 | No | 25.75 | No | No | No | 0 | 0 | No | Female | 80 or older | White | No | Yes | Very good | 6 | No | No | Yes |
| 27 | No | 34.34 | Yes | No | No | 21 | 8 | Yes | Female | 65-69 | White | No | Yes | Fair | 9 | No | No | No |
| 30 | No | 36.58 | No | No | No | 0 | 0 | No | Female | 60-64 | White | Yes | No | Good | 5 | No | No | Yes |
| 43 | Yes | 25.06 | No | No | No | 0 | 0 | Yes | Female | 80 or older | White | Yes | No | Good | 7 | No | No | Yes |
| 47 | No | 33.23 | No | No | No | 0 | 0 | No | Male | 65-69 | White | Yes | Yes | Very good | 8 | No | No | No |
| 48 | No | 25.11 | No | No | No | 5 | 5 | No | Female | 65-69 | Black | No | Yes | Good | 7 | No | No | No |
| 55 | No | 32.10 | No | No | No | 14 | 0 | No | Male | 65-69 | White | Yes | Yes | Very good | 9 | No | No | No |
| 60 | No | 27.20 | Yes | No | Yes | 0 | 0 | No | Male | 80 or older | White | No | No | Very good | 8 | No | No | Yes |
| 61 | No | 28.94 | Yes | No | No | 0 | 0 | No | Female | 70-74 | White | Yes | Yes | Good | 5 | Yes | No | No |
| 62 | No | 21.03 | No | No | No | 1 | 0 | No | Female | 80 or older | White | No | Yes | Excellent | 8 | No | No | No |
| 64 | No | 31.46 | Yes | No | No | 0 | 0 | No | Male | 75-79 | White | No | Yes | Very good | 8 | No | No | No |
| 72 | No | 27.76 | Yes | No | No | 15 | 0 | Yes | Female | 80 or older | White | No | No | Good | 8 | Yes | No | No |
| 74 | No | 30.23 | No | No | No | 0 | 5 | No | Female | 65-69 | White | No | Yes | Good | 6 | No | No | No |
| 79 | Yes | 28.29 | Yes | No | No | 30 | 30 | No | Female | 70-74 | White | Yes | Yes | Poor | 9 | No | Yes | No |
| 89 | No | 32.81 | Yes | No | No | 0 | 0 | Yes | Female | 70-74 | White | Yes | Yes | Good | 5 | No | No | No |
| 91 | No | 44.29 | No | No | No | 30 | 10 | Yes | Female | 70-74 | White | No | No | Fair | 7 | No | No | Yes |
| 93 | No | 21.80 | Yes | No | No | 0 | 0 | No | Female | 75-79 | White | No | Yes | Very good | 8 | No | No | Yes |
| 99 | No | 24.37 | No | No | No | 0 | 0 | No | Female | 55-59 | White | No | Yes | Very good | 7 | Yes | No | No |
| 111 | No | 26.63 | No | No | No | 0 | 0 | No | Female | 75-79 | Black | Yes | Yes | Good | 8 | No | No | No |
Se construye el modelo con los datos de entrenamiento mediante la función rpart().
El árbol no se puede visualizar cn todos los registros de los datos de entrenamiento, se hicieron las pruebas y se logra visualizar aproximadamente con 2000 registros de una muestra a partir de los datos de entrenamiento.
Si se construye el modelo con todos los registros de los datos de entrenamiento, pero no se puede observar la visualización del árbol y sus ramificaciones, razón por la cual se hace con una muestra de los datos de entrenamiento.
muestra <- sample(x = 1:nrow(datos.entrenamiento), size = 2000, replace = FALSE)
modelo.ac = rpart(data = datos.entrenamiento[muestra,],formula = HeartDisease ~ .)
El resumen del modelo muestra algunos estadísticos importantes:
summary(modelo.ac)
## Call:
## rpart(formula = HeartDisease ~ ., data = datos.entrenamiento[muestra,
## ])
## n= 2000
##
## CP nsplit rel error xerror xstd
## 1 0.01577564 0 1.0000000 1.0000000 0.07506643
## 2 0.01226994 7 0.8895706 0.9877301 0.07464508
## 3 0.01000000 8 0.8773006 0.9815951 0.07443313
##
## Variable importance
## AgeCategory GenHealth BMI SkinCancer
## 37 13 9 9
## Sex PhysicalHealth Stroke DiffWalking
## 7 6 5 4
## PhysicalActivity Diabetic Race KidneyDisease
## 3 3 2 1
##
## Node number 1: 2000 observations, complexity param=0.01577564
## predicted class=No expected loss=0.0815 P(node) =1
## class counts: 1837 163
## probabilities: 0.918 0.082
## left son=2 (1277 obs) right son=3 (723 obs)
## Primary splits:
## AgeCategory splits as LLLLLLLLLRRRR, improve=16.160870, (0 missing)
## GenHealth splits as LRLRL, improve=11.888480, (0 missing)
## DiffWalking splits as LR, improve= 8.507471, (0 missing)
## Stroke splits as LR, improve= 8.081361, (0 missing)
## SkinCancer splits as LR, improve= 6.972766, (0 missing)
## Surrogate splits:
## SkinCancer splits as LR, agree=0.685, adj=0.130, (0 split)
## DiffWalking splits as LR, agree=0.659, adj=0.058, (0 split)
## Diabetic splits as LRRL, agree=0.658, adj=0.054, (0 split)
## Stroke splits as LR, agree=0.650, adj=0.033, (0 split)
## KidneyDisease splits as LR, agree=0.649, adj=0.030, (0 split)
##
## Node number 2: 1277 observations
## predicted class=No expected loss=0.03367267 P(node) =0.6385
## class counts: 1234 43
## probabilities: 0.966 0.034
##
## Node number 3: 723 observations, complexity param=0.01577564
## predicted class=No expected loss=0.1659751 P(node) =0.3615
## class counts: 603 120
## probabilities: 0.834 0.166
## left son=6 (372 obs) right son=7 (351 obs)
## Primary splits:
## GenHealth splits as LRRRL, improve=7.920088, (0 missing)
## Sex splits as LR, improve=7.407025, (0 missing)
## Stroke splits as LR, improve=4.262868, (0 missing)
## SkinCancer splits as LR, improve=2.448364, (0 missing)
## Race splits as RLLRRR, improve=2.363588, (0 missing)
## Surrogate splits:
## PhysicalHealth < 1.5 to the left, agree=0.682, adj=0.345, (0 split)
## DiffWalking splits as LR, agree=0.633, adj=0.245, (0 split)
## PhysicalActivity splits as RL, agree=0.611, adj=0.199, (0 split)
## BMI < 28.515 to the left, agree=0.607, adj=0.191, (0 split)
## Diabetic splits as LRRL, agree=0.595, adj=0.165, (0 split)
##
## Node number 6: 372 observations
## predicted class=No expected loss=0.09408602 P(node) =0.186
## class counts: 337 35
## probabilities: 0.906 0.094
##
## Node number 7: 351 observations, complexity param=0.01577564
## predicted class=No expected loss=0.2421652 P(node) =0.1755
## class counts: 266 85
## probabilities: 0.758 0.242
## left son=14 (194 obs) right son=15 (157 obs)
## Primary splits:
## Sex splits as LR, improve=5.172049, (0 missing)
## Race splits as LLLRRR, improve=3.751722, (0 missing)
## Stroke splits as LR, improve=3.285883, (0 missing)
## SkinCancer splits as LR, improve=2.762222, (0 missing)
## GenHealth splits as -RLR-, improve=1.864107, (0 missing)
## Surrogate splits:
## AgeCategory splits as ---------LRLL, agree=0.587, adj=0.076, (0 split)
## AlcoholDrinking splits as LR, agree=0.573, adj=0.045, (0 split)
## PhysicalHealth < 1.5 to the right, agree=0.573, adj=0.045, (0 split)
## Race splits as LRLLRL, agree=0.564, adj=0.025, (0 split)
## SleepTime < 2.5 to the right, agree=0.558, adj=0.013, (0 split)
##
## Node number 14: 194 observations
## predicted class=No expected loss=0.1649485 P(node) =0.097
## class counts: 162 32
## probabilities: 0.835 0.165
##
## Node number 15: 157 observations, complexity param=0.01577564
## predicted class=No expected loss=0.3375796 P(node) =0.0785
## class counts: 104 53
## probabilities: 0.662 0.338
## left son=30 (127 obs) right son=31 (30 obs)
## Primary splits:
## SkinCancer splits as LR, improve=3.892676, (0 missing)
## BMI < 26.445 to the right, improve=3.115661, (0 missing)
## AgeCategory splits as ---------LRLR, improve=2.996827, (0 missing)
## Stroke splits as LR, improve=1.802553, (0 missing)
## Race splits as -LLRRR, improve=1.383697, (0 missing)
##
## Node number 30: 127 observations, complexity param=0.01577564
## predicted class=No expected loss=0.2834646 P(node) =0.0635
## class counts: 91 36
## probabilities: 0.717 0.283
## left son=60 (90 obs) right son=61 (37 obs)
## Primary splits:
## BMI < 25.015 to the right, improve=3.234395, (0 missing)
## Stroke splits as LR, improve=2.999642, (0 missing)
## GenHealth splits as -RLR-, improve=2.177253, (0 missing)
## Race splits as -RLRRR, improve=1.556653, (0 missing)
## AgeCategory splits as ---------LRLR, improve=1.398798, (0 missing)
## Surrogate splits:
## Race splits as -RLLLL, agree=0.717, adj=0.027, (0 split)
## GenHealth splits as -LLR-, agree=0.717, adj=0.027, (0 split)
##
## Node number 31: 30 observations, complexity param=0.01577564
## predicted class=Yes expected loss=0.4333333 P(node) =0.015
## class counts: 13 17
## probabilities: 0.433 0.567
## left son=62 (9 obs) right son=63 (21 obs)
## Primary splits:
## AgeCategory splits as ---------LRRR, improve=3.0507940, (0 missing)
## BMI < 29.09 to the right, improve=1.5206640, (0 missing)
## Smoking splits as LR, improve=0.6000000, (0 missing)
## Diabetic splits as L-R-, improve=0.5333333, (0 missing)
## DiffWalking splits as LR, improve=0.3979296, (0 missing)
## Surrogate splits:
## MentalHealth < 11 to the right, agree=0.733, adj=0.111, (0 split)
## Asthma splits as RL, agree=0.733, adj=0.111, (0 split)
##
## Node number 60: 90 observations, complexity param=0.01226994
## predicted class=No expected loss=0.2111111 P(node) =0.045
## class counts: 71 19
## probabilities: 0.789 0.211
## left son=120 (82 obs) right son=121 (8 obs)
## Primary splits:
## Stroke splits as LR, improve=3.0082660, (0 missing)
## GenHealth splits as -RLR-, improve=2.1777780, (0 missing)
## DiffWalking splits as LR, improve=2.0063310, (0 missing)
## Race splits as -LLRRL, improve=1.1700850, (0 missing)
## BMI < 33.9 to the left, improve=0.9148407, (0 missing)
##
## Node number 61: 37 observations, complexity param=0.01577564
## predicted class=No expected loss=0.4594595 P(node) =0.0185
## class counts: 20 17
## probabilities: 0.541 0.459
## left son=122 (18 obs) right son=123 (19 obs)
## Primary splits:
## AgeCategory splits as ---------LRLR, improve=6.0099570, (0 missing)
## Race splits as -LLLLR, improve=2.8863150, (0 missing)
## PhysicalHealth < 2.5 to the right, improve=1.7195550, (0 missing)
## BMI < 23.87 to the left, improve=1.5250450, (0 missing)
## SleepTime < 6.5 to the left, improve=0.8956198, (0 missing)
## Surrogate splits:
## BMI < 19.515 to the left, agree=0.622, adj=0.222, (0 split)
## PhysicalHealth < 0.5 to the right, agree=0.595, adj=0.167, (0 split)
## Race splits as -LRLLR, agree=0.595, adj=0.167, (0 split)
## PhysicalActivity splits as LR, agree=0.568, adj=0.111, (0 split)
## GenHealth splits as -RRL-, agree=0.568, adj=0.111, (0 split)
##
## Node number 62: 9 observations
## predicted class=No expected loss=0.2222222 P(node) =0.0045
## class counts: 7 2
## probabilities: 0.778 0.222
##
## Node number 63: 21 observations
## predicted class=Yes expected loss=0.2857143 P(node) =0.0105
## class counts: 6 15
## probabilities: 0.286 0.714
##
## Node number 120: 82 observations
## predicted class=No expected loss=0.1707317 P(node) =0.041
## class counts: 68 14
## probabilities: 0.829 0.171
##
## Node number 121: 8 observations
## predicted class=Yes expected loss=0.375 P(node) =0.004
## class counts: 3 5
## probabilities: 0.375 0.625
##
## Node number 122: 18 observations
## predicted class=No expected loss=0.1666667 P(node) =0.009
## class counts: 15 3
## probabilities: 0.833 0.167
##
## Node number 123: 19 observations
## predicted class=Yes expected loss=0.2631579 P(node) =0.0095
## class counts: 5 14
## probabilities: 0.263 0.737
Entonces una posible predicción sería siguiendo las reglas de asociación y condicionales del modelo.
prp(modelo.ac, main = "Arbol de Clasificación")
Se generan predicciones con datos de validación con el argumento class de clasificación, es decir, Yes o No.
prediciones_ac = predict(object = modelo.ac,newdata = datos.validacion, type = "class")
Head(predicciones, 20) los primeros 20 predicciones
head(prediciones_ac, 20)
## 19 25 27 30 43 47 48 55 60 61 62 64 72 74 79 89 91 93 99 111
## No No No No No No No No No No No No No No No No No No No No
## Levels: No Yes
Se construye una tabla comparativa con los valores de interés
t_comparativa = data.frame("real" = datos.validacion[,c('HeartDisease')],"prediccion"= prediciones_ac)
# t_comparativa <- t_comparativa %>%
# mutate(heartDiseasePred =
top20 = head(t_comparativa,20)
kable(top20,caption = 'Primeros 20 registros')
| real | prediccion | |
|---|---|---|
| 19 | No | No |
| 25 | No | No |
| 27 | No | No |
| 30 | No | No |
| 43 | Yes | No |
| 47 | No | No |
| 48 | No | No |
| 55 | No | No |
| 60 | No | No |
| 61 | No | No |
| 62 | No | No |
| 64 | No | No |
| 72 | No | No |
| 74 | No | No |
| 79 | Yes | No |
| 89 | No | No |
| 91 | No | No |
| 93 | No | No |
| 99 | No | No |
| 111 | No | No |
Una matriz de confusión es una herramienta que permite evaluación de un modelo de clasificación
Cada columna de la matriz representa el número de predicciones de cada clase, mientras que cada fila representa a las instancias en la clase real.
Uno de los beneficios de las matrices de confusión es que facilitan ver si el sistema está confundiendo las diferentes clases o resultados.
Hay que encontrar a cuantos casos se le atinaron utilizando los datos de validación y con ello encontrar el porcentaje de aciertos.
Se puede evaluar el modelo con la matriz de confusión interpretando algunos estadísticos:
Se evalúa el modelo de acuerdo a estas condiciones:
Accuracy o exactitud \[ accuracy = \frac{VP + VN}{VP+FP+FN+VN} \\ n = VP+FP+FN+VN \]
Precision o precisión
\[ precision = \frac{VP}{VP + FP} \]
Recall o recuperación \[ recall = \frac{VP}{VP + FN} \]
Especificity o especificidad (tasa de verdaderos negativos)
\[ especificity = \frac{VN}{VN + FP} \]
Factorizar las columnas
Factorizar en R significa categorizar con la función “as.factor” o “factor”
Se muestra a tabla con las columnas de interés para interpretar las predicciones.
t_comparativa$real = as.factor(t_comparativa$real)
t_comparativa$prediccion = as.factor(t_comparativa$prediccion)
kable(head(t_comparativa, 20), caption = "Tabla comparativa, primeros 20 registros")
| real | prediccion | |
|---|---|---|
| 19 | No | No |
| 25 | No | No |
| 27 | No | No |
| 30 | No | No |
| 43 | Yes | No |
| 47 | No | No |
| 48 | No | No |
| 55 | No | No |
| 60 | No | No |
| 61 | No | No |
| 62 | No | No |
| 64 | No | No |
| 72 | No | No |
| 74 | No | No |
| 79 | Yes | No |
| 89 | No | No |
| 91 | No | No |
| 93 | No | No |
| 99 | No | No |
| 111 | No | No |
Creando de la matriz de confusión con la función confusionMatrix() de la librería caret con las variables de interés: “real” y “prediccion”, que representan los valores reales y las predicciones respectivamente.
matrixConfusion <- confusionMatrix(t_comparativa$real,t_comparativa$prediccion)
matrixConfusion
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 57389 1095
## Yes 4861 613
##
## Accuracy : 0.9069
## 95% CI : (0.9046, 0.9091)
## No Information Rate : 0.9733
## P-Value [Acc > NIR] : 1
##
## Kappa : 0.1355
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.9219
## Specificity : 0.3589
## Pos Pred Value : 0.9813
## Neg Pred Value : 0.1120
## Prevalence : 0.9733
## Detection Rate : 0.8973
## Detection Prevalence : 0.9144
## Balanced Accuracy : 0.6404
##
## 'Positive' Class : No
##
El valor estadístico de Accuracy = Exactitud igual a 0.9069 significa un valor aproximado del 90.69; se interpreta que de cada 100 el modelo acierta en la predicción el 90.69% de las ocasiones.
El modelo se construyó solo con una muestra de 2000 registros de los datos de entrenamiento.
Si la métrica era que debiera tener un valor por encima del 70% el modelo se acepta pero debe compararse contra otro modelo de clasificación para ver cual es más eficiente en relación tan solo en el estadístico de exactitud.
Este valor de Accuracy = Exactitud deberá compararse contra otros modelos.
Se crea un registro de una persona con ciertas condiciones de salud.
BMI <- 38
Smoking <- 'Yes'
AlcoholDrinking = 'Yes'
Stroke <- 'Yes'
PhysicalHealth <- 2
MentalHealth = 5
DiffWalking = 'Yes'
Sex = 'Male'
AgeCategory = '70-74'
Race = 'Black'
Diabetic <- 'Yes'
PhysicalActivity = "No"
GenHealth = "Fair"
SleepTime = 12
Asthma = "Yes"
KidneyDisease = "Yes"
SkinCancer = 'No'
persona <- data.frame(BMI,Smoking, AlcoholDrinking, Stroke, PhysicalHealth, MentalHealth, DiffWalking, Sex, AgeCategory, Race, Diabetic, PhysicalActivity, GenHealth, SleepTime, Asthma, KidneyDisease, SkinCancer)
persona
## BMI Smoking AlcoholDrinking Stroke PhysicalHealth MentalHealth DiffWalking
## 1 38 Yes Yes Yes 2 5 Yes
## Sex AgeCategory Race Diabetic PhysicalActivity GenHealth SleepTime Asthma
## 1 Male 70-74 Black Yes No Fair 12 Yes
## KidneyDisease SkinCancer
## 1 Yes No
Se hace la predicción con estos valores:
prediccion <- predict(object = modelo.ac, newdata = persona, type = "class")
prediccion
## 1
## Yes
## Levels: No Yes
# prediccion <- prediccion$fit
# prediccion
Entonces la predicción es:
Si la predicción es ‘No’ entonces no tienen afección del corazón, en caso contrario de ‘Yes’ entonces implica que si tiene daño del corazón.
Pendiente …