Primeramente se recomiendacon el uso de los paquetes y librerias a utilizar.
NOTA.
En el contenido a continuación, define los pasos para la elaboración de un modelo de Regreción Logística Binaria Multiple, conociendo que cada uno de los códigos tienen su propia interpretación respecto a la estructura de R. Por lo cosiguiente se sugiere acgualizar los paquetes de R y acontinuación las librerias.
Posterior a esto procedemos a importar nuestra base de datos
Rows: 299 Columns: 13
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
dbl (13): age, anaemia, creatinine_phosphokinase, diabetes, ejection_fractio...
ℹ 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.
Con la siguiente función podemos, obtener una visualisación del contenido y podemos asegurarnos que los datos son un data frame. Este código realiza varias operaciones relacionads con la inspección y la conversión de un objeto el cual hemos llamado “misdatos”. Te explico:
View(misdatos) : Esta función abre una ventana en donde puedes observar una presentación tabular(la información se dispone en filas y columnas).
misdatos=as.data.frame(misdatos): Esta línea trasforma a “misdatos” en un data frame si no lo es aun.
La función as.data.frame toma un objeto y lo convierte en un data frame, que es una estructura de datos muy utilizada en R para guardar datos en forma de tabla (filas y columnas).
str(misdatos): Esta función nos presenta la estructura interna del objeto misdatos; nos facilita un resumen sólido de su tipo, las dimensiones, y una vista previa de los datos almacenados.
Al utilizar el head nos proporcionará una forma mas rapida de obtener una vista previa de las primeras filas del data frame, y asi obtenemos una muestra representativa del inicio poder comprender su estructura y contenido inicial. Tambien si quieres ver mas filas lo puedes hacer como un segundo argumento utilizando “head(misdatos,15)”, esto dara la pauta y podras vizualizar las primeras 15 filas.
Tenemos la función set.seed est fija lo que es la semilla que es la que genera los números aleatorios a un valor especifico, en este caso seria, 2021. Cuando fijamos la semilla esta te garantiza que cualquier operación que contenga crear números aleatorios, crera los mismos resultados cada vez que ejecute el código.
set.seed(2021)
Cuando utilizamos n=nrow cuenta el número de filas de misdatos y los almacena en la variable n, luego los imprime y asi puedes visualizar cuatas filas tiene tu data frame.
n=nrow(misdatos)n
[1] 299
Y Por lo que puedes observar, dice que tenemos 299 filas.
Con el siguiente codigo costruye una muestra aleatoria de tamaño “n” de indices de fila de “misdatos” toma un aproximado de un 70% de las filas del data frame y los almacenara en la variable d_ind.
d_ind=sample(n,n*0.70) #0.7*299
El codigo records crea un nuevo data frame que contiene las filas seleccionadas aleatoriamente llamado “conjunto de entrenamiento”, tambien se puede utilizar para realizar análisis exploratorios y ajustar modelos. Y el “d_ind”, es una lista de indices que representan aproximadamente el 70% de las filas de “misdatos”, lo cual son seleccionados aleatoriamente; El resultado se asigna a la variable “records”.
records=misdatos[d_ind,] #training
Ahora bien al utilizar este codigo vamos a obtener un nuevo data frame pero con la diferencia del anterior, aca obtendremos las filas no selecionadas aleatoriamente, es decir que es el 30% restante, por lo que a este subconjunto de datos es llamado “conjunto de prueba”, este se puede utilizar para evaluar el rendimiento de los modelos ajustados junto con el “conjunto de entrenamiento” (records).
d_test=misdatos[-d_ind,] #test
Aca tenemos la función names es utilizada para alcanzar o crear un vector de caracteres que contiene los nombres de las columnas de un data frame. Lo podemos visualizar a continiación.
El codigo acontinuación se utiliza para ajustar un modelo, primero cargamos el paquete MASS, la contiene funciones y conjuntos de datos para lo que es análisis estadísticos.
Luego glm Esta funcion ajusta un modelo lineal generalizado.
data=records este especifica los datos a utilizar estan en el data frame “records”.
DEATH_EVENT Esta es la variable respuesta y todas las demas variables en “records” solo son predictoras.
family = binomial(): Explica como se ajusta un modelo de regresión logística, ya que DEATH_EVENT es una variable binaria (0 o 1).
summary Nos da un resumen detallado del modelo, incluyendo coeficientes y estadísticas de significancia.
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
Ahora cargaremos la libreria cardataesta cntiene conjuntos de datos que se utilizan para demosraciones y ejemplos en estadística y análisis de datos. y la libreria car esta proporciona varias funciones para análisis estadísticos avanzados y gráficos, Pero especialmente para el análisis de regresión y mejorar el modelo.
library(carData)library(car)
vif es factor de inflacion de la varianza para detectar multicolinealidad.
Con el código vif(my_model) podemos calcula y devuelve los Factores de Inflación de la Varianza para cada una de las variables independientes en el modelo my_model, ayudando así a diagnosticar problemas de multicolinealidad que podrían afectar la interpretación y la estabilidad del modelo de regresión.
vif(my_model)
age anaemia creatinine_phosphokinase
1.129135 1.046886 1.150944
diabetes ejection_fraction high_blood_pressure
1.077959 1.220016 1.076420
platelets serum_creatinine serum_sodium
1.059796 1.116415 1.096600
sex smoking time
1.624757 1.451073 1.269458
Quitar dos variables con el mayor p-valor.
Con el siguiente código podremos observar como ajusta un nuevo modelo de regresion logística, en donde excluye las variables high_blood_pressure y smoking del conjunto de predictores, posteriormente proporciona un resumen del modelo ajustado.
glm: Esta función ajusta un modelo lineal generalizado.
data = records: Especifica que los datos a utilizar están en el data frame records.
DEATH_EVENT ~ . - high_blood_pressure - smoking: Esta fórmula indica que “DEATH_EVENT” es la variable de respuesta y que todas las demás variables en records se utilizan como predictores, excepto high_blood_pressure y smoking (que se excluyen con el operador -).
family = binomial(link = “logit”): Especifica que se ajusta un modelo de regresión logística con la función de enlace logit (la opción por defecto para regresión logística).
summary La cuál nos propporciona un resumen del modelo ajustado,donde engloba estadísticos como coeficientes de regresión, errores estándar, valores z, valores p, y medidas de ajuste del modelo.
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
Este procedimiento nos sirve para poder evaluar como efectua la exclución de ciertas variables y asu vez de como afecta al modelo y su capacidad de predicción.
En R. podemos acceder al valor del criterio Akaike (AIC) de un modelo ajustado empleando $aic en lo que es el objeto del modelo. El AIC es una medida que se utiliza para evaluar la calidad de un modelo estadístico para un conjunto de datos y penaliza la complejidad del modelo para evitar el sobreajuste. Fue desarrollado por el estadístico japonés Hirotugu Akaike.
Su fórmula AIC:
AIC = 2k - 2ln(L) donde:
k es el número de parámetros del modelo.
L es el valor de la función de verosimilitud del modelo ajustado.
Con este codigo se puede acceder al valor del criterio de información de Akaike(AIC) de un modelo ajustado utilizando “$aic” en el objeto del modelo.
my_model2$aic: Este código extrae el valor del AIC del modelo dado.
Ejemplo: “my_model2$aic” el resultado obtenido nos indica que criterio de información de Akaike (AIC)para el modelo “my_model2” es 175.6393, por lo que representa una medida de la calidad del model en terminos de su ajuste alos datos y su complejidad.
my_model2$aic
[1] 175.6393
Interpretación del AIC:
Menor es mejor: Un valor de AIC más bajo indica un modelo que se ajusta mejor a los datos con menos complejidad.
Comparación de modelos: El AIC solo es útil para comparar modelos ajustados a los mismos datos. El modelo con el AIC más bajo es preferible.
Penalización por complejidad: El AIC penaliza los modelos con más parámetros para evitar el sobreajuste, donde un modelo demasiado complejo ajusta bien los datos de entrenamiento pero no generaliza bien a nuevos datos.
Quitamos de nuevo dos variables con el mayor p-valor
Nuevamente utilizaremos el siguiente código para quitar otras dos variables que se ajustara un nuevo modelo de regresión logística excluyendo las variables high_blood_pressure, smoking, platelets, y diabetes, del conjunto de predictores, luego proporcionará un resumen del modelo ajustado.
Este procedimiento de ajuste y resumen del modelo nos permitirá poder evaluar el efecto de cada predictor en la variable de respuesta DEATH_EVENT y así poder compararla con la calidad del modelo con otros modelos posibles.
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
El código my_model3$aic se utiliza para extraer y mostrar el valor del criterio de información Akaike (AIC)del modelo de regreción logística “my_model13”,por lo que te permite evaluar la calidad del modelo y asi poder compararlo con otros modelos utilizando AIC
my_model3$aic
[1] 172.388
El siguiente código se utiliza para extraer y mostrar el valor del criterio de información de Akaike (AIC) del modelo de regresión logística
my_model$aic
[1] 179.2415
El código acontinuación, ajusta un nuevo modelo de regresión logística (my_model4) excluyendo las variables high_blood_pressure, smoking, platelets, diabetes, creatinine_phosphokinase, y serum_sodium del conjunto de predictores. Luego, hace un resumen detallado del modelo ajustado,
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
Acontinuacion tenemos el siguiente código lo cuál ajusta un nuevo modelo de regresión logística “my_model15”, excluyendo las siguietes variables “high_blood_pressure”, “smoking”, “platelets”, “diabetes”, “creatinine_phosphokinase”, “serum_sodium”, “anaemia”, y “sex”, del conjuto de predictores, además del término -1 lo que significa es que elimina el intercepto y posteriormente provee un resumen del modelo ajustado.
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
Utilizaremos la libreria zoo en R se utiliza para trabajar con series temporales irregulares y objetos indexados por fecha. Por loque ejecuta una infraestrutura para manipular y analizar los datos de la serie temporal, la incluye nterpolación, agregación y alineación de series temporales.
library(zoo)
Attaching package: 'zoo'
The following objects are masked from 'package:base':
as.Date, as.Date.numeric
Tambien agragaremos la libreria lmtest la cual se utiliza para realizar pruebas estadísticas y diagnósticos en modelos de regresión. Esta librería proporciona una variedad de pruebas para poder evaluar los supuestos y la validez de los modelos de regresión, incluyendo pruebas de heterocedasticidad, autocorrelación, multicolinealidad, entre otras.
library(lmtest)
La función waldtest() en la librería lmtest se utiliza para comparar dos modelos de regresión para poder determinar si la inclusión de un conjunto adicional de variables mejora significativamente el ajuste del modelo. Esto ayuda a poder tomar una decisión si la complejidad adicional del modelo más completo está justificada por una mejora significativa en el ajuste.
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
Específicamente, realiza una prueba de Wald para comparar la calidad de ajuste entre un modelo restringido (menos complejo) y un modelo no restringido (más complejo).
Bondad de Ajuste
La librería ResourceSelection se utiliza para evaluar la bondad de ajuste de modelos de regresión logística, exclusivamente para realizar pruebas de especificación del modelo y para diagnosticar problemas en modelos de regresión, con la función más destacada siendo el test de Hosmer-Lemeshow.
library(ResourceSelection)
Warning: package 'ResourceSelection' was built under R version 4.3.3
ResourceSelection 0.3-6 2023-06-27
Ahora bien la función hoslem.test() de la librería “ResourceSelection” se utiliza para realizar el test de Hosmer-Lemeshow, que evalúa la bondad de ajuste de un modelo de regresión logística comparando las predicciones del modelo con las observaciones reales en grupos de datos. Poer lo que te permite determinar si el modelo está ajustando adecuadamente los datos.
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 función coef() esta se ocupa de extraer los coeficientes del modelo ajustado. Cuando aplicas coef() a un modelo de regresión, como un modelo de regresión logística, devuelve los coeficientes estimados para cada predictor en el modelo, los cuales son fundamentales para interpretar el impacto de cada predictor en el resultado del modelo.
coef(my_model5)
age ejection_fraction serum_creatinine time
0.04762671 -0.06292788 0.61243102 -0.02030746
La expresión my_model5$coefficients Esta es otra manera de aprobar los coeficientes del modelo de regresión ajustado. Esta es una forma directa de obtener los coeficientes del modelo desde el objeto my_model5.
my_model5$coefficients
age ejection_fraction serum_creatinine time
0.04762671 -0.06292788 0.61243102 -0.02030746
La función confint() se utiliza para calcular los intervalos de confianza de dicos coeficientes de un modelo ajustado. Estos intervalos proporcionan un rango dentro del cual se espera que el verdadero valor del coeficiente se encuentre con un cierto nivel de confianza (generalmente del 95%).
confint(my_model5)
Waiting for profiling to be done...
2.5 % 97.5 %
age 0.02712785 0.07051571
ejection_fraction -0.09572358 -0.03334280
serum_creatinine 0.26755137 0.98855160
time -0.02731683 -0.01431199
Pronósticos
La función predict() hace predicciones con un modelo ajustado. Cuando usas type = “response”, la función predict() devuelve las probabilidades predichas para el modelo de regresión logística en lugar de los valores en el espacio de la escala lineal. Estos valores reflejan la probabilidad estimada de que ocurra el evento para cada observación en el conjunto de datos, permitiendo una evaluación más detallada del modelo ajustado.
Este código pred = ifelse(as.double(y) > 0.5, 1, 0) convertira las probabilidades predichas en valores binarios (0 o 1), basándose en un acceso de probabilidad. En este caso, el acceso es 0.5, lo que significa que las probabilidades superiores a 0.5 se clasifican como 1 (evento positivo), y las probabilidades inferiores o iguales a 0.5 se clasifican como 0 (evento negativo).
Usando el código data.frame(y = y, pred = pred) crea un data frame que combina dos vectores: y y pred. Esto te permite ver las probabilidades predichas y las predicciones binarias correspondientes en un formato tabular. Esto es útil para visualizar y analizar cómo las probabilidades se traducen en predicciones, y asi poder evaluar el rendimiento del modelo.
El siguiente código nd = data.frame(age = 50.0, ejection_fraction = 35.0, serum_creatinine = 0.75, time = 67) construye un data frame con valores para nuevas observaciones. Este data frame es útil para realizar predicciones con un modelo ajustado, proporcionando una forma de poder ingresar datos nuevos y obtener predicciones basadas dicho modelo.
age ejection_fraction serum_creatinine time
1 50 35 0.75 67
Con el siguiente código predict(my_model5, newdata = nd) podemos efectuar una predicción con un nuevo conjunto de datos (nd) utilizando el modelo de regresión logística ajustado (my_model5). devolviendo asi una probabilidad predicha para el evento de interés.
#predict(my_model5, newdata = nd)
Para limpiar el entorno de trabajo eliminando todos los objetos actuales. Esto significa que todos los data frames, vectores, listas y otros objetos almacenados en el entorno serán eliminados, dejando un entorno vacío, utilizando el sigiente código.
Por lo que si intentas usar un objeto después de ejecutar este código, como records, recibirás un error indicando que el objeto no existe. Esto es útil para asegurar un entorno limpio antes de comenzar nuevas tareas en R.
Utilizando el comando head(records) te mostrará las primeras filas de un data frame en R.
Al cargar la libreria MLmetrics, este proporcionará las funciones para evaluar el rendimiento de modelos de machine learning utilizando métricas comunes.
library(MLmetrics)
Warning: package 'MLmetrics' was built under R version 4.3.3
Attaching package: 'MLmetrics'
The following object is masked from 'package:base':
Recall
El comando **Accuracy(pred, recordsDEATH_EVENT)** calcula la precisión del modelo comparando las predicciones "pred", con las etiquetas verdaderas "recordsDEATH_EVENT”. La precisión mide qué porcentaje de las predicciones fueron correctas. Este comando utiliza la libreria “MLmetrics”.
Accuracy(pred,records$DEATH_EVENT)
[1] 0.8277512
El siguiente código pred2 = ifelse(my_model$fitted.values > 0.5, 1, 0) se usa para convertir las probabilidades predichas en predicciones binarias, basándose en un acceso de 0.5. Este acceso es común utilizarlo en modelos de clasificación binaria, como la regresión logística.
El siguiente comando Accuracy(pred2, records$DEATH_EVENT) se utiliza para calcular la precisión del modelo de clasificación utilizando la biblioteca “MLmetrics”. La precisión (accuracy) mide la proporción de predicciones correctas entre las predicciones totales realizadas. La precisión muestra qué porcentaje de las predicciones fueron correctas, proporcionando una medida general del rendimiento del modelo en términos de clasificación.