En el presente trabajo se buscará desarrollar una tecnica de la inteligencia artificial para resolver la siguiente tarea: "Predecir el salario neto por hora de un empleado del sector tecnologico en Argentina en base a las caracteristicas del empleo y su desarrollo profesional". Para esta tarea se implementará una red neuronal artificial donde el output será una aproximación al salario.
El mercado laboral del sector tecnologico argentino tiene caracteristicas muy particulares y resulta de especial interes, sobre todo para trabajadores y empleadores del sector, tener una vision más certera de como se mueve el mercado laboral. Una de las caracteristicas de mayor interes es el salario de los empleados. Para relevar esta información de mano directa de los empleados se creo la plataforma www.encuestasit.com, donde se encuesta a los empleados sobre las caracteristicas de su trabajo, su desarrollo profesional y su salario. Esta encuesta se realiza anualmente y luego se publican los resultados en el sitio. Ademas se suben los datos en crudo en formato csv. Para este trabajo solo se utilizarán datos del 2016. El objetivo es aproximar el salario neto por hora de un empleado en función de las caracteristicas del trabajo y del trabajador.
Modelo de RNA utilizada con la justificación de su elección. Se utilizará el modelo Backpropagation ya que es el que mejor se ajusta a la tareas de aproximación y clasificación.
Arquitectura y topología final de la RNA. En principio una sola capa oculta de 20 neuronas. Esta limitación en el modelo corresponde más a limitaciones de infraestructura hardware necesaria para entrenar el modelo que a un ajuste que busque minimizar el error de la aproximación
TODO
Descripción de los patrones utilizados para el entrenamiento y la validación de la RNA (por lo menos se debe utilizar un 25% de los patrones disponibles para la validación). Se separa el dataset en 2 sub conjuntos: un conjunto de entrenamiento que contiene el 70% de los casos, elegidos aleatoreamente, que se utilizará para el entrenamiento. Y otro subconjunto de validación con el 30% de los casos restantes.
Herramientas, lenguajes y/o librerías seleccionadas para la implementación de la RNA. Se implementara en R, utilizando la libreria de redes neuronales llamada neuralnet
En caso de haber utilizado varios prototipos, las características de las principales versiones utilizadas.
El promedio de los salarios es de $261. Podemos decir que la predicción está en promedio en un +/- 24% del salario real.
La aproximación es lo suficientemente buena para al menos poder tener una idea del rango salarial de la persona.
Ademas podemos analizar el histograma del error en la predicción, lo que nos da una idea más clara de como lo está haciendo nuestro modelo al predecir los salarios:
TODO: Agregar histograma
Vemos que es una distribuccion normal con centro en 0, y la gran mayoria de los casos están en el intervalo (-100; 100).
Análisis de los resultados obtenidos en la sección anterior. Para ello, se puede evaluar de los resultados según dos perspectivas: - ¿El Sistema Inteligente propuesto resuelve satisfactoriamente el problema? En el caso en que el resultado no fuese satisfactorio, indique posibles causas y proponga cursos de acción. El modelo propuesto aproxima suficientemente bien el salario neto por hora. Se podria mejorar aun más aumentando la cantidad de iteraciones de entrenamiento en conjunto con una disminución del learning rate para aumentar las probabilidades de que el modelo converga en un minimo global. - ¿Cómo se compara con otras arquitecturas? TODO: a que otras arquitecturas se refiere?
# ---------------------- Levantar DataFrame ----------------------
# Levantamos el archivo ya formateado,
encuestas <- read.csv("./datos.csv")
encuestas$X <- NULLVisualizamos un resumen de los datos que vamos a usar para esta clasificación.
# ---------------------- imprimir resumen de campos ----------------------
str(encuestas)## 'data.frame': 17940 obs. of 46 variables:
## $ Edad : int 32 34 52 37 26 31 39 33 30 31 ...
## $ IdSexo : Factor w/ 3 levels "Femenino","Masculino",..: 2 2 2 2 2 2 2 2 2 2 ...
## $ IdNivelEducativo : Factor w/ 10 levels "Master o postgrado completo",..: 10 10 9 10 10 7 9 9 10 10 ...
## $ IdTipoDeEmpresa : Factor w/ 7 levels "Mi propia empresa",..: 7 7 7 7 7 7 7 7 7 7 ...
## $ IdProvincia : Factor w/ 28 levels "Buenos Aires",..: 1 12 2 8 2 2 28 1 25 2 ...
## $ IdPuesto : Factor w/ 90 levels "Administrador Middleware",..: 7 29 7 41 77 27 29 5 47 27 ...
## $ horasTrabajadasXSemana : int 40 45 40 40 35 40 40 50 40 40 ...
## $ TrabajaDesdeCasa : Factor w/ 2 levels "No","Si": 1 1 1 1 1 2 2 1 1 1 ...
## $ LeGustaTrabajarDesdeCasa : Factor w/ 2 levels "No","Si": 2 2 1 2 2 2 1 2 2 2 ...
## $ MesesDeExperiencia : int 96 36 144 96 12 12 36 60 6 60 ...
## $ IdTecnologiaPrincipal : Factor w/ 65 levels ".Net","AS/400",..: 41 1 41 20 41 30 33 33 53 42 ...
## $ MesesEnElPuestoActual : int 36 36 0 36 28 18 30 60 24 24 ...
## $ SalarioActualNeto : int 6000 4500 4300 4750 3300 4900 3200 3900 3200 4500 ...
## $ SalarioIdealNeto : int 10000 7500 6500 6500 4100 6000 4500 5000 5000 6800 ...
## $ SeSientePresionado : int 0 0 0 0 0 0 0 0 10 0 ...
## $ SeSienteSobreexigido : int 10 0 0 0 0 0 10 0 10 0 ...
## $ EnElLugarSeDesarrolla : int 0 10 10 10 10 10 0 10 1 10 ...
## $ LaboresDiariasGratas : int 10 10 10 10 0 10 10 10 0 10 ...
## $ SeLoReconoceComoDebiera : int 10 10 10 0 10 10 0 0 0 10 ...
## $ HayDesarrolloProfesional : int 10 10 10 0 0 10 10 0 0 0 ...
## $ SeSienteMotivado : int 10 10 10 0 0 10 10 0 0 0 ...
## $ RelacionConJefes : int 8 10 10 9 9 6 9 8 4 10 ...
## $ CambioPorMejorSalario : Factor w/ 2 levels "No","Si": 2 2 1 2 2 2 2 2 2 2 ...
## $ CambioPorMejorAmbiente : Factor w/ 2 levels "No","Si": 1 1 1 2 1 1 2 1 2 1 ...
## $ CambioPorFormaDeTrabajo : Factor w/ 2 levels "No","Si": 1 2 1 2 2 1 2 2 2 2 ...
## $ CambioPorTecnologia : Factor w/ 2 levels "No","Si": 1 1 1 2 2 1 2 2 1 2 ...
## $ NoCambio : Factor w/ 2 levels "False","True": 1 1 2 1 1 1 1 1 1 1 ...
## $ CantidadDeMesesParaCambiarDeTrabajo: int NA 12 NA 1 1 12 12 1 12 12 ...
## $ NivelDeDesconfianza : int 0 0 0 0 0 0 1 0 0 0 ...
## $ CambioPorCercania : Factor w/ 3 levels "No","No informa",..: 2 2 2 2 2 2 2 2 2 2 ...
## $ CambioPorMenorCargaHoraria : Factor w/ 3 levels "No","No informa",..: 2 2 2 2 2 2 2 2 2 2 ...
## $ CambioPorOportunidadDeCarrera : Factor w/ 3 levels "No","No informa",..: 2 2 2 2 2 2 2 2 2 2 ...
## $ TienePersonasACargo : Factor w/ 3 levels "No","No informa",..: 2 2 2 2 2 2 2 2 2 2 ...
## $ Relaci.nLaboral : int NA NA NA NA NA NA NA NA NA NA ...
## $ Anio : int 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 ...
## $ Mes : int 6 6 6 6 6 6 6 6 6 6 ...
## $ Semestre : Factor w/ 2 levels "Primer","Segundo": 1 1 1 1 1 1 1 1 1 1 ...
## $ Hora : int 10 10 10 10 11 11 11 11 11 11 ...
## $ RangoHora : Factor w/ 5 levels "Madrugada","Ma\361ana",..: 2 2 2 2 3 3 3 3 3 3 ...
## $ DiferenciaSalarioRealIdeal : int 4000 3000 2200 1750 800 1100 1300 1100 1800 2300 ...
## $ SalarioNetoPorHora : num 150 100 107.5 118.8 94.3 ...
## $ RangoSalario : Factor w/ 5 levels "Alto","Bajo",..: 2 5 5 5 5 5 5 5 5 5 ...
## $ CargaLaboral : Factor w/ 4 levels "Extra Time","Full Time",..: 2 2 2 2 3 2 2 1 2 2 ...
## $ Antiguedad : Factor w/ 4 levels "Expert","Junior",..: 3 3 NA 3 3 2 3 4 3 3 ...
## $ Experiencia : Factor w/ 4 levels "Expert","Junior",..: 4 3 1 4 2 2 3 3 2 3 ...
## $ RangoEdad : Factor w/ 10 levels "(0,20]","(20,25]",..: 4 4 8 5 3 4 5 4 3 4 ...
summary(encuestas)## Edad IdSexo
## Min. :18.00 Femenino : 1859
## 1st Qu.:28.00 Masculino :14926
## Median :32.00 No informa: 1155
## Mean :33.52
## 3rd Qu.:38.00
## Max. :65.00
##
## IdNivelEducativo
## Universitario en curso o incompleto :6015
## Universitario completo :4181
## Terciario completo :3445
## Terciario en curso o incompleto :1397
## Secundario completo :1107
## Master o postgrado en curso o incompleto: 873
## (Other) : 922
## IdTipoDeEmpresa IdProvincia
## Mi propia empresa : 381 Buenos Aires :6817
## No informa : 1376 Capital Federal:6695
## Otro : 317 C<c3><b3>rdoba :1671
## Soy independiente / freelance: 102 Sante Fe : 710
## Un organismo estatal : 980 GBA Zona Norte : 453
## Una ONG : 58 Mendoza : 321
## Una empresa privada :14726 (Other) :1273
## IdPuesto horasTrabajadasXSemana
## Desarrollador de software / Programador:4694 Min. :20.00
## Analista Funcional :1325 1st Qu.:40.00
## Lider de Proyecto :1244 Median :40.00
## Consultor TI : 890 Mean :41.52
## Soporte T<c3><a9>cnico : 672 3rd Qu.:45.00
## Gerente de Sistemas : 623 Max. :96.00
## (Other) :8492
## TrabajaDesdeCasa LeGustaTrabajarDesdeCasa MesesDeExperiencia
## No:14374 No: 5588 Min. : 0.00
## Si: 3566 Si:12352 1st Qu.: 36.00
## Median : 60.00
## Mean : 65.58
## 3rd Qu.: 96.00
## Max. :144.00
##
## IdTecnologiaPrincipal MesesEnElPuestoActual SalarioActualNeto
## .Net :3812 Min. : 0.0 Min. : 3011
## Windows:2557 1st Qu.: 9.0 1st Qu.: 6000
## Java :2447 Median : 24.0 Median : 9000
## Otro :1338 Mean : 33.9 Mean :10811
## Oracle :1086 3rd Qu.: 48.0 3rd Qu.:13500
## SAP :1047 Max. :456.0 Max. :70000
## (Other):5653
## SalarioIdealNeto SeSientePresionado SeSienteSobreexigido
## Min. : 0 Min. : 0.000 Min. : 0.000
## 1st Qu.: 8000 1st Qu.: 2.000 1st Qu.: 1.000
## Median :12000 Median : 5.000 Median : 5.000
## Mean :14563 Mean : 4.815 Mean : 4.728
## 3rd Qu.:18000 3rd Qu.: 7.000 3rd Qu.: 7.000
## Max. :85000 Max. :10.000 Max. :10.000
##
## EnElLugarSeDesarrolla LaboresDiariasGratas SeLoReconoceComoDebiera
## Min. : 0.0 Min. : 0.000 Min. : 0.000
## 1st Qu.: 3.0 1st Qu.: 5.000 1st Qu.: 3.000
## Median : 6.0 Median : 7.000 Median : 5.000
## Mean : 6.1 Mean : 6.744 Mean : 5.265
## 3rd Qu.: 9.0 3rd Qu.:10.000 3rd Qu.: 8.000
## Max. :10.0 Max. :10.000 Max. :10.000
##
## HayDesarrolloProfesional SeSienteMotivado RelacionConJefes
## Min. : 0.000 Min. : 0.000 Min. : 0.000
## 1st Qu.: 2.000 1st Qu.: 2.000 1st Qu.: 6.000
## Median : 5.000 Median : 5.000 Median : 8.000
## Mean : 5.141 Mean : 5.316 Mean : 7.212
## 3rd Qu.: 8.000 3rd Qu.: 8.000 3rd Qu.: 9.000
## Max. :10.000 Max. :10.000 Max. :10.000
##
## CambioPorMejorSalario CambioPorMejorAmbiente CambioPorFormaDeTrabajo
## No: 3411 No:12969 No:10042
## Si:14529 Si: 4971 Si: 7898
##
##
##
##
##
## CambioPorTecnologia NoCambio CantidadDeMesesParaCambiarDeTrabajo
## No:12661 False:15872 Min. : 0.000
## Si: 5279 True : 2068 1st Qu.: 0.000
## Median : 6.000
## Mean : 5.379
## 3rd Qu.:12.000
## Max. :12.000
## NA's :5588
## NivelDeDesconfianza CambioPorCercania CambioPorMenorCargaHoraria
## Min. :0.0000 No :10602 No :10900
## 1st Qu.:0.0000 No informa: 3396 No informa: 3396
## Median :0.0000 Si : 3942 Si : 3644
## Mean :0.2838
## 3rd Qu.:0.0000
## Max. :5.0000
##
## CambioPorOportunidadDeCarrera TienePersonasACargo Relaci.nLaboral
## No :6391 No :9725 Min. :0.00
## No informa:3396 No informa:4603 1st Qu.:1.00
## Si :8153 Si :3612 Median :1.00
## Mean :1.02
## 3rd Qu.:1.00
## Max. :3.00
## NA's :4603
## Anio Mes Semestre Hora
## Min. :2010 Min. : 1.000 Primer :10291 Min. : 0.00
## 1st Qu.:2011 1st Qu.: 2.000 Segundo: 7649 1st Qu.:10.00
## Median :2013 Median : 6.000 Median :13.00
## Mean :2013 Mean : 5.497 Mean :13.26
## 3rd Qu.:2014 3rd Qu.: 8.000 3rd Qu.:17.00
## Max. :2016 Max. :12.000 Max. :23.00
##
## RangoHora DiferenciaSalarioRealIdeal SalarioNetoPorHora
## Madrugada:1381 Min. :-4800 Min. : 46.25
## Ma<f1>ana:3789 1st Qu.: 1600 1st Qu.: 147.17
## Mediodia :5006 Median : 3000 Median : 212.50
## Noche :2591 Mean : 3752 Mean : 263.14
## Tarde :4824 3rd Qu.: 5000 3rd Qu.: 325.00
## NA's : 349 Max. :29500 Max. :1425.00
##
## RangoSalario CargaLaboral Antiguedad
## Alto :3592 Extra Time : 1390 Expert :2304
## Bajo :2754 Full Time :14902 Junior :7672
## Medio :7328 Part Time : 1256 SemiSenior:4600
## Muy Alto:1493 Very Extra Time: 392 Senior :3063
## Muy Bajo:2772 NA's : 301
## NA's : 1
##
## Experiencia RangoEdad
## Expert :3555 (30,35]:4866
## Junior :3282 (25,30]:4794
## SemiSenior:7368 (35,40]:3023
## Senior :2829 (20,25]:2226
## NA's : 906 (40,45]:1455
## (45,50]: 836
## (Other): 740
# ---------------------- primeros campos ----------------------
kable(head(encuestas))| Edad | IdSexo | IdNivelEducativo | IdTipoDeEmpresa | IdProvincia | IdPuesto | horasTrabajadasXSemana | TrabajaDesdeCasa | LeGustaTrabajarDesdeCasa | MesesDeExperiencia | IdTecnologiaPrincipal | MesesEnElPuestoActual | SalarioActualNeto | SalarioIdealNeto | SeSientePresionado | SeSienteSobreexigido | EnElLugarSeDesarrolla | LaboresDiariasGratas | SeLoReconoceComoDebiera | HayDesarrolloProfesional | SeSienteMotivado | RelacionConJefes | CambioPorMejorSalario | CambioPorMejorAmbiente | CambioPorFormaDeTrabajo | CambioPorTecnologia | NoCambio | CantidadDeMesesParaCambiarDeTrabajo | NivelDeDesconfianza | CambioPorCercania | CambioPorMenorCargaHoraria | CambioPorOportunidadDeCarrera | TienePersonasACargo | Relaci.nLaboral | Anio | Mes | Semestre | Hora | RangoHora | DiferenciaSalarioRealIdeal | SalarioNetoPorHora | RangoSalario | CargaLaboral | Antiguedad | Experiencia | RangoEdad |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 32 | Masculino | Universitario en curso o incompleto | Una empresa privada | Buenos Aires | Administrador de Redes | 40 | No | Si | 96 | Otro | 36 | 6000 | 10000 | 0 | 10 | 0 | 10 | 10 | 10 | 10 | 8 | Si | No | No | No | False | NA | 0 | No informa | No informa | No informa | No informa | NA | 2010 | 6 | Primer | 10 | Ma |
400 | 0 150.0000 | 0 Bajo | Full Time | SemiSenior | Senior | (30,35] |
| 34 | Masculino | Universitario en curso o incompleto | Una empresa privada | GBA Zona Oeste | Director de Sistemas | 45 | No | Si | 36 | .Net | 36 | 4500 | 7500 | 0 | 0 | 10 | 10 | 10 | 10 | 10 | 10 | Si | No | Si | No | False | 12 | 0 | No informa | No informa | No informa | No informa | NA | 2010 | 6 | Primer | 10 | Ma |
300 | 0 100.0000 | 0 Muy Bajo | Full Time | SemiSenior | SemiSenior | (30,35] |
| 52 | Masculino | Universitario completo | Una empresa privada | Capital Federal | Administrador de Redes | 40 | No | No | 144 | Otro | 0 | 4300 | 6500 | 0 | 0 | 10 | 10 | 10 | 10 | 10 | 10 | No | No | No | No | True | NA | 0 | No informa | No informa | No informa | No informa | NA | 2010 | 6 | Primer | 10 | Ma |
220 | 0 107.5000 | 0 Muy Bajo | Full Time | NA | Expert | (50,55] |
| 37 | Masculino | Universitario en curso o incompleto | Una empresa privada | C |
Gerente de Operaciones | 40 No | Si | 96 Delphi | 36 | 4750 | 6500 | 0 | 0 | 10 | 10 | 0 | 0 | 0 | 9 Si | Si | Si | Si | False | 1 | 0 No informa | No informa | No informa | No informa | NA | 2010 | 6 Prime | r | 10 Ma |
ana | 1750 11 | 8.75000 Muy Ba | jo Full T | ime Semi | Senior Senio | r (35,40] | |||||
| 26 | Masculino | Universitario en curso o incompleto | Una empresa privada | Capital Federal | Otro | 35 | No | Si | 12 | Otro | 28 | 3300 | 4100 | 0 | 0 | 10 | 0 | 10 | 0 | 0 | 9 | Si | No | Si | Si | False | 1 | 0 | No informa | No informa | No informa | No informa | NA | 2010 | 6 | Primer | 11 | Mediodia | 800 | 94.28571 | Muy Bajo | Part Time | SemiSenior | Junior | (25,30] |
| 31 | Masculino | Terciario completo | Una empresa privada | Capital Federal | Desarrollador de software / Programador | 40 | Si | Si | 12 | Java | 18 | 4900 | 6000 | 0 | 0 | 10 | 10 | 10 | 10 | 10 | 6 | Si | No | No | No | False | 12 | 0 | No informa | No informa | No informa | No informa | NA | 2010 | 6 | Primer | 11 | Mediodia | 1100 | 122.50000 | Muy Bajo | Full Time | Junior | Junior | (30,35] |
# Borramos caracteristicas que estan demasiado vinculadas a lo que vamos a predecir
# No las vamos a utilizar ya que queremos poder predecir el salario en base a
# otras caracteristicas del empleo
encuestas$SalarioActualNeto <- NULL
encuestas$SalarioIdealNeto <- NULL
encuestas$DiferenciaSalarioRealIdeal <- NULL
encuestas$RangoSalario <- NULL
# Convercion de Enums a Int
encuestas$IdSexo <- as.numeric(encuestas$IdSexo)
encuestas$IdNivelEducativo <- as.numeric(encuestas$IdNivelEducativo)
encuestas$IdTipoDeEmpresa <- as.numeric(encuestas$IdTipoDeEmpresa)
encuestas$IdProvincia <- as.numeric(encuestas$IdProvincia)
encuestas$IdPuesto <- as.numeric(encuestas$IdPuesto)
encuestas$TrabajaDesdeCasa <- as.numeric(encuestas$TrabajaDesdeCasa)
encuestas$LeGustaTrabajarDesdeCasa <- as.numeric(encuestas$LeGustaTrabajarDesdeCasa)
encuestas$CambioPorMejorSalario <- as.numeric(encuestas$CambioPorMejorSalario)
encuestas$CambioPorMejorAmbiente <- as.numeric(encuestas$CambioPorMejorAmbiente)
encuestas$CambioPorFormaDeTrabajo <- as.numeric(encuestas$CambioPorFormaDeTrabajo)
encuestas$CambioPorTecnologia <- as.numeric(encuestas$CambioPorTecnologia)
encuestas$NoCambio <- as.numeric(encuestas$NoCambio)
encuestas$NivelDeDesconfianza <- as.numeric(encuestas$NivelDeDesconfianza)
encuestas$CambioPorCercania <- as.numeric(encuestas$CambioPorCercania)
encuestas$CambioPorMenorCargaHoraria <- as.numeric(encuestas$CambioPorMenorCargaHoraria)
encuestas$CambioPorOportunidadDeCarrera <- as.numeric(encuestas$CambioPorOportunidadDeCarrera)
encuestas$TienePersonasACargo <- as.numeric(encuestas$TienePersonasACargo)
encuestas$Relaci.nLaboral <- as.numeric(encuestas$Relaci.nLaboral)
encuestas$RangoHora <- as.numeric(encuestas$RangoHora)
encuestas$CargaLaboral <- as.numeric(encuestas$CargaLaboral)
encuestas$Antiguedad <- as.numeric(encuestas$Antiguedad)
encuestas$Experiencia <- as.numeric(encuestas$Experiencia)
encuestas$RangoEdad <- as.numeric(encuestas$RangoEdad)
encuestas$IdTecnologiaPrincipal <- as.numeric(encuestas$IdTecnologiaPrincipal)
encuestas$CargaLaboral <- as.numeric(encuestas$CargaLaboral)
encuestas$Semestre <- as.numeric(encuestas$Semestre)
# Los valores faltantes (NA) los ponemos en 0
encuestas[is.na(encuestas$CantidadDeMesesParaCambiarDeTrabajo),]$CantidadDeMesesParaCambiarDeTrabajo <- 0
encuestas[is.na(encuestas$Relaci.nLaboral),]$Relaci.nLaboral <- 0
encuestas[is.na(encuestas$RangoHora),]$RangoHora <- 0
encuestas[is.na(encuestas$Experiencia),]$Experiencia <- 0
encuestas[is.na(encuestas$Antiguedad),]$Antiguedad <- 0
# Guardamos el max y min salario neto por hora, para poder reescalar el valor
maxSal = max(encuestas$SalarioNetoPorHora)
minSal = min(encuestas$SalarioNetoPorHora)
# Escalado entre 0 y 1
range01 <- function(x){(x-min(x))/(max(x)-min(x))}
encuestas <- as.data.frame(sapply(encuestas, range01))
# Output
Output <- encuestas$SalarioNetoPorHora
encuestas$SalarioNetoPorHora <- NULL
# Borramos algunas caracteristicas a fin de simplificar el modelo
encuestas$LeGustaTrabajarDesdeCasa <- NULL
encuestas$CambioPorMejorAmbiente <- NULL
encuestas$CambioPorFormaDeTrabajo <- NULL
encuestas$CambioPorTecnologia <- NULL
encuestas$NoCambio <- NULL
encuestas$NivelDeDesconfianza <- NULL
encuestas$CambioPorCercania <- NULL
encuestas$CambioPorMenorCargaHoraria <- NULL
encuestas$CambioPorOportunidadDeCarrera <- NULL
encuestas$Relaci.nLaboral <- NULL
encuestas$RangoHora <- NULL
encuestas$Semestre <- NULLSelección de una submuestra del 70% para entrenamiento y 30% para test.
set.seed(101)
indices <- sample(1:nrow(encuestas),size=round(0.3*nrow(encuestas)))
entrenamiento_input <- encuestas[-indices,]
entrenamiento_output = Output[-indices]
entrenamiento <- entrenamiento_input
entrenamiento$Output <- entrenamiento_output
test_input <- encuestas[indices,]
test_output <- Output[indices]# Outputs:
nombres <- names(encuestas)
# Inputs:
f <- paste(nombres,collapse=' + ')
f <- paste('Output ~',f)
# Formula (Output en función de los inputs):
f <- as.formula(f)
# -------------------
# Creación y entrenamiento de la red neuronal
nn <- neuralnet(formula = f,
data = entrenamiento,
threshold = 0.1,
hidden=c(12,8),
linear.output=TRUE,
stepmax = 20000)# Calculamos las predicciones usando el modelo para el conjunto de TEST
predicciones_test <- compute(nn,test_input)
# Reescalamos los resultados (que estaban escalados al rango [0;1]) para que sean entendibles
salariosPredichos_test <- predicciones_test$net.result * (maxSal - minSal) + minSal
salariosReales_test <- test_output * (maxSal - minSal) + minSal
# Calculamos la diferencia entre el valor predicho y el valor real, en valor absoluto
errorPrediccion_test <- salariosReales_test - salariosPredichos_test
errorPrediccionAbs_test <- abs(errorPrediccion_test)
# Calculamos la media del error
errorPromedio_test <- mean(errorPrediccionAbs_test)
salarioPromedioReal_test <- mean(salariosReales_test)
salarioPromedioPredicho_test <- mean(salariosReales_test)
hist(errorPrediccion_test, breaks = 300, main="Histograma del error", xlim=c(-500, 500))# Armamos resumen con los primeros casos
resumen <- test_input
resumen$SalarioNetoPorHoraReal <- salariosReales_test
resumen$SalarioNetoPorHoraPredicho <- salariosPredichos_test
resumen$ErrorPrediccion <- errorPrediccion_test
# Imprimimos resultado de implementar el modelo a los casos de test.
# Para facilitar la lectura redondeamos en 2 decimales.
round_df <- function(x, digits) {
numeric_columns <- sapply(x, mode) == 'numeric'
x[numeric_columns] <- round(x[numeric_columns], digits)
x
}
kable(as.data.frame(t(head(round_df(resumen, 2), 10))))| 6678 | 787 | 12731 | 11797 | 4482 | 5382 | 10489 | 5981 | 11154 | 9788 | |
|---|---|---|---|---|---|---|---|---|---|---|
| Edad | 0.43 | 0.36 | 0.19 | 0.60 | 0.23 | 0.15 | 0.43 | 0.23 | 0.09 | 0.55 |
| IdSexo | 0.50 | 0.50 | 1.00 | 0.50 | 0.50 | 0.50 | 0.50 | 1.00 | 0.50 | 0.50 |
| IdNivelEducativo | 0.11 | 0.44 | 1.00 | 1.00 | 0.89 | 1.00 | 0.78 | 1.00 | 0.67 | 0.11 |
| IdTipoDeEmpresa | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 |
| IdProvincia | 0.04 | 0.04 | 0.00 | 0.89 | 0.11 | 0.00 | 0.00 | 0.04 | 0.00 | 0.26 |
| IdPuesto | 0.73 | 0.29 | 0.02 | 0.53 | 0.29 | 0.11 | 0.51 | 0.29 | 0.29 | 0.49 |
| horasTrabajadasXSemana | 0.26 | 0.26 | 0.26 | 0.33 | 0.26 | 0.33 | 0.26 | 0.26 | 0.26 | 0.39 |
| TrabajaDesdeCasa | 1.00 | 1.00 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 | 0.00 | 0.00 | 1.00 |
| MesesDeExperiencia | 1.00 | 0.08 | 0.08 | 0.08 | 0.04 | 0.42 | 1.00 | 0.25 | 0.08 | 1.00 |
| IdTecnologiaPrincipal | 0.45 | 0.00 | 0.47 | 0.00 | 0.36 | 1.00 | 1.00 | 0.45 | 0.06 | 0.91 |
| MesesEnElPuestoActual | 0.05 | 0.08 | 0.04 | 0.13 | 0.00 | 0.11 | 0.05 | 0.00 | 0.01 | 0.22 |
| SeSientePresionado | 0.70 | 1.00 | 0.50 | 0.50 | 1.00 | 0.10 | 0.30 | 0.40 | 0.10 | 0.50 |
| SeSienteSobreexigido | 0.80 | 1.00 | 0.60 | 0.80 | 0.00 | 0.30 | 0.30 | 0.50 | 0.70 | 0.50 |
| EnElLugarSeDesarrolla | 0.80 | 0.00 | 0.70 | 0.80 | 1.00 | 0.80 | 0.70 | 0.90 | 1.00 | 0.20 |
| LaboresDiariasGratas | 0.90 | 0.00 | 0.40 | 0.80 | 1.00 | 1.00 | 0.80 | 0.80 | 1.00 | 0.50 |
| SeLoReconoceComoDebiera | 0.80 | 0.00 | 0.40 | 0.50 | 1.00 | 0.80 | 0.40 | 0.90 | 1.00 | 0.80 |
| HayDesarrolloProfesional | 0.80 | 0.00 | 0.70 | 0.30 | 1.00 | 0.80 | 0.80 | 1.00 | 1.00 | 0.20 |
| SeSienteMotivado | 0.80 | 1.00 | 0.40 | 0.60 | 1.00 | 0.70 | 0.80 | 1.00 | 1.00 | 0.50 |
| RelacionConJefes | 1.00 | 0.50 | 0.40 | 0.60 | 0.80 | 1.00 | 0.30 | 0.70 | 1.00 | 1.00 |
| CambioPorMejorSalario | 1.00 | 1.00 | 1.00 | 1.00 | 0.00 | 1.00 | 1.00 | 1.00 | 0.00 | 1.00 |
| CantidadDeMesesParaCambiarDeTrabajo | 0.00 | 1.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.50 | 0.00 | 0.00 | 0.00 |
| TienePersonasACargo | 0.00 | 0.50 | 0.00 | 0.00 | 0.50 | 0.00 | 1.00 | 0.00 | 0.00 | 1.00 |
| Anio | 0.33 | 0.00 | 0.67 | 0.67 | 0.17 | 0.33 | 0.50 | 0.33 | 0.50 | 0.50 |
| Mes | 0.55 | 0.55 | 0.09 | 0.00 | 0.55 | 0.00 | 0.64 | 0.18 | 0.73 | 0.18 |
| Hora | 0.70 | 1.00 | 0.78 | 0.52 | 0.48 | 0.70 | 0.30 | 0.57 | 0.74 | 0.57 |
| CargaLaboral | 0.33 | 0.33 | 0.33 | 0.33 | 0.33 | 0.33 | 0.33 | 0.33 | 0.33 | 0.00 |
| Antiguedad | 0.75 | 0.75 | 0.75 | 1.00 | 0.50 | 1.00 | 0.75 | 0.50 | 0.50 | 0.25 |
| Experiencia | 0.25 | 0.50 | 0.50 | 0.50 | 0.50 | 0.75 | 0.25 | 0.75 | 0.50 | 0.25 |
| RangoEdad | 0.44 | 0.33 | 0.22 | 0.67 | 0.22 | 0.11 | 0.44 | 0.22 | 0.11 | 0.56 |
| SalarioNetoPorHoraReal | 225.00 | 187.50 | 137.50 | 288.89 | 87.50 | 88.89 | 375.00 | 192.50 | 237.50 | 280.00 |
| SalarioNetoPorHoraPredicho | 283.78 | 112.64 | 223.30 | 286.38 | 144.89 | 155.99 | 437.38 | 169.77 | 157.31 | 319.29 |
| ErrorPrediccion | -58.78 | 74.86 | -85.80 | 2.51 | -57.39 | -67.10 | -62.38 | 22.73 | 80.19 | -39.29 |
# Calculamos las predicciones usando el modelo para el conjunto de ENTRENAMIENTO
predicciones_entrenamiento <- compute(nn,entrenamiento_input)
# Reescalamos los resultados (que estaban escalados al rango [0;1]) para que sean entendibles
salariosPredichos_entrenamiento <- predicciones_entrenamiento$net.result * (maxSal - minSal) + minSal
salariosReales_entrenamiento <- entrenamiento_output * (maxSal - minSal) + minSal
# Calculamos la diferencia entre el valor predicho y el valor real, en valor absoluto
errorPrediccion_entrenamiento <- abs(salariosReales_entrenamiento - salariosPredichos_entrenamiento)
# Calculamos la media del error
errorPromedio_entrenamiento <- mean(errorPrediccion_entrenamiento)
salarioPromedioReal_test <- mean(salariosReales_entrenamiento)
salarioPromedioPredicho_test <- mean(salariosReales_entrenamiento)plot(nn)