Introducción.

El propósito de este informe es construir un modelo de regresión logística para predecir la probabilidad de que un empleado cambie de cargo en el próximo período, identificando los factores que influyen de manera significativa en la rotación interna. A través de este análisis, se busca comprender cómo variables como la antigüedad en el cargo actual, el nivel de satisfacción laboral, el salario, la edad y otros factores relevantes impactan en la decisión de los empleados de permanecer o cambiar de rol dentro de la organización.

Para ello se hará uso de las recomendaciones propuestas por la gerencia de la empresa:

# Verificar e instalar devtools solo si no está instalado
if (!requireNamespace("devtools", quietly = TRUE)) {
  install.packages("devtools")}

# Verificar y reinstalar 'paqueteMODELOS' desde GitHub solo si no está instalado
if (!requireNamespace("paqueteMODELOS", quietly = TRUE)) {
  devtools::install_github("centromagis/paqueteMODELOS", force = TRUE)}

devtools::install_github("ibecav/CGPfunctions")
devtools::install_github("tidymodels/themis")

# Cargar el paquete
library(paqueteMODELOS)

# Cargar los datos 'rotacion'
data("rotacion")
# install.packages("ROSE","DMwR2","performanceEstimation")

Valores faltantes y tipo de variable.

Se verifican los valores faltantes por cada variable y su tipo de datos.

library(dplyr)
library(knitr)
library(purrr)
library(kableExtra)
library(tibble)

variables_df <- tibble(
  Variable = names(rotacion),
  Tipo = map_chr(rotacion, ~ paste(class(.x), collapse = ", ")),  # Convierte en string sin nombres extra
  Faltantes = map_int(rotacion, ~ sum(is.na(.x)))  # Asegura valores enteros
)

# Tabla con estilo predeterminado "basic"
kable(variables_df, align = "c", col.names = c("Variable", "Tipo de Dato", "Faltantes"), 
      caption = "<div align='center'>Variables, Tipos de Datos y Valores Faltantes del Dataset 'rotacion'</div>") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = F)
Variables, Tipos de Datos y Valores Faltantes del Dataset ‘rotacion’
Variable Tipo de Dato Faltantes
Rotación character 0
Edad numeric 0
Viaje de Negocios character 0
Departamento character 0
Distancia_Casa numeric 0
Educación numeric 0
Campo_Educación character 0
Satisfacción_Ambiental numeric 0
Genero character 0
Cargo character 0
Satisfación_Laboral numeric 0
Estado_Civil character 0
Ingreso_Mensual numeric 0
Trabajos_Anteriores numeric 0
Horas_Extra character 0
Porcentaje_aumento_salarial numeric 0
Rendimiento_Laboral numeric 0
Años_Experiencia numeric 0
Capacitaciones numeric 0
Equilibrio_Trabajo_Vida numeric 0
Antigüedad numeric 0
Antigüedad_Cargo numeric 0
Años_ultima_promoción numeric 0
Años_acargo_con_mismo_jefe numeric 0
# Convertir las variables categóricas ordinales a factor ordenado
rotacion$Rendimiento_Laboral <- factor(rotacion$Rendimiento_Laboral, 
                                       levels = c(1, 2, 3, 4),
                                       labels = c("Bajo", "Medio", "Alto", "Muy Alto"),
                                       ordered = TRUE)

rotacion$Educación <- factor(rotacion$Educación, 
                             levels = c(1, 2, 3, 4, 5),
                             labels = c("Primaria", "Secundaria", "Técnico/Tecnólogo", "Pregrado", "Posgrado"),
                             ordered = TRUE)

rotacion$Satisfacción_Ambiental <- factor(rotacion$Satisfacción_Ambiental, 
                                          levels = c(1, 2, 3, 4),
                                          labels = c("Muy Insatisfecho", "Insatisfecho", "Satisfecho", "Muy Satisfecho"),
                                          ordered = TRUE)

rotacion$Satisfación_Laboral <- factor(rotacion$Satisfación_Laboral, 
                                       levels = c(1, 2, 3, 4),
                                       labels = c("Muy Insatisfecho", "Insatisfecho", "Satisfecho", "Muy Satisfecho"),
                                       ordered = TRUE)

rotacion$Equilibrio_Trabajo_Vida <- factor(rotacion$Equilibrio_Trabajo_Vida, 
                                           levels = c(1, 2, 3, 4),
                                           labels = c("Muy Bajo", "Bajo", "Medio", "Alto"),
                                           ordered = TRUE)

Valores Únicos por cada variable categórica.

Se verifican los valores únicos para identificar posibles inconsistencias.

library(dplyr)
library(knitr)
library(kableExtra)
library(purrr)

# Identificar variables categóricas
categoricas <- rotacion[, sapply(rotacion, is.character) | sapply(rotacion, is.factor)]

# Crear un dataframe con los valores únicos
categoricas_df <- tibble(
  Variable = names(categoricas),
  Valores_Unicos = map_chr(categoricas, ~ paste(unique(.x), collapse = ", "))
)

# Mostrar la tabla en formato Markdown
kable(categoricas_df, align = "c", col.names = c("Variable", "Valores Únicos"), 
      caption = "<div align='center'>Valores Únicos de Variables Categóricas</div>") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = F)
Valores Únicos de Variables Categóricas
Variable Valores Únicos
Rotación Si, No
Viaje de Negocios Raramente, Frecuentemente, No_Viaja
Departamento Ventas, IyD, RH
Educación Secundaria, Primaria, Pregrado, Técnico/Tecnólogo, Posgrado
Campo_Educación Ciencias, Otra, Salud, Mercadeo, Tecnicos, Humanidades
Satisfacción_Ambiental Insatisfecho, Satisfecho, Muy Satisfecho, Muy Insatisfecho
Genero F, M
Cargo Ejecutivo_Ventas, Investigador_Cientifico, Tecnico_Laboratorio, Director_Manofactura, Representante_Salud, Gerente, Representante_Ventas, Director_Investigación, Recursos_Humanos
Satisfación_Laboral Muy Satisfecho, Insatisfecho, Satisfecho, Muy Insatisfecho
Estado_Civil Soltero, Casado, Divorciado
Horas_Extra Si, No
Rendimiento_Laboral Alto, Muy Alto
Equilibrio_Trabajo_Vida Muy Bajo, Medio, Bajo, Alto

A continuación se describen los pasos que la gerencia ha propuesto para el análisis:

1. Selección de variables

Se seleccionarán tres variables cuantitativas y categóricas para realizar los análisis posteriores:

Variables categóricas seleccionadas:

Cargo: Los empleados en cargos operativos o de menor jerarquía pueden tener una mayor probabilidad de rotación, ya que podrían enfrentar menos barreras para cambiar de empleo y podrían recibir menos incentivos para permanecer en la empresa.

  • Hipótesis: Los empleados en cargos operativos o de menor jerarquía pueden tener una mayor probabilidad de rotación debido a menores barreras para el cambio y menores incentivos para la permanencia.

Horas Extra: Los empleados que trabajan horas extra pueden tener una mayor probabilidad de rotación debido al agotamiento, la insatisfacción laboral y el posible desequilibrio entre la vida personal y profesional.

  • Hipótesis: Los empleados que trabajan horas extra pueden tener una mayor probabilidad de rotación debido al agotamiento y la insatisfacción laboral.

Estado Civil: El estado civil de un empleado puede influir en su probabilidad de rotación. Empleados solteros podrían estar más dispuestos a cambiar de trabajo en busca de nuevas oportunidades, mientras que aquellos casados o con familia podrían valorar más la estabilidad laboral. Sin embargo, factores como el apoyo familiar y las responsabilidades pueden afectar esta relación de manera distinta según el contexto.

  • Hipótesis: Los empleados solteros pueden tener una mayor probabilidad de rotación debido a una mayor flexibilidad para buscar nuevas oportunidades laborales, mientras que aquellos casados o con familia podrían mostrar una menor tendencia a cambiar de empleo por motivos de estabilidad.

Variables cuantitativas seleccionadas:

Ingreso_Mensual: El salario es un factor clave para la satisfacción y la permanencia en un empleo. Ingresos bajos pueden motivar la búsqueda de mejores oportunidades.

  • Hipótesis: Los empleados con ingresos mensuales bajos tienen mayor probabilidad de rotación, ya que podrían buscar mejores condiciones económicas.

Años_Experiencia: Los empleados con más años de experiencia pueden tener una menor probabilidad de rotación, ya que suelen haber desarrollado estabilidad en sus roles, adquirido beneficios dentro de la empresa y enfrentan mayores costos de cambio al buscar nuevas oportunidades laborales.

  • Hipótesis: Los empleados con más años de experiencia pueden tener una menor probabilidad de rotación debido a su estabilidad laboral y los costos asociados a cambiar de empleo.

Distancia_Casa: Los empleados con un bajo equilibrio entre trabajo y vida personal, especialmente aquellos con largas distancias entre su hogar y el trabajo, tienen una mayor probabilidad de rotación, ya que pueden priorizar la búsqueda de mejores condiciones laborales y una mejor calidad de vida.

  • Hipótesis: Los empleados con mayores distancias al trabajo pueden tener una myor probabilidad de buscar mejores ofertas

2. Análisis univariado

A continuación se realiza el analisis univariado de la base de datos de rotación, permitiendo identificiar caracteristicas de cada variable de manera individual, realizando distinción entre variables categóricas y cuantitativas.

Gráficos de variables Categóricas

# librerías necesarias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtrar variables categóricas (character y ordered factor)
cualitativas <- rotacion %>%
  select_if(~ is.character(.) || is.ordered(.))

# Lista para almacenar los gráficos
graficos <- list()

# Crear gráficos de barras y almacenarlos en la lista
for (var in colnames(cualitativas)) {
  p <- ggplot(rotacion, aes(x = .data[[var]], fill = .data[[var]])) +
    geom_bar(width = 0.7, color = "black") +
    labs(title = paste(var), x = var, y = "Frecuencia") +
    theme_minimal() +
    theme(
      plot.title = element_text(hjust = 0.5, size = 9),            # Tamaño del título
      axis.text.x = element_text(angle = 0, hjust = 1, size = 8),  # Tamaño de etiquetas eje X
      axis.text.y = element_text(size = 8),                        # Tamaño de etiquetas eje Y
      axis.title.x = element_text(size = 8),                       # Tamaño del nombre del eje X
      axis.title.y = element_text(size = 8),                       # Tamaño del nombre del eje Y
      legend.position = "none"
    ) +
    coord_flip()  # Rotación para mejor visibilidad

  graficos[[var]] <- p
}

# Mostrar todos los gráficos en un solo panel (ajusta ncol según prefieras)
grid.arrange(grobs = graficos, ncol = 4)

Rotación: La mayoría de los empleados se mantienen en la empresa, pero hay un porcentaje notable que experimenta rotación. Esto sugiere que, aunque la retención es generalmente buena, existen otros factores motivan a los empleados a buscar otras oportunidades.

Viaje de Negocios: La mayoría de los empleados rara vez o nunca viajan por negocios, lo que indica que esta no es una parte fundamental de sus roles. Solo una minoría viaja con frecuencia, lo que podría representar diferencias en los distintos cargos.

Departamento: El departamento de I+D cuenta con el mayor número de empleados, lo que resalta la importancia de la investigación y el desarrollo en la empresa. Ventas y Recursos Humanos tienen una menor representación.

Educación: La mayoría de los empleados poseen títulos de pregrado.También hay un número significativo con formación técnica/tecnológica, mientras que la educación secundaria o primaria es menos común, el nivel educativo podría estar en función del cargo desempeñado.

Campo_Educación: Ciencias es el campo de estudio predominante entre los empleados, aunque Humanidades y Mercadeo también están presentes. Esto se encuentra conforme a que el departamento de I+D es el que mayor número de personas cuenta.

Satisfacción_Ambiental: La mayoría de los empleados están satisfechos o muy satisfechos con el ambiente laboral, lo que sugiere un entorno de trabajo positivo. Sin embargo, existe un porcentaje menor que experimenta insatisfacción, lo que podría tener relación con la rotación.

Género: Se presenta una predominancia del género masculino en la empresa, aunque esta podría variar dependiendo del cargo.

Cargo: Los técnicos de laboratorio, investigadores cientificos y los representantes de ventas son los cargos más comunes, lo que refleja las necesidades operativas de la empresa.

Satisfacción_Laboral: La mayoría de los empleados están satisfechos o muy satisfechos con su trabajo, lo que indica un buen clima laboral. Sin embargo, un porcentaje menor muestra insatisfacción, lo cual podría estar relacionado a cierto tipo de cargo o área.

Estado_Civil: La mayoría de los empleados están casados, lo que podría influir en sus necesidades y expectativas laborales.

Horas_Extra: La mayoría de los empleados no trabaja horas extra, lo que sugiere un equilibrio saludable entre trabajo y vida personal. Sin embargo, un porcentaje menor sí lo hace, por lo que podría existir una relación con la rotación.

Rendimiento_Laboral: La mayoría de los empleados tienen un rendimiento alto o muy alto, lo que refleja la eficiencia y la calidad del trabajo. Pocos empleados tienen un rendimiento bajo, lo que indica un buen nivel general de productividad.

Equilibrio_Trabajo_Vida: La mayoría de los empleados perciben un buen equilibrio entre trabajo y vida personal, lo que contribuye a su bienestar. Sin embargo, un porcentaje menor experimenta un equilibrio deficiente que podría incidir en la rotación.

Gráficos de variables cuantitativas.

#librerías necesarias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtrar variables cuantitativas
cuantitativas <- rotacion %>%
  select_if(is.numeric)

# almacenar los gráficos
graficos_cuantitativos <- list()

# Crear histogramas
for (var in colnames(cuantitativas)) {
  # Ajustes específicos para "Ingreso_Mensual"
  if (var == "Ingreso_Mensual") {
    p <- ggplot(rotacion, aes(x = .data[[var]])) +
      geom_histogram(binwidth = 2000, fill = "skyblue", color = "black", alpha = 0.5) +  # Ajustar binwidth
      scale_x_continuous(labels = scales::comma, breaks = seq(0, 20000, by = 2000)) +   # Escala del eje x
      labs(title = paste(var), x = var, y = "Frecuencia") +
      theme_minimal(base_size = 9) +  # Tamaño base de la fuente más grande
      theme(
        plot.title = element_text(hjust = 0.5, size = 9, face = "bold"),  # Título más grande y en negrita
        axis.text.x = element_text(angle =90, hjust = 1, size = 8),       # Tamaño de etiquetas eje X
        axis.text.y = element_text(size = 8),                             # Tamaño de etiquetas eje Y
        axis.title.x = element_text(size = 8),                            # Tamaño del nombre del eje X
        axis.title.y = element_text(size = 8)                             # Tamaño del nombre del eje Y
      )
  } else {
    # Gráficos para otras variables cuantitativas
    p <- ggplot(rotacion, aes(x = .data[[var]])) +
      geom_histogram(binwidth = 5, fill = "skyblue", color = "black", alpha = 0.8) +
      labs(title = paste(var), x = var, y = "Frecuencia") +
      theme_minimal(base_size = 12) +
      theme(
        plot.title = element_text(hjust = 0.5, size = 9, face = "bold"),
        axis.text.x = element_text(angle = 0, hjust = 1, size = 8),
        axis.text.y = element_text(size = 8),
        axis.title.x = element_text(size = 8),
        axis.title.y = element_text(size = 8)
      )
  }
  
  graficos_cuantitativos[[var]] <- p
}

# gráficos en un solo panel
grid.arrange(grobs = graficos_cuantitativos, ncol = 3)

Edad: La distribución de edades muestra una concentración en el rango de 30 a 40 años, con una disminución gradual hacia edades mayores. Esto sugiere una fuerza laboral relativamente joven con una distribución sesgada hacia la derecha.

Distancia_Casa: La mayoría de los empleados viven a una distancia relativamente corta de su lugar de trabajo, con una disminución en la frecuencia a medida que aumenta la distancia.

Ingreso_Mensual: La distribución del ingreso mensual está fuertemente sesgada hacia la derecha, con una alta frecuencia de ingresos bajos y una disminución gradual hacia ingresos más altos, esta desigualdad podría deberse al cargo y área.

Trabajos_Anteriores: La mayoría de los empleados han tenido pocos trabajos anteriores, con una disminución significativa en la frecuencia a medida que aumenta el número de trabajos anteriores. Esto sugiere una fuerza laboral relativamente estable.

Porcentaje_aumento_salarial: La distribución del porcentaje de aumento salarial se concentra en un rango específico, con una disminución hacia porcentajes más altos.

Años_Experiencia: La distribución de los años de experiencia muestra una concentración en los primeros años, con una disminución gradual hacia años de experiencia más largos, lo cual muestra que la fuerza laboral está compuesta principalmente de empleados con poca antigüedad.

Capacitaciones: La mayoría de los empleados han recibido un número limitado de capacitaciones, con una disminución en la frecuencia a medida que aumenta el número de capacitaciones.

Antigüedad: La distribución de la antigüedad muestra una concentración en los primeros años, con una disminución gradual hacia años de antigüedad más largos. Esto sugiere una fuerza laboral con una mezcla de empleados nuevos y antiguos.

Antigüedad_Cargo: La distribución de la antigüedad en el cargo es similar a la antigüedad general, con una concentración en los primeros años y una disminución gradual. Esto indica que los empleados tienden a permanecer en sus cargos durante períodos relativamente cortos.

Años_ultima_promoción: La mayoría de los empleados han sido promocionados recientemente, con una disminución en la frecuencia a medida que aumenta el tiempo desde la última promoción. Esto sugiere que las promociones son relativamente frecuentes.

Años_acargo_con_mismo_jefe: La mayoría de los empleados han estado bajo el mismo jefe durante un período relativamente corto, con una disminución en la frecuencia a medida que aumenta el tiempo. Esto indica una posible rotación de jefes o cambios en la estructura organizativa.

3. Análisis bivariado

A continuación se presenta el análisis bivariado de las variables cuantitativas y categóricas con la variable de respuesta de rotación, esto con el fin de identificar cuales con las variables determinantes para examinar la rotación de personal en la empresa, para compararlas con las hipótesis planteadas en la selección inicial de variables

Variables Categóricas.

#librerías necesarias
library(CGPfunctions)
library(ggplot2)
library(ggpubr)
library(plotly)
library(gridExtra)

# Variables categóricas
categoricas <- c("Viaje de Negocios", "Departamento", "Campo_Educación", "Satisfacción_Ambiental",
                 "Genero", "Cargo", "Satisfación_Laboral", "Estado_Civil", "Horas_Extra", 
                 "Rendimiento_Laboral", "Equilibrio_Trabajo_Vida")

# almacenar las gráficas
graficas <- list()

# Definir una paleta de colores con suficientes valores
paleta_colores <- c("skyblue", "salmon", "lightgreen", "orange", "purple", "pink", "brown", "gray", "cyan")

# Generación de gráficas individuales
for (variable in categoricas) {
  # Generar el gráfico con PlotXTabs2
  grafica <- PlotXTabs2(rotacion, Rotación, !!as.name(variable), plottype = "percent") +
    ggtitle(paste("Rotación vs", variable)) +
    theme_minimal(base_size = 9) +
    theme(
      plot.title = element_text(size = 10, face = "bold", hjust = 0.5, color = "darkblue"),
      axis.text.x = element_text(size = 9, angle = 0, hjust = 1),
      axis.text.y = element_text(size = 9),
      axis.title.x = element_text(size = 9, face = "bold"),
      axis.title.y = element_text(size = 9, face = "bold"),
      legend.title = element_text(size = 9, face = "bold"),
      legend.text = element_text(size = 9)
    ) +
    scale_fill_manual(values = paleta_colores) +
    labs(x = variable, y = "Porcentaje")

  # tamaño de los porcentajes dentro del gráfico
  grafica$layers[[2]]$aes_params$size <- 3

  graficas[[variable]] <- grafica
}

# Mostrar todos los gráficos juntos
grid.arrange(grobs = graficas, ncol = 2)

Rotación vs. Viaje de Negocios:

  • La rotación es más alta entre los empleados que viajan frecuentemente por negocios en los empleados que rotan.Esto sugiere que los viajes frecuentes podrían estar relacionados con la insatisfacción o el agotamiento laboral.

  • La relación es significativa (p < 0.001), pero la V de Cramer (0.13) indica que la relación es débil.

Rotación vs. Departamento:

  • La rotación varía según el departamento, se muestra un aumento en la participación porcentual en el departamento de ventas en el grupo de los empleados que rotan.

  • La relación es significativa (p = 0.005), pero V de Cramer (0.09) sugiere que la relación es débil.

Rotación vs. Campo de Educación:

  • Los Técnicos y Mercadeo tienen mas incidencia en el grupo de empleados que rotan.Esto sugiere que estos empleados pueden enfrentar desafíos específicos en la empresa que los llevan a buscar otras oportunidades.

  • La relación es significativa (p < 0.001), pero V de Cramer (0.11) sugiere que la relación es débil.

Rotación vs. Satisfacción Ambiental:

  • La rotación es más alta entre los empleados insatisfechos o muy insatisfechos con el ambiente laboral.Un ambiente de trabajo negativo parece influir en la decisión de renunciar.

  • Relación significativa (p < 0.001), pero V de Cramer (0.12) sugiere que la relación es débil.

Rotación vs. Género:

  • La rotación es similar entre hombres y mujeres.

  • p = 0.29 indica que no hay una asociación significativa, por lo que el género no parece influir en la rotación.

Rotación vs. Cargo:

  • Los empleados en cargos técnicos y de ventas presentan tasas de rotación más altas.

  • Relación significativa (p < 0.001) y la V de Cramer (0.24), que indica una relación moderada.

Rotación vs. Satisfacción Laboral:

  • La rotación es más alta entre los empleados insatisfechos y muy insatisfechos.

  • Relación significativa (p < 0.001) y la V de Cramer (0.11) sugiere una relación débil.

Rotación vs. Estado Civil:

  • La rotación es más alta entre empleados solteros, seguida de divorciados y casados, lo que podría reflejar las distintas prioridades de estos grupos.

  • Relación significativa (p < 0.001) y la V de Cramer (0.18) indica una relación débil a moderada.

Rotación vs. Horas Extra:

  • La rotación es mucho mayor entre empleados que trabajan horas extra , en comparación con los que no las hacen. Esto sugiere que las horas extra pueden contribuir al agotamiento y la decisión de renunciar.

  • Relación significativa (p < 0.001), Phi (0.25) indica una relación moderada.

Rotación vs. Rendimiento Laboral:

  • La rotación es similar entre empleados de rendimiento alto y muy alto.

  • p = 0.99 indica que no hay una asociación significativa.

Rotación vs. Equilibrio Trabajo-Vida:

  • La rotación es más alta entre los empleados con un bajo equilibrio o muy bajo entre trabajo y vida personal. Esto sugiere que un equilibrio deficiente afecta la retención de empleados.

  • Relación significativa (p < 0.001) y la V de Cramer (0.11) indica que la relación es débil.

Finalmente se resalta que las relaciones mas relevantes son Rotación VS Cargo y Rotación VS Horas Extra, ambas con relaciones moderadas de acuerdo a la V de Cramer. Adicionalmente El género y el Rendimiento Laboral no tienen influencia significativa en la rotación de empleados.

Variables Cuantitativas.

library(ggplot2)
library(gridExtra)

# Identificar variables cuantitativas automáticamente
cuantitativas <- names(rotacion)[sapply(rotacion, is.numeric)]

# Inicializar la lista de gráficos
graficos <- list()

# Verificar si hay variables cuantitativas
if (length(cuantitativas) == 0) {
  stop("No se encontraron variables cuantitativas en el dataset 'rotacion'.")
}

# Generar histogramas para cada variable cuantitativa
for (var in cuantitativas) {
  p <- ggplot(rotacion, aes(x = .data[[var]], fill = Rotación)) +
    geom_histogram(position = "identity", alpha = 0.3, bins = 15, color = "black") +
    labs(title = paste("Distribución de", var, "por Rotación"),
         x = var, y = "Frecuencia") +
    theme_minimal() +
    theme(
      plot.title = element_text(hjust = 0.5, size = 10, face = "bold"),
      axis.text.x = element_text(size = 9),
      axis.text.y = element_text(size = 9),
      axis.title.x = element_text(size = 10, face = "bold"),
      axis.title.y = element_text(size = 10, face = "bold"),
      legend.title = element_text(size = 10, face = "bold"),
      legend.text = element_text(size = 9)
    ) +
    scale_fill_manual(values = c("skyblue", "salmon"))  # Personaliza colores

  # Agregar el gráfico a la lista
  graficos[[length(graficos) + 1]] <- p
}

# Mostrar los gráficos en un panel
if (length(graficos) > 0) {
  grid.arrange(grobs = graficos, ncol = 2)
} else {
  message("No se generaron gráficos debido a errores en las variables.")
}

Distribución de Edad por Rotación:La mayoría de los empleados se concentran entre 30 y 40 años. La rotación ocurre en todos los grupos de edad, pero parece más frecuente en empleados jóvenes (20-35 años).

Distribución de Distancia_Casa por Rotación: La mayoría de los empleados viven cerca del trabajo (0-5 km). No hay una tendencia clara de que la distancia tenga un fuerte impacto en la rotación.

Distribución de Ingreso_Mensual por Rotación: La mayoría de los empleados tienen ingresos entre 2,000 y 6,000. La rotación parece ser mayor en empleados con ingresos más bajos.

Distribución de Trabajos_Anteriores por Rotación: La mayoría de los empleados han tenido 0-2 trabajos anteriores. La rotación es más común en aquellos con más trabajos anteriores, lo que podría indicar una tendencia a cambiar de empleo frecuentemente.

Distribución de Porcentaje_aumento_salarial por Rotación: La mayoría ha recibido aumentos salariales entre 10% y 15%. No hay un patrón claro que indique que un aumento salarial bajo o alto influya directamente en la rotación.

Distribución de Años_Experiencia por Rotación: La mayoría de los empleados tienen menos de 15 años de experiencia. La rotación parece más frecuente en empleados con menos experiencia.

Distribución de Capacitaciones por Rotación: La mayoría ha recibido 0-2 capacitaciones. No se observa una relación clara entre la cantidad de capacitaciones y la rotación.

Distribución de Antigüedad por Rotación: La mayoría de los empleados tiene menos de 10 años en la empresa. La rotación es más común en empleados con poca antigüedad.

Distribución de Antigüedad_Cargo por Rotación: La mayoría lleva menos de 5 años en su cargo actual. La rotación es más frecuente en aquellos con menor tiempo en su cargo.

Distribución de Años_ultima_promoción por Rotación: La mayoría de los empleados no ha sido promovido en los últimos años. No hay una tendencia clara entre el tiempo desde la última promoción y la rotación.

Distribución de Años_acargo_con_mismo_jefe por Rotación :La mayoría ha estado con el mismo jefe por menos de 5 años. La rotación es más frecuente cuando los empleados tienen menos tiempo con su jefe, lo que podría indicar que el liderazgo influye en la retención.

A continuación se muestran los resultados del test T Student de las variables cuantitativas del conjunto de datos de rotación.

#librerías
library(dplyr)
library(kableExtra)

# Asegurar que "Rotación" es un factor para evitar errores.
rotacion$Rotación <- as.factor(rotacion$Rotación)

# Identificar variables cuantitativas
cuantitativas <- rotacion %>%
  select_if(is.numeric) %>%
  colnames()

# Aplicar prueba t a cada variable
resultados_ttest <- lapply(cuantitativas, function(var) {
  prueba <- t.test(rotacion[[var]] ~ rotacion$Rotación)
  interpretacion <- ifelse(prueba$p.value < 0.05, "Diferencia significativa", "No significativa")
  
  data.frame(Variable = var, p_value = round(prueba$p.value, 4), Interpretación = interpretacion)
})

# resultados en un dataframe
resultados_ttest_df <- do.call(rbind, resultados_ttest)

# Ordenar por p-value
resultados_ttest_df <- resultados_ttest_df[order(resultados_ttest_df$p_value), ]

# Crear tabla con formato kableExtra
resultados_ttest_df %>%
  kbl(caption = "<div align='center'>Resultados del Test t para Variables Cuantitativas</div>") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE) %>%
  column_spec(2, bold = TRUE) %>%  # Resaltar p-value
  row_spec(which(resultados_ttest_df$p_value < 0.05), background = "#D4EDDA")  # Resaltar filas
Resultados del Test t para Variables Cuantitativas
Variable p_value Interpretación
1 Edad 0.0000 Diferencia significativa
3 Ingreso_Mensual 0.0000 Diferencia significativa
6 Años_Experiencia 0.0000 Diferencia significativa
8 Antigüedad 0.0000 Diferencia significativa
9 Antigüedad_Cargo 0.0000 Diferencia significativa
11 Años_acargo_con_mismo_jefe 0.0000 Diferencia significativa
2 Distancia_Casa 0.0041 Diferencia significativa
7 Capacitaciones 0.0204 Diferencia significativa
4 Trabajos_Anteriores 0.1163 No significativa
10 Años_ultima_promoción 0.1987 No significativa
5 Porcentaje_aumento_salarial 0.6144 No significativa

El análisis muestra que variables como la edad, ingreso mensual, años de experiencia, antigüedad y distancia al trabajo tienen un impacto significativo en la rotación de empleados. Esto sugiere que factores relacionados con la estabilidad y la ubicación pueden influir en la decisión de permanecer o dejar la empresa. Adicionalmente, el porcentaje de aumento salarial, los años desde la última promoción y la cantidad de trabajos anteriores no muestran una relación significativa con la rotación, lo que indica que otros aspectos, como el ambiente laboral o el crecimiento profesional, podrían tener mayor relevancia.

Comparación de las hipótesis:

Respecto a las variables seleccionadas en el apartado anterior, se resalta lo siguiente:

Variables categóricas:

Cargo:

La prueba de Chi-cuadrado muestra una asociación significativa entre el cargo y la rotación laboral (p=2.75×10−15), lo que indica que la probabilidad de rotación varía según el cargo.

# Tabla de contingencia y prueba de Chi-cuadrado
tabla_cargo <- table(rotacion$Cargo, rotacion$Rotación)
print(tabla_cargo)
##                          
##                            No  Si
##   Director_Investigación   78   2
##   Director_Manofactura    135  10
##   Ejecutivo_Ventas        269  57
##   Gerente                  97   5
##   Investigador_Cientifico 245  47
##   Recursos_Humanos         40  12
##   Representante_Salud     122   9
##   Representante_Ventas     50  33
##   Tecnico_Laboratorio     197  62
chisq.test(tabla_cargo)
## 
##  Pearson's Chi-squared test
## 
## data:  tabla_cargo
## X-squared = 86.19, df = 8, p-value = 2.752e-15

Horas Extra:

La prueba de Chi-cuadrado indica una asociación significativa entre las horas extra y la rotación laboral (p<2.2e−16)

# Tabla de contingencia y prueba de Chi-cuadrado
tabla_horas <- table(rotacion$Horas_Extra, rotacion$Rotación)
print(tabla_horas)
##     
##       No  Si
##   No 944 110
##   Si 289 127
chisq.test(tabla_horas)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  tabla_horas
## X-squared = 87.564, df = 1, p-value < 2.2e-16

Estado Civil:

La prueba de Chi-cuadrado indica una asociación significativa entre el estado civil y la rotación laboral (p<0.001).

# Tabla de contingencia y prueba de Chi-cuadrado
tabla_estado <- table(rotacion$`Estado_Civil`, rotacion$Rotación)
print(tabla_estado)
##             
##               No  Si
##   Casado     589  84
##   Divorciado 294  33
##   Soltero    350 120
chisq.test(tabla_estado)
## 
##  Pearson's Chi-squared test
## 
## data:  tabla_estado
## X-squared = 46.164, df = 2, p-value = 9.456e-11

Variables Cuantitativas:

Ingreso Mensual

La prueba t indica una diferencia significativa en el ingreso mensual entre empleados que permanecen y los que rotan (p<0.001).

# Prueba t para comparar medias
t.test(Ingreso_Mensual ~ Rotación, data = rotacion)
## 
##  Welch Two Sample t-test
## 
## data:  Ingreso_Mensual by Rotación
## t = 7.4826, df = 412.74, p-value = 4.434e-13
## alternative hypothesis: true difference in means between group No and group Si is not equal to 0
## 95 percent confidence interval:
##  1508.244 2583.050
## sample estimates:
## mean in group No mean in group Si 
##         6832.740         4787.093

Años de Experiencia:

La prueba t indica una diferencia significativa en los años de experiencia entre empleados que permanecen y los que rotan (p<0.001)

# Prueba t para comparar medias
t.test(Años_Experiencia ~ Rotación, data = rotacion)
## 
##  Welch Two Sample t-test
## 
## data:  Años_Experiencia by Rotación
## t = 7.0192, df = 350.88, p-value = 1.16e-11
## alternative hypothesis: true difference in means between group No and group Si is not equal to 0
## 95 percent confidence interval:
##  2.604401 4.632019
## sample estimates:
## mean in group No mean in group Si 
##        11.862936         8.244726

Distancia a la casa:

La prueba t indica una diferencia significativa en la distancia al hogar entre empleados que permanecen y los que rotan (p<0.01)

# Prueba t para comparar medias
t.test(Distancia_Casa ~ Rotación, data = rotacion)
## 
##  Welch Two Sample t-test
## 
## data:  Distancia_Casa by Rotación
## t = -2.8882, df = 322.72, p-value = 0.004137
## alternative hypothesis: true difference in means between group No and group Si is not equal to 0
## 95 percent confidence interval:
##  -2.8870025 -0.5475146
## sample estimates:
## mean in group No mean in group Si 
##         8.915653        10.632911

Teniendo en cuenta lo anterior, se confirman todas las hipótesis planteadas en el apartado anterior en relación a la rotación de personal, por lo cual se procederá a la construcción del modelo.

4. Estimación del modelo

Creación del Modelo.

A continuación, se presenta la transformación de los datos para entrenar el modelo de Regresión Logística con el objetivo de predecir la rotación de empleados.

En primer lugar, se aplica la técnica de One-Hot Encoding para convertir las variables categóricas a un formato adecuado para el modelo. Posteriormente, se escalan las variables numéricas para evitar que aquellas con valores más grandes dominen el modelo. Además, la variable objetivo se convierte a una escala binaria (0 y 1).

Una vez transformados los datos, se dividen en conjuntos de entrenamiento y prueba (70%-30%). Dado que el conjunto de datos está desbalanceado, se utiliza la técnica SMOTE (Synthetic Minority Over-sampling Technique) la cual crea muestras sintéticas de la clase minoritaria (rotación) para equilibrar el conjunto de datos y mejorar el rendimiento del modelo.

Finalmente, tras el análisis bivariado, se seleccionan las siguientes variables para la construcción del modelo de regresión logística con función GLM.

  • Cargo

  • Horas Extra

  • Estado Civil

  • Ingreso Mensual por Categoría

  • Años de Experiencia

  • Distancia al Trabajo

  • Rotación (variable objetivo)

# librerías
library(dplyr)
library(caret)
library(themis)   # SMOTE
library(recipes)  # step_smote()

# Cargar el dataset
rotacion_data <- rotacion

rotacion_data$Ingreso_Cat <- cut(
  rotacion_data$Ingreso_Mensual,
  breaks = quantile(rotacion_data$Ingreso_Mensual, probs = seq(0, 1, 0.25), na.rm = TRUE),
  include.lowest = TRUE,
  labels = c("Bajo", "Medio Bajo", "Medio Alto", "Alto")
)

# Correción de los nombres de las columnas
colnames(rotacion_data) <- gsub(" ", "_", colnames(rotacion_data))

# Convertir la variable de respuesta a factor
rotacion_data$Rotación <- factor(ifelse(rotacion_data$Rotación == "Si", "Sí", "No"), levels = c("No", "Sí"))

# Agregar id para poder hacer comparaciones.
rotacion_data$ID <- 1:nrow(rotacion_data)

# Seleccionar columnas de interés.
columnas_seleccionadas <- c("ID", "Cargo", "Horas_Extra", "Estado_Civil", 
                             "Ingreso_Cat", "Años_Experiencia", "Distancia_Casa", "Rotación")
data_seleccionado <- rotacion_data[, columnas_seleccionadas]

# Manejo de valores faltantes para evitar problemas
data_seleccionado <- na.omit(data_seleccionado)

# Dividir en entrenamiento (70%) y prueba (30%)
set.seed(123)
split <- createDataPartition(data_seleccionado$Rotación, p = 0.7, list = FALSE)
train_data <- data_seleccionado[split, ]
test_data <- data_seleccionado[-split, ]

# Guardar ID en test_data para su uso posterior
test_data_IDs <- test_data$ID  

# Eliminar ID para el preprocesamiento y modelo
train_data <- train_data[, !(colnames(train_data) %in% "ID")]
test_data <- test_data[, !(colnames(test_data) %in% "ID")]

# Crear un recipe para preprocesamiento y SMOTE
rec <- recipe(Rotación ~ ., data = train_data) %>%
  step_dummy(all_nominal_predictors(), one_hot = FALSE) %>%  # One-Hot Encoding
  step_normalize(all_numeric_predictors()) %>%  # Escalar variables numéricas
  step_smote(Rotación, over_ratio = 1)  # Aplicar SMOTE

# Preparar y aplicar el preprocesamiento
prep_rec <- prep(rec)
train_data_balanced <- juice(prep_rec)
test_data_prepared <- bake(prep_rec, new_data = test_data)

# Entrenar el modelo de Regresión Logística
model <- glm(Rotación ~ ., data = train_data_balanced, family = binomial)

# Predicciones en el conjunto de prueba
pred_prob <- predict(model, newdata = test_data_prepared, type = "response")
pred_class <- ifelse(pred_prob > 0.5, "Sí", "No")

# Restaurar los IDs en test_data para futuras referencias
test_data_prepared$ID <- test_data_IDs

Matriz de confusión.

# Crear matriz de confusión
conf_matrix <- confusionMatrix(factor(pred_class, levels = c("No", "Sí")), test_data_prepared$Rotación)

# Visualizar la Matriz de Confusión con ggplot2
library(ggplot2)
library(reshape2)

conf_matrix_df <- as.data.frame(conf_matrix$table)
colnames(conf_matrix_df) <- c("Predicción", "Clase_Real", "Frecuencia")

ggplot(conf_matrix_df, aes(x = Predicción, y = Clase_Real, fill = Frecuencia)) +
  geom_tile(color = "white") +
  geom_text(aes(label = Frecuencia), color = "black", size = 5) + 
  scale_fill_gradient(low = "white", high = "blue") +  # Colores de intensidad
  labs(title = "Matriz de Confusión", x = "Predicción", y = "Clase Real") +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
    axis.text.x = element_text(face = "bold", size = 12),
    axis.text.y = element_text(face = "bold", size = 12),
    legend.title = element_text(face = "bold"),
    legend.text = element_text(size = 10)
  )

Métricas de desempeño

library(kableExtra)

# métricas de evaluación.
metrics <- tibble::tibble(
  Métrica = c("Accuracy", "Precision", "Recall (Sensibilidad)", 
              "Specificity (Especificidad)", "F1-Score", "Balanced Accuracy"),
  Valor = c(
    as.numeric(conf_matrix$overall["Accuracy"]),
    as.numeric(conf_matrix$byClass["Precision"]),
    as.numeric(conf_matrix$byClass["Recall"]),
    as.numeric(conf_matrix$byClass["Specificity"]),
    as.numeric(conf_matrix$byClass["F1"]),
    as.numeric(conf_matrix$byClass["Balanced Accuracy"])
  )
)

# Mostrar la tabla en Kable Extra.
metrics %>%
  kable(align = "c", col.names = c("Métrica", "Valor"), 
        caption = "<div align='center'>Métricas de Evaluación del Modelo</div>") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = F)
Métricas de Evaluación del Modelo
Métrica Valor
Accuracy 0.7090909
Precision 0.9169550
Recall (Sensibilidad) 0.7181572
Specificity (Especificidad) 0.6619718
F1-Score 0.8054711
Balanced Accuracy 0.6900645

Respecto a las métricas se puede resaltar lo siguiente:

El modelo tiene una precisión (Precision) alta (91.69%), lo que indica que la mayoría de las predicciones de rotación fueron correctas. Sin embargo, el recall (71.81%) sugiere que aún se están perdiendo algunos casos de empleados que realmente rotan.

La accuracy general es 70.9%, pero la Balanced Accuracy (69.0%) muestra que el modelo mantiene un rendimiento equilibrado entre clases. La especificidad (71.83%) indica que también identifica bien a los empleados que no rotan.

El F1-Score (80.54%) refleja un buen balance entre precisión y recall, lo que sugiere un rendimiento aceptable, aunque aún se pueden hacer mejoras para detectar mejor la clase minoritaria, como por ejemplo implementar validación cruzada.

Significancia del modelo -prueba de razón de verosimilitud.

La prueba de razón de verosimilitud muestra un estadístico chi-cuadrado de 630.22 con 16 grados de libertad y un p-valor extremadamente bajo (9.70 × 10⁻¹⁰⁵), lo que indica una fuerte evidencia contra el modelo nulo. Esto sugiere que el modelo ajustado con predictores mejora significativamente el ajuste en comparación con el modelo sin ellos.

# Cargar las librerías necesarias
library(knitr)
library(kableExtra)

# Calcular la chi-cuadrado de razón de verosimilitud
X2 <- with(model, null.deviance - deviance)

# Grados de libertad
df <- with(model, df.null - df.residual)

# Calcular el p-valor asociado a la estadística chi-cuadrado
p_value <- pchisq(X2, df, lower.tail = FALSE)

# Data frame con los resultados
resultados <- data.frame(
  Estadístico = c("Chi-cuadrado", "Grados de libertad", "P-valor"),
  Valor = c(X2, df, p_value)
)

# Mostrar la tabla
kable(resultados, col.names = c("Estadístico", "Valor"), digits = 9, align = "c") %>%
  kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover", "condensed", "responsive"))
Estadístico Valor
Chi-cuadrado 630.2207
Grados de libertad 16.0000
P-valor 0.0000

Análisis de Variables Predictoras del Modelo

library(kableExtra)

# Coeficientes del modelo
tabla_coeficientes <- as.data.frame(summary(model)$coefficients)
colnames(tabla_coeficientes) <- c("Estimado", "Error Estándar", "Z-valor", "p-valor")

# Agregar nombres de variables sin repetir
tabla_coeficientes <- tibble::rownames_to_column(tabla_coeficientes, var = "Variable")

# Calcular el Chi-cuadrado de Wald
tabla_coeficientes$Chi_Cuadrado_Wald <- tabla_coeficientes$`Z-valor`^2

# Ordenar las columnas
tabla_coeficientes <- tabla_coeficientes[, c("Variable", "Estimado", "Error Estándar", "Z-valor", "Chi_Cuadrado_Wald", "p-valor")]

# Generar tabla con kableExtra
tabla_coeficientes %>%
  kable("html", caption = "<div align='center'>Resumen del Modelo de Regresión Logística</div>") %>%
  kable_styling(full_width = FALSE, position = "center", bootstrap_options = c("striped", "hover"))
Resumen del Modelo de Regresión Logística
Variable Estimado Error Estándar Z-valor Chi_Cuadrado_Wald p-valor
(Intercept) -0.6428665 0.0707704 -9.083833 82.516023 0.0000000
Años_Experiencia -0.2998441 0.0977671 -3.066922 9.406013 0.0021628
Distancia_Casa 0.2660477 0.0616121 4.318110 18.646077 0.0000157
Cargo_Director_Manofactura 0.4802639 0.1415346 3.393263 11.514230 0.0006907
Cargo_Ejecutivo_Ventas 1.0719976 0.1847643 5.801974 33.662905 0.0000000
Cargo_Gerente -0.2670376 0.1595778 -1.673401 2.800269 0.0942485
Cargo_Investigador_Cientifico 0.6270748 0.1933601 3.243042 10.517319 0.0011826
Cargo_Recursos_Humanos 0.5381468 0.1029788 5.225800 27.308989 0.0000002
Cargo_Representante_Salud 0.3988596 0.1358477 2.936080 8.620564 0.0033239
Cargo_Representante_Ventas 0.6665110 0.1245579 5.351014 28.633353 0.0000001
Cargo_Tecnico_Laboratorio 1.0685376 0.1827554 5.846817 34.185269 0.0000000
Horas_Extra_Si 0.6889922 0.0582497 11.828246 139.907406 0.0000000
Estado_Civil_Divorciado -0.0719833 0.0707378 -1.017607 1.035524 0.3088649
Estado_Civil_Soltero 0.5846157 0.0650581 8.986054 80.749171 0.0000000
Ingreso_Cat_Medio.Bajo -0.4383412 0.0776946 -5.641848 31.830446 0.0000000
Ingreso_Cat_Medio.Alto -0.4367468 0.1103834 -3.956633 15.654946 0.0000760
Ingreso_Cat_Alto 0.2539905 0.1389227 1.828286 3.342631 0.0675066

Cargo:

Varios cargos muestran una influencia significativa en la probabilidad de rotación. Por ejemplo:

  • Ser “Director de Investigación” o “Director de Manufactura” se asocia con una disminución significativa en la probabilidad de rotación (valores Z negativos y p-valores cercanos a 0).
  • Ser “Gerente” también tiene un impacto negativo fuerte en la probabilidad de rotación (p-valor ≈ 0).
  • Por otro lado, ser “Representante de Ventas” no muestra un impacto significativo en la probabilidad de rotación (p-valor = 0.1946), lo que sugiere que esta variable no es estadísticamente significativa en el modelo.
  • Cargos como “Recursos Humanos” y “Representante de Salud” también muestran efectos no significativos (p-valores > 0.05).

Horas Extra (Horas_Extra_si):

No trabajar horas extras (Horas_Extra_No) tiene un efecto negativo y muy significativo en la probabilidad de rotación (valor Z = 11.49, p-valor ≈ 0). Esto sugiere que los empleados que trabajan horas extras tienen una probabilidad significativamente mayor de rotar.

Estado Civil:

  • Estar “Casado” o “Divorciado” se asocia con una disminución significativa en la probabilidad de rotación (valores Z negativos y p-valores cercanos a 0).

  • El estado civil “Soltero” tiene un efecto significativo en la probabilidad de rotación,sugiriendo que estos empleados tienen mayor probabilidad de rotar.

Ingreso Mensual por Categoría (Ingreso_Cat):

Cuando se utilizó la variable Ingreso Mensual de forma continua en el modelo, se observó una relación positiva con la probabilidad de rotación (coeficiente = 0.7366, p-valor ≈ 0), lo que sugiere que, a mayor ingreso, mayor probabilidad de que un empleado rote. Este resultado resulta contraintuitivo, ya que normalmente se espera que salarios más altos estén asociados con una mayor retención.

Sin embargo, al transformar el ingreso en una variable categórica por cuartiles (Ingreso_Cat), el modelo ofreció una perspectiva más coherente con la lógica esperada. Las categorías “Medio Bajo” y “Medio Alto” mostraron una relación negativa y significativa con la rotación, lo que indica que empleados en estos rangos de ingreso tienen menor probabilidad de dejar la empresa, con respecto a la categoria “Baja”. Por otro lado, la categoría “Alto” mantuvo una relación positiva, aunque no significativa, lo cual sugiere que este grupo podría estar influenciado por otros factores no capturados en el modelo, como mayores oportunidades externas o mayores exigencias laborales.

Estos resultados demuestran que el efecto del ingreso sobre la rotación no es lineal, y que la categorización por niveles ofrece un análisis más realista que permite detectar matices importantes que se pierden al tratar el ingreso como una variable numérica continua.

Años de Experiencia (Años_Experiencia):

Los años de experiencia tienen una relación negativa con la probabilidad de rotación (coeficiente = -0.2998, p-valor ≈ 0). Esto indica que, a mayor experiencia, menor es la probabilidad de rotación.

Distancia a Casa (Distancia_Casa):

La distancia de la casa al trabajo tiene una relación positiva con la probabilidad de rotación (coeficiente = 0.266, p-valor ≈ 0). Esto sugiere que, a mayor distancia, mayor es la probabilidad de rotación.

Significancia Estadística:

Los p-valores indican la significancia estadística de cada variable. Valores pequeños (< 0.05) sugieren que la variable tiene un efecto estadísticamente significativo en la predicción de la rotación de personal. En este caso: - Variables como Cargo, Horas Extra, Estado Civil, Ingreso Mensual, Años de Experiencia y Distancia a Casa son altamente significativas (p-valores < 0.05). Algunas categorías de Cargo, como “Gerente” no son significativas (p-valores > 0.05).

Finalmente, no todas las variables aparecen en la tabla porque algunas son categorías de referencia, utilizadas como base para la comparación y evitar colinealidad.

5. Evaluación

A continuación se evalua la capacidad de poder predictivo del modelo usando la Curva ROC y el AUC. El Área Bajo la Curva (AUC) de 0.7508 indica una capacidad moderada del modelo para discriminar entre clases. La curva azul por encima de la línea diagonal roja muestra que el modelo tiene cierta capacidad predictiva.

library(ggplot2)
library(pROC)

# Calcular la curva ROC
roc_curve <- roc(test_data_prepared$Rotación, pred_prob)

# Calcular el valor del AUC
auc_value <- auc(roc_curve)

# Crear un data frame con los valores de la curva ROC
roc_df <- data.frame(
  Sensitivity = roc_curve$sensitivities,
  Specificity = roc_curve$specificities
)

# Graficar con ggplot2
ggplot(roc_df, aes(x = 1 - Specificity, y = Sensitivity)) +
  geom_line(color = "blue", linewidth = 1) +  # Línea de la curva ROC
  geom_abline(linetype = "dashed", color = "red") +  # Línea de referencia (diagonal)
  labs(
    x = "1 - Especificidad", 
    y = "Sensibilidad",
    title = "Curva ROC"
  ) +
  annotate("text", x = 0.6, y = 0.3, label = paste("AUC =", round(auc_value, 4)), color = "red", size = 5) +  # Anotación del AUC
  theme_minimal() + theme(plot.title = element_text(hjust = 0.5))

6. Predicciones

En este caso se tomó un empleado hipotético que cumple con las características para tener una alta probabilidad de rotación teniendo en cuenta el análisis realizado en las variables categóricas y cuantitativas, dando como resultado que se tiene que intervenir a ese empleado para generar medidas para evitar su posible rotación.

Atributo Valor
Cargo Ejecutivo_Ventas
Horas_Extra Si
Estado_Civil Soltero
Ingreso_Mensual 1500
Años_Experiencia 3
Distancia_Casa 20
# Cargar las librerías necesarias
library(dplyr)
library(recipes)
library(kableExtra)

# Crear un individuo hipotético con valores personalizados
individuo_hipotetico <- data.frame(
  Cargo = "Ejecutivo_Ventas",  
  Horas_Extra = "Si",  
  Estado_Civil = "Soltero",  
  Ingreso_Mensual = 1500,  
  Años_Experiencia = 3,  
  Distancia_Casa = 20  
)

individuo_hipotetico$Ingreso_Cat <- cut(
  individuo_hipotetico$Ingreso_Mensual,
  breaks = quantile(rotacion_data$Ingreso_Mensual, probs = seq(0, 1, 0.25), na.rm = TRUE),
  include.lowest = TRUE,
  labels = c("Bajo", "Medio Bajo", "Medio Alto", "Alto")
)

individuo_hipotetico <- individuo_hipotetico %>% select(-Ingreso_Mensual)

# Supongamos que ya tienes un modelo y una receta de preprocesamiento
# Aplicar el preprocesamiento al individuo hipotético
individuo_preprocesado <- bake(prep_rec, new_data = individuo_hipotetico)

# Predecir la probabilidad de rotación
probabilidad_rotacion <- predict(model, newdata = individuo_preprocesado, type = "response")

# Definir un umbral de intervención
corte_intervencion <- 0.5
intervenir <- ifelse(probabilidad_rotacion > corte_intervencion, "Sí", "No")

# Crear un data frame con los resultados
resultados <- data.frame(
  Probabilidad_Rotacion = round(probabilidad_rotacion, 4),
  Intervencion = intervenir
)

# Mostrar los resultados en una tabla usando kableExtra (con hover)
kable(resultados) %>%
  kable_styling(full_width = FALSE,position = "center",bootstrap_options = c("hover", "condensed"))
Probabilidad_Rotacion Intervencion
0.956

7. Conclusiones

El análisis evidencia que la rotación de empleados está influenciada principalmente por variables como el cargo, las horas extra, el equilibrio entre trabajo y vida personal, la satisfacción laboral y ambiental, el estado civil y los viajes de negocio. Estas variables reflejan que la estabilidad, las condiciones laborales y la carga de trabajo son factores determinantes en la permanencia de los empleados.

Entre los hallazgos más relevantes, se destaca que los empleados en cargos técnicos y de ventas presentan mayores tasas de rotación, así como aquellos que trabajan horas extra con frecuencia. Además, un ambiente de trabajo negativo y un bajo equilibrio entre vida personal y laboral aumentan la probabilidad de renuncia. Por otro lado, factores como el género y el rendimiento laboral no mostraron una influencia significativa en la rotación, lo que indica que la permanencia en la empresa está más relacionada con condiciones externas y percepciones del entorno laboral.

Dado lo anterior, se proponen las siguientes estrategias para reducir la rotación en la empresa:

Optimización de la carga laboral y reducción de horas extra:

  • Implementar una mejor planificación de turnos para reducir la sobrecarga de trabajo.

  • Contratar personal adicional en áreas con alta demanda de horas extra.

  • Evaluar incentivos para compensar el esfuerzo adicional cuando las horas extra sean inevitables.

Mejoramiento del ambiente y la satisfacción laboral:

  • Realizar encuestas periódicas de clima laboral para identificar áreas de mejora.

  • Implementar programas de bienestar y reconocimiento para reforzar la motivación.

  • Ofrecer oportunidades de crecimiento y capacitación para mejorar la percepción de desarrollo profesional.

Equilibrio entre trabajo y vida personal:

  • Fomentar políticas de teletrabajo o flexibilidad horaria para empleados en posiciones adecuadas.

  • Crear programas de apoyo para empleados con dificultades en la conciliación familiar.

Revisión de condiciones en cargos con alta rotación:

  • Evaluar el nivel de exigencia y carga laboral de los cargos técnicos y de ventas.

  • Implementar planes de carrera y promociones internas para aumentar la retención en estos puestos.

Minimizar el impacto de los viajes de negocio:

  • Revisar la necesidad de viajes frecuentes y priorizar alternativas como reuniones virtuales.

  • Ofrecer beneficios adicionales a empleados que requieran viajar con frecuencia.

En conclusión, para reducir la rotación de empleados, la empresa debe enfocarse en mejorar las condiciones laborales, promover un equilibrio entre la vida personal y profesional, reducir la carga de trabajo excesiva y optimizar la gestión del talento en los cargos con mayor rotación. Implementar estas estrategias no solo contribuirá a la retención del talento, sino que también mejorará la productividad y satisfacción general de los empleados.