Regresión Logística Binaria Múltiple en R

Jenniffer Alemán

29-07-2024

1 GENERALIDADES

1.1 Modelo De Regresión Logística Binaria Múltiple

Un modelo de regresión logística binaria múltiple es una técnica estadística utilizada para predecir la probabilidad de un resultado binario (dos posibles resultados, como “sí” o “no”, “1” o “0”) basado en uno o más predictores, que pueden ser variables continuas o categóricas.

1.2 Características Principales

  • Variable Dependiente Binaria: El resultado que se predice es una variable binaria, es decir, tiene dos categorías.

  • Variables Independientes: Puede incluir múltiples variables independientes (predictores) que pueden ser tanto continuas como categóricas.

  • Función Logística: Utiliza la función logística para modelar la probabilidad de que ocurra un evento. La salida del modelo es la probabilidad de que la variable dependiente tome un valor específico (por ejemplo, “1”).

🛈 NOTA


El contenido del documento, define los pasos para la construcción de un modelo de Regresión Logística Binaria Múltiple e incluye la debida interpretación del código que se presenta, en relación con la estructura en R.

1.3 Base De Datos

La base de datos con la que se trabajará en este documento, es de tipo .csv y para poder acceder a ella se necesita la librería readr. Este paquete está diseñado para facilitar la importación y exportación de datos en R, especialmente para archivos de texto, como CSV y TSV.

library(readr)
misdatos <- read_csv("heart_failure_clinical_records_dataset.csv")
class(misdatos)
## [1] "spec_tbl_df" "tbl_df"      "tbl"         "data.frame"

Para asegurar la compatibilidad y funcionalidad con diversas funciones y paquetes de R, los datos se deben transformar a Data.Frame.

misdatos = as.data.frame(misdatos)
str(misdatos)
## 'data.frame':    299 obs. of  13 variables:
##  $ age                     : num  75 55 65 50 65 90 75 60 65 80 ...
##  $ anaemia                 : num  0 0 0 1 1 1 1 1 0 1 ...
##  $ creatinine_phosphokinase: num  582 7861 146 111 160 ...
##  $ diabetes                : num  0 0 0 0 1 0 0 1 0 0 ...
##  $ ejection_fraction       : num  20 38 20 20 20 40 15 60 65 35 ...
##  $ high_blood_pressure     : num  1 0 0 0 0 1 0 0 0 1 ...
##  $ platelets               : num  265000 263358 162000 210000 327000 ...
##  $ serum_creatinine        : num  1.9 1.1 1.3 1.9 2.7 2.1 1.2 1.1 1.5 9.4 ...
##  $ serum_sodium            : num  130 136 129 137 116 132 137 131 138 133 ...
##  $ sex                     : num  1 1 1 1 0 1 1 1 0 1 ...
##  $ smoking                 : num  0 0 1 0 0 1 0 1 0 1 ...
##  $ time                    : num  4 6 7 7 8 8 10 10 10 10 ...
##  $ DEATH_EVENT             : num  1 1 1 1 1 1 1 1 1 1 ...

En la salida anterior se puede observar que la base de datos contiene 13 variables y 299 filas, ademas los datos ya están en formato Data.Frame por lo que se puede continuar trabajando. Para comenzar se obtendrá la visualización de las primeras filas de la base de datos.

head(misdatos,5)
age anaemia creatinine_phosphokinase diabetes ejection_fraction high_blood_pressure platelets serum_creatinine serum_sodium sex smoking time DEATH_EVENT
75 0 582 0 20 1 265000 1.9 130 1 0 4 1
55 0 7861 0 38 0 263358 1.1 136 1 0 6 1
65 0 146 0 20 0 162000 1.3 129 1 1 7 1
50 1 111 0 20 0 210000 1.9 137 1 0 7 1
65 1 160 1 20 0 327000 2.7 116 0 0 8 1

1.4 Descripción De Variables

names(misdatos)
Variable Tipo Descripción Categorías
age Numérica Edad del paciente
anaemia Categórica Presencia de anemia 0 = El paciente no tiene anemia 1 = El paciente tiene anemia
creatinine_phosphokinase Numérica Niveles de creatina fosfoquinasa en la sangre
diabetes Categórica Indicador de si el paciente tiene diabetes 0 = Ausencia de diabetes 1 = Presencia de diabetes
ejection_fraction Numérica Cantidad de sangre que el ventrículo izquierdo expulsa con cada contracción (Indicador de la función cardíaca)
high_blood_pressure Categórica Indicador de hipertensión arterial 0 = Ausencia de hipertensión 1 = Presencia de hipertensión
platelets Numérica Recuento de plaquetas en la sangre
serum_creatinine Numérica Nivel de creatinina en suero (Indicador de la función renal)
serum_sodium Numérica Nivel de sodio en suero
sex Categórica Género del paciente 0 = Masculino 1 = Femenino
smoking Categórica Indicador de si el paciente es fumador 0 = No fuma 1 = Si fuma
time Numérica Días de ingreso que tiene el paciente
DEATH_EVENT Categórica Indicador de evento de muerte 0 = No muerte del paciente 1 = Muerte del paciente

1.5 Datos De Entrenamiento Y Datos De Prueba

Ahora se establecerá una semilla para el generador de números aleatorios en R. Esto es importante para garantizar que los resultados sean reproducibles, esto significa que si alguien más ejecuta el mismo código con la misma semilla, obtendrá los mismos resultados, especialmente en procesos que involucran aleatoriedad, como la selección de muestras. Para establecer la semilla se usara el siguiente código:

set.seed(2021)

Una vez establecida la semilla se determinará el tamaño de la base de datos con la que se esta trabajando:

n = nrow(misdatos)
n
## [1] 299

Se tienen 299 filas en la base. Ahora que se conoce el número de filas, se puede proceder a dividir la base de datos en un conjunto de entrenamiento y un conjunto de datos de prueba. Para realizar dicha partición se debe generar una muestra aleatoria de índices (números de filas) que representan el \(70\%\) del conjunto de datos total para poder generar el conjunto de datos de entrenamiento:

d_ind = sample(n,n*0.70)

Una vez creado los indices se realiza la partición en los datos de la base original:

records=misdatos[d_ind,]

El código anterior crea el subconjunto de entrenamiento records, que contiene el 70% de las observaciones seleccionadas aleatoriamente de la base misdatos usando los índices generados en d_ind. Además, se debe crear la partición de prueba:

d_test=misdatos[-d_ind,] 

El código anterior crea el subconjunto de prueba d_test, que contiene el 30% restante de las observaciones que no fueron seleccionadas para el conjunto de entrenamiento. Para verificar que las variables seleccionadas sean las correctas se leerán los nombres de las variables de la partición de entrenamiento (records).

names(records)
Variable
age
anaemia
creatinine_phosphokinase
diabetes
ejection_fraction
high_blood_pressure
platelets
serum_creatinine
serum_sodium
sex
smoking
time
DEATH_EVENT

Se puede observar que son las mismas variables de la base de datos originales. Ahora se calculará la matriz de correlación para las variables seleccionadas del subconjunto de entrenamiento. Esto ayudará a identificar si hay multicolinealidad entre las variables predictoras, lo cual puede afectar la estabilidad y la interpretación del modelo de regresión.

cor(records[c(1,3,5,7,8,9)])
age creatinine_phosphokinase ejection_fraction platelets serum_creatinine serum_sodium
age 1.0000000 -0.0187324 0.0256468 -0.1097173 0.1356862 -0.0726885
creatinine_phosphokinase -0.0187324 1.0000000 -0.0080132 -0.0020113 0.0541629 0.0727306
ejection_fraction 0.0256468 -0.0080132 1.0000000 0.0413740 0.0517453 0.1013551
platelets -0.1097173 -0.0020113 0.0413740 1.0000000 -0.0873660 0.0705143
serum_creatinine 0.1356862 0.0541629 0.0517453 -0.0873660 1.0000000 -0.1412220
serum_sodium -0.0726885 0.0727306 0.1013551 0.0705143 -0.1412220 1.0000000

La multicolinealidad ocurre cuando dos o más variables predictoras en un modelo de regresión están altamente correlacionadas entre sí. En el resultado anterior se puede apreciar que la mayoría de las variables no tienen una correlación alta, ya que los valores no sobrepasan el \(|0.14|\). Esto es justo lo que se necesita para poder obtener un modelo de regresión logística múltiple adecuado.

2 Modelo De Regresión Logística Binaria Multiple

La construcción del modelo se realizará con la librería MASS. La variable respuesta que se utilizará será DEATH_EVENT que representa la muerte de un paciente, donde \(1\) representa cuando el paciente muere y \(0\) significa que el paciente no muere.

library(MASS)
my_model=glm(data = records,DEATH_EVENT~.,
             family = binomial())
summary(my_model)
## 
## Call:
## glm(formula = DEATH_EVENT ~ ., family = binomial(), data = records)
## 
## Coefficients:
##                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)               1.102e+01  7.542e+00   1.461  0.14410    
## age                       5.624e-02  1.927e-02   2.918  0.00352 ** 
## anaemia                   4.698e-01  4.160e-01   1.129  0.25874    
## creatinine_phosphokinase  4.584e-04  3.483e-04   1.316  0.18807    
## diabetes                  1.068e-01  4.252e-01   0.251  0.80174    
## ejection_fraction        -7.459e-02  1.905e-02  -3.916 9.01e-05 ***
## high_blood_pressure      -2.212e-01  4.511e-01  -0.490  0.62391    
## platelets                -1.896e-06  2.294e-06  -0.826  0.40870    
## serum_creatinine          5.489e-01  1.926e-01   2.849  0.00438 ** 
## serum_sodium             -7.284e-02  5.314e-02  -1.371  0.17043    
## sex                      -1.338e+00  5.321e-01  -2.514  0.01195 *  
## smoking                   2.293e-01  5.223e-01   0.439  0.66061    
## time                     -2.250e-02  3.911e-03  -5.754 8.73e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 259.12  on 208  degrees of freedom
## Residual deviance: 153.24  on 196  degrees of freedom
## AIC: 179.24
## 
## Number of Fisher Scoring iterations: 6

EL código anterior ajusta un modelo de regresión logística binaria múltiple utilizando el conjunto de datos records. La variable de respuesta es DEATH_EVENT y el símbolo ~. indica que se incluyen todas las demás variables como predictores. La familia binomial() especifica que el modelo es de tipo logístico binario. Mientras que summary proporciona un resumen del modelo ajustado, incluyendo los coeficientes estimados, errores estándar, valores z, y valores p para cada predictor, así como estadísticas de ajuste globales como el AIC.

2.1 Análisis

Los coeficientes estimados (Estimate) indican el cambio esperado en el logaritmo de las probabilidades (log-odds) de DEATH_EVENT por unidad de cambio en la variable predictora, manteniendo constantes las demás variables. Los valores positivos indican un aumento en la probabilidad del evento, mientras que los valores negativos indican una disminución.

Los errores estándar se espera que sean lo más pequeños posibles para poder obtener una estimación más precisa de los coeficientes. En los resultados se puede observar que los errores son muy pequeños por lo que se tiene una buena estimación de los coeficientes.

Variables Significativas
Variable p.valor
age 0.0035200
ejection_fraction 0.0000901
serum_creatinine 0.0043800
sex 0.0119500
time 0.0000000
Variables No Significativas
Variable p.valor
Intercept 0.14410
anaemia 0.25874
creatinine_phosphokinase 0.18807
diabetes 0.80174
high_blood_pressure 0.62391
platelets 0.40870
serum_sodium 0.17043
smoking 0.66061

2.1.1 Interpretación Para Las Variables Signifcativas

  • Para la variable age el coeficiente positivo sugiere que a medida que aumenta la edad, la probabilidad de que ocurra el evento de interés (muerte del paciente) también aumenta. Esto indica que la edad es un factor de riesgo para la mortalidad en este grupo de pacientes.

  • Para la variable ejection_fraction el coeficiente negativo indica que una mayor fracción de eyección se asocia con una menor probabilidad de muerte. La fracción de eyección es un indicador de la función cardíaca, y un valor mayor generalmente se asocia con un mejor estado de salud cardiovascular.

  • Para la variable serum_creatinin su coeficiente positivo sugiere que niveles más altos de creatinina en suero están asociados con una mayor probabilidad de muerte. Esto es consistente con la comprensión médica de que niveles elevados de creatinina pueden indicar problemas renales o daño, lo que puede ser un factor de riesgo para la mortalidad.

  • Para la variable sex el coeficiente negativo indicando que, en comparación con el grupo de referencia (\(masculino = 0\)), el grupo codificado con el otro valor (\(femenio = 1\)) tiene una menor probabilidad de morir. Esto podría reflejar diferencias en la supervivencia entre hombres y mujeres en la muestra.

  • Para la variable time que representa los días de ingreso que tiene el paciente, el coeficiente negativo sugiere que por cada día de ingreso, la probabilidad de muerte disminuye.

2.2 Detección De Multicolinealidad

La multicolinealidad ocurre cuando dos o más variables predictoras en un modelo de regresión están altamente correlacionadas entre sí. El VIF( ) calcula los Factores de Inflación de la Varianza para cada predictor en el modelo \(my model\). Un VIF alto sugiere que existe multicolinealidad, es decir, que una variable predictora está altamente correlacionada con una o más variables predictoras, lo cual puede inflar las varianzas de los coeficientes estimados y afectar la interpretación del modelo.

library(carData)
library(car)
vif(my_model)
VIF
age 1.129135
anaemia 1.046886
creatinine_phosphokinase 1.150944
diabetes 1.077959
ejection_fraction 1.220016
high_blood_pressure 1.076420
platelets 1.059796
serum_creatinine 1.116415
serum_sodium 1.096600
sex 1.624757
smoking 1.451073
time 1.269458

2.2.1 VIF: General

  • \(VIF < 5\): Generalmente considerado aceptable, sugiere que no hay una multicolinealidad preocupante.

  • \(VIF > 5\): Indica una multicolinealidad moderada, lo cual puede ser motivo de preocupación, pero no necesariamente un problema grave.

  • \(VIF > 10\): Considerado una señal de alerta de multicolinealidad alta, lo que podría invalidar la interpretación de los coeficientes.

2.2.2 VIF: Resultados

Los valores de VIF indican que no hay problemas significativos de multicolinealidad en el modelo. Por lo tanto, los coeficientes de las variables predictoras son relativamente estables y confiables, y las interpretaciones sobre los efectos de cada predictor en el resultado de la regresión logística binaria múltiple no están comprometidas por la multicolinealidad entre las variables predictoras.

3 Modificación Del Modelo De Regresión Logística Binaria Multiple

La selección de variables es crucial para construir modelos que sean interpretables, precisos y generalizables. En el modelo anterior hay muchas variables que no son significativas, para comenzar a reducir variables no significativas es recomendable iniciar eliminando las 2 variables que tengan el mayor p-valor y dependiendo de los resultados, se puede continuar con la eliminación de variables.

3.1 Selección Del Modelo

3.1.1 Primera Eliminación

my_model2=glm(data=records,DEATH_EVENT~.-high_blood_pressure-smoking,
              family = binomial(link = "logit"))
summary(my_model2)
## 
## Call:
## glm(formula = DEATH_EVENT ~ . - high_blood_pressure - smoking, 
##     family = binomial(link = "logit"), data = records)
## 
## Coefficients:
##                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)               1.043e+01  7.403e+00   1.409  0.15877    
## age                       5.516e-02  1.918e-02   2.876  0.00403 ** 
## anaemia                   4.404e-01  4.110e-01   1.072  0.28387    
## creatinine_phosphokinase  4.491e-04  3.389e-04   1.325  0.18509    
## diabetes                  8.655e-02  4.237e-01   0.204  0.83815    
## ejection_fraction        -7.481e-02  1.905e-02  -3.928 8.57e-05 ***
## platelets                -1.913e-06  2.283e-06  -0.838  0.40205    
## serum_creatinine          5.381e-01  1.888e-01   2.850  0.00437 ** 
## serum_sodium             -6.842e-02  5.201e-02  -1.316  0.18831    
## sex                      -1.197e+00  4.562e-01  -2.624  0.00870 ** 
## time                     -2.232e-02  3.887e-03  -5.742 9.35e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 259.12  on 208  degrees of freedom
## Residual deviance: 153.64  on 198  degrees of freedom
## AIC: 175.64
## 
## Number of Fisher Scoring iterations: 6

En el resultado anterior, se puede observar que las variables significativas son:

  • age
  • ejection_fraction
  • serum_creatinine
  • sex
  • time

El AIC proporciona una medida de la calidad del modelo ajustado. Un AIC más bajo indica un mejor ajuste del modelo, considerando tanto la bondad del ajuste como la complejidad del modelo.

3.1.1.1 Comparando Los AIC

# Modelo original
my_model$aic

# Modelo con las 2 variables eliminadas
my_model2$aic
Modelo AIC
Modelo Original 179.2415
Modelo 2 175.6393

Al comparar el AIC del modelo original y el nuevo modelo con las 2 variables eliminadas, se puede verificar que el nuevo AIC es menor que el del primer modelo. Este AIC significa que el nuevo modelo tiene un mejor ajuste del modelo.

3.1.2 Segunda Eliminación

Ahora se procederá a eliminar otras 2 variables que tienen un mayor p-valor para poder obtener un mejor ajuste del modelo.

my_model3=glm(data=records,DEATH_EVENT~.-high_blood_pressure-smoking-platelets-diabetes,
              family = binomial(link = "logit"))
summary(my_model3)
## 
## Call:
## glm(formula = DEATH_EVENT ~ . - high_blood_pressure - smoking - 
##     platelets - diabetes, family = binomial(link = "logit"), 
##     data = records)
## 
## Coefficients:
##                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)              10.1176501  7.2122510   1.403  0.16066    
## age                       0.0543893  0.0187074   2.907  0.00364 ** 
## anaemia                   0.4637488  0.4101194   1.131  0.25815    
## creatinine_phosphokinase  0.0004687  0.0003342   1.403  0.16075    
## ejection_fraction        -0.0738926  0.0188889  -3.912 9.16e-05 ***
## serum_creatinine          0.5413446  0.1876921   2.884  0.00392 ** 
## serum_sodium             -0.0699922  0.0511068  -1.370  0.17083    
## sex                      -1.1717596  0.4515627  -2.595  0.00946 ** 
## time                     -0.0219631  0.0038254  -5.741 9.39e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 259.12  on 208  degrees of freedom
## Residual deviance: 154.39  on 200  degrees of freedom
## AIC: 172.39
## 
## Number of Fisher Scoring iterations: 6

En el resultado anterior, se puede observar que las variables significativas son:

  • age
  • ejection_fraction
  • serum_creatinine
  • sex
  • time

3.1.2.1 Comparando Los AIC

# Modelo original
my_model$aic

# Modelo con las 2 variables eliminadas
my_model2$aic

# Modelo con las 4 variables eliminadas
my_model3$aic
Modelo AIC
Modelo Original 179.2415
Modelo 2 175.6393
Modelo 3 172.3880

Al comparar el AIC del modelo original y los nuevos modelos variables eliminadas, se puede verificar que en el modelo 3 el AIC es menor que el de los otros modelos. Este AIC significa que el nuevo modelo tiene un mejor ajuste del modelo.

3.1.3 Tercera Eliminación

Ahora se procederá a eliminar otras 2 variables que tienen un mayor p-valor para poder obtener un mejor ajuste del modelo.

my_model4=glm(data=records,DEATH_EVENT~.-high_blood_pressure-smoking-platelets-diabetes-creatinine_phosphokinase-serum_sodium ,
              family = binomial(link = "logit"))
summary(my_model4)
## 
## Call:
## glm(formula = DEATH_EVENT ~ . - high_blood_pressure - smoking - 
##     platelets - diabetes - creatinine_phosphokinase - serum_sodium, 
##     family = binomial(link = "logit"), data = records)
## 
## Coefficients:
##                    Estimate Std. Error z value Pr(>|z|)    
## (Intercept)        0.708705   1.385597   0.511  0.60902    
## age                0.053327   0.017994   2.964  0.00304 ** 
## anaemia            0.401068   0.403233   0.995  0.31992    
## ejection_fraction -0.073797   0.018512  -3.986 6.71e-05 ***
## serum_creatinine   0.569549   0.176790   3.222  0.00127 ** 
## sex               -1.077485   0.441182  -2.442  0.01460 *  
## time              -0.021078   0.003659  -5.761 8.37e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 259.12  on 208  degrees of freedom
## Residual deviance: 158.21  on 202  degrees of freedom
## AIC: 172.21
## 
## Number of Fisher Scoring iterations: 5

En el resultado anterior, se puede observar que las variables significativas son:

  • age
  • ejection_fraction
  • serum_creatinine
  • sex
  • time

3.1.3.1 Comparando Los AIC

# Modelo original
my_model$aic

# Modelo con las 2 variables eliminadas
my_model2$aic

# Modelo con las 4 variables eliminadas
my_model3$aic

# Modelo con las 6 variables eliminadas
my_model4$aic
Modelo AIC
Modelo Original 179.2415
Modelo 2 175.6393
Modelo 3 172.3880
Modelo 4 172.2077

Al comparar el AIC del modelo original y los nuevos modelos variables eliminadas, se puede verificar que en el modelo 4 el AIC es menor que el de los otros modelos. Este AIC significa que el nuevo modelo tiene un mejor ajuste del modelo. Aunque comparado con el AIC de modelo 3, la diferencia solo es de -0.1803.

3.1.4 Cuarta Eliminación

Ahora se procederá a eliminar otras 2 variables que tienen un mayor p-valor para poder obtener un mejor ajuste del modelo.

my_model5=glm(data=records,DEATH_EVENT~.-high_blood_pressure-smoking-platelets-diabetes-creatinine_phosphokinase-serum_sodium-anaemia-sex-1 ,family = binomial(link = "logit"))
summary(my_model5)
## 
## Call:
## glm(formula = DEATH_EVENT ~ . - high_blood_pressure - smoking - 
##     platelets - diabetes - creatinine_phosphokinase - serum_sodium - 
##     anaemia - sex - 1, family = binomial(link = "logit"), data = records)
## 
## Coefficients:
##                    Estimate Std. Error z value Pr(>|z|)    
## age                0.047627   0.010969   4.342 1.41e-05 ***
## ejection_fraction -0.062928   0.015835  -3.974 7.07e-05 ***
## serum_creatinine   0.612431   0.178637   3.428 0.000607 ***
## time              -0.020307   0.003297  -6.159 7.31e-10 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 289.74  on 209  degrees of freedom
## Residual deviance: 165.67  on 205  degrees of freedom
## AIC: 173.67
## 
## Number of Fisher Scoring iterations: 5

Este modelo (my_model5) ha reducido significativamente el número de predictores a aquellos que son altamente significativos, proporcionando un mejor enfoque. Las variables:

  • age
  • ejection_fraction
  • serum_creatinine
  • time

permanecen como predictores significativos de la probabilidad de muerte. Es decir, todas estas variables son significativas para el modelo. Esto mejora la interpretabilidad del modelo y potencialmente su estabilidad predictiva.

3.1.4.1 Comparando Los AIC

# Modelo original
my_model$aic

# Modelo con las 2 variables eliminadas
my_model2$aic

# Modelo con las 4 variables eliminadas
my_model3$aic

# Modelo con las 6 variables eliminadas
my_model4$aic

# Modelo con las 8 variables eliminadas
my_model5$aic
Modelo AIC
Modelo Original 179.2415
Modelo 2 175.6393
Modelo 3 172.3880
Modelo 4 172.2077
Modelo 5 173.6705

Al comparar el AIC del modelo original y los nuevos modelos variables eliminadas, se puede verificar que en el modelo 4 el AIC es menor que el de los otros modelos. Sin embargo, en el modelo 4 aun se encuentran variables no significativas, mientras que en el modelo 5 todas las variables son significativas, lo que implica que todas las variables del modelo contribuyen de manera importante a la predicción del evento de interés. Por lo que se trabajará con este ultimo modelo, es decir, el modelo 5.

3.2 Interpretación De Los Coeficientes

  • age: El signo del coeficiente sugiere que a medida que aumenta la edad, la probabilidad de muerte también aumenta.

  • ejection_fraction: El signo del coeficiente sugiere que una mejor función cardíaca (mayor fracción de eyección) reduce la probabilidad de muerte.

  • serum_creatinine: El signo del coeficiente sugiere que niveles más altos de creatinina en suero (indicativo de problemas renales) aumentan la probabilidad de muerte.

  • time: El signo del coeficiente sugiere que un tiempo de seguimiento más largo se asocia con una menor probabilidad de muerte, esto podría significar que los pacientes que sobreviven más tiempo tienen un mejor pronóstico.

3.3 Prueba De Wald

La prueba de Wald se utiliza para comparar modelos anidados, es decir, un modelo completo y un modelo reducido, para verificar si la simplificación es justificable. Esta prueba evalúa si la restricción de ciertas variables (es decir, si sus coeficientes son 0) en el modelo reducido es razonable o si esas variables son necesarias para explicar la variabilidad en la variable dependiente.

library(zoo)
library(lmtest)
waldtest(my_model,my_model5)
## Wald test
## 
## Model 1: DEATH_EVENT ~ age + anaemia + creatinine_phosphokinase + diabetes + 
##     ejection_fraction + high_blood_pressure + platelets + serum_creatinine + 
##     serum_sodium + sex + smoking + time
## Model 2: DEATH_EVENT ~ (age + anaemia + creatinine_phosphokinase + diabetes + 
##     ejection_fraction + high_blood_pressure + platelets + serum_creatinine + 
##     serum_sodium + sex + smoking + time) - high_blood_pressure - 
##     smoking - platelets - diabetes - creatinine_phosphokinase - 
##     serum_sodium - anaemia - sex - 1
##   Res.Df Df      F Pr(>F)
## 1    196                 
## 2    205 -9 1.1655 0.3191

En el resultado anterior se puede observar que el \(p-valor = 0.3191\) indica que no hay suficiente evidencia estadística para rechazar la hipótesis nula de que las variables eliminadas del modelo no contribuyen significativamente a explicar la variabilidad de DEATH_EVENT. Es decir, esto significa que el modelo reducido (my_model5) no es significativamente peor que el modelo completo (my_model). Por lo tanto, es razonable utilizar el modelo reducido, ya que es menos complejo y parece retener las variables más informativas y significativas.

4 Bondad De Ajuste

Las pruebas de bondad de ajuste son medidas que evalúan la capacidad del modelo para explicar la variabilidad en los datos y si el modelo es una representación adecuada de la relación entre las variables dependientes e independientes.

La librería ResourceSelection proporciona herramientas para evaluar la bondad de ajuste de los modelos de regresión logística, incluyendo la prueba de Hosmer-Lemeshow.

4.1 Prueba De Hosme-Lomeshow

Esta prueba evalúa la bondad de ajuste de un modelo de regresión logística. Compara los valores observados con los valores predichos por el modelo, agrupando los datos en deciles de riesgo.

library(ResourceSelection)
hoslem.test(records$DEATH_EVENT,fitted(my_model5))
## 
##  Hosmer and Lemeshow goodness of fit (GOF) test
## 
## data:  records$DEATH_EVENT, fitted(my_model5)
## X-squared = 8.2596, df = 8, p-value = 0.4085

La prueba de Hosmer-Lemeshow se utiliza para evaluar si hay una discrepancia significativa entre los valores observados y los predichos por el modelo. Un p-valor alto (generalmente mayor a 0.05) indica que no hay suficiente evidencia para rechazar la hipótesis nula de que el modelo tiene un buen ajuste. En este caso, con un p-valor de 0.4085, no hay indicios de un mal ajuste, lo que sugiere que el modelo my_model5 se ajusta adecuadamente a los datos.

5 Coeficientes Del Modelo

Dado que ya se verifico la significancia de las variables y se comprobo el ajuste del modelo, se puede proceder a la extracción de los coeficientes formales del modelo. Estos coeficientes ayudan a entender cómo cada variable afecta la probabilidad de ocurrencia del evento de interés (muerte del paciente en este caso). La dirección y magnitud de los coeficientes indican el tipo y la fuerza de la relación entre cada predictor y la variable de respuesta.

coef(my_model5)
Coeficientes
age 0.0476267
ejection_fraction -0.0629279
serum_creatinine 0.6124310
time -0.0203075

5.1 Interpretación De Los Coeficientes

  • age (0.0476): Un incremento de un año en la edad se asocia con un aumento del 4.76% en el logaritmo de las probabilidades de DEATH_EVENT.

  • ejection_fraction (-0.0629): Por cada punto porcentual de incremento en la fracción de eyección, el logaritmo de las probabilidades de DEATH_EVENT disminuye en 6.29%.

  • serum_creatinine (0.6124): Un incremento de una unidad en los niveles de creatinina en suero se asocia con un aumento del 61.24% en el logaritmo de las probabilidades de DEATH_EVENT.

  • time (-0.0203): Por cada día adicional, el logaritmo de las probabilidades de DEATH_EVENT disminuye en 2.03%.

Otra forma de obtener estos coeficientes es por medio del siguiente código:

my_model5$coefficients
Coeficientes
age 0.0476267
ejection_fraction -0.0629279
serum_creatinine 0.6124310
time -0.0203075

Se puede observar que es el mismo resultado que con el código anterior.

5.2 Variabilidad De Coeficientes

Para poder conocer la variabilidad estimada en estos coeficientes se deben obtener los intervalos de confianza para cada variable:

confint(my_model5)
2.5 % 97.5 %
age 0.0271278 0.0705157
ejection_fraction -0.0957236 -0.0333428
serum_creatinine 0.2675514 0.9885516
time -0.0273168 -0.0143120

Como los intervalos anteriores no contienen el valor cero, esto indica que las variables tiene un efecto estadísticamente significativo en el modelo. Además, de acuerdo con los resultados se puede decir que el valor de los coeficientes esta dentro de los intervalos obtenidos, con un 95% de confianza.

6 Pronosticos

Las predicciones son los valores estimados para la variable dependiente o de respuesta basados en los valores de las variables independientes o predictoras.

Las predicciones que se utilizarán se obtendrán en la escala de probabilidad, es decir, las probabilidades predichas de que ocurra el evento (muerte) para cada observación en los datos.

y=predict(my_model5,type='response')
y
##         166         231          70         192         251         102 
## 0.395337332 0.100403958 0.782907081 0.034144461 0.028029152 0.424621188 
##         110         103          23         146         123         188 
## 0.259192557 0.758388640 0.765159807 0.205505369 0.268245654 0.284474942 
##         125          26         164         101         159         240 
## 0.658578649 0.892393393 0.138394211 0.605745862 0.318827534 0.022433962 
##          68         133          73         191         274         171 
## 0.759213560 0.144733928 0.730288932 0.345307371 0.006284166 0.141918277 
##         242         297         198         278          79         162 
## 0.091030220 0.001125953 0.111120945 0.032947115 0.511360771 0.116445356 
##         150         114          88          17         230         148 
## 0.244337847 0.186439489 0.142548706 0.882792890 0.166200267 0.082422799 
##          67         130         169         121         201         155 
## 0.630084525 0.567515754 0.160839958 0.126902100 0.039934661 0.258517279 
##         293         126         207         210         279          19 
## 0.010544370 0.093459443 0.019462792 0.040066777 0.016734066 0.887802844 
##          16         236         226         284         127         106 
## 0.784343438 0.045229512 0.029048934 0.024157346 0.593008011 0.688981827 
##          44          22          38         120          27         245 
## 0.556017419 0.855899307 0.681832007 0.710163515 0.894019698 0.045541110 
##          13          33         174         149         115          89 
## 0.669440978 0.555441613 0.205516540 0.624847107 0.315922634 0.168383525 
##          95         173          75         137         291         214 
## 0.291992370 0.061052966 0.782476760 0.090986708 0.002359596 0.073019672 
##         285          94          46         176           7          29 
## 0.008812797 0.659333870 0.608957966 0.036596226 0.959298131 0.967554059 
##         129         147         109         113         227         256 
## 0.339419859 0.221494096 0.376563903 0.490090614 0.101769551 0.039725469 
##         259         235         218         253         138         275 
## 0.026319711 0.020270242 0.425192989 0.014714604 0.680988745 0.032510885 
##          65         289          37         276         157          80 
## 0.030836646 0.025786636 0.758269882 0.008719470 0.213261305 0.237968571 
##         197         187         220          76          58         205 
## 0.036184536 0.020026246 0.040899673 0.633045075 0.404040780 0.102382882 
##         223          64         172          57         139         263 
## 0.026332184 0.335013147 0.079130007 0.844007734 0.303561812 0.083761035 
##         225          20         151          45           1         143 
## 0.086160350 0.421664523 0.448455981 0.286071315 0.967574113 0.237067347 
##         117         258         219         209         228         132 
## 0.083304779 0.024430386 0.091891616 0.054962390 0.040937434 0.830444338 
##         239         249          85         272          39         128 
## 0.044213115 0.017450683 0.565921143 0.011074388 0.854349946 0.066897466 
##         141         165         112         193         158         136 
## 0.469796577 0.155694064 0.337208199 0.036937801 0.265743863 0.402432254 
##         215          71         202         267         262          53 
## 0.071994962 0.189174633 0.008185057 0.082229261 0.020488416 0.904424693 
##         177          43         287          77         118          69 
## 0.167473913 0.638044435 0.032907162 0.189293127 0.580171199 0.760477293 
##          48         232         222         156         252         260 
## 0.505375720 0.081744096 0.031114435 0.472189689 0.030496720 0.007506146 
##         216         244          14         108         264         189 
## 0.131299292 0.056536818 0.608346786 0.214983764 0.008684507 0.075285552 
##         154          93         175         277         281         269 
## 0.180190295 0.061925716 0.179396727 0.040300421 0.026942039 0.009453343 
##         255          41          83          49         211          84 
## 0.006658840 0.928676190 0.777612889 0.988034265 0.280642932 0.533577040 
##         134          24         160         163          56         145 
## 0.104151261 0.230006195 0.141206330 0.187969008 0.945121432 0.655415823 
##         208          63         105          74         243         229 
## 0.169483091 0.468098441 0.343677511 0.328134597 0.019285768 0.594126598 
##         282          11          32         182         196         107 
## 0.068718354 0.968549768 0.923097769 0.232025677 0.152198121 0.230909790 
##         194         237         206          72         119           8 
## 0.206892447 0.041289750 0.025693645 0.418053795 0.115306305 0.389962353 
##         204         296         180           9          28          50 
## 0.408642548 0.010558667 0.079136308 0.430698001 0.683581841 0.642539655 
##         299          31         233          82         292         153 
## 0.005177953 0.934508416 0.018155176 0.315160545 0.023504159 0.091495439 
##         221          15          81          92         111 
## 0.335829566 0.693091861 0.582933699 0.271640102 0.305730548

Ahora se debe convertir la variable y en una variable binaria a la que se llamará pred, donde los valores mayores a 0.5 se convertirán en 1 y los valores iguales o menores a 0.5 se convertirán en 0. Este umbral de 0.5 se utiliza para clasificar las probabilidades en predicciones finales de 0 o 1.

pred=ifelse(as.double(y)>0.5,1,0)
pred
##   [1] 0 0 1 0 0 0 0 1 1 0 0 0 1 1 0 1 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1
##  [38] 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 1 0 0 0 0 1
##  [75] 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0
## [112] 0 1 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 0
## [149] 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 1 1 0 0
## [186] 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 1 0 0

La salida anterior muestra las clasificaciones finales para cada observación, donde 1 indica que el modelo predice que DEATH_EVENT es 1 (muerte) y 0 indica que predice que DEATH_EVENT es 0 (no muerte). Para poder realizar una mejor comparación entre las probabilidades y las clasificaciones binarias se usará la siguiente tabla:

data.frame(y=y,pred=pred)
y pred
166 0.3953373 0
231 0.1004040 0
70 0.7829071 1
192 0.0341445 0
251 0.0280292 0
102 0.4246212 0
110 0.2591926 0
103 0.7583886 1
23 0.7651598 1
146 0.2055054 0
123 0.2682457 0
188 0.2844749 0
125 0.6585786 1
26 0.8923934 1
164 0.1383942 0
101 0.6057459 1
159 0.3188275 0
240 0.0224340 0
68 0.7592136 1
133 0.1447339 0
73 0.7302889 1
191 0.3453074 0
274 0.0062842 0
171 0.1419183 0
242 0.0910302 0
297 0.0011260 0
198 0.1111209 0
278 0.0329471 0
79 0.5113608 1
162 0.1164454 0
150 0.2443378 0
114 0.1864395 0
88 0.1425487 0
17 0.8827929 1
230 0.1662003 0
148 0.0824228 0
67 0.6300845 1
130 0.5675158 1
169 0.1608400 0
121 0.1269021 0
201 0.0399347 0
155 0.2585173 0
293 0.0105444 0
126 0.0934594 0
207 0.0194628 0
210 0.0400668 0
279 0.0167341 0
19 0.8878028 1
16 0.7843434 1
236 0.0452295 0
226 0.0290489 0
284 0.0241573 0
127 0.5930080 1
106 0.6889818 1
44 0.5560174 1
22 0.8558993 1
38 0.6818320 1
120 0.7101635 1
27 0.8940197 1
245 0.0455411 0
13 0.6694410 1
33 0.5554416 1
174 0.2055165 0
149 0.6248471 1
115 0.3159226 0
89 0.1683835 0
95 0.2919924 0
173 0.0610530 0
75 0.7824768 1
137 0.0909867 0
291 0.0023596 0
214 0.0730197 0
285 0.0088128 0
94 0.6593339 1
46 0.6089580 1
176 0.0365962 0
7 0.9592981 1
29 0.9675541 1
129 0.3394199 0
147 0.2214941 0
109 0.3765639 0
113 0.4900906 0
227 0.1017696 0
256 0.0397255 0
259 0.0263197 0
235 0.0202702 0
218 0.4251930 0
253 0.0147146 0
138 0.6809887 1
275 0.0325109 0
65 0.0308366 0
289 0.0257866 0
37 0.7582699 1
276 0.0087195 0
157 0.2132613 0
80 0.2379686 0
197 0.0361845 0
187 0.0200262 0
220 0.0408997 0
76 0.6330451 1
58 0.4040408 0
205 0.1023829 0
223 0.0263322 0
64 0.3350131 0
172 0.0791300 0
57 0.8440077 1
139 0.3035618 0
263 0.0837610 0
225 0.0861604 0
20 0.4216645 0
151 0.4484560 0
45 0.2860713 0
1 0.9675741 1
143 0.2370673 0
117 0.0833048 0
258 0.0244304 0
219 0.0918916 0
209 0.0549624 0
228 0.0409374 0
132 0.8304443 1
239 0.0442131 0
249 0.0174507 0
85 0.5659211 1
272 0.0110744 0
39 0.8543499 1
128 0.0668975 0
141 0.4697966 0
165 0.1556941 0
112 0.3372082 0
193 0.0369378 0
158 0.2657439 0
136 0.4024323 0
215 0.0719950 0
71 0.1891746 0
202 0.0081851 0
267 0.0822293 0
262 0.0204884 0
53 0.9044247 1
177 0.1674739 0
43 0.6380444 1
287 0.0329072 0
77 0.1892931 0
118 0.5801712 1
69 0.7604773 1
48 0.5053757 1
232 0.0817441 0
222 0.0311144 0
156 0.4721897 0
252 0.0304967 0
260 0.0075061 0
216 0.1312993 0
244 0.0565368 0
14 0.6083468 1
108 0.2149838 0
264 0.0086845 0
189 0.0752856 0
154 0.1801903 0
93 0.0619257 0
175 0.1793967 0
277 0.0403004 0
281 0.0269420 0
269 0.0094533 0
255 0.0066588 0
41 0.9286762 1
83 0.7776129 1
49 0.9880343 1
211 0.2806429 0
84 0.5335770 1
134 0.1041513 0
24 0.2300062 0
160 0.1412063 0
163 0.1879690 0
56 0.9451214 1
145 0.6554158 1
208 0.1694831 0
63 0.4680984 0
105 0.3436775 0
74 0.3281346 0
243 0.0192858 0
229 0.5941266 1
282 0.0687184 0
11 0.9685498 1
32 0.9230978 1
182 0.2320257 0
196 0.1521981 0
107 0.2309098 0
194 0.2068924 0
237 0.0412897 0
206 0.0256936 0
72 0.4180538 0
119 0.1153063 0
8 0.3899624 0
204 0.4086425 0
296 0.0105587 0
180 0.0791363 0
9 0.4306980 0
28 0.6835818 1
50 0.6425397 1
299 0.0051780 0
31 0.9345084 1
233 0.0181552 0
82 0.3151605 0
292 0.0235042 0
153 0.0914954 0
221 0.3358296 0
15 0.6930919 1
81 0.5829337 1
92 0.2716401 0
111 0.3057305 0

6.1 Prueba De Predicción

La prueba se realizará con los siguientes datos:

nd=data.frame(age=50.0,ejection_fraction=35.0,serum_creatinine=0.75,time=6)
nd
age ejection_fraction serum_creatinine time
50 35 0.75 6

Para garantizar que la prueba que se llevará acabo sea de forma correcta, se deben excluir del modelo las variables no significativas de la siguiente forma:

# Eliminar variables no deseadas del data frame original
var_para_predicciones <- records[, !(names(records) %in% c("anaemia", "high_blood_pressure", "smoking", "platelets", "diabetes", "creatinine_phosphokinase", "serum_sodium", "sex"))]

# Ajustar el modelo sin las variables eliminadas
my_model_final <- glm(data = var_para_predicciones, DEATH_EVENT ~ .-1, family = binomial(link = "logit"))
summary(my_model_final)
## 
## Call:
## glm(formula = DEATH_EVENT ~ . - 1, family = binomial(link = "logit"), 
##     data = var_para_predicciones)
## 
## Coefficients:
##                    Estimate Std. Error z value Pr(>|z|)    
## age                0.047627   0.010969   4.342 1.41e-05 ***
## ejection_fraction -0.062928   0.015835  -3.974 7.07e-05 ***
## serum_creatinine   0.612431   0.178637   3.428 0.000607 ***
## time              -0.020307   0.003297  -6.159 7.31e-10 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 289.74  on 209  degrees of freedom
## Residual deviance: 165.67  on 205  degrees of freedom
## AIC: 173.67
## 
## Number of Fisher Scoring iterations: 5

Se puede observar que el modelo es el mismo que el my_model5, por lo que no se esta alterando nada. Ahora se puede proceder a realizar la predición:

predict(my_model_final, newdata = nd)
##         1 
## 0.5163384

La predicción obtenida indica que, según el modelo, el individuo con las características especificadas en nd tiene una probabilidad del 51.6% de experimentar el evento DEATH_EVENT (muerte del paciente). Este resultado puede ser utilizado en el contexto de análisis de riesgo o para informar decisiones médicas, siempre considerando la precisión y las limitaciones del modelo.

6.2 Evaluación De Precisión Del Modelo

Ahora se va evalúar la precisión de un modelo de regresión logística utilizando dos conjuntos de predicciones y luego se comparan estas precisiones con el valor real del evento de muerte (DEATH_EVENT).

library(MLmetrics)
Accuracy(pred,records$DEATH_EVENT)
## [1] 0.8277512

La precisión calculada para pred es 0.8277512, lo que significa que el modelo clasificó correctamente el 82.8% de los casos.

Se asignará a pred2 las clasificaciones según las probabilidades de las predicciones:

pred2=ifelse(my_model$fitted.values>0.5,1,0)
pred2
## 166 231  70 192 251 102 110 103  23 146 123 188 125  26 164 101 159 240  68 133 
##   1   0   1   0   0   0   0   1   1   0   0   0   1   1   1   0   0   0   1   0 
##  73 191 274 171 242 297 198 278  79 162 150 114  88  17 230 148  67 130 169 121 
##   1   0   0   0   0   0   0   0   1   0   0   0   0   1   0   0   1   0   0   0 
## 201 155 293 126 207 210 279  19  16 236 226 284 127 106  44  22  38 120  27 245 
##   0   0   0   0   0   0   0   1   1   0   0   0   1   1   0   1   1   1   1   0 
##  13  33 174 149 115  89  95 173  75 137 291 214 285  94  46 176   7  29 129 147 
##   1   1   0   1   0   0   0   0   1   0   0   0   0   1   1   0   1   1   0   0 
## 109 113 227 256 259 235 218 253 138 275  65 289  37 276 157  80 197 187 220  76 
##   0   0   0   0   0   0   0   0   1   0   0   0   1   0   0   0   0   0   0   1 
##  58 205 223  64 172  57 139 263 225  20 151  45   1 143 117 258 219 209 228 132 
##   0   0   0   0   0   1   0   0   0   1   1   0   1   0   0   0   0   0   0   1 
## 239 249  85 272  39 128 141 165 112 193 158 136 215  71 202 267 262  53 177  43 
##   0   0   1   0   1   0   0   0   0   0   0   0   0   0   0   0   0   1   0   1 
## 287  77 118  69  48 232 222 156 252 260 216 244  14 108 264 189 154  93 175 277 
##   0   0   1   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0 
## 281 269 255  41  83  49 211  84 134  24 160 163  56 145 208  63 105  74 243 229 
##   0   0   0   1   1   1   0   0   0   0   0   0   1   1   0   0   0   0   0   1 
## 282  11  32 182 196 107 194 237 206  72 119   8 204 296 180   9  28  50 299  31 
##   0   1   1   0   0   0   0   0   0   0   0   0   0   0   0   0   1   1   0   1 
## 233  82 292 153 221  15  81  92 111 
##   0   0   0   0   0   1   1   0   0

Volviendo a evaluar la precisión del modelo:

Accuracy(pred2,records$DEATH_EVENT)
## [1] 0.8564593

La precisión para pred2 es 0.8564593, lo que indica que el modelo clasificó correctamente el 85.6% de los casos con este nuevo conjunto de predicciones.

El aumento en precisión al cambiar de pred a pred2 sugiere una mejora en la capacidad del modelo para hacer predicciones correctas.