Objetivo

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.

Descripció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:

Los modelo se aceptan si tienen un valor de exactitud por encima del 70%..

Fundamento teórico

Desarrollo

Cargar librerías

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

Cargar datos de manera local.

datos <- read.csv("https://raw.githubusercontent.com/rpizarrog/Machine-Learning-con-R/main/datos/heart_2020_cleaned.csv")

Explorar datos

str(datos)
## 'data.frame':    319795 obs. of  18 variables:
##  $ HeartDisease    : chr  "No" "No" "No" "No" ...
##  $ BMI             : num  16.6 20.3 26.6 24.2 23.7 ...
##  $ Smoking         : chr  "Yes" "No" "Yes" "No" ...
##  $ AlcoholDrinking : chr  "No" "No" "No" "No" ...
##  $ Stroke          : chr  "No" "Yes" "No" "No" ...
##  $ 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     : chr  "No" "No" "No" "No" ...
##  $ Sex             : chr  "Female" "Female" "Male" "Female" ...
##  $ AgeCategory     : chr  "55-59" "80 or older" "65-69" "75-79" ...
##  $ Race            : chr  "White" "White" "White" "White" ...
##  $ Diabetic        : chr  "Yes" "No" "Yes" "No" ...
##  $ PhysicalActivity: chr  "Yes" "Yes" "Yes" "No" ...
##  $ GenHealth       : chr  "Very good" "Very good" "Fair" "Good" ...
##  $ SleepTime       : num  5 7 8 6 8 12 4 9 5 10 ...
##  $ Asthma          : chr  "Yes" "No" "Yes" "No" ...
##  $ KidneyDisease   : chr  "No" "No" "No" "No" ...
##  $ SkinCancer      : chr  "Yes" "No" "No" "Yes" ...
summary(datos)
##  HeartDisease            BMI          Smoking          AlcoholDrinking   
##  Length:319795      Min.   :12.02   Length:319795      Length:319795     
##  Class :character   1st Qu.:24.03   Class :character   Class :character  
##  Mode  :character   Median :27.34   Mode  :character   Mode  :character  
##                     Mean   :28.33                                        
##                     3rd Qu.:31.42                                        
##                     Max.   :94.85                                        
##     Stroke          PhysicalHealth    MentalHealth    DiffWalking       
##  Length:319795      Min.   : 0.000   Min.   : 0.000   Length:319795     
##  Class :character   1st Qu.: 0.000   1st Qu.: 0.000   Class :character  
##  Mode  :character   Median : 0.000   Median : 0.000   Mode  :character  
##                     Mean   : 3.372   Mean   : 3.898                     
##                     3rd Qu.: 2.000   3rd Qu.: 3.000                     
##                     Max.   :30.000   Max.   :30.000                     
##      Sex            AgeCategory            Race             Diabetic        
##  Length:319795      Length:319795      Length:319795      Length:319795     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  PhysicalActivity    GenHealth           SleepTime         Asthma         
##  Length:319795      Length:319795      Min.   : 1.000   Length:319795     
##  Class :character   Class :character   1st Qu.: 6.000   Class :character  
##  Mode  :character   Mode  :character   Median : 7.000   Mode  :character  
##                                        Mean   : 7.097                     
##                                        3rd Qu.: 8.000                     
##                                        Max.   :24.000                     
##  KidneyDisease       SkinCancer       
##  Length:319795      Length:319795     
##  Class :character   Class :character  
##  Mode  :character   Mode  :character  
##                                       
##                                       
## 

Limpiar datos

No es necesario alguna transformación

Las variables de interés

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’.

Datos de entrenamiento y validación

Se parten los datos en en datos de entrenamiento con el 80% y datos de validación con el 20%.

set.seed(1280)
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, ]

Datos de entrenamiento

Se muestran los primeros 20 registros datos de entrenamiento

kable(head(datos.entrenamiento, 20), caption = "Primeros 20 registros de datos de entrenamiento")
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
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
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
18 No 22.59 Yes No No 0 30 Yes Male 70-74 White No, borderline diabetes Yes Good 8 No No No
19 No 29.86 Yes No No 0 0 Yes Female 75-79 Black Yes No Fair 5 No Yes No
21 No 21.16 No No No 0 0 No Female 80 or older Black No, borderline diabetes No Good 8 No No No
22 No 28.90 No No No 2 5 No Female 70-74 White Yes No Very good 7 No No No
23 No 26.17 Yes No No 0 15 No Female 45-49 White No Yes Very good 6 No No No
26 No 29.18 Yes No No 30 30 Yes Female 60-64 White No No Poor 6 Yes No No

Datos de validación

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")
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
7 No 21.63 No No No 15 0 No Female 70-74 White No Yes Fair 4 Yes No Yes
13 No 28.37 Yes No No 0 0 Yes Male 75-79 White Yes Yes Very good 8 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
20 No 18.13 No No No 0 0 No Male 80 or older White No Yes Excellent 8 No No Yes
24 No 25.82 Yes No No 0 30 No Male 80 or older White Yes Yes Fair 8 No No No
25 No 25.75 No No No 0 0 No Female 80 or older White No Yes Very good 6 No No Yes
29 No 24.89 No No No 1 0 No Female 55-59 White No Yes Very good 7 No No No
32 No 30.67 No No No 4 4 Yes Female 80 or older White No Yes Fair 8 Yes No No
33 No 45.35 No No No 30 0 Yes Male 70-74 White Yes No Good 8 No No No
38 No 20.43 Yes No No 3 3 No Female 65-69 White No Yes Fair 5 Yes No Yes
40 No 21.93 No No No 3 2 No Female 70-74 Black No Yes Fair 4 No Yes No
41 No 22.60 Yes No Yes 0 10 No Female 55-59 White No No 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
49 No 20.12 No No No 0 0 Yes Female 80 or older White No No Fair 7 No No Yes
55 No 32.10 No No No 14 0 No Male 65-69 White Yes Yes Very good 9 No No No
57 No 32.55 Yes No No 0 0 No Male 75-79 White No No Very good 8 No 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
67 No 34.01 Yes No No 14 0 No Female 80 or older White No No Good 7 Yes Yes Yes
71 No 21.97 No No No 0 0 No Female 65-69 Black No No Very good 10 Yes No No

Arbol de Clasificación

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 ~ .)

Resumen y/o estadísticos del modelo

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.02339181      0 1.0000000 1.0000000 0.07312970
## 2 0.01461988      3 0.9298246 0.9824561 0.07254480
## 3 0.01169591      5 0.9005848 0.9941520 0.07293549
## 4 0.01000000      7 0.8771930 1.0058480 0.07332317
## 
## Variable importance
##    AgeCategory      GenHealth  KidneyDisease PhysicalHealth            BMI 
##             26             20             15             10             10 
##   MentalHealth      SleepTime     SkinCancer    DiffWalking       Diabetic 
##              8              4              2              2              1 
##           Race         Stroke 
##              1              1 
## 
## Node number 1: 2000 observations,    complexity param=0.02339181
##   predicted class=No   expected loss=0.0855  P(node) =1
##     class counts:  1829   171
##    probabilities: 0.914 0.086 
##   left son=2 (1289 obs) right son=3 (711 obs)
##   Primary splits:
##       AgeCategory   splits as  LLLLLLLLLRRRR, improve=16.35216, (0 missing)
##       GenHealth     splits as  LRLRL, improve=15.41274, (0 missing)
##       KidneyDisease splits as  LR, improve=14.66334, (0 missing)
##       DiffWalking   splits as  LR, improve=11.40130, (0 missing)
##       Diabetic      splits as  LLRL, improve=10.68975, (0 missing)
##   Surrogate splits:
##       SkinCancer    splits as  LR,         agree=0.678, adj=0.094, (0 split)
##       DiffWalking   splits as  LR,         agree=0.658, adj=0.038, (0 split)
##       KidneyDisease splits as  LR,         agree=0.656, adj=0.032, (0 split)
##       SleepTime     < 8.5    to the left,  agree=0.655, adj=0.031, (0 split)
##       Diabetic      splits as  LLRL,       agree=0.655, adj=0.030, (0 split)
## 
## Node number 2: 1289 observations
##   predicted class=No   expected loss=0.03801396  P(node) =0.6445
##     class counts:  1240    49
##    probabilities: 0.962 0.038 
## 
## Node number 3: 711 observations,    complexity param=0.02339181
##   predicted class=No   expected loss=0.1715893  P(node) =0.3555
##     class counts:   589   122
##    probabilities: 0.828 0.172 
##   left son=6 (577 obs) right son=7 (134 obs)
##   Primary splits:
##       GenHealth      splits as  LRLRL,      improve=12.439430, (0 missing)
##       KidneyDisease  splits as  LR,         improve=12.059900, (0 missing)
##       DiffWalking    splits as  LR,         improve= 8.374490, (0 missing)
##       Sex            splits as  LR,         improve= 5.899227, (0 missing)
##       PhysicalHealth < 4.5    to the left,  improve= 5.472885, (0 missing)
##   Surrogate splits:
##       PhysicalHealth < 14.5   to the left,  agree=0.850, adj=0.201, (0 split)
##       MentalHealth   < 17.5   to the left,  agree=0.826, adj=0.075, (0 split)
##       DiffWalking    splits as  LR,         agree=0.820, adj=0.045, (0 split)
##       BMI            < 17.99  to the right, agree=0.817, adj=0.030, (0 split)
## 
## Node number 6: 577 observations
##   predicted class=No   expected loss=0.1265165  P(node) =0.2885
##     class counts:   504    73
##    probabilities: 0.873 0.127 
## 
## Node number 7: 134 observations,    complexity param=0.02339181
##   predicted class=No   expected loss=0.3656716  P(node) =0.067
##     class counts:    85    49
##    probabilities: 0.634 0.366 
##   left son=14 (116 obs) right son=15 (18 obs)
##   Primary splits:
##       KidneyDisease splits as  LR,         improve=9.095214, (0 missing)
##       MentalHealth  < 0.5    to the right, improve=4.058771, (0 missing)
##       Sex           splits as  LR,         improve=1.782710, (0 missing)
##       SleepTime     < 6.5    to the left,  improve=1.345381, (0 missing)
##       BMI           < 23.625 to the left,  improve=1.330096, (0 missing)
## 
## Node number 14: 116 observations,    complexity param=0.01461988
##   predicted class=No   expected loss=0.2931034  P(node) =0.058
##     class counts:    82    34
##    probabilities: 0.707 0.293 
##   left son=28 (50 obs) right son=29 (66 obs)
##   Primary splits:
##       MentalHealth < 0.5    to the right, improve=4.119875, (0 missing)
##       Sex          splits as  LR, improve=2.311754, (0 missing)
##       AgeCategory  splits as  ---------RRLR, improve=2.219836, (0 missing)
##       BMI          < 35.11  to the right, improve=1.603420, (0 missing)
##       GenHealth    splits as  -L-R-, improve=1.145509, (0 missing)
##   Surrogate splits:
##       PhysicalHealth < 1      to the right, agree=0.681, adj=0.26, (0 split)
##       SleepTime      < 5.5    to the left,  agree=0.638, adj=0.16, (0 split)
##       AgeCategory    splits as  ---------LRRR, agree=0.621, adj=0.12, (0 split)
##       BMI            < 17.375 to the left,  agree=0.586, adj=0.04, (0 split)
##       Race           splits as  R-RLRR, agree=0.586, adj=0.04, (0 split)
## 
## Node number 15: 18 observations
##   predicted class=Yes  expected loss=0.1666667  P(node) =0.009
##     class counts:     3    15
##    probabilities: 0.167 0.833 
## 
## Node number 28: 50 observations
##   predicted class=No   expected loss=0.14  P(node) =0.025
##     class counts:    43     7
##    probabilities: 0.860 0.140 
## 
## Node number 29: 66 observations,    complexity param=0.01461988
##   predicted class=No   expected loss=0.4090909  P(node) =0.033
##     class counts:    39    27
##    probabilities: 0.591 0.409 
##   left son=58 (43 obs) right son=59 (23 obs)
##   Primary splits:
##       PhysicalHealth < 12     to the left,  improve=2.813034, (0 missing)
##       Sex            splits as  LR, improve=2.104804, (0 missing)
##       BMI            < 23.56  to the left,  improve=2.074091, (0 missing)
##       GenHealth      splits as  -L-R-, improve=1.469715, (0 missing)
##       AgeCategory    splits as  ---------RRLR, improve=1.363636, (0 missing)
##   Surrogate splits:
##       GenHealth       splits as  -L-R-, agree=0.758, adj=0.304, (0 split)
##       DiffWalking     splits as  LR, agree=0.682, adj=0.087, (0 split)
##       BMI             < 43.28  to the left,  agree=0.667, adj=0.043, (0 split)
##       AlcoholDrinking splits as  LR, agree=0.667, adj=0.043, (0 split)
##       AgeCategory     splits as  ---------RLLL, agree=0.667, adj=0.043, (0 split)
## 
## Node number 58: 43 observations,    complexity param=0.01169591
##   predicted class=No   expected loss=0.3023256  P(node) =0.0215
##     class counts:    30    13
##    probabilities: 0.698 0.302 
##   left son=116 (9 obs) right son=117 (34 obs)
##   Primary splits:
##       BMI            < 35.2   to the right, improve=2.0807110, (0 missing)
##       Sex            splits as  LR, improve=1.5920240, (0 missing)
##       PhysicalHealth < 1      to the right, improve=1.0668080, (0 missing)
##       AgeCategory    splits as  ---------RRLR, improve=0.8323453, (0 missing)
##       Diabetic       splits as  RLLL, improve=0.6126532, (0 missing)
## 
## Node number 59: 23 observations
##   predicted class=Yes  expected loss=0.3913043  P(node) =0.0115
##     class counts:     9    14
##    probabilities: 0.391 0.609 
## 
## Node number 116: 9 observations
##   predicted class=No   expected loss=0  P(node) =0.0045
##     class counts:     9     0
##    probabilities: 1.000 0.000 
## 
## Node number 117: 34 observations,    complexity param=0.01169591
##   predicted class=No   expected loss=0.3823529  P(node) =0.017
##     class counts:    21    13
##    probabilities: 0.618 0.382 
##   left son=234 (18 obs) right son=235 (16 obs)
##   Primary splits:
##       BMI            < 26.05  to the left,  improve=3.5588240, (0 missing)
##       AgeCategory    splits as  ---------RRLR, improve=1.8010460, (0 missing)
##       Sex            splits as  LR, improve=1.2237360, (0 missing)
##       PhysicalHealth < 1      to the right, improve=1.0112040, (0 missing)
##       SleepTime      < 6.5    to the left,  improve=0.9672484, (0 missing)
##   Surrogate splits:
##       SleepTime   < 6.5    to the left,  agree=0.735, adj=0.438, (0 split)
##       Stroke      splits as  LR, agree=0.588, adj=0.125, (0 split)
##       AgeCategory splits as  ---------RLLL, agree=0.588, adj=0.125, (0 split)
##       Race        splits as  L-LRRL, agree=0.588, adj=0.125, (0 split)
##       Diabetic    splits as  LLRR, agree=0.588, adj=0.125, (0 split)
## 
## Node number 234: 18 observations
##   predicted class=No   expected loss=0.1666667  P(node) =0.009
##     class counts:    15     3
##    probabilities: 0.833 0.167 
## 
## Node number 235: 16 observations
##   predicted class=Yes  expected loss=0.375  P(node) =0.008
##     class counts:     6    10
##    probabilities: 0.375 0.625

Entonces una posible predicción sería siguiendo las reglas de asociación y condicionales del modelo.

Visualizar árbol de clasificación

prp(modelo.ac, main = "Arbol de Clasificación")

Generar predicciones del modelo regresión logística

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")

Predicciones

Head(predicciones, 20) los primeros 20 predicciones

head(prediciones_ac, 20)
##   7  13  17  20  24  25  29  32  33  38  40  41  48  49  55  57  62  64  67  71 
## Yes  No  No  No  No  No  No  No  No  No Yes  No  No  No  No  No  No  No  No  No 
## Levels: No Yes

Generar tabla comparativa

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')
Primeros 20 registros
real prediccion
7 No Yes
13 No No
17 No No
20 No No
24 No No
25 No No
29 No No
32 No No
33 No No
38 No No
40 No Yes
41 No No
48 No No
49 No No
55 No No
57 No No
62 No No
64 No No
67 No No
71 No No

Evaluando el modelo

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} \]

Construyendo la matriz de confusión del modelo de regresión logística

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")
Tabla comparativa, primeros 20 registros
real prediccion
7 No Yes
13 No No
17 No No
20 No No
24 No No
25 No No
29 No No
32 No No
33 No No
38 No No
40 No Yes
41 No No
48 No No
49 No No
55 No No
57 No No
62 No No
64 No No
67 No No
71 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  57152  1332
##        Yes  4715   759
##                                           
##                Accuracy : 0.9055          
##                  95% CI : (0.9032, 0.9077)
##     No Information Rate : 0.9673          
##     P-Value [Acc > NIR] : 1               
##                                           
##                   Kappa : 0.161           
##                                           
##  Mcnemar's Test P-Value : <2e-16          
##                                           
##             Sensitivity : 0.9238          
##             Specificity : 0.3630          
##          Pos Pred Value : 0.9772          
##          Neg Pred Value : 0.1387          
##              Prevalence : 0.9673          
##          Detection Rate : 0.8936          
##    Detection Prevalence : 0.9144          
##       Balanced Accuracy : 0.6434          
##                                           
##        'Positive' Class : No              
## 

El valor estadístico de Accuracy = Exactitud igual a 0.9055 significa un valor aproximado del 90.55; se interpreta que de cada 100 el modelo acierta en la predicción el 90.55% 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.

Predicciones con datos nuevos

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.

Interpretación

En esta ocasión el algoritmo de clasificación que se ha contemplado para evaluar se llama Árbol de Clasificación y se hace con respecto al estádistico Accuracy de la Matriz de Confusión que se refiere explicitamente a la exactitud que existe en la predicción con la que trabaja el modelo, y a través del cual se define, de manera cuantificada, que tanta diferencia hay entre los datos reales y los que son predichos por el modelo en cuestión.

Un dato interesante de este modelo es que se construyó solo con una muestra de 2000 registros de los datos de entrenamiento, debido a que si se hacia con todos los datos de entrenamiento, sería impoisble visualizar el esquema del árbol de clasificación y sus ramificaciones.

El contexto de los datos reside en su relación con la condición de salud de las personas, misma que es utilizada para predecir anomalías de corazón. Durante este proceso se busca evaluar la exactitud del modelo mediante la matriz de confusión que ya se ha mencionado. Bajo mi punto de vista, yo considero que el objetivo de este modelo es bastante útil debido a que clasifica a las personas en dos áreas, si tiene problemas del corazón o no, así de simple. No obstante, esto lo hace basadonse en una gran cantidad de parámetros de manera análitica y siguiendo un proceso matemático que resulta muy interesante descubrir.

Después de realizar algunas predicciones utilizando la semilla 1280, se obtuvo un valor aproximado del 90.55% de exactitud (Accuracy) en el modelo de árbol de clasificación. Cabe señalar que este valor es un poco menor comparado con en el que arroja el mismo modelo en lenguaje Python, que es del 91.48% haciendo uso de los mismos datos de entrada, es decir, de la semilla 1280.

El modelo se aprueba dado que la métrica es igual o superior al 70%.

Aunque en este caso la utilidad de conocer el dato arrojado por la estádistica Accuracy es bastante, es necesario compararla con otro modelo de clasificación, por ejemplo, el modelo de Regresión Logística Binaria. Sin embargo, quiero recalcar la importancia de este tipo de algoritmos que son utilizados cuando la variable dependiente es de tipo categórica o cualitativa y que tienen un significado conforme a una etiqueta, que a decir verdad, suelen darse en muchas situaciones de la vida real.

Se hizo una predicción de un caso e una persona con ciertas condiciones de salud y en la predicción, en términos de clasificación, resulta que la persona tiene daño al corazón.

Bibliografía