> library(tidyverse)
> library(broom)
> library(car)
La idea de este notebook es hacer un ejercicio integrador de los diferentes temas que estuvimos viendo de regresión logística. Para ello, vamos a seguir trabajando con la base de la ENES y nos vamos a seguir preguntando por la autopercepción de clase. La propuesta es que avancen en las siguientes consignas.
Veamos la forma en que está abordada el problema de la autopercepción de clase:
Discutamos…
> psh_cony <- read_rds("./data/ENES_psh_cony.rds")
Tal y como hicimos la semana pasada, tenemos que recodificar las
variables de percecpión de clase MS_v260
y
MS_v261
a una sola variable que vamos a llamar
percep_clase
y luego a esta, dicotomizarla. A su vez, vamos
a tratar de replicar el esquema que utilizó Rodolfo Elbert en este
artículo. Allí, realizó una desagregación de los trabajadores por
cuenta propia en dos categorías:
Dado que de esta forma, quedan muy pocos casos en la cateogría “Pequeña burguesía”, la vamos a unificar con la categoría de “Empleadores” bajo el rótulo: “Clases propietarias”.
> psh_cony <- psh_cony %>%
+ mutate(
+ v109 = if_else(v109 == 'Varón', 'Masculino', 'No masculino'),
+ percep_clase = case_when(
+ !is.na(MS_v260) ~ MS_v260,
+ is.na(MS_v260) ~ MS_v261
+ )
+ )
>
> psh_cony <- psh_cony %>%
+ mutate(
+ salud = case_when(
+ v134a %in% c("Obra social", "Prepaga", "Prepaga a través de Obra Social") ~ 'Tiene cobertura',
+ TRUE ~ 'No tiene cobertura'
+ ),
+
+ percep_obrera = as.factor(case_when(
+ percep_clase == 'Clase baja' | percep_clase == 'Clase obrera' ~ 'Obrera',
+ is.na(percep_clase) ~ NA_character_,
+ TRUE ~ 'Media y alta')),
+
+ percep_obrera_orig = as.factor(case_when(
+ MS_v260 == 'Clase baja' | MS_v260 == 'Clase obrera' ~ 'Obrera',
+ is.na(MS_v260) ~ NA_character_,
+ TRUE ~ 'No obrera')),
+ CNO_calif_agg = case_when(
+ CNO_calif == 'Profesional' | CNO_calif == 'Técnica' ~ 'Prof./técn',
+ CNO_calif == 'Operativa' | CNO_calif == 'No calificada' ~ 'Op./no calif.',
+ ),
+ nivel_ed_agg = case_when(
+ nivel_ed == 'Menores de 5 años' |
+ nivel_ed == 'Sin instrucción (incluye nunca asistió o sólo asistió a sala de 5)' |
+ nivel_ed == 'Primaria/EGB incompleto' |
+ nivel_ed == 'Primaria/EGB completo' |
+ nivel_ed == 'Educación especial' | nivel_ed == 'NS/NR'~ '0_Bajo',
+
+ nivel_ed == 'Secundario/Polimodal incompleto' |
+ nivel_ed == 'Secundario/Polimodal completo' ~ '1_Medio',
+
+ nivel_ed == 'Terciario incompleto' |
+ nivel_ed == 'Terciario completo' |
+ nivel_ed == 'Universitario incompleto' |
+ nivel_ed == 'Universitario completo' ~ '2_Alto'),
+
+ class_eow_agg = case_when(
+ EOW_class == 'Managers' | EOW_class == 'Supervisores' ~ 'Manag./superv.',
+ EOW_class == 'Trabajadores' ~ 'Trabajadores',
+ EOW_class == 'Pequeña burguesía' & CNO_calif_agg == 'Prof./técn' ~ 'Propietarias',
+ EOW_class == 'Pequeña burguesía' & CNO_calif_agg == 'Op./no calif.' ~ 'TCP informales',
+
+ EOW_class == 'Empleadores' ~ 'Propietarias'),
+ )
Primero dicotomizamos la variable MS_v258
> ###
Luego, podemos intentar una regresión logística tomando como variable dependiente la “percepcion_escalera” y como independiente la percepción obrera.
> ###
> ###
> ###
Pista: Van a tener que usar la función predict
. Revisen
el notebook de la semana pasada
> ###
Pista: elijan un perfil y hagan variar la edad a lo largo de ese
perfil. Luego, van a tener que usar de nuevo predict
.
> ###
Esta pregunta nos lleva a pensar, entre otras cosas, en términos del “ajuste” del modelo. Esto supone que vamos a tener que comparar las predicciones del modelo con los valores observados respecto a la percepción de clase en escalera y a la percepción de clase obrera. Pero el problema que tenemos acá es que los valores observados son cualitativos y discretos, mientras que el modelo nos devuelve probabilidades (o sea, un valor continuo y numérico).
Entonces, de alguna forma, tenemos que transformar el output del modelo (cuantitativo) a una categoría. Pero dado que la regresión logística nos devuelve la probabilidad de ocurrencia del fenómeno (\(P(y=1 | X)\)) podemos establecer un criterio. En nuestro caso, si la probabilidad de que la persona tenga una percepción escalera “alta” es mayor a 0.5, vamos a considerar que tiene una percepcion “alta”; en cambio, si la probabilidad es 0.5 o menos vamos a considerar que tiene una probabilidad no alta o “baja”.
Vamos a crear una tibble que tenga
> eval_model <- tibble(
+ y_probs = predict(glm2, psh_cony, 'response'), #probabildades predichas por el modelo
+ y_preds = if_else(y_probs >= 0.5, '0_Alta', '1_Baja'), # valores predichos
+ y_obs = psh_cony$percep_escalera # valores observados
+ ) %>%
+ drop_na()
>
> eval_model
## # A tibble: 11,023 × 3
## y_probs y_preds y_obs
## <dbl> <chr> <fct>
## 1 0.459 1_Baja 0_Alta
## 2 0.536 0_Alta 0_Alta
## 3 0.438 1_Baja 1_Baja
## 4 0.543 0_Alta 0_Alta
## 5 0.523 0_Alta 0_Alta
## 6 0.563 0_Alta 1_Baja
## 7 0.552 0_Alta 0_Alta
## 8 0.565 0_Alta 1_Baja
## 9 0.542 0_Alta 1_Baja
## 10 0.404 1_Baja 0_Alta
## # ℹ 11,013 more rows
Una forma natural de evaluar un modelo de regresión logística (y cualquier modelo que haga predicciones de variables cualitativas) es cuantifiar la cantidad de casos “bien clasificados” es decir, los casos en que el modelo y realidad coinciden.
Para esto, suele ser muy útil hacer una tabulación cruzada entre ambas variables (valores observados y predichos). A la misma se la llama “matriz de confusión”.
> eval_model %>%
+ group_by(y_obs, y_preds) %>%
+ summarise(n = n()) %>%
+ pivot_wider(id_cols = y_obs, values_from = n, names_from = y_preds)
## # A tibble: 2 × 3
## # Groups: y_obs [2]
## y_obs `0_Alta` `1_Baja`
## <fct> <int> <int>
## 1 0_Alta 3586 1585
## 2 1_Baja 4633 1219
En general, cada casilla de esta matriz tiene un nombre:
Entonces, los casos correctamente clasificados o “accuracy” se calculan como:
\[Acc = \frac{TP + TN}{TP + TN + FP + FN} = \frac{3586+1219}{3586+1219 + 4633 + 1585} = \frac{4805}{11026} = 0.4359\] Podemos calcular esto bien rápido haciendo:
> mean(eval_model$y_obs == eval_model$y_preds)
## [1] 0.4359067
Pero también podemos pensar en otras dos métricas (entre muchas otras):
\[Prec = \frac{TP}{TP + FP}\]
\[Recall = \frac{TP}{TP + FN}\]
> ###
> ###