## 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
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.
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
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.
Las variables numericas a escoger son:
Las variables categoricas a escoger son:
# 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>
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.
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.
datos_entrenamiento$Rotación
## [1] 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0
## [38] 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0
## [75] 1 0 1 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
## [112] 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0
## [149] 1 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
## [186] 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
## [223] 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0
## [260] 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0
## [297] 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0
## [334] 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0
## [371] 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1
## [408] 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
## [445] 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0
## [482] 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0
## [519] 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0
## [556] 0 1 0 1 1 0 1 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0
## [593] 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
## [630] 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
## [667] 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0
## [704] 0 0 1 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0
## [741] 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1
## [778] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
## [815] 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 1
## [852] 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0
## [889] 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0
## [926] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
## [963] 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
## [1000] 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
# 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)}}\)
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, "1", "0")
# Calcular la precisión
precision <- mean(clases_predichas == datos_prueba$Rotación)
precision
## [1] 0.845805
Obtuvimos una métrica de precision de 0.85 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\RtmpOcZB8S\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.
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