# install.packages("caret")
library(caret)
## Cargando paquete requerido: ggplot2
## Cargando paquete requerido: lattice
# install.packages("tidyverse")
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.2.0 ✔ readr 2.1.6
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ lubridate 1.9.5 ✔ tibble 3.3.1
## ✔ purrr 1.2.1 ✔ tidyr 1.3.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ✖ purrr::lift() masks caret::lift()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
heart <- library(readr)
heart <- heart <- read_csv("heart.csv")
## Rows: 1025 Columns: 14
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (14): age, sex, cp, trestbps, chol, fbs, restecg, thalach, exang, oldpea...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
colnames(heart)
## [1] "age" "sex" "cp" "trestbps" "chol" "fbs"
## [7] "restecg" "thalach" "exang" "oldpeak" "slope" "ca"
## [13] "thal" "target"
summary(heart)
## 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
heart <- na.omit(heart)
heart$target <- as.factor(heart$target)
heart$sex <- as.factor(heart$sex)
heart$cp <- as.factor(heart$cp)
heart$fbs <- as.factor(heart$fbs)
heart$restecg <- as.factor(heart$restecg)
heart$exang <- as.factor(heart$exang)
heart$slope <- as.factor(heart$slope)
heart$ca <- as.factor(heart$ca)
heart$thal <- as.factor(heart$thal)
summary(heart)
## age sex cp trestbps chol fbs restecg
## Min. :29.00 0:312 0:497 Min. : 94.0 Min. :126 0:872 0:497
## 1st Qu.:48.00 1:713 1:167 1st Qu.:120.0 1st Qu.:211 1:153 1:513
## Median :56.00 2:284 Median :130.0 Median :240 2: 15
## Mean :54.43 3: 77 Mean :131.6 Mean :246
## 3rd Qu.:61.00 3rd Qu.:140.0 3rd Qu.:275
## Max. :77.00 Max. :200.0 Max. :564
## thalach exang oldpeak slope ca thal target
## Min. : 71.0 0:680 Min. :0.000 0: 74 0:578 0: 7 0:499
## 1st Qu.:132.0 1:345 1st Qu.:0.000 1:482 1:226 1: 64 1:526
## Median :152.0 Median :0.800 2:469 2:134 2:544
## Mean :149.1 Mean :1.072 3: 69 3:410
## 3rd Qu.:166.0 3rd Qu.:1.800 4: 18
## Max. :202.0 Max. :6.200
str(heart)
## tibble [1,025 × 14] (S3: tbl_df/tbl/data.frame)
## $ age : num [1:1025] 52 53 70 61 62 58 58 55 46 54 ...
## $ sex : Factor w/ 2 levels "0","1": 2 2 2 2 1 1 2 2 2 2 ...
## $ cp : Factor w/ 4 levels "0","1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
## $ trestbps: num [1:1025] 125 140 145 148 138 100 114 160 120 122 ...
## $ chol : num [1:1025] 212 203 174 203 294 248 318 289 249 286 ...
## $ fbs : Factor w/ 2 levels "0","1": 1 2 1 1 2 1 1 1 1 1 ...
## $ restecg : Factor w/ 3 levels "0","1","2": 2 1 2 2 2 1 3 1 1 1 ...
## $ thalach : num [1:1025] 168 155 125 161 106 122 140 145 144 116 ...
## $ exang : Factor w/ 2 levels "0","1": 1 2 2 1 1 1 1 2 1 2 ...
## $ oldpeak : num [1:1025] 1 3.1 2.6 0 1.9 1 4.4 0.8 0.8 3.2 ...
## $ slope : Factor w/ 3 levels "0","1","2": 3 1 1 3 2 2 1 2 3 2 ...
## $ ca : Factor w/ 5 levels "0","1","2","3",..: 3 1 1 2 4 1 4 2 1 3 ...
## $ thal : Factor w/ 4 levels "0","1","2","3": 4 4 4 4 3 3 2 4 4 3 ...
## $ target : Factor w/ 2 levels "0","1": 1 1 1 1 1 2 1 1 1 1 ...
modelo <- glm(target ~ ., data=heart, family=binomial)
summary(modelo)
##
## Call:
## glm(formula = target ~ ., family = binomial, data = heart)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.081901 2.028691 -0.040 0.967797
## age 0.026846 0.013950 1.924 0.054297 .
## sex1 -1.992347 0.314204 -6.341 2.28e-10 ***
## cp1 0.886380 0.308803 2.870 0.004100 **
## cp2 2.006394 0.286281 7.008 2.41e-12 ***
## cp3 2.409722 0.391965 6.148 7.86e-10 ***
## trestbps -0.024979 0.006537 -3.821 0.000133 ***
## chol -0.005462 0.002307 -2.367 0.017914 *
## fbs1 0.380096 0.319620 1.189 0.234356
## restecg1 0.397268 0.217975 1.823 0.068374 .
## restecg2 -0.800417 1.536998 -0.521 0.602530
## thalach 0.021692 0.006525 3.324 0.000886 ***
## exang1 -0.750331 0.248746 -3.016 0.002557 **
## oldpeak -0.403411 0.132156 -3.053 0.002269 **
## slope1 -0.595618 0.472076 -1.262 0.207057
## slope2 0.799689 0.504500 1.585 0.112941
## ca1 -2.334076 0.286781 -8.139 3.99e-16 ***
## ca2 -3.597039 0.444870 -8.086 6.19e-16 ***
## ca3 -2.288131 0.532138 -4.300 1.71e-05 ***
## ca4 1.565677 0.930256 1.683 0.092363 .
## thal1 2.796813 1.466219 1.908 0.056456 .
## thal2 2.404646 1.421542 1.692 0.090727 .
## thal3 0.991243 1.423972 0.696 0.486359
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1420.24 on 1024 degrees of freedom
## Residual deviance: 606.82 on 1002 degrees of freedom
## AIC: 652.82
##
## Number of Fisher Scoring iterations: 6
nuevos_datos <- heart[1:2, ]
probabilidades <- predict(modelo, newdata = nuevos_datos, type = "response")
cbind(nuevos_datos, prob = probabilidades)
## 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
## target prob
## 1 0 0.04202510
## 2 0 0.07415506
El modelo reveló la siguiente información:
En términos generales, el modelo sugiere que las variables clínicas relacionadas con tipo de dolor de pecho, frecuencia cardíaca máxima, depresión ST y número de vasos afectados son los predictores más relevantes.
Al evaluar los dos casos con el modelo:
El primer caso (52 años, hombre, cp = 0, presión 125, colesterol 212, sin angina inducida, oldpeak = 1, ca = 2, thal = 3) presenta una probabilidad estimada de 2.83% de presentar problemas del corazón. Con esto se puede inferir que, dadas sus características clínicas, el modelo lo clasifica como de muy bajo riesgo.
En cambio, el segundo caso (53 años, hombre, cp = 0, presión 140, colesterol 203, con angina inducida, oldpeak = 3.1, ca = 0, thal = 3) presenta una probabilidad prácticamente nula (≈ 0.0000003%) de tener problemas en el corazon.