Respuesta: En busca de obtener una línea inicial para abordar el ejercicio, le pregunté a copilot lo siguiente:
I need to create a model that allows me to predict staff turnover in a company. To do this, I must determine 3 quantitative variables and 3 qualitative variables in order to determine those that may have the greatest significance in this prediction. Which variables do you think I should take into account?
A lo cual la inteligencia artificial me respondió que las variables a considerar deberían ser:
Cuantitativas:
Tenure –> Antigüedad
Salary –> Ingreso_Mensual
Age –> Edad
Cualitativas:
Job Satisfaction –> Satisfación_Laboral
Work Environment –> Satisfacción_Ambiental
Department –> Departamento
Basado en mi experiencia laboral, considero que estas variables son, al menos en un primer acercamiento, las que podrían tener un impacto directo y significativo para responder a la variable de estudio. En cuanto a las variables cuantitativas, mi hipótesis es que todas estarán inversamente relacionadas con la ocurrencia del evento en cuestión; es decir, a medida que aumentan sus valores, la probabilidad de que los empleados se retiren de la empresa disminuirá.
Por otro lado, es evidente que altos niveles de satisfacción tanto en las actividades realizadas como en el entorno laboral generarán mayor lealtad por parte de los colaboradores. Este comportamiento es diferente según el departamento o área al que pertenezcan, y en este sentido será muy interesante observar, en términos cuantitativos, cuáles de estas áreas presentan mayores niveles de retención.
df_rotacion = rotacion
df_rotacion <- as.data.frame(df_rotacion)
df_rota_logit = df_rotacion[, c(1, 2, 4, 8, 11, 13, 21)]
# Convertir variables categoricas a factores:
df_rota_logit$Rotación <- ifelse(df_rota_logit$Rotación == "Si", 1, 0)
df_rota_logit$Rotación <- as.factor(df_rota_logit$Rotación)
df_rota_logit$Departamento <- as.factor(df_rota_logit$Departamento)
df_rota_logit$Satisfacción_Ambiental <- as.factor(df_rota_logit$Satisfacción_Ambiental)
df_rota_logit$Satisfación_Laboral <- as.factor(df_rota_logit$Satisfación_Laboral)
##Estadísticas descriptivas:
summary(df_rota_logit)
## Rotación Edad Departamento Satisfacción_Ambiental
## 0:1233 Min. :18.00 IyD :961 1:284
## 1: 237 1st Qu.:30.00 RH : 63 2:287
## Median :36.00 Ventas:446 3:453
## Mean :36.92 4:446
## 3rd Qu.:43.00
## Max. :60.00
## Satisfación_Laboral Ingreso_Mensual Antigüedad
## 1:289 Min. : 1009 Min. : 0.000
## 2:280 1st Qu.: 2911 1st Qu.: 3.000
## 3:442 Median : 4919 Median : 5.000
## 4:459 Mean : 6503 Mean : 7.008
## 3rd Qu.: 8379 3rd Qu.: 9.000
## Max. :19999 Max. :40.000
# Frecuencias:
frecuencias_rotacion <- table(df_rota_logit$Rotación)
print(frecuencias_rotacion)
##
## 0 1
## 1233 237
# Gráfico de Barras:
df_rota_logit$Rotación <- fct_infreq(df_rota_logit$Rotación)
ggplot(df_rota_logit, aes(x = Rotación)) +
geom_bar(fill = "steelblue") +
labs(title = "Distribución - [Rotación]", x = "", y = "Frecuencia") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 0, hjust = 1),
plot.title = element_text(hjust = 0.5))
# Gráfico de Mosaico:
ggplot(data = df_rota_logit) +
geom_mosaic(aes(x = product(Rotación), fill = Rotación)) +
labs(title = "Mosaico - [Rotación]", x = "", y = "") +
theme_minimal() +
theme(axis.text.y = element_blank(),
plot.title = element_text(hjust = 0.5))
## Warning: The `scale_name` argument of `continuous_scale()` is deprecated as of ggplot2
## 3.5.0.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: The `trans` argument of `continuous_scale()` is deprecated as of ggplot2 3.5.0.
## ℹ Please use the `transform` argument instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# Gráfico de Densidad:
ggplot(df_rota_logit, aes(x = Edad)) +
geom_density(fill = "#85c1e9", alpha = 0.5) +
labs(title = "Densidad - [Edad]", x = "", y = "Densidad") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
# Boxplot:
ggplot(df_rota_logit, aes(y = Edad)) +
geom_boxplot(fill = "#85c1e9") +
labs(title = "Boxplot - [Edad]", y = "") +
theme_minimal() +
theme(axis.text.x = element_blank()) +
theme(plot.title = element_text(hjust = 0.5))
# Gráfico de Puntos:
ggplot(df_rota_logit, aes(x = Edad)) +
geom_point(aes(y = 0), position = position_jitter(width = 0.2), color = "blue") +
labs(title = "Gráfico de puntos - [Edad]", x = "", y = "") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5)) +
theme(axis.text.y = element_blank()) +
ylim(-0.5, 0.5)
# Identificación de outliers:
outliers <- boxplot.stats(df_rota_logit$Edad)$out
outliers
## numeric(0)
# Frecuencias:
frecuencias_departamento <- table(df_rota_logit$Departamento)
print(frecuencias_departamento)
##
## IyD RH Ventas
## 961 63 446
# Gráfico de Barras:
df_rota_logit$Departamento <- fct_infreq(df_rota_logit$Departamento)
ggplot(df_rota_logit, aes(x = Departamento)) +
geom_bar(fill = "steelblue") +
labs(title = "Distribución - [Departamento]", x = "", y = "Frecuencia") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 0, hjust = 1),
plot.title = element_text(hjust = 0.5))
# Gráfico de Mosaico:
ggplot(data = df_rota_logit) +
geom_mosaic(aes(x = product(Departamento), fill = Departamento)) +
labs(title = "Mosaico - [Departamento]", x = "", y = "") +
theme_minimal() +
theme(axis.text.y = element_blank(),
plot.title = element_text(hjust = 0.5))
# Frecuencias:
frecuencias_satisfaccion_ambiental <- table(df_rota_logit$Satisfacción_Ambiental)
print(frecuencias_satisfaccion_ambiental)
##
## 1 2 3 4
## 284 287 453 446
# Gráfico de Barras:
df_rota_logit$Satisfacción_Ambiental <- fct_infreq(df_rota_logit$Satisfacción_Ambiental)
ggplot(df_rota_logit, aes(x = Satisfacción_Ambiental)) +
geom_bar(fill = "steelblue") +
labs(title = "Distribución - [Satisfacción_Ambiental]", x = "", y = "Frecuencia") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 0, hjust = 1),
plot.title = element_text(hjust = 0.5))
# Gráfico de Mosaico:
ggplot(data = df_rota_logit) +
geom_mosaic(aes(x = product(Satisfacción_Ambiental), fill = Satisfacción_Ambiental)) +
labs(title = "Mosaico - [Satisfacción_Ambiental]", x = "", y = "") +
theme_minimal() +
theme(axis.text.y = element_blank(),
plot.title = element_text(hjust = 0.5))
# Frecuencias:
frecuencias_satisfacion_laboral <- table(df_rota_logit$Satisfación_Laboral)
print(frecuencias_satisfacion_laboral)
##
## 1 2 3 4
## 289 280 442 459
# Gráfico de Barras:
df_rota_logit$Satisfación_Laboral <- fct_infreq(df_rota_logit$Satisfación_Laboral)
ggplot(df_rota_logit, aes(x = Satisfación_Laboral)) +
geom_bar(fill = "steelblue") +
labs(title = "Distribución - [Satisfación_Laboral]", x = "", y = "Frecuencia") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 0, hjust = 1),
plot.title = element_text(hjust = 0.5))
# Gráfico de Mosaico:
ggplot(data = df_rota_logit) +
geom_mosaic(aes(x = product(Satisfación_Laboral), fill = Satisfación_Laboral)) +
labs(title = "Mosaico - [Satisfación_Laboral]", x = "", y = "") +
theme_minimal() +
theme(axis.text.y = element_blank(),
plot.title = element_text(hjust = 0.5))
# Gráfico de Densidad:
ggplot(df_rota_logit, aes(x = Ingreso_Mensual)) +
geom_density(fill = "#85c1e9", alpha = 0.5) +
labs(title = "Densidad - [Ingreso_Mensual]", x = "", y = "Densidad") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
# Boxplot:
ggplot(df_rota_logit, aes(y = Ingreso_Mensual)) +
geom_boxplot(fill = "#85c1e9") +
labs(title = "Boxplot - [Ingreso_Mensual]", y = "") +
theme_minimal() +
theme(axis.text.x = element_blank()) +
theme(plot.title = element_text(hjust = 0.5))
# Gráfico de Puntos:
ggplot(df_rota_logit, aes(x = Ingreso_Mensual)) +
geom_point(aes(y = 0), position = position_jitter(width = 0.2), color = "blue") +
labs(title = "Gráfico de puntos - [Ingreso_Mensual]", x = "", y = "") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5)) +
theme(axis.text.y = element_blank()) +
ylim(-0.5, 0.5)
# Identificación de outliers:
outliers <- boxplot.stats(df_rota_logit$Ingreso_Mensual)$out
outliers
## [1] 19094 18947 19545 18740 18844 18172 17328 16959 19537 17181 19926 19033
## [13] 18722 19999 16792 19232 19517 19068 19202 19436 16872 19045 19144 17584
## [25] 18665 17068 19272 18300 16659 19406 19197 19566 18041 17046 17861 16835
## [37] 16595 19502 18200 16627 19513 19141 19189 16856 19859 18430 17639 16752
## [49] 19246 17159 17924 17099 17444 17399 19419 18303 19973 19845 17650 19237
## [61] 19627 16756 17665 16885 17465 19626 19943 18606 17048 17856 19081 17779
## [73] 19740 18711 18265 18213 18824 18789 19847 19190 18061 17123 16880 17861
## [85] 19187 19717 16799 17328 19701 17169 16598 17007 16606 19586 19331 19613
## [97] 17567 19049 19658 17426 17603 16704 19833 19038 19328 19392 19665 16823
## [109] 17174 17875 19161 19636 19431 18880
# Gráfico de Densidad:
ggplot(df_rota_logit, aes(x = Antigüedad)) +
geom_density(fill = "#85c1e9", alpha = 0.5) +
labs(title = "Densidad - [Antigüedad]", x = "", y = "Densidad") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
# Boxplot:
ggplot(df_rota_logit, aes(y = Antigüedad)) +
geom_boxplot(fill = "#85c1e9") +
labs(title = "Boxplot - [Antigüedad]", y = "") +
theme_minimal() +
theme(axis.text.x = element_blank()) +
theme(plot.title = element_text(hjust = 0.5))
# Gráfico de Puntos:
ggplot(df_rota_logit, aes(x = Ingreso_Mensual)) +
geom_point(aes(y = 0), position = position_jitter(width = 0.2), color = "blue") +
labs(title = "Gráfico de puntos - [Antigüedad]", x = "", y = "") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5)) +
theme(axis.text.y = element_blank()) +
ylim(-0.5, 0.5)
# Identificación de outliers:
outliers <- boxplot.stats(df_rota_logit$Antigüedad)$out
outliers
## [1] 25 22 22 27 21 22 37 25 20 40 20 24 20 24 33 20 19 22 33 24 19 21 20 36 20
## [26] 20 22 24 21 21 25 21 29 20 27 20 31 32 20 20 21 22 22 34 24 26 31 20 31 26
## [51] 19 21 21 32 21 19 20 22 20 21 26 20 22 24 33 29 25 21 19 19 20 19 33 19 19
## [76] 20 20 20 20 20 32 20 21 33 36 26 30 22 23 23 21 21 22 22 19 22 19 22 20 20
## [101] 20 22 20 20
Interpretación: En términos generales, todas las variables presentan un buen comportamiento a nivel de datos. Es decir, las variables categóricas no muestran un desbalance significativo, y las variables cuantitativas no tienen un número elevado de outliers que pudiera generar distorsiones en la estimación de los modelos. Por esta razón, no se realizará, por el momento, balanceo de clases ni eliminación de outliers.
# Ajustar "modelo_base":
modelo_base <- glm(Rotación ~ Edad, data = df_rota_logit, family = binomial)
summary(modelo_base)
##
## Call:
## glm(formula = Rotación ~ Edad, family = binomial, data = df_rota_logit)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.20637 0.30597 0.674 0.5
## Edad -0.05225 0.00870 -6.006 1.9e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1298.6 on 1469 degrees of freedom
## Residual deviance: 1259.1 on 1468 degrees of freedom
## AIC: 1263.1
##
## Number of Fisher Scoring iterations: 4
# Ajustar "modelo1":
modelo1 <- glm(Rotación ~ Edad + Departamento, data = df_rota_logit, family = binomial)
summary(modelo1)
##
## Call:
## glm(formula = Rotación ~ Edad + Departamento, family = binomial,
## data = df_rota_logit)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.026160 0.312849 0.084 0.93336
## Edad -0.052210 0.008743 -5.971 2.35e-09 ***
## DepartamentoVentas 0.471082 0.151869 3.102 0.00192 **
## DepartamentoRH 0.432718 0.339380 1.275 0.20230
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1298.6 on 1469 degrees of freedom
## Residual deviance: 1249.0 on 1466 degrees of freedom
## AIC: 1257
##
## Number of Fisher Scoring iterations: 4
# Likelihood Ratio Test (Prueba de Razón de Verosimilitud):
anova(modelo_base, modelo1, test = "Chisq")
## Analysis of Deviance Table
##
## Model 1: Rotación ~ Edad
## Model 2: Rotación ~ Edad + Departamento
## Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1 1468 1259.1
## 2 1466 1249.0 2 10.026 0.00665 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Ajustar "modelo2":
modelo2 <- glm(Rotación ~ Edad + Departamento + Satisfacción_Ambiental, data = df_rota_logit, family = binomial)
summary(modelo2)
##
## Call:
## glm(formula = Rotación ~ Edad + Departamento + Satisfacción_Ambiental,
## family = binomial, data = df_rota_logit)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.157489 0.333243 -0.473 0.63650
## Edad -0.053203 0.008784 -6.057 1.39e-09 ***
## DepartamentoVentas 0.487428 0.153402 3.177 0.00149 **
## DepartamentoRH 0.447043 0.344916 1.296 0.19494
## Satisfacción_Ambiental4 0.014238 0.198208 0.072 0.94274
## Satisfacción_Ambiental2 0.094152 0.217988 0.432 0.66580
## Satisfacción_Ambiental1 0.815848 0.197548 4.130 3.63e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1298.6 on 1469 degrees of freedom
## Residual deviance: 1227.2 on 1463 degrees of freedom
## AIC: 1241.2
##
## Number of Fisher Scoring iterations: 5
# Likelihood Ratio Test (Prueba de Razón de Verosimilitud):
anova(modelo1, modelo2, test = "Chisq")
## Analysis of Deviance Table
##
## Model 1: Rotación ~ Edad + Departamento
## Model 2: Rotación ~ Edad + Departamento + Satisfacción_Ambiental
## Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1 1466 1249.0
## 2 1463 1227.2 3 21.887 6.885e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Ajustar "modelo3":
modelo3 <- glm(Rotación ~ Edad + Departamento + Satisfacción_Ambiental + Satisfación_Laboral, data = df_rota_logit, family = binomial)
summary(modelo3)
##
## Call:
## glm(formula = Rotación ~ Edad + Departamento + Satisfacción_Ambiental +
## Satisfación_Laboral, family = binomial, data = df_rota_logit)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.572998 0.357457 -1.603 0.10894
## Edad -0.053974 0.008833 -6.110 9.94e-10 ***
## DepartamentoVentas 0.504340 0.154797 3.258 0.00112 **
## DepartamentoRH 0.444526 0.348088 1.277 0.20159
## Satisfacción_Ambiental4 0.022256 0.199652 0.111 0.91124
## Satisfacción_Ambiental2 0.097853 0.219510 0.446 0.65576
## Satisfacción_Ambiental1 0.831489 0.199720 4.163 3.14e-05 ***
## Satisfación_Laboral3 0.445793 0.200071 2.228 0.02587 *
## Satisfación_Laboral1 0.900687 0.209031 4.309 1.64e-05 ***
## Satisfación_Laboral2 0.461643 0.224241 2.059 0.03952 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1298.6 on 1469 degrees of freedom
## Residual deviance: 1208.3 on 1460 degrees of freedom
## AIC: 1228.3
##
## Number of Fisher Scoring iterations: 5
# Likelihood Ratio Test (Prueba de Razón de Verosimilitud):
anova(modelo2, modelo3, test = "Chisq")
## Analysis of Deviance Table
##
## Model 1: Rotación ~ Edad + Departamento + Satisfacción_Ambiental
## Model 2: Rotación ~ Edad + Departamento + Satisfacción_Ambiental + Satisfación_Laboral
## Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1 1463 1227.2
## 2 1460 1208.3 3 18.861 0.0002922 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Ajustar "modelo4":
modelo4 <- glm(Rotación ~ Edad + Departamento + Satisfacción_Ambiental + Satisfación_Laboral + Ingreso_Mensual, data = df_rota_logit, family = binomial)
summary(modelo4)
##
## Call:
## glm(formula = Rotación ~ Edad + Departamento + Satisfacción_Ambiental +
## Satisfación_Laboral + Ingreso_Mensual, family = binomial,
## data = df_rota_logit)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -8.022e-01 3.601e-01 -2.228 0.02590 *
## Edad -3.060e-02 9.699e-03 -3.155 0.00161 **
## DepartamentoVentas 6.307e-01 1.593e-01 3.959 7.52e-05 ***
## DepartamentoRH 4.143e-01 3.530e-01 1.174 0.24053
## Satisfacción_Ambiental4 1.527e-02 2.010e-01 0.076 0.93946
## Satisfacción_Ambiental2 9.754e-02 2.210e-01 0.441 0.65890
## Satisfacción_Ambiental1 8.627e-01 2.017e-01 4.277 1.89e-05 ***
## Satisfación_Laboral3 4.469e-01 2.011e-01 2.222 0.02626 *
## Satisfación_Laboral1 9.167e-01 2.107e-01 4.351 1.36e-05 ***
## Satisfación_Laboral2 4.583e-01 2.260e-01 2.028 0.04255 *
## Ingreso_Mensual -1.158e-04 2.548e-05 -4.546 5.46e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1298.6 on 1469 degrees of freedom
## Residual deviance: 1183.8 on 1459 degrees of freedom
## AIC: 1205.8
##
## Number of Fisher Scoring iterations: 5
# Likelihood Ratio Test (Prueba de Razón de Verosimilitud):
anova(modelo3, modelo4, test = "Chisq")
## Analysis of Deviance Table
##
## Model 1: Rotación ~ Edad + Departamento + Satisfacción_Ambiental + Satisfación_Laboral
## Model 2: Rotación ~ Edad + Departamento + Satisfacción_Ambiental + Satisfación_Laboral +
## Ingreso_Mensual
## Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1 1460 1208.3
## 2 1459 1183.8 1 24.447 7.639e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Ajustar "modelo5":
modelo5 <- glm(Rotación ~ Edad + Departamento + Satisfacción_Ambiental + Satisfación_Laboral + Ingreso_Mensual + Antigüedad, data = df_rota_logit, family = binomial)
summary(modelo5)
##
## Call:
## glm(formula = Rotación ~ Edad + Departamento + Satisfacción_Ambiental +
## Satisfación_Laboral + Ingreso_Mensual + Antigüedad, family = binomial,
## data = df_rota_logit)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -7.728e-01 3.590e-01 -2.153 0.031348 *
## Edad -2.813e-02 9.674e-03 -2.908 0.003638 **
## DepartamentoVentas 6.190e-01 1.594e-01 3.883 0.000103 ***
## DepartamentoRH 4.109e-01 3.543e-01 1.160 0.246085
## Satisfacción_Ambiental4 1.381e-02 2.014e-01 0.069 0.945333
## Satisfacción_Ambiental2 1.052e-01 2.214e-01 0.475 0.634761
## Satisfacción_Ambiental1 8.512e-01 2.023e-01 4.208 2.58e-05 ***
## Satisfación_Laboral3 4.377e-01 2.014e-01 2.173 0.029751 *
## Satisfación_Laboral1 9.109e-01 2.110e-01 4.317 1.58e-05 ***
## Satisfación_Laboral2 4.490e-01 2.263e-01 1.983 0.047314 *
## Ingreso_Mensual -9.259e-05 2.723e-05 -3.400 0.000674 ***
## Antigüedad -3.858e-02 1.855e-02 -2.080 0.037536 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1298.6 on 1469 degrees of freedom
## Residual deviance: 1179.4 on 1458 degrees of freedom
## AIC: 1203.4
##
## Number of Fisher Scoring iterations: 5
# Likelihood Ratio Test (Prueba de Razón de Verosimilitud):
anova(modelo4, modelo5, test = "Chisq")
## Analysis of Deviance Table
##
## Model 1: Rotación ~ Edad + Departamento + Satisfacción_Ambiental + Satisfación_Laboral +
## Ingreso_Mensual
## Model 2: Rotación ~ Edad + Departamento + Satisfacción_Ambiental + Satisfación_Laboral +
## Ingreso_Mensual + Antigüedad
## Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1 1459 1183.8
## 2 1458 1179.3 1 4.491 0.03407 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
colnames(df_rota_logit)
## [1] "Rotación" "Edad" "Departamento"
## [4] "Satisfacción_Ambiental" "Satisfación_Laboral" "Ingreso_Mensual"
## [7] "Antigüedad"
# Obtener AIC para todos los modelos:
AIC(modelo_base, modelo1, modelo2, modelo3, modelo4, modelo5)
## df AIC
## modelo_base 2 1263.064
## modelo1 4 1257.037
## modelo2 7 1241.150
## modelo3 10 1228.290
## modelo4 11 1205.843
## modelo5 12 1203.352
Interpretación: En efecto, al realizar una comparación incremental de los modelos ajustados y aplicar la prueba de AIC a todos ellos, se observa que la inclusión de cada variable seleccionada aporta un valor significativo para explicar la variable predictora (Rotación).
Por otro lado, los coeficientes obtenidos para las variables cuantitativas son negativos, lo que indica que, a medida que aumentan la edad, el salario o la antigüedad en la empresa, la probabilidad de que el colaborador deje la empresa disminuye.
En contraste, los coeficientes de las variables dummy para las variables categóricas presentan un comportamiento curioso, ya que son valores positivos pero de magnitud muy baja. Esto sugiere que no existe un impacto significativo entre estas categorías y las correspondientes categorías de referencia para cada variable en términos de la probabilidad de que se presente el evento en análisis (Rotación).
Departamento –> IyD
Ambiental: 3 –> satisfecho
Laboral: 4 –> muy insatisfecho
# Partición de los datos:
set.seed(123)
indices <- createDataPartition(df_rota_logit$Rotación, p = 0.7, list = FALSE)
train_data <- df_rota_logit[indices, ]
test_data <- df_rota_logit[-indices, ]
# Estimación del modelo logístico:
modelo_logistico <- glm(Rotación ~ Edad + Departamento + Satisfacción_Ambiental + Satisfación_Laboral + Ingreso_Mensual + Antigüedad,
data = train_data,
family = binomial)
# Mostrar resultados del modelo:
summary(modelo_logistico)
##
## Call:
## glm(formula = Rotación ~ Edad + Departamento + Satisfacción_Ambiental +
## Satisfación_Laboral + Ingreso_Mensual + Antigüedad, family = binomial,
## data = train_data)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -5.353e-01 4.315e-01 -1.240 0.214851
## Edad -2.803e-02 1.187e-02 -2.362 0.018180 *
## DepartamentoVentas 6.330e-01 1.905e-01 3.323 0.000890 ***
## DepartamentoRH 5.037e-01 3.964e-01 1.271 0.203890
## Satisfacción_Ambiental4 -1.969e-01 2.396e-01 -0.822 0.411188
## Satisfacción_Ambiental2 -3.447e-02 2.605e-01 -0.132 0.894736
## Satisfacción_Ambiental1 7.670e-01 2.418e-01 3.172 0.001512 **
## Satisfación_Laboral3 3.285e-01 2.383e-01 1.379 0.167975
## Satisfación_Laboral1 8.285e-01 2.488e-01 3.330 0.000869 ***
## Satisfación_Laboral2 2.221e-01 2.718e-01 0.817 0.413871
## Ingreso_Mensual -8.462e-05 3.299e-05 -2.565 0.010330 *
## Antigüedad -5.568e-02 2.312e-02 -2.408 0.016033 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 909.69 on 1029 degrees of freedom
## Residual deviance: 824.97 on 1018 degrees of freedom
## AIC: 848.97
##
## Number of Fisher Scoring iterations: 5
# Predicciones:
predicciones <- predict(modelo_logistico, newdata = test_data, type = "response")
predicciones_clasificadas <- ifelse(predicciones > 0.5, 1, 0) %>%
factor(.)
# Calcular la precisión del modelo:
precision <- mean(predicciones_clasificadas == test_data$Rotación)
cat("Precisión del modelo en el conjunto de prueba:", precision)
## Precisión del modelo en el conjunto de prueba: 0.8431818
# Graficar la curva ROC
curva_ROC <- roc(test_data$Rotación, predicciones)
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
auc<- round(auc(curva_ROC, levels =c(0,1), direction = "<"),4) # 0.9177
ggroc(curva_ROC, colour = "#FF7F00", size=1)+
ggtitle(paste0("Curva ROC ", "(AUC = ", auc, ")"))+
xlab("Especificidad")+
ylab("Sensibilidad") +
theme(plot.title = element_text(hjust = 0.5))
# Matriz de confusión:
cm <- confusionMatrix(predicciones_clasificadas, test_data$Rotación, , positive = "1")
print(cm)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 367 67
## 1 2 4
##
## Accuracy : 0.8432
## 95% CI : (0.8058, 0.8759)
## No Information Rate : 0.8386
## P-Value [Acc > NIR] : 0.4285
##
## Kappa : 0.0808
##
## Mcnemar's Test P-Value : 1.312e-14
##
## Sensitivity : 0.056338
## Specificity : 0.994580
## Pos Pred Value : 0.666667
## Neg Pred Value : 0.845622
## Prevalence : 0.161364
## Detection Rate : 0.009091
## Detection Prevalence : 0.013636
## Balanced Accuracy : 0.525459
##
## 'Positive' Class : 1
##
cm_data <- as.data.frame(cm$table)
cm_data$Prediction <- factor(cm_data$Prediction, levels = unique(cm_data$Prediction))
cm_data$Reference <- factor(cm_data$Reference, levels = unique(cm_data$Reference))
# Graficar la matriz de confusión:
ggplot(data = cm_data, aes(x = Reference, y = Prediction, fill = Freq)) +
geom_tile(color = "white") +
scale_fill_gradient(low = "lightblue", high = "darkblue") +
geom_text(aes(label = Freq), vjust = 1, color = "white") +
labs(title = "Matriz de confusión",
x = "Predicción del modelo de Y",
y = "Valores observados de Y") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5),
legend.position = "none")
Respuesta: Como parte de los resultados del estudio realizado, se sugiere que la empresa centre sus esfuerzos en mantener o mejorar las condiciones laborales relacionadas con el salario de los colaboradores, ya que esta variable tiene una especial incidencia en la toma de decisiones respecto al cambio de trabajo. Por otro lado, la contratación de personas de mayor edad representa una excelente estrategia para generar estabilidad en el personal. Si se presta especial atención a estas dos variables, se incrementará la antigüedad de los empleados y, a su vez, se reducirá el riesgo de que decidan abandonar la empresa por iniciativa propia.