CLASE 8. Regresión Logística en R

Autor/a

Gerson Rivera

Fecha de publicación

19 julio 2024

Leer base de datos

Para este proceso se recomienda el uso de la librería readr.

NOTA.

Se sugiere actualizar los paquetes de R y además previo a utilizar las librerías, verifique la compatibilidad entre la versión del paquete y del software.

Posterior a la instalación de la librería, se procede a almacenar la base en datos\_rl, que significa \textit{datos asociados a regresión logística}. Finalmente se muestran los datos en una ventana externa con View() o en el documento con head().

library(readr)
library(lattice)
library(ggplot2)
library(caret)
datos_rl<-read_csv("https://raw.githubusercontent.com/Statology/Python-Guides/main/default.csv",col_types = cols(default=col_integer(),student=col_integer()))
View(datos_rl)
head(datos_rl,3)
# A tibble: 3 × 4
  default student balance income
    <int>   <int>   <dbl>  <dbl>
1       0       0    730. 44362.
2       0       1    817. 12106.
3       0       0   1074. 31767.

Se verifica el formato de la base de datos:

class(datos_rl)
[1] "spec_tbl_df" "tbl_df"      "tbl"         "data.frame" 

Se transforma en un data.frame y se verifica dicha tranformación, mostrando la estructura de la transformación con str()

Tdatos_rl=as.data.frame(datos_rl)
class(Tdatos_rl)
[1] "data.frame"
str(Tdatos_rl)
'data.frame':   10000 obs. of  4 variables:
 $ default: int  0 0 0 0 0 0 0 0 0 0 ...
 $ student: int  0 1 0 0 0 1 0 1 0 0 ...
 $ balance: num  730 817 1074 529 786 ...
 $ income : num  44362 12106 31767 35704 38463 ...

Se convierten las variables default y student definidas como int, en factores (variables cualitativas categóricas) para que el software reconozca la variable en regresión logística.

Tdatos_rl$default=as.factor(Tdatos_rl$default)
Tdatos_rl$student=as.factor(Tdatos_rl$student)

Se comprueba la conversión de las variables, definidas anteriormente.

head(Tdatos_rl$default)
[1] 0 0 0 0 0 0
Levels: 0 1
head(Tdatos_rl$student)
[1] 0 1 0 0 0 1
Levels: 0 1

Aplicación del modelo

para aplicar el modelo, activamos las librerías ggplot2() y caret(); posteriormente habilitamos la semilla aleatoria y completamos con la partición de la base en:

  • Entrenamiento, que le llamamos train.id (contiene el 70\% de los datos)
  • Prueba (test), el cual R lo reconoce como complemento de train.id, es decir será -train.id (contiene el 30\% de los datos)
set.seed(2024)
train.id <- createDataPartition(Tdatos_rl$default,p=0.7,list=F)
head(train.id)
     Resample1
[1,]         3
[2,]         4
[3,]         5
[4,]         6
[5,]         7
[6,]        11

Propuesta del modelo

Le llamaremos modelo a la aplicación gml en la base de entrenamiento (aprendizaje) y verificamos los resultados con summary()

modelo<-glm(default~. ,data=Tdatos_rl[train.id,],family="binomial")
summary((modelo))

Call:
glm(formula = default ~ ., family = "binomial", data = Tdatos_rl[train.id, 
    ])

Coefficients:
              Estimate Std. Error z value Pr(>|z|)    
(Intercept) -1.080e+01  5.736e-01 -18.829   <2e-16 ***
student1    -6.838e-01  2.796e-01  -2.446   0.0144 *  
balance      5.665e-03  2.735e-04  20.709   <2e-16 ***
income       4.600e-06  9.544e-06   0.482   0.6298    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 2050.6  on 7000  degrees of freedom
Residual deviance: 1112.8  on 6997  degrees of freedom
AIC: 1120.8

Number of Fisher Scoring iterations: 8

Al analizar los resultados debemos considerar si los coeficientes del modelo propuesto son importantes. Además, en caso que existan varios modelos, la calidad la define el valor de AIC

NOTA.
  • Si p\_value<0.05 entonces el coeficiente resulta significativo
  • Si p\_value>0.05 entonces el coeficiente no es significativo

También se debe considerar:

  • Si z\notin [-2,2] entonces el coeficiente resulta significativo
  • Si z\in [-2,2] entonces el coeficiente no es significativo

Además, si se comparan varios modelos, siempre será más robusto aquel que tenga el AIC más pequeño.

Generando predicciones

En esta etapa se utiliza el 30\% que corresponde al porcentaje de la partición, para la base de prueba y se visualiza el output.

pred1=predict(modelo,newdata =Tdatos_rl[-train.id,],type="response")
head(pred1)
           1            2            8            9           10           22 
1.556862e-03 1.113425e-03 1.088192e-03 1.711054e-02 2.333903e-05 5.244802e-03 

Construimos una adecuación, para una nueva columna conocida como proba\_exito de tipo \textit{respuesta (response)}

Tdatos_rl[-train.id,"prob_exito"]<-predict(modelo,newdata=Tdatos_rl[-train.id,],type="response")
head(Tdatos_rl)
  default student   balance    income  prob_exito
1       0       0  729.5265 44361.625 0.001556862
2       0       1  817.1804 12106.135 0.001113425
3       0       0 1073.5492 31767.139          NA
4       0       0  529.2506 35704.494          NA
5       0       0  785.6559 38463.496          NA
6       0       1  919.5885  7491.559          NA

Definimos un condicional, para clasificar los resultados de la nueva columna en 0 y 1.

Tdatos_rl[-train.id,"pred_50"]<-ifelse(Tdatos_rl[-train.id,"prob_exito"]>=0.5,1,0)
head(Tdatos_rl,20)
   default student   balance    income   prob_exito pred_50
1        0       0  729.5265 44361.625 1.556862e-03       0
2        0       1  817.1804 12106.135 1.113425e-03       0
3        0       0 1073.5492 31767.139           NA      NA
4        0       0  529.2506 35704.494           NA      NA
5        0       0  785.6559 38463.496           NA      NA
6        0       1  919.5885  7491.559           NA      NA
7        0       0  825.5133 24905.227           NA      NA
8        0       1  808.6675 17600.451 1.088192e-03       0
9        0       0 1161.0579 37468.529 1.711054e-02       0
10       0       0    0.0000 29275.268 2.333903e-05       0
11       0       1    0.0000 21871.073           NA      NA
12       0       1 1220.5838 13268.562           NA      NA
13       0       0  237.0451 28251.695           NA      NA
14       0       0  606.7423 44994.556           NA      NA
15       0       0 1112.9684 23810.174           NA      NA
16       0       0  286.2326 45042.413           NA      NA
17       0       0    0.0000 50265.312           NA      NA
18       0       1  527.5402 17636.540           NA      NA
19       0       0  485.9369 61566.106           NA      NA
20       0       0 1095.0727 26464.631           NA      NA

Validación

Utilizando la \textit{matriz de confusión} en la base de prueba, analizamos la confiabilidad del modelo en estudio.

table(Tdatos_rl[-train.id,"default"],Tdatos_rl[-train.id,"pred_50"],dnn=c("ACTUAL","PREDICCIÓN"))
      PREDICCIÓN
ACTUAL    0    1
     0 2891    9
     1   69   30

Conclusión

De acuerdo a lo anterior, se define que 2,891+30 fueron ubicados correctamente, lo que corresponde al 0.974 de la base de prueba, indicando que 0.026 están ubicados de manera incorrecta (precisamente 9+69). Lo que indica que el modelo explica el 97.4\% aproximadamente de los datos, bajo la propuesta de regresión logística en R (machine learning).

IMPORTANTE.
  • Para verificar los resultados anteriores, puede utilizar:

\begin{aligned} \dfrac{2,891+30}{3,000}&=\dfrac{2,921}{3,000}&y&&\dfrac{9+69}{3,000}&=\dfrac{78}{3,000}\\ &=0.974&&&&=0.026\\ &\approx 97.4\%&&&&\approx2.6\% \end{aligned} \\

Estructura del modelo

El modelo resultante es:

\begin{aligned} y&=a_0+a_1x_1+a_2x_2+a_3x_3\\ y&=-1.080e^{+01}-6.838e^{-01}x_1+5.665e^{-03}x_2 \end{aligned}