## Loading required package: cubature
## Loading required package: dplyr
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:MASS':
## 
##     select
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
## Loading required package: flextable
## Warning: package 'flextable' was built under R version 4.3.2
## Loading required package: ggplot2
## Loading required package: lmtest
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: psych
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
## Loading required package: summarytools
## Loading required package: randtests
## Loading required package: rapportools
## 
## Attaching package: 'rapportools'
## The following objects are masked from 'package:summarytools':
## 
##     label, label<-
## The following object is masked from 'package:dplyr':
## 
##     n
## The following objects are masked from 'package:stats':
## 
##     IQR, median, sd, var
## The following objects are masked from 'package:base':
## 
##     max, mean, min, range, sum

1. Problema Rotación de cargo

1.1 Análisis Exploratorio del Dataset

Comenzamos por revisar que tipo de datos tiene cada columna y que tipo de datos podemos tener en cada uno de las columnas

tipos_de_datos <- sapply(rotacion, class)
print(tipos_de_datos)
##                    Rotación                        Edad 
##                 "character"                   "numeric" 
##           Viaje de Negocios                Departamento 
##                 "character"                 "character" 
##              Distancia_Casa                   Educación 
##                   "numeric"                   "numeric" 
##             Campo_Educación      Satisfacción_Ambiental 
##                 "character"                   "numeric" 
##                      Genero                       Cargo 
##                 "character"                 "character" 
##         Satisfación_Laboral                Estado_Civil 
##                   "numeric"                 "character" 
##             Ingreso_Mensual         Trabajos_Anteriores 
##                   "numeric"                   "numeric" 
##                 Horas_Extra Porcentaje_aumento_salarial 
##                 "character"                   "numeric" 
##         Rendimiento_Laboral            Años_Experiencia 
##                   "numeric"                   "numeric" 
##              Capacitaciones     Equilibrio_Trabajo_Vida 
##                   "numeric"                   "numeric" 
##                  Antigüedad            Antigüedad_Cargo 
##                   "numeric"                   "numeric" 
##       Años_ultima_promoción  Años_acargo_con_mismo_jefe 
##                   "numeric"                   "numeric"

De lo anterior tenemos que las variables que nos interesan son 14 variables que son de tipo numérico, por lo que no hay necesidad de transformarlas. Y tenemos otras 10 de tipo string incluidas la variable objetivo “Rotación”. Vamos a ver un resumen descriptivo de las variables.

summary(rotacion)
##    Rotación              Edad       Viaje de Negocios  Departamento      
##  Length:1470        Min.   :18.00   Length:1470        Length:1470       
##  Class :character   1st Qu.:30.00   Class :character   Class :character  
##  Mode  :character   Median :36.00   Mode  :character   Mode  :character  
##                     Mean   :36.92                                        
##                     3rd Qu.:43.00                                        
##                     Max.   :60.00                                        
##  Distancia_Casa     Educación     Campo_Educación    Satisfacción_Ambiental
##  Min.   : 1.000   Min.   :1.000   Length:1470        Min.   :1.000         
##  1st Qu.: 2.000   1st Qu.:2.000   Class :character   1st Qu.:2.000         
##  Median : 7.000   Median :3.000   Mode  :character   Median :3.000         
##  Mean   : 9.193   Mean   :2.913                      Mean   :2.722         
##  3rd Qu.:14.000   3rd Qu.:4.000                      3rd Qu.:4.000         
##  Max.   :29.000   Max.   :5.000                      Max.   :4.000         
##     Genero             Cargo           Satisfación_Laboral Estado_Civil      
##  Length:1470        Length:1470        Min.   :1.000       Length:1470       
##  Class :character   Class :character   1st Qu.:2.000       Class :character  
##  Mode  :character   Mode  :character   Median :3.000       Mode  :character  
##                                        Mean   :2.729                         
##                                        3rd Qu.:4.000                         
##                                        Max.   :4.000                         
##  Ingreso_Mensual Trabajos_Anteriores Horas_Extra       
##  Min.   : 1009   Min.   :0.000       Length:1470       
##  1st Qu.: 2911   1st Qu.:1.000       Class :character  
##  Median : 4919   Median :2.000       Mode  :character  
##  Mean   : 6503   Mean   :2.693                         
##  3rd Qu.: 8379   3rd Qu.:4.000                         
##  Max.   :19999   Max.   :9.000                         
##  Porcentaje_aumento_salarial Rendimiento_Laboral Años_Experiencia
##  Min.   :11.00               Min.   :3.000       Min.   : 0.00   
##  1st Qu.:12.00               1st Qu.:3.000       1st Qu.: 6.00   
##  Median :14.00               Median :3.000       Median :10.00   
##  Mean   :15.21               Mean   :3.154       Mean   :11.28   
##  3rd Qu.:18.00               3rd Qu.:3.000       3rd Qu.:15.00   
##  Max.   :25.00               Max.   :4.000       Max.   :40.00   
##  Capacitaciones  Equilibrio_Trabajo_Vida   Antigüedad     Antigüedad_Cargo
##  Min.   :0.000   Min.   :1.000           Min.   : 0.000   Min.   : 0.000  
##  1st Qu.:2.000   1st Qu.:2.000           1st Qu.: 3.000   1st Qu.: 2.000  
##  Median :3.000   Median :3.000           Median : 5.000   Median : 3.000  
##  Mean   :2.799   Mean   :2.761           Mean   : 7.008   Mean   : 4.229  
##  3rd Qu.:3.000   3rd Qu.:3.000           3rd Qu.: 9.000   3rd Qu.: 7.000  
##  Max.   :6.000   Max.   :4.000           Max.   :40.000   Max.   :18.000  
##  Años_ultima_promoción Años_acargo_con_mismo_jefe
##  Min.   : 0.000        Min.   : 0.000            
##  1st Qu.: 0.000        1st Qu.: 2.000            
##  Median : 1.000        Median : 3.000            
##  Mean   : 2.188        Mean   : 4.123            
##  3rd Qu.: 3.000        3rd Qu.: 7.000            
##  Max.   :15.000        Max.   :17.000

Con lo anterior identificamos los rangos en los que se mueven las distintas variables numéricas, observamos que la mayoría de los datos se encuentran en rangos de similares, entre 0 y 10.

Comenzamos por la relación entre nuestras variables y la variable numéricas con la variable objetivo.

1.1.1 Análisis Para Variables Numericas

library(GGally)
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
# Seleccionar las variables de interés
variables_interes <- c("Rendimiento_Laboral", "Años_Experiencia", "Capacitaciones",
                       "Equilibrio_Trabajo_Vida", "Porcentaje_aumento_salarial",
                       "Satisfacción_Ambiental", "Edad", "Educación", "Rotación")

# Subconjunto de datos con las variables de interés
datos_interes <- rotacion[, variables_interes]

# Gráfico de pares con la variable categórica "Rotacion"
ggpairs(datos_interes, aes(color = Rotación),
        title = "Correlación entre variables y rotación", progress = FALSE)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

library(GGally)

# Seleccionar las variables de interés
variables_interes <- c("Antigüedad", "Antigüedad_Cargo",
                       "Años_ultima_promoción", "Años_acargo_con_mismo_jefe",
                       "Satisfación_Laboral", "Distancia_Casa", "Rotación")

# Subconjunto de datos con las variables de interés
datos_interes <- rotacion[, variables_interes]

# Gráfico de pares con la variable categórica "Rotacion"
ggpairs(datos_interes, aes(color = Rotación),
        title = "Correlación entre variables y rotación", progress = FALSE)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

De lo anterior observanmos que las variables que mejor me puedan ayudar a segmentar ambas poblaciones son la Edad, ya que vemos que como las dos distribuciones de Si(verde) y No(Rojo) se segmentan mejor sobre esta variables, así mismo la satisfacción laboral, y satisfacción ambiental.

# Convertir "Si" a 1 y "No" a 0 en la columna "Rotación"
rotacion$Rotación <- as.numeric(rotacion$Rotación == "Si")
rotacion
## # A tibble: 1,470 × 24
##    Rotación  Edad `Viaje de Negocios` Departamento Distancia_Casa Educación
##       <dbl> <dbl> <chr>               <chr>                 <dbl>     <dbl>
##  1        1    41 Raramente           Ventas                    1         2
##  2        0    49 Frecuentemente      IyD                       8         1
##  3        1    37 Raramente           IyD                       2         2
##  4        0    33 Frecuentemente      IyD                       3         4
##  5        0    27 Raramente           IyD                       2         1
##  6        0    32 Frecuentemente      IyD                       2         2
##  7        0    59 Raramente           IyD                       3         3
##  8        0    30 Raramente           IyD                      24         1
##  9        0    38 Frecuentemente      IyD                      23         3
## 10        0    36 Raramente           IyD                      27         3
## # ℹ 1,460 more rows
## # ℹ 18 more variables: Campo_Educación <chr>, Satisfacción_Ambiental <dbl>,
## #   Genero <chr>, Cargo <chr>, Satisfación_Laboral <dbl>, Estado_Civil <chr>,
## #   Ingreso_Mensual <dbl>, Trabajos_Anteriores <dbl>, Horas_Extra <chr>,
## #   Porcentaje_aumento_salarial <dbl>, Rendimiento_Laboral <dbl>,
## #   Años_Experiencia <dbl>, Capacitaciones <dbl>,
## #   Equilibrio_Trabajo_Vida <dbl>, Antigüedad <dbl>, Antigüedad_Cargo <dbl>, …
library(ltm)
## Warning: package 'ltm' was built under R version 4.3.3
## Loading required package: msm
## Warning: package 'msm' was built under R version 4.3.3
## Loading required package: polycor
## Warning: package 'polycor' was built under R version 4.3.3
## 
## Attaching package: 'polycor'
## The following object is masked from 'package:psych':
## 
##     polyserial
## 
## Attaching package: 'ltm'
## The following object is masked from 'package:psych':
## 
##     factor.scores
# Definir las variables de interés
variables_interes <- c("Rendimiento_Laboral", "Años_Experiencia", "Capacitaciones",
                       "Equilibrio_Trabajo_Vida", "Porcentaje_aumento_salarial",
                       "Satisfacción_Ambiental", "Edad", "Educación", "Antigüedad", "Antigüedad_Cargo",
                       "Años_ultima_promoción", "Años_acargo_con_mismo_jefe",
                       "Satisfación_Laboral", "Distancia_Casa")


# Inicializar una lista para almacenar los resultados de correlación
correlation_results <- list()

# Calcular el coeficiente de punto biserial para cada variable continua
for (column in variables_interes) {
  result <- biserial.cor(rotacion[[column]], rotacion$Rotación)
  correlation_results[[column]] <- result
}

# Crear un dataframe con los resultados de la correlación
correlation_df <- data.frame(Variable = names(correlation_results), Correlation = unlist(correlation_results))

# Ordenar el dataframe por el valor absoluto de la correlación
correlation_df <- correlation_df[order(abs(correlation_df$Correlation), decreasing = TRUE),]

correlation_df
##                                                Variable  Correlation
## Años_Experiencia                       Años_Experiencia  0.171063246
## Antigüedad_Cargo                       Antigüedad_Cargo  0.160545004
## Edad                                               Edad  0.159227826
## Años_acargo_con_mismo_jefe   Años_acargo_con_mismo_jefe  0.156199316
## Antigüedad                                   Antigüedad  0.134392214
## Satisfación_Laboral                 Satisfación_Laboral  0.103481126
## Satisfacción_Ambiental           Satisfacción_Ambiental  0.103368978
## Distancia_Casa                           Distancia_Casa -0.077923583
## Equilibrio_Trabajo_Vida         Equilibrio_Trabajo_Vida  0.063939047
## Capacitaciones                           Capacitaciones  0.059477799
## Años_ultima_promoción             Años_ultima_promoción  0.033018775
## Educación                                     Educación  0.031372820
## Porcentaje_aumento_salarial Porcentaje_aumento_salarial  0.013478202
## Rendimiento_Laboral                 Rendimiento_Laboral -0.002888752
# Inicializar una lista para almacenar los resultados de correlación
correlation_results <- list()

# Calcular la correlación de Kendall para cada variable
for (column in variables_interes) {
  result <- cor(rotacion[[column]], rotacion$Rotación, method = "kendall")
  correlation_results[[column]] <- result
}

# Crear un dataframe con los resultados de la correlación
correlation_df <- data.frame(Variable = names(correlation_results), Correlation = unlist(correlation_results))

# Ordenar el dataframe por el valor absoluto de la correlación
correlation_df <- correlation_df[order(abs(correlation_df$Correlation), decreasing = TRUE),]

correlation_df
##                                                Variable  Correlation
## Años_Experiencia                       Años_Experiencia -0.166781144
## Antigüedad                                   Antigüedad -0.161005913
## Antigüedad_Cargo                       Antigüedad_Cargo -0.156710954
## Años_acargo_con_mismo_jefe   Años_acargo_con_mismo_jefe -0.152006156
## Edad                                               Edad -0.142027312
## Satisfación_Laboral                 Satisfación_Laboral -0.094304759
## Satisfacción_Ambiental           Satisfacción_Ambiental -0.088376678
## Distancia_Casa                           Distancia_Casa  0.066764681
## Equilibrio_Trabajo_Vida         Equilibrio_Trabajo_Vida -0.049365275
## Años_ultima_promoción             Años_ultima_promoción -0.047753106
## Capacitaciones                           Capacitaciones -0.047153882
## Educación                                     Educación -0.027817077
## Porcentaje_aumento_salarial Porcentaje_aumento_salarial -0.020189908
## Rendimiento_Laboral                 Rendimiento_Laboral  0.002888752
# Inicializar una lista para almacenar los resultados de correlación
correlation_results <- list()

# Calcular la correlación de Kendall para cada variable
for (column in variables_interes) {
  result <- cor(rotacion[[column]], rotacion$Rotación, method = "spearman")
  correlation_results[[column]] <- result
}

# Crear un dataframe con los resultados de la correlación
correlation_df <- data.frame(Variable = names(correlation_results), Correlation = unlist(correlation_results))

# Ordenar el dataframe por el valor absoluto de la correlación
correlation_df <- correlation_df[order(abs(correlation_df$Correlation), decreasing = TRUE),]

correlation_df
##                                                Variable  Correlation
## Años_Experiencia                       Años_Experiencia -0.199002020
## Antigüedad                                   Antigüedad -0.190419098
## Antigüedad_Cargo                       Antigüedad_Cargo -0.180623030
## Años_acargo_con_mismo_jefe   Años_acargo_con_mismo_jefe -0.175355081
## Edad                                               Edad -0.171231659
## Satisfación_Laboral                 Satisfación_Laboral -0.102948195
## Satisfacción_Ambiental           Satisfacción_Ambiental -0.096486420
## Distancia_Casa                           Distancia_Casa  0.079248186
## Años_ultima_promoción             Años_ultima_promoción -0.053272642
## Equilibrio_Trabajo_Vida         Equilibrio_Trabajo_Vida -0.051951357
## Capacitaciones                           Capacitaciones -0.051757308
## Educación                                     Educación -0.030345908
## Porcentaje_aumento_salarial Porcentaje_aumento_salarial -0.023612035
## Rendimiento_Laboral                 Rendimiento_Laboral  0.002888752

De acuerdo a lo anterior pensamos que las variables mas adecuadas y mas relacionadas para trabajar serían los años de experiencia, la antiguedad, antiguedad cargo, edad y años a cargo con mismo jefe

1.1.2 Análisis Para Variables Categoricas

Con las variables categóricas procedemos a observar los valores únicos para cada una de las categorías. Para saber que datos tenemos disponibles por categoría.

# Obtener los valores únicos de cada columna
valores_viaje_negocios <- unique(rotacion$'Viaje de Negocios')
valores_departamento <- unique(rotacion$Departamento)
valores_educacion <- unique(rotacion$Campo_Educación)
valores_genero <- unique(rotacion$Genero)
valores_cargo <- unique(rotacion$Cargo)
valores_estado_civil <- unique(rotacion$Estado_Civil)
valores_horas_extra <- unique(rotacion$Horas_Extra)
valores_rotacion <- unique(rotacion$Rotación)

# Imprimir los valores únicos de cada columna
print("Valores únicos de la columna 'Viaje de Negocios':")
## [1] "Valores únicos de la columna 'Viaje de Negocios':"
print(valores_viaje_negocios)
## [1] "Raramente"      "Frecuentemente" "No_Viaja"
print("Valores únicos de la columna 'Departamento':")
## [1] "Valores únicos de la columna 'Departamento':"
print(valores_departamento)
## [1] "Ventas" "IyD"    "RH"
print("Valores únicos de la columna 'Campo Educación':")
## [1] "Valores únicos de la columna 'Campo Educación':"
print(valores_educacion)
## [1] "Ciencias"    "Otra"        "Salud"       "Mercadeo"    "Tecnicos"   
## [6] "Humanidades"
print("Valores únicos de la columna 'Género':")
## [1] "Valores únicos de la columna 'Género':"
print(valores_genero)
## [1] "F" "M"
print("Valores únicos de la columna 'Cargo':")
## [1] "Valores únicos de la columna 'Cargo':"
print(valores_cargo)
## [1] "Ejecutivo_Ventas"        "Investigador_Cientifico"
## [3] "Tecnico_Laboratorio"     "Director_Manofactura"   
## [5] "Representante_Salud"     "Gerente"                
## [7] "Representante_Ventas"    "Director_Investigación" 
## [9] "Recursos_Humanos"
print("Valores únicos de la columna 'Estado Civil':")
## [1] "Valores únicos de la columna 'Estado Civil':"
print(valores_estado_civil)
## [1] "Soltero"    "Casado"     "Divorciado"
print("Valores únicos de la columna 'Horas Extra':")
## [1] "Valores únicos de la columna 'Horas Extra':"
print(valores_horas_extra)
## [1] "Si" "No"
print("Valores únicos de la columna 'Rotación':")
## [1] "Valores únicos de la columna 'Rotación':"
print(valores_rotacion)
## [1] 1 0

Ahora para determinar si nuestra variables categóricas están relacionadas con Rotación procedemos a usar la prueba de Chi-Cuadrado, que son “Viaje de Negocios”, “Departamento”, “Campo Educación”, “Género”, “Cargo” y “Estado Civil”.

Para las variables binaria “Horas Extra” y la variable objetivo “Rotación”, vamos a usar la prueba de chi-cuadrado y el coeficiente de contingencia para evaluar la asociación entre estas variables.

# Instalacion de paquete
library(grid)

# Instalacion de paquete
library(vcd)
## Warning: package 'vcd' was built under R version 4.3.3
# Prueba de independencia chi-cuadrado para variables categóricas
chi_square_test_viaje_negocios <- chisq.test(rotacion$'Viaje de Negocios', rotacion$Rotación)
chi_square_test_departamento <- chisq.test(rotacion$Departamento, rotacion$Rotación)
chi_square_test_educacion <- chisq.test(rotacion$Campo_Educación, rotacion$Rotación)
## Warning in chisq.test(rotacion$Campo_Educación, rotacion$Rotación): Chi-squared
## approximation may be incorrect
chi_square_test_genero <- chisq.test(rotacion$Genero, rotacion$Rotación)
chi_square_test_cargo <- chisq.test(rotacion$Cargo, rotacion$Rotación)
chi_square_test_estado_civil <- chisq.test(rotacion$Estado_Civil, rotacion$Rotación)

# Prueba de independencia chi-cuadrado para variables binarias
chi_square_test_horas_extra <- chisq.test(rotacion$Horas_Extra, rotacion$Rotación)

# Coeficiente de contingencia para variables binarias
coef_contingencia_horas_extra <- assocstats(table(rotacion$Horas_Extra, rotacion$Rotación))

# Mostrar resultados
print("Prueba de independencia chi-cuadrado para variables categóricas:")
## [1] "Prueba de independencia chi-cuadrado para variables categóricas:"
print(chi_square_test_viaje_negocios)
## 
##  Pearson's Chi-squared test
## 
## data:  rotacion$"Viaje de Negocios" and rotacion$Rotación
## X-squared = 24.182, df = 2, p-value = 5.609e-06
print(chi_square_test_departamento)
## 
##  Pearson's Chi-squared test
## 
## data:  rotacion$Departamento and rotacion$Rotación
## X-squared = 10.796, df = 2, p-value = 0.004526
print(chi_square_test_educacion)
## 
##  Pearson's Chi-squared test
## 
## data:  rotacion$Campo_Educación and rotacion$Rotación
## X-squared = 16.025, df = 5, p-value = 0.006774
print(chi_square_test_genero)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  rotacion$Genero and rotacion$Rotación
## X-squared = 1.117, df = 1, p-value = 0.2906
print(chi_square_test_cargo)
## 
##  Pearson's Chi-squared test
## 
## data:  rotacion$Cargo and rotacion$Rotación
## X-squared = 86.19, df = 8, p-value = 2.752e-15
print(chi_square_test_estado_civil)
## 
##  Pearson's Chi-squared test
## 
## data:  rotacion$Estado_Civil and rotacion$Rotación
## X-squared = 46.164, df = 2, p-value = 9.456e-11
print("Prueba de independencia chi-cuadrado y coeficiente de contingencia para variable binaria:")
## [1] "Prueba de independencia chi-cuadrado y coeficiente de contingencia para variable binaria:"
print(chi_square_test_horas_extra)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  rotacion$Horas_Extra and rotacion$Rotación
## X-squared = 87.564, df = 1, p-value < 2.2e-16
print(coef_contingencia_horas_extra)
##                     X^2 df P(> X^2)
## Likelihood Ratio 81.402  1        0
## Pearson          89.044  1        0
## 
## Phi-Coefficient   : 0.246 
## Contingency Coeff.: 0.239 
## Cramer's V        : 0.246

Para seleccionar las tres variables más significativas para predecir la “Rotación” basado en los resultados de las pruebas de independencia chi-cuadrado, podrías considerar aquellas variables que tienen los valores de chi-cuadrado más altos y los p-values más bajos. Esto indicaría una asociación más fuerte entre esas variables y la variable objetivo “Rotación”. Basado en los resultados proporcionados, las tres variables más prometedoras podrían ser:

Cargo: Tiene el valor de chi-cuadrado más alto y el p-valor más bajo entre todas las variables categóricas, lo que indica una fuerte asociación entre el cargo y la rotación.

Estado Civil: También tiene un alto valor de chi-cuadrado y un p-valor muy bajo, lo que sugiere una relación significativa con la rotación.

Horas Extra: Para la variable binaria “Horas Extra”, el valor de chi-cuadrado es muy alto y el p-valor es extremadamente bajo, lo que indica una fuerte asociación con la rotación. Además, el coeficiente de contingencia y otras medidas también sugieren una asociación moderada.

Por lo tanto, basado en estos resultados, podrías considerar estas tres variables (Cargo, Estado Civil y Horas Extra) como las más prometedoras para predecir la rotación en tu modelo. Sin embargo, siempre es importante tener en cuenta el contexto específico de tu problema y las características de tus datos al seleccionar las variables para tu modelo predictivo.

1.2 Escoger variables.

Las variables numericas a escoger son:

  • experiencia
  • antiguedad
  • Años a cargo con mismo jefe

Las variables categoricas a escoger son:

  • Cargo
  • Estado Civil
  • Horas Extra
# Seleccionar las variables de interés
variables_seleccionadas <- c("Años_Experiencia", "Antigüedad", "Años_acargo_con_mismo_jefe", "Cargo", "Horas_Extra", "Estado_Civil","Rotación")

# Crear un nuevo dataframe con las variables seleccionadas
rotacion_df <- rotacion[, variables_seleccionadas]

# Mostrar las primeras filas del nuevo dataset
head(rotacion_df)
## # A tibble: 6 × 7
##   Años_Experiencia Antigüedad Años_acargo_con_mismo_jefe Cargo       Horas_Extra
##              <dbl>      <dbl>                      <dbl> <chr>       <chr>      
## 1                8          6                          5 Ejecutivo_… Si         
## 2               10         10                          7 Investigad… No         
## 3                7          0                          0 Tecnico_La… Si         
## 4                8          8                          0 Investigad… Si         
## 5                6          2                          2 Tecnico_La… No         
## 6                8          7                          6 Tecnico_La… No         
## # ℹ 2 more variables: Estado_Civil <chr>, Rotación <dbl>

2. Analisis Univariado

Comenzamos por revisar un histograma de cada uno de las variables numericas a continuacion para observar como se comporta la variable.

El histograma de años de Experiencia y comportarse de manera mas cerca una normal, pero podríamos hacer hipótesis para confirmarlo.

Tambien revisamos para las categóricas cuantos valores diferentes tenemos para cada categoría.

3. Analisis Bivariado.

4. Desarrollo de Modelo.

4.1 Division Train-Test Modelo

Ya que sabmos con que variables vamos a trabajar procedemos a dividir nuestro dataset en train y test.

## Warning: package 'caret' was built under R version 4.3.3
## Loading required package: lattice

Procedemos a observar el conjunto de datos obtenido.

# Mostrar las primeras filas del nuevo dataset
head(datos_entrenamiento)
## # A tibble: 6 × 7
##   Años_Experiencia Antigüedad Años_acargo_con_mismo_jefe Cargo       Horas_Extra
##              <dbl>      <dbl>                      <dbl> <chr>       <chr>      
## 1                8          6                          5 Ejecutivo_… Si         
## 2               10         10                          7 Investigad… No         
## 3                8          8                          0 Investigad… Si         
## 4                6          2                          2 Tecnico_La… No         
## 5                8          7                          6 Tecnico_La… No         
## 6                1          1                          0 Tecnico_La… No         
## # ℹ 2 more variables: Estado_Civil <chr>, Rotación <dbl>
# Mostrar las primeras filas del nuevo dataset
head(datos_prueba)
## # A tibble: 6 × 7
##   Años_Experiencia Antigüedad Años_acargo_con_mismo_jefe Cargo       Horas_Extra
##              <dbl>      <dbl>                      <dbl> <chr>       <chr>      
## 1                7          0                          0 Tecnico_La… Si         
## 2               12          1                          0 Tecnico_La… Si         
## 3                3          2                          2 Tecnico_La… No         
## 4                6          4                          3 Tecnico_La… Si         
## 5                5          4                          3 Director_M… No         
## 6               10          5                          3 Representa… No         
## # ℹ 2 more variables: Estado_Civil <chr>, Rotación <dbl>

Ya con esto podemos proceder a generar el modelo con los datos de entrenamiento generados.

4.2 Entrenamiento Modelo Logit

datos_entrenamiento$Rotaciondatos_entrenamiento$Rotación
## Warning: Unknown or uninitialised column: `Rotaciondatos_entrenamiento`.
## NULL
# Estimar el modelo logit con variables categóricas
modelo_logit <- glm(datos_entrenamiento$Rotación ~ ., data = datos_entrenamiento, family = binomial)

# Mostrar un resumen del modelo
summary(modelo_logit)
## 
## Call:
## glm(formula = datos_entrenamiento$Rotación ~ ., family = binomial, 
##     data = datos_entrenamiento)
## 
## Coefficients:
##                              Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                  -4.08496    1.09567  -3.728 0.000193 ***
## Años_Experiencia             -0.03369    0.02190  -1.538 0.123994    
## Antigüedad                    0.04644    0.03327   1.396 0.162671    
## Años_acargo_con_mismo_jefe   -0.11090    0.04706  -2.357 0.018439 *  
## CargoDirector_Manofactura     1.40403    1.09091   1.287 0.198084    
## CargoEjecutivo_Ventas         2.07758    1.05675   1.966 0.049299 *  
## CargoGerente                  0.79187    1.19468   0.663 0.507440    
## CargoInvestigador_Cientifico  1.77748    1.06892   1.663 0.096337 .  
## CargoRecursos_Humanos         2.96360    1.12669   2.630 0.008530 ** 
## CargoRepresentante_Salud      1.30556    1.10444   1.182 0.237168    
## CargoRepresentante_Ventas     3.10745    1.10121   2.822 0.004775 ** 
## CargoTecnico_Laboratorio      2.51856    1.06491   2.365 0.018028 *  
## Horas_ExtraSi                 1.50162    0.19792   7.587 3.27e-14 ***
## Estado_CivilDivorciado       -0.41054    0.29155  -1.408 0.159100    
## Estado_CivilSoltero           0.95829    0.20705   4.628 3.69e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 896.03  on 1028  degrees of freedom
## Residual deviance: 728.42  on 1014  degrees of freedom
## AIC: 758.42
## 
## Number of Fisher Scoring iterations: 6

De lo anterior obtenemos unos valores similares a lo anterior. Un \(b_{0}\) pequeño, y el modelo logit quedaria de la siguiente manera.

\(Rotacion = \frac{1}{1 + e^{-(\beta_{0} + \beta_{1}* AnosExperiencia + \beta_{2}* Antiguedad + \beta_{3}* AnosCargoConMismoJefe + \beta_{4} * CargoDirectorManofactura + \beta_{5} * CargoEjecutivoVentas + \beta_{6} * Cargo_Gerente + \beta_{7} * CargoInvestigadorCientifico + \beta_{8} * CargoRecursosHumanos + \beta_{9} * CargoRepresentanteSalud + \beta_{10} * CargoRepresentanteVentas + \beta_{11} * CargoTecnicoLaboratorio + \beta_{12} * HorasExtraSi + \beta_{13} * EstadoCivilDivorciado + \beta_{14} * EstadoCivilSoltero)}}\)

5. Evaluacion Modelo

Lo que observamos de nuestro \(R^{2}\) es que con un valor \(R^{2}=0.6507\), nos puede explicar 65% de la variabilidad de los datos, de manera proporcional. Lo ideal sería que fuera cerca 1, pero en este caso no se presenta.

Para mejorar esta metrica podríamos tomar acciones como buscar mas variables relevante para el modelo, escalar las variables para que esten en la misma magnitud, también eliminar outliers, detectar de multicolinealidad para eliminar variables que tal vez presenten redundancia de información.

# Predecir las probabilidades de rotación para los datos de prueba
#predicciones <- predict(modelo_logit, newdata = datos_prueba, type = "response")

predicciones <- predict(modelo_logit, newdata = datos_prueba, type = "response")

# Convertir las predicciones en clases basadas en un umbral de decisión
clases_predichas <- ifelse(predicciones > 0.5, "Si", "No")

# Calcular la precisión
precision <- mean(clases_predichas == datos_prueba$Rotación)
precision
## [1] 0

Obtuvimos una métrica de precision de 0.84 de los valores, lo cual es muy positivo. Ahora procedemos a graficar la curva ROC

# Instalar y cargar el paquete pROC si aún no lo has hecho
install.packages("pROC")
## Installing package into 'C:/Users/CARLOS AREVALO/AppData/Local/R/win-library/4.3'
## (as 'lib' is unspecified)
## Warning in download.file(url, destfile, method, mode = "wb", ...): the
## 'wininet' method is deprecated for http:// and https:// URLs
## package 'pROC' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'pROC'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\CARLOS
## AREVALO\AppData\Local\R\win-library\4.3\00LOCK\pROC\libs\x64\pROC.dll a
## C:\Users\CARLOS AREVALO\AppData\Local\R\win-library\4.3\pROC\libs\x64\pROC.dll:
## Permission denied
## Warning: restored 'pROC'
## 
## The downloaded binary packages are in
##  C:\Users\CARLOS AREVALO\AppData\Local\Temp\Rtmpasb5TA\downloaded_packages
library(pROC)
## Warning: package 'pROC' was built under R version 4.3.3
## Type 'citation("pROC")' for a citation.
## 
## Attaching package: 'pROC'
## The following object is masked from 'package:rapportools':
## 
##     var
## The following objects are masked from 'package:stats':
## 
##     cov, smooth, var
# Calcular la curva ROC
curva_roc <- roc(datos_prueba$Rotación, predicciones)
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
# Graficar la curva ROC
plot(curva_roc, main = "Curva ROC", col = "blue", lwd = 2)

# Calcular el área bajo la curva (AUC)
auc <- auc(curva_roc)

# Mostrar el valor del AUC en la gráfica
text(0.5, 0.5, paste("AUC =", round(auc, 2)), adj = c(0.5, -0.5))

# Añadir una línea de referencia diagonal
abline(a = 0, b = 1, lty = 2)

# Añadir leyenda
legend("bottomright", legend = paste("AUC =", round(auc, 2)), col = "blue", lty = 1, cex = 0.8)

Con lo anterior obtuvimos una gran métrica, lo que mas queremos evitar es la es que sea 0.5, que significa que no tiene la capacidad de predecir, con un 0,78 significa que tiene un buen nivel para segmentar ambos grupos y captar la generalidad de cada uno de los grupos. Hay buen equilibrio entre sensitividad y especificidad. Ademas de que con un accuracy de 0.841 es buen valor.

6. Conclusiones :

  • Hacer un buen tratamiento de datos y análisis extenso antes de generar un modelo predictivo es importante para que cuando el modelo y algoritmo se configure pueda tener un mejor desempeño al momento de evaluarlo.

  • Las métricas para determinar si el resultado de un modelo es bueno, en este caso lo mejor es usar ROC y accuracy. Para determinar el comportamiento del modelo.

  • Lo que observamos es que las personas casadas o con mas años de experiencia. Suelen buscar lugares mas estables para permanecer, lo que ayuda a evitar la rotación, en general la sensación de inestabilidad de un lugar de trabajo, por eso tambien manetener el jefe usual, es algo que ayuda a determinar si alguien se va a quedar, o las horas extra, ya que las horas extra para alguien que quiere estabilidad no es algo muy positivo, en general como estrategia para poder retener trabajadores lo mejor es ofrecer estabilidad laboral, donde los horarios sean claros, las funcionalidades y asi mismo las personas con las que se va trabajar para generar la sensación de familiaridad y constancia