Emilio Olvera A01625200
Mayra Campoy Ramos A00226914
Ximena Gutierrez Briseño A00829505
Mariana Ulloa Encinas A01253076
Héctor Javier Villarreal A01570227

1) Definición de Conceptos Clave:

1. K-Vecinos más Cercanos y/o K-Means Clustering:

Los K-MEAN CLUSTERS ayudan a la hora de querer identificar segmentos de elementos similares, pues su principal función es agrupar de acuerdo a características que estos diversos grupos tengan en en común. Esta clasificación ayuda a organizar grandes cantidades de datos y describir patrones de similaridad y diferencia. Obtener información importante de cada variable, limpia y dentro del mismo rango es un paso importante a la hora de querer realizar los clústers. Un claro ejemplo de clústers puede ser el agrupar clientes por su cantidad de compra y frecuencia de visita en un supermercado, clasificandolos en: habitual, frecuente y ocasional.

2. Aprendizaje No Supervisado y/o Unsupervised Learning:

Para comenzar, el “Aprendizaje Supervisado” es aquel que se relaciona con la clasificación o regresión de datos que ya tienen “etiquetas” o bien, ya se conoce el nombre o clase de este grupo o segmento de datos, por lo que se pueden realizar modelos entrenados para trabajar con ellos.
Por otro lado, el “Aprendizaje No Supervisado” es lo contrario, en este caso no se conocen las “etiquetas” o nombres de los segmentos o conjuntos de datos por lo que no se pueden crear mapeos o modelos directos con ellos, es por eso que el objetivo de este aprendizaje es dectectar patrones en los datos y explotarlos. En este caso, “K-means Clustering” es un tipo de modelo de Aprendizaje No Supervisado, ya que el objetivo de esta función es agrupar la información y nombrar o realizar desde cero los conjuntos de datos, pues bien se puede saber la cantidad de grupos que hay pero estos no estarán etiquetados.
Con esto, se puede deducir que en la base de datos trabajada a continuación se ocupará el Algoritmo de Agrupamiento No Supervisado, ya que esta cuenta con datos de entrada sin respuestas etiquetadas.

3. Distancia Euclidiana // Eucliedean Distance:

La distancia euclidiana es cuando se encuentra un espacio vectorial, que es igual o inferior a la variable que se está analizando. Un claro ejemplo es cuando se están identificando clusters y llegamos a descubir los centroides. La parte donde se utiliza la distancia euclidiana es cuando los centroides ya no se repiten, encuentran una posición y ya no cambian, por lo que se hace la relación con puntos alrededor de los centroides; cada punto es una variable, por lo tanto la distancia que existe entre variables es la distancia euclidiana.
Esta distancia nos ayuda a descubrir la similitud entre las variables que estamos analizando.

2) Identificar y visualizar las características de clústers:

Paso 1. Instalar librerías:

library(foreign)
library(dplyr)        
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)      
library(psych)        
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
library(corrplot)     
## corrplot 0.92 loaded
library(jtools)       
library(lmtest)       
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(car)          
## Loading required package: carData
## 
## Attaching package: 'car'
## The following object is masked from 'package:psych':
## 
##     logit
## The following object is masked from 'package:dplyr':
## 
##     recode
library(factoextra)  
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test

Paso 2. Importar y limpiar la base de datos:

bd1 <- read.csv("C:\\Users\\maria\\Documents\\ITESM LAET\\Semestre 7\\Reto\\FORM BASES DE DATOS\\FORM - Recursos Humanos - BAJAS BUENA.csv")
bajas <- clean_names(bd1)
summary(bajas)
##   apellidos            nombre          fecha_de_nacimiento      edad      
##  Length:236         Length:236         Length:236          Min.   :19.00  
##  Class :character   Class :character   Class :character    1st Qu.:23.00  
##  Mode  :character   Mode  :character   Mode  :character    Median :29.00  
##                                                            Mean   :31.08  
##                                                            3rd Qu.:37.00  
##                                                            Max.   :61.00  
##                                                            NA's   :3      
##     genero              rfc            fecha_de_alta      motivo_de_baja    
##  Length:236         Length:236         Length:236         Length:236        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##     no_dias            baja              puesto          departamento      
##  Min.   :   0.00   Length:236         Length:236         Length:236        
##  1st Qu.:   9.00   Class :character   Class :character   Class :character  
##  Median :  19.00   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :  79.76                                                           
##  3rd Qu.:  49.00                                                           
##  Max.   :1966.00                                                           
##  NA's   :23                                                                
##  no_seguro_social   salario_diario_imss factor_cred_infonavit
##  Length:236         Min.   :144.4       Length:236           
##  Class :character   1st Qu.:180.7       Class :character     
##  Mode  :character   Median :180.7       Mode  :character     
##                     Mean   :178.0                            
##                     3rd Qu.:180.7                            
##                     Max.   :500.0                            
##                                                              
##  n_credito_infonavit lugar_de_nacimiento     curp              calle          
##  Length:236          Length:236          Length:236         Length:236        
##  Class :character    Class :character    Class :character   Class :character  
##  Mode  :character    Mode  :character    Mode  :character   Mode  :character  
##                                                                               
##                                                                               
##                                                                               
##                                                                               
##  numero_interno       colonia          codigo_postal       municipio        
##  Length:236         Length:236         Length:236         Length:236        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##     estado          estado_civil       tarjeta_cuenta    
##  Length:236         Length:236         Length:236        
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##                                                          
##                                                          
## 
#Técnica 1:
#Borrar columnas.
bajas <- subset(bajas, select = -c(apellidos, nombre, fecha_de_nacimiento,rfc, fecha_de_alta, baja, departamento, no_seguro_social, factor_cred_infonavit, n_credito_infonavit, lugar_de_nacimiento, curp, calle, numero_interno, colonia, codigo_postal, municipio, estado, tarjeta_cuenta))

#Técnica 2: 
#Reemplezar NAs con el promedio en la columna de "Edad", "Salario Diario" y "Número de días".
bajas$edad[is.na(bajas$edad)]<-mean(bajas$edad, na.rm = TRUE)
bajas$salario_diario_imss[is.na(bajas$salario_diario_imss)]<-mean(bajas$salario_diario_imss, na.rm = TRUE)
bajas$no_dias[is.na(bajas$no_dias)]<-mean(bajas$no_dias, na.rm = TRUE)
summary (bajas)
##       edad          genero          motivo_de_baja        no_dias       
##  Min.   :19.00   Length:236         Length:236         Min.   :   0.00  
##  1st Qu.:23.00   Class :character   Class :character   1st Qu.:   9.00  
##  Median :29.00   Mode  :character   Mode  :character   Median :  24.00  
##  Mean   :31.08                                         Mean   :  79.76  
##  3rd Qu.:37.00                                         3rd Qu.:  79.76  
##  Max.   :61.00                                         Max.   :1966.00  
##     puesto          salario_diario_imss estado_civil      
##  Length:236         Min.   :144.4       Length:236        
##  Class :character   1st Qu.:180.7       Class :character  
##  Mode  :character   Median :180.7       Mode  :character  
##                     Mean   :178.0                         
##                     3rd Qu.:180.7                         
##                     Max.   :500.0
#Técnica 3:
#Convertir las variables como factor o número
bajas$edad<-as.numeric(bajas$edad)
bajas$genero<-as.factor(bajas$genero)
bajas$motivo_de_baja<-as.factor(bajas$motivo_de_baja)
bajas$no_dias<-as.numeric(bajas$no_dias)
bajas$puesto<-as.factor(bajas$puesto)
bajas$salario_diario_imss<-as.numeric(bajas$salario_diario_imss)
bajas$estado_civil<-as.factor(bajas$estado_civil)
summary (bajas)
##       edad             genero                motivo_de_baja    no_dias       
##  Min.   :19.00   FEMENINO :139   ABANDONO           :  1    Min.   :   0.00  
##  1st Qu.:23.00   MASCULINO: 97   BAJA POR FALTAS    :141    1st Qu.:   9.00  
##  Median :29.00                   JUBILACION         :  1    Median :  24.00  
##  Mean   :31.08                   RENUNCIA VOLUNTARIA: 85    Mean   :  79.76  
##  3rd Qu.:37.00                   TERMINO DE CONTRATO:  8    3rd Qu.:  79.76  
##  Max.   :61.00                                              Max.   :1966.00  
##                                                                              
##                    puesto    salario_diario_imss      estado_civil
##  AYUDANTE GENERAL     :179   Min.   :144.4       CASADO     : 64  
##  COSTURERA            : 11   1st Qu.:180.7       DIVORCIADO :  3  
##  SOLDADOR             : 11   Median :180.7       SOLTERO    :108  
##  AYUDANTE DE EMBARQUES:  7   Mean   :178.0       UNION LIBRE: 61  
##  MONTACARGUISTA       :  5   3rd Qu.:180.7                        
##  INSPECTOR CALIDAD    :  4   Max.   :500.0                        
##  (Other)              : 19
#Exportar base de datos limpia
write.csv(bajas, file="bajas_bd_limpia.csv", row.names = FALSE)

Paso 3. Creación de Clústers:

Cluster 1: Relación de variables de Edad y Número de días.
edad<-bajas %>% select(genero,estado_civil,motivo_de_baja, puesto, salario_diario_imss,no_dias, edad)

#Normalizar variables
edad_norm<-scale(edad[6:7]) 

#Función fviz para la visualización de un Elbow Plot y así determinar el número de clusters.
fviz_nbclust(edad_norm, kmeans, method="wss")+ 
  geom_vline(xintercept=4, linetype=2)+            
  labs(subtitle = "Elbow method")
## Registered S3 methods overwritten by 'broom':
##   method            from  
##   tidy.glht         jtools
##   tidy.summary.glht jtools

Con esta gráfica podemos visualizar que el número óptimo de clústers son 4 (optimización).

#Visualizar clusters
edad_cluster<-kmeans(edad_norm,4)
edad_cluster
## K-means clustering with 4 clusters of sizes 108, 4, 45, 79
## 
## Cluster means:
##       no_dias       edad
## 1 -0.16123563 -0.8436899
## 2  6.69236023  1.0613529
## 3 -0.10238449  1.5986678
## 4 -0.06011001  0.1890259
## 
## Clustering vector:
##   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20 
##   4   4   1   1   4   3   4   4   3   1   1   4   1   4   4   1   1   1   1   1 
##  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40 
##   4   2   1   4   3   1   4   1   1   1   4   1   1   1   4   1   1   4   4   1 
##  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60 
##   1   4   1   1   1   1   1   1   3   3   3   2   1   3   1   1   3   1   1   1 
##  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80 
##   1   1   4   1   1   3   1   3   4   1   1   1   4   1   4   1   3   1   1   3 
##  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100 
##   2   4   3   1   1   1   3   1   1   1   4   3   3   1   1   1   4   3   4   1 
## 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 
##   4   1   1   3   4   1   1   4   2   4   1   4   4   1   4   4   4   3   3   3 
## 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 
##   1   1   1   1   1   4   1   4   3   1   4   1   3   1   4   4   4   3   4   3 
## 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 
##   4   4   3   3   3   1   4   4   4   4   1   1   1   4   3   3   1   4   1   4 
## 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 
##   3   3   3   3   4   3   1   1   4   1   1   3   4   3   1   3   4   4   3   4 
## 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 
##   4   1   1   1   4   3   4   4   1   1   4   4   4   4   4   4   4   1   4   4 
## 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 
##   4   4   1   4   3   4   1   1   1   3   1   1   1   4   4   1   1   4   4   4 
## 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 
##   3   1   1   4   1   1   1   1   3   4   3   1   1   1   1   1 
## 
## Within cluster sum of squares by cluster:
## [1] 16.47707 16.07044 21.67511 33.84920
##  (between_SS / total_SS =  81.3 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
#Visualizar resultados:
fviz_cluster(edad_cluster,data=edad_norm)

Los más jóvenes son los que menos días de trabajo laboran. Así como que los que más días laborales tienen, son los adultos desde los 27 años hasta los 61.

Cluster 2: Relación de variables de Edad y Salario Diario.
edad_salario <-bajas %>% select(genero,estado_civil,motivo_de_baja, puesto, no_dias, salario_diario_imss, edad)

#Normalizar variables
edad_salario_norm<-scale(edad_salario[6:7]) 

#Función fviz para la visualización de un Elbow Plot y así determinar el número de clusters.
fviz_nbclust(edad_salario_norm, kmeans, method="wss")+ 
  geom_vline(xintercept=4, linetype=2)+            
  labs(subtitle = "Elbow method") 

Con esta gráfica podemos visualizar que el número óptimo de clústers son 4 (optimización).

#Visualizar clusters:
edad_salario_cluster<-kmeans(edad_salario_norm,4)
edad_salario_cluster
## K-means clustering with 4 clusters of sizes 1, 106, 47, 82
## 
## Cluster means:
##   salario_diario_imss        edad
## 1         13.84560348  0.09627292
## 2         -0.08355516 -0.85551942
## 3         -0.05258548  1.63906906
## 4         -0.03069803  0.16527488
## 
## Clustering vector:
##   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20 
##   1   4   2   2   4   3   4   4   3   2   2   4   2   4   4   2   2   2   2   2 
##  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40 
##   4   3   2   4   3   2   4   2   2   2   4   2   2   2   4   2   2   4   4   2 
##  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60 
##   2   4   2   2   2   2   2   2   3   3   3   3   2   3   2   2   3   2   2   2 
##  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80 
##   2   2   4   4   4   3   2   3   4   2   2   2   4   2   4   2   3   2   2   3 
##  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100 
##   2   2   3   2   2   2   3   2   2   2   4   3   3   2   2   4   4   3   4   2 
## 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 
##   4   2   2   3   4   2   2   4   2   4   2   4   4   2   4   4   4   3   3   3 
## 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 
##   2   2   2   2   2   4   2   4   3   4   4   2   3   2   4   4   4   3   4   3 
## 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 
##   4   4   3   3   3   2   4   4   4   4   2   2   2   4   3   3   2   4   2   4 
## 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 
##   3   3   3   3   4   3   2   2   4   2   2   3   4   3   2   3   4   4   3   4 
## 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 
##   4   2   2   2   4   3   4   4   2   2   4   4   4   4   4   4   4   2   4   4 
## 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 
##   4   4   2   4   3   4   2   2   2   3   2   2   2   4   4   2   2   4   4   4 
## 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 
##   3   2   2   4   2   2   2   4   3   4   3   2   2   2   2   2 
## 
## Within cluster sum of squares by cluster:
## [1]  0.00000 29.24335 19.71590 22.29302
##  (between_SS / total_SS =  84.8 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
#Visualizar resultados:
fviz_cluster(edad_salario_cluster,data=edad_salario_norm)

La edad no tiene mucha influencia en el salario. Pues los colaboradores que se han dado de baja tienen un salario muy similar independientemente de su edad.

Cluster 3: Relación de variables de Salario Diario y Número de días.
dias_salario <-bajas %>% select(genero,estado_civil,motivo_de_baja, puesto, edad, no_dias, salario_diario_imss)

#Normalizar variables:
dias_salario_norm<-scale(dias_salario[6:7]) 

#Función fviz para la visualización de un Elbow Plot y así determinar el número de clusters.
fviz_nbclust(dias_salario_norm, kmeans, method="wss")+ 
  geom_vline(xintercept=4, linetype=2)+            
  labs(subtitle = "Elbow method") 

Con esta gráfica podemos visualizar que el número óptimo de clústers son 4 (optimización).

#Visualizar clusters:
dias_salario_cluster<-kmeans(dias_salario_norm,4)
dias_salario_cluster
## K-means clustering with 4 clusters of sizes 158, 5, 43, 30
## 
## Cluster means:
##      no_dias salario_diario_imss
## 1 -0.2914687          0.11550041
## 2  5.8670410          2.44889716
## 3  0.2568332          0.08119347
## 4  0.1891008         -1.13282901
## 
## Clustering vector:
##   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20 
##   2   4   4   4   4   4   4   4   4   3   4   4   1   1   4   4   4   4   4   4 
##  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40 
##   4   2   4   4   1   1   1   1   1   1   1   1   1   1   1   1   4   3   1   1 
##  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60 
##   3   3   1   1   1   1   1   1   1   1   1   2   3   1   1   1   1   1   1   4 
##  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80 
##   1   1   1   1   1   1   1   4   3   4   1   1   1   1   1   1   1   1   1   1 
##  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100 
##   2   4   4   4   4   3   1   1   1   1   1   1   1   1   1   1   1   4   4   3 
## 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 
##   3   1   1   1   1   1   1   1   2   1   1   1   1   1   1   1   1   1   1   1 
## 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 
##   1   3   1   1   1   1   1   1   1   1   1   1   4   3   3   3   3   1   1   1 
## 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 
##   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   3   1   1   1 
## 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 
##   1   1   3   3   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   3 
## 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 
##   3   3   3   3   3   3   3   3   3   3   3   3   1   3   3   3   3   3   3   3 
## 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 
##   3   3   3   1   1   1   1   3   1   1   1   1   1   1   1   1   1   1   1   1 
## 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 
##   3   3   1   1   1   1   1   1   1   1   1   1   1   1   1   1 
## 
## Within cluster sum of squares by cluster:
## [1]   0.9925715 183.9930875  12.7855972  11.9101814
##  (between_SS / total_SS =  55.4 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
#Visualizar resultados:
fviz_cluster(dias_salario_cluster,data=dias_salario_norm)

promedio_dias <- mean(bajas$no_dias)
promedio_dias
## [1] 79.76056

En este clúster podemos observar que por más antigüedad o días que labores en FORM, no hay mucha posibilidad de crecimiento laboral (económicamente hablando), pues según el cluster realizado, no influyen los días laborados con el salario diario.

Paso 4. Creación de Segmentos apartir de los Clústers:

#Decidimos usar el Cluster 2 para generar la clasificación de variables y poder comparar con datos cualitativos.

#Añadir a la base de datos la columna de Clusters y su clasificación:
bajas1<-bajas
bajas1$Clusters<-edad_salario_cluster$cluster

#Identificamos la clasificación de las distintas edades de los colaboradores.
bajas2<-bajas1 %>% group_by(Clusters) %>% summarise(edad=max(edad)) %>% arrange(desc(edad))
bajas1$Cluster_Names<-factor(bajas1$Clusters,levels = c(1,2,3,4), 
                              labels=c("Outlier", "Joven", "Avanzada", "Adulta"))
bajas3 <- bajas1 %>% group_by(Cluster_Names) %>% summarize(edad_años=max(edad), 
                                                             salario_imss=mean(salario_diario_imss),
                                                             Count=n())
clusters<-as.data.frame(bajas3)
clusters
##   Cluster_Names edad_años salario_imss Count
## 1       Outlier        32     500.0000     1
## 2         Joven        28     176.0192   106
## 3      Avanzada        61     176.7396    47
## 4        Adulta        39     177.2487    82

Paso 5. Generación de gráficos:

Gráficos cuantitativos:
#Se realizó una gráfica para analizar el número de registros por cada segmento: 
ggplot(bajas3,aes(x=reorder(Cluster_Names,Count),y=Count,fill=Cluster_Names)) +
  geom_bar(stat="identity")

Los colaboradores que más bajas han presentado según la gráfica anterior son jóvenes, seguido por los adultos y después los colaboradores de edad avanzada.

#Visualizar la edad por cada segmento:
ggplot(bajas3, aes(x=Cluster_Names,y=edad_años,fill= Cluster_Names,label=round(edad_años,digits=2))) + 
  geom_col() + 
  geom_text()

Visualización de los máximos de cada segmento: Jóvenes (hasta los 28), Avanzada (Hasta los 61), Adulta (Hasta los 40) y el Outlier de 32.

Gráficas mixtas (Datos Cualitativos y Cuantitativos):
Gráfica de barras: (Clusters y Género)
ggplot(bajas1, aes(factor(Cluster_Names), fill = factor(genero))) +
  geom_bar(position = position_dodge2(preserve = "single")) 

Este gráfico nos dice que de cada segmento, hay más mujeres que se han dado de baja.

Gráfica de barras: (Clusters y Estado Civil)
ggplot(bajas1, aes(factor(Cluster_Names), fill = factor(estado_civil))) +
  geom_bar(position = position_dodge2(preserve = "single")) 

Podemos visualizar que de de los jóvenes, la mayoría eran solteros, de los adultos había la misma cantidad de casados, soleros y en unión libre y en avanzados eran más solteros y casados. Más sin embargo, hay muy pocos colaboradores que se han dado de baja divorciados.

Gráfica de barras: (Clusters y Motivo de Baja)
ggplot(bajas1, aes(factor(Cluster_Names), fill = factor(motivo_de_baja))) +
  geom_bar(position = position_dodge2(preserve = "single")) 

Podemos observar que en el segmento de colaboradores jovenes, adultos y de edad avanzada, la mayor parte se ha dado de baja por faltas, siguiendo así por renuncia voluntaria.

Gráfica de pay: (Puesto)
table(bajas1$puesto)
## 
## ANALISTA DE NOMINAS /AUX DE R.H.            AYUDANTE DE EMBARQUES 
##                                1                                7 
##                 AYUDANTE DE MTTO             AYUDANTE DE SOLDADOR 
##                                1                                1 
##                 AYUDANTE GENERAL                           CHOFER 
##                              179                                1 
##                         CORTADOR                        COSTURERA 
##                                1                               11 
##                           DISEÑO             ENCARGADA DE CALIDAD 
##                                1                                1 
##                      FACTURACION             GUARDIA DE SEGURIDAD 
##                                1                                2 
##                INSPECTOR CALIDAD                         LIMPIEZA 
##                                4                                1 
##                        MARCADORA                     MATERIALISTA 
##                                1                                2 
##                   MONTACARGUISTA              PRACTICANTE DE MTTO 
##                                5                                1 
##                        RESIDENTE              SERVICIO AL CLIENTE 
##                                3                                1 
##                         SOLDADOR 
##                               11
proporciones <- c(23, 179, 11, 11, 7, 5)
etiquetas <- c("Otros","Ayudante General", "Costurera", "Soldador", "Ayudante Embarques", "Montacarguista")
pct <- round(proporciones/sum(proporciones)*100)
etiquetas <- paste(etiquetas, pct)
etiquetas <- paste(etiquetas,"%",sep="")
pie(proporciones,labels = etiquetas,
    col=rainbow(length(etiquetas)),
    main="Puesto de los Ex-Colaboradores")

La mayor parte de los ex-colaboradores de Form eran Ayudantes generales (76%).

3) Identificar y describir los hallazgos de los clústers:

1. La edad de los colaboradores que se han dado de baja, no tiene influencia en su salario.
2. El salario influye mucho en las bajas, pues todos los que se han dado de baja tienen un salario promedio menor a $180 diarios. Solamente un colaborador con un salario mayor ($500) se ha dado de baja.
3. Los días laborales (antigüedad) de un colaborador, no influyen con el salario, al menos con los que se han dado de baja. Lo que puede significar que la oportunidad de crecer económicamente en FORM de acuerdo a tu antigüedad es mínima.
4. La mayoría de los colaboradores que se han dado de baja, no han trabajado más de 3 meses (79 días) en FORM.
5. Los colaboradores que más bajas han presentado son jóvenes (de edades de los 18-28 años).
6. Independientemente de si los ex-colaboradores son jóvenes, adultos o mayores, de cada segmento las mujeres son las que han presentado más bajas.
7. FORM ha despedido más colaboradores de los que han renunciado, siendo la principal causa la “Baja por faltas”. Lo que puede significar que su proceso de contratación no es el más óptimo ya que terminan contratando personal que no era el adecuado para el puesto.

4) Referencias:

(LEDU), E. E. (2018, September 12). Understanding K-means clustering in machine learning. Medium. Retrieved October 8, 2022, from https://towardsdatascience.com/understanding-k-means-clustering-in-machine-learning-6a6e67336aa1
K-means clustering in R programming. GeeksforGeeks. (2020, July 2). Retrieved October 9, 2022, from https://www.geeksforgeeks.org/k-means-clustering-in-r-programming/
Supervised and unsupervised learning in R programming. GeeksforGeeks. (2021, November 29). Retrieved October 9, 2022, from https://www.geeksforgeeks.org/supervised-and-unsupervised-clustering-in-r-programming/
Shadan, M. (n.d.). Unsupervised learning in R. R. Retrieved October 9, 2022, from https://rstudio-pubs-static.s3.amazonaws.com/273129_453610ca694541e1a2c5664bf7ccba1a.html
How to compute the euclidean distance between two arrays in R -. ProjectPro. (n.d.). Retrieved October 9, 2022, from https://www.projectpro.io/recipes/compute-euclidean-distance-between-two-arrays-r
LS0tDQp0aXRsZTogPHNwYW4gc3R5bGU9IkNvbG9yOk9yYW5nZSI+IEVudHJlZ2FibGUgIDIuNSAiRGVzYXJyb2xsYXIgY2xhc2lmaWNhY2nDs24gSyBWZWNpbm9zIg0KYXV0aG9yOiAiRXF1aXBvIDQiDQpkYXRlOiAiMjAyMi0xMC0wNSINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KLS0tDQoNCiMjIyMjIEVtaWxpbyBPbHZlcmEgQTAxNjI1MjAwDQojIyMjIyBNYXlyYSBDYW1wb3kgUmFtb3MgQTAwMjI2OTE0DQojIyMjIyBYaW1lbmEgR3V0aWVycmV6IEJyaXNlw7FvIEEwMDgyOTUwNQ0KIyMjIyMgTWFyaWFuYSBVbGxvYSBFbmNpbmFzIEEwMTI1MzA3Ng0KIyMjIyMgSMOpY3RvciBKYXZpZXIgVmlsbGFycmVhbCBBMDE1NzAyMjcNCg0KPGltZyBzcmM9ICJDOlxcVXNlcnNcXG1hcmlhXFxEb2N1bWVudHNcXElURVNNIExBRVRcXFNlbWVzdHJlIDdcXFJldG9cXGxvZ28gZm9ybS5wbmciPg0KDQojIyMgKioxKSBEZWZpbmljacOzbiBkZSBDb25jZXB0b3MgQ2xhdmU6KioNCg0KPGRpdiBjbGFzcz10ZXh0LWp1c3RpZnk+DQoNCiMjIyMgKioxLiBLLVZlY2lub3MgbcOhcyBDZXJjYW5vcyB5L28gSy1NZWFucyBDbHVzdGVyaW5nOioqIA0KIyMjIyMgTG9zIEstTUVBTiBDTFVTVEVSUyBheXVkYW4gYSBsYSBob3JhIGRlIHF1ZXJlciBpZGVudGlmaWNhciBzZWdtZW50b3MgZGUgZWxlbWVudG9zIHNpbWlsYXJlcywgcHVlcyBzdSBwcmluY2lwYWwgZnVuY2nDs24gZXMgKiphZ3J1cGFyKiogZGUgYWN1ZXJkbyBhICpjYXJhY3RlcsOtc3RpY2FzIHF1ZSBlc3RvcyBkaXZlcnNvcyBncnVwb3MgdGVuZ2FuIGVuIGVuIGNvbcO6bi4qIEVzdGEgY2xhc2lmaWNhY2nDs24gYXl1ZGEgYSAqKm9yZ2FuaXphciBncmFuZGVzIGNhbnRpZGFkZXMgZGUgZGF0b3MgeSBkZXNjcmliaXIgcGF0cm9uZXMgZGUgc2ltaWxhcmlkYWQgeSBkaWZlcmVuY2lhLioqIE9idGVuZXIgaW5mb3JtYWNpw7NuIGltcG9ydGFudGUgZGUgY2FkYSB2YXJpYWJsZSwgbGltcGlhIHkgZGVudHJvIGRlbCBtaXNtbyByYW5nbyBlcyB1biBwYXNvIGltcG9ydGFudGUgYSBsYSBob3JhIGRlIHF1ZXJlciByZWFsaXphciBsb3MgY2zDunN0ZXJzLiBVbiBjbGFybyBlamVtcGxvIGRlIGNsw7pzdGVycyBwdWVkZSBzZXIgZWwgYWdydXBhciBjbGllbnRlcyBwb3Igc3UgY2FudGlkYWQgZGUgY29tcHJhIHkgZnJlY3VlbmNpYSBkZSB2aXNpdGEgZW4gdW4gc3VwZXJtZXJjYWRvLCBjbGFzaWZpY2FuZG9sb3MgZW46ICpoYWJpdHVhbCwgZnJlY3VlbnRlIHkgb2Nhc2lvbmFsLioNCg0KIyMjIyAqKjIuIEFwcmVuZGl6YWplIE5vIFN1cGVydmlzYWRvIHkvbyBVbnN1cGVydmlzZWQgTGVhcm5pbmc6KiogDQojIyMjIyBQYXJhIGNvbWVuemFyLCBlbCAqIkFwcmVuZGl6YWplIFN1cGVydmlzYWRvIiBlcyBhcXVlbCBxdWUgc2UgcmVsYWNpb25hIGNvbiBsYSBjbGFzaWZpY2FjacOzbiBvIHJlZ3Jlc2nDs24gZGUgZGF0b3MgcXVlIHlhIHRpZW5lbiAiZXRpcXVldGFzIiogbyBiaWVuLCB5YSBzZSBjb25vY2UgZWwgbm9tYnJlIG8gY2xhc2UgZGUgZXN0ZSBncnVwbyBvIHNlZ21lbnRvIGRlIGRhdG9zLCBwb3IgbG8gcXVlIHNlIHB1ZWRlbiByZWFsaXphciBtb2RlbG9zIGVudHJlbmFkb3MgcGFyYSB0cmFiYWphciBjb24gZWxsb3MuIA0KDQojIyMjIyBQb3Igb3RybyBsYWRvLCBlbCAqKiJBcHJlbmRpemFqZSBObyBTdXBlcnZpc2FkbyIqKiBlcyBsbyBjb250cmFyaW8sIGVuIGVzdGUgY2FzbyAqKm5vIHNlIGNvbm9jZW4gbGFzICJldGlxdWV0YXMiIG8gbm9tYnJlcyBkZSBsb3Mgc2VnbWVudG9zIG8gY29uanVudG9zIGRlIGRhdG9zIHBvciBsbyBxdWUgbm8gc2UgcHVlZGVuIGNyZWFyIG1hcGVvcyBvIG1vZGVsb3MgZGlyZWN0b3MgY29uIGVsbG9zKiosIGVzIHBvciBlc28gcXVlIGVsICoqb2JqZXRpdm8gZGUgZXN0ZSBhcHJlbmRpemFqZSBlcyBkZWN0ZWN0YXIgcGF0cm9uZXMgZW4gbG9zIGRhdG9zIHkgZXhwbG90YXJsb3MuKiogRW4gZXN0ZSBjYXNvLCAqKiJLLW1lYW5zIENsdXN0ZXJpbmciIGVzIHVuIHRpcG8gZGUgbW9kZWxvIGRlIEFwcmVuZGl6YWplIE5vIFN1cGVydmlzYWRvKiosIHlhIHF1ZSBlbCBvYmpldGl2byBkZSBlc3RhIGZ1bmNpw7NuIGVzIGFncnVwYXIgbGEgaW5mb3JtYWNpw7NuIHkgbm9tYnJhciBvIHJlYWxpemFyIGRlc2RlIGNlcm8gbG9zIGNvbmp1bnRvcyBkZSBkYXRvcywgcHVlcyBiaWVuIHNlIHB1ZWRlIHNhYmVyIGxhIGNhbnRpZGFkIGRlIGdydXBvcyBxdWUgaGF5IHBlcm8gZXN0b3Mgbm8gZXN0YXLDoW4gZXRpcXVldGFkb3MuDQoNCiMjIyMjIENvbiBlc3RvLCBzZSBwdWVkZSBkZWR1Y2lyIHF1ZSBlbiBsYSBiYXNlIGRlIGRhdG9zIHRyYWJhamFkYSBhIGNvbnRpbnVhY2nDs24gc2Ugb2N1cGFyw6EgZWwgKkFsZ29yaXRtbyBkZSBBZ3J1cGFtaWVudG8gTm8gU3VwZXJ2aXNhZG8qLCB5YSBxdWUgZXN0YSBjdWVudGEgY29uIGRhdG9zIGRlIGVudHJhZGEgc2luIHJlc3B1ZXN0YXMgZXRpcXVldGFkYXMuDQoNCjwvZGl2Pg0KDQojIyMjICoqMy4gRGlzdGFuY2lhIEV1Y2xpZGlhbmEgLy8gRXVjbGllZGVhbiBEaXN0YW5jZToqKiANCiMjIyMjIExhIGRpc3RhbmNpYSBldWNsaWRpYW5hIGVzIGN1YW5kbyBzZSBlbmN1ZW50cmEgdW4gZXNwYWNpbyB2ZWN0b3JpYWwsIHF1ZSBlcyBpZ3VhbCBvIGluZmVyaW9yIGEgbGEgdmFyaWFibGUgcXVlIHNlIGVzdMOhIGFuYWxpemFuZG8uIFVuIGNsYXJvIGVqZW1wbG8gZXMgY3VhbmRvIHNlIGVzdMOhbiBpZGVudGlmaWNhbmRvIGNsdXN0ZXJzIHkgbGxlZ2Ftb3MgYSBkZXNjdWJpciBsb3MgY2VudHJvaWRlcy4gTGEgcGFydGUgZG9uZGUgc2UgdXRpbGl6YSAqKmxhIGRpc3RhbmNpYSBldWNsaWRpYW5hIGVzIGN1YW5kbyBsb3MgY2VudHJvaWRlcyB5YSBubyBzZSByZXBpdGVuLCBlbmN1ZW50cmFuIHVuYSBwb3NpY2nDs24geSB5YSBubyBjYW1iaWFuKiosIHBvciBsbyBxdWUgc2UgaGFjZSBsYSByZWxhY2nDs24gY29uIHB1bnRvcyBhbHJlZGVkb3IgZGUgbG9zIGNlbnRyb2lkZXM7ICoqY2FkYSBwdW50byBlcyB1bmEgdmFyaWFibGUsIHBvciBsbyB0YW50byBsYSBkaXN0YW5jaWEgcXVlIGV4aXN0ZSBlbnRyZSB2YXJpYWJsZXMgZXMgbGEgZGlzdGFuY2lhIGV1Y2xpZGlhbmEuKioNCg0KIyMjIyMgRXN0YSAqKmRpc3RhbmNpYSBub3MgYXl1ZGEgYSBkZXNjdWJyaXIgbGEgc2ltaWxpdHVkIGVudHJlIGxhcyB2YXJpYWJsZXMgcXVlIGVzdGFtb3MgYW5hbGl6YW5kby4qKiANCg0KIyMjICoqMikgSWRlbnRpZmljYXIgeSB2aXN1YWxpemFyIGxhcyBjYXJhY3RlcsOtc3RpY2FzIGRlIGNsw7pzdGVyczoqKg0KDQoNCiMjIyMgKipQYXNvIDEuIEluc3RhbGFyIGxpYnJlcsOtYXM6KioNCmBgYHtyfQ0KbGlicmFyeShmb3JlaWduKQ0KbGlicmFyeShkcGx5cikgICAgICAgIA0KbGlicmFyeShnZ3Bsb3QyKSAgICAgIA0KbGlicmFyeShwc3ljaCkgICAgICAgIA0KbGlicmFyeShjb3JycGxvdCkgICAgIA0KbGlicmFyeShqdG9vbHMpICAgICAgIA0KbGlicmFyeShsbXRlc3QpICAgICAgIA0KbGlicmFyeShjYXIpICAgICAgICAgIA0KbGlicmFyeShmYWN0b2V4dHJhKSAgDQpsaWJyYXJ5KGphbml0b3IpDQpgYGANCg0KIyMjIyAqKlBhc28gMi4gSW1wb3J0YXIgeSBsaW1waWFyIGxhIGJhc2UgZGUgZGF0b3M6KioNCmBgYHtyfQ0KYmQxIDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXG1hcmlhXFxEb2N1bWVudHNcXElURVNNIExBRVRcXFNlbWVzdHJlIDdcXFJldG9cXEZPUk0gQkFTRVMgREUgREFUT1NcXEZPUk0gLSBSZWN1cnNvcyBIdW1hbm9zIC0gQkFKQVMgQlVFTkEuY3N2IikNCmJhamFzIDwtIGNsZWFuX25hbWVzKGJkMSkNCnN1bW1hcnkoYmFqYXMpDQoNCiNUw6ljbmljYSAxOg0KI0JvcnJhciBjb2x1bW5hcy4NCmJhamFzIDwtIHN1YnNldChiYWphcywgc2VsZWN0ID0gLWMoYXBlbGxpZG9zLCBub21icmUsIGZlY2hhX2RlX25hY2ltaWVudG8scmZjLCBmZWNoYV9kZV9hbHRhLCBiYWphLCBkZXBhcnRhbWVudG8sIG5vX3NlZ3Vyb19zb2NpYWwsIGZhY3Rvcl9jcmVkX2luZm9uYXZpdCwgbl9jcmVkaXRvX2luZm9uYXZpdCwgbHVnYXJfZGVfbmFjaW1pZW50bywgY3VycCwgY2FsbGUsIG51bWVyb19pbnRlcm5vLCBjb2xvbmlhLCBjb2RpZ29fcG9zdGFsLCBtdW5pY2lwaW8sIGVzdGFkbywgdGFyamV0YV9jdWVudGEpKQ0KDQojVMOpY25pY2EgMjogDQojUmVlbXBsZXphciBOQXMgY29uIGVsIHByb21lZGlvIGVuIGxhIGNvbHVtbmEgZGUgIkVkYWQiLCAiU2FsYXJpbyBEaWFyaW8iIHkgIk7Dum1lcm8gZGUgZMOtYXMiLg0KYmFqYXMkZWRhZFtpcy5uYShiYWphcyRlZGFkKV08LW1lYW4oYmFqYXMkZWRhZCwgbmEucm0gPSBUUlVFKQ0KYmFqYXMkc2FsYXJpb19kaWFyaW9faW1zc1tpcy5uYShiYWphcyRzYWxhcmlvX2RpYXJpb19pbXNzKV08LW1lYW4oYmFqYXMkc2FsYXJpb19kaWFyaW9faW1zcywgbmEucm0gPSBUUlVFKQ0KYmFqYXMkbm9fZGlhc1tpcy5uYShiYWphcyRub19kaWFzKV08LW1lYW4oYmFqYXMkbm9fZGlhcywgbmEucm0gPSBUUlVFKQ0Kc3VtbWFyeSAoYmFqYXMpDQoNCiNUw6ljbmljYSAzOg0KI0NvbnZlcnRpciBsYXMgdmFyaWFibGVzIGNvbW8gZmFjdG9yIG8gbsO6bWVybw0KYmFqYXMkZWRhZDwtYXMubnVtZXJpYyhiYWphcyRlZGFkKQ0KYmFqYXMkZ2VuZXJvPC1hcy5mYWN0b3IoYmFqYXMkZ2VuZXJvKQ0KYmFqYXMkbW90aXZvX2RlX2JhamE8LWFzLmZhY3RvcihiYWphcyRtb3Rpdm9fZGVfYmFqYSkNCmJhamFzJG5vX2RpYXM8LWFzLm51bWVyaWMoYmFqYXMkbm9fZGlhcykNCmJhamFzJHB1ZXN0bzwtYXMuZmFjdG9yKGJhamFzJHB1ZXN0bykNCmJhamFzJHNhbGFyaW9fZGlhcmlvX2ltc3M8LWFzLm51bWVyaWMoYmFqYXMkc2FsYXJpb19kaWFyaW9faW1zcykNCmJhamFzJGVzdGFkb19jaXZpbDwtYXMuZmFjdG9yKGJhamFzJGVzdGFkb19jaXZpbCkNCnN1bW1hcnkgKGJhamFzKQ0KDQojRXhwb3J0YXIgYmFzZSBkZSBkYXRvcyBsaW1waWENCndyaXRlLmNzdihiYWphcywgZmlsZT0iYmFqYXNfYmRfbGltcGlhLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KDQpgYGANCg0KIyMjIyAqKlBhc28gMy4gQ3JlYWNpw7NuIGRlIENsw7pzdGVyczoqKg0KIyMjIyMgKkNsdXN0ZXIgMTogUmVsYWNpw7NuIGRlIHZhcmlhYmxlcyBkZSBFZGFkIHkgTsO6bWVybyBkZSBkw61hcy4qDQpgYGB7cn0NCmVkYWQ8LWJhamFzICU+JSBzZWxlY3QoZ2VuZXJvLGVzdGFkb19jaXZpbCxtb3Rpdm9fZGVfYmFqYSwgcHVlc3RvLCBzYWxhcmlvX2RpYXJpb19pbXNzLG5vX2RpYXMsIGVkYWQpDQoNCiNOb3JtYWxpemFyIHZhcmlhYmxlcw0KZWRhZF9ub3JtPC1zY2FsZShlZGFkWzY6N10pIA0KDQojRnVuY2nDs24gZnZpeiBwYXJhIGxhIHZpc3VhbGl6YWNpw7NuIGRlIHVuIEVsYm93IFBsb3QgeSBhc8OtIGRldGVybWluYXIgZWwgbsO6bWVybyBkZSBjbHVzdGVycy4NCmZ2aXpfbmJjbHVzdChlZGFkX25vcm0sIGttZWFucywgbWV0aG9kPSJ3c3MiKSsgDQogIGdlb21fdmxpbmUoeGludGVyY2VwdD00LCBsaW5ldHlwZT0yKSsgICAgICAgICAgICANCiAgbGFicyhzdWJ0aXRsZSA9ICJFbGJvdyBtZXRob2QiKQ0KDQpgYGANCg0KQ29uIGVzdGEgZ3LDoWZpY2EgcG9kZW1vcyB2aXN1YWxpemFyIHF1ZSBlbCAqKm7Dum1lcm8gw7NwdGltbyBkZSBjbMO6c3RlcnMgc29uIDQgKG9wdGltaXphY2nDs24pLioqDQoNCmBgYHtyfQ0KI1Zpc3VhbGl6YXIgY2x1c3RlcnMNCmVkYWRfY2x1c3Rlcjwta21lYW5zKGVkYWRfbm9ybSw0KQ0KZWRhZF9jbHVzdGVyDQoNCiNWaXN1YWxpemFyIHJlc3VsdGFkb3M6DQpmdml6X2NsdXN0ZXIoZWRhZF9jbHVzdGVyLGRhdGE9ZWRhZF9ub3JtKQ0KYGBgDQoNCkxvcyAqKm3DoXMgasOzdmVuZXMgc29uIGxvcyBxdWUgbWVub3MgZMOtYXMgZGUgdHJhYmFqbyBsYWJvcmFuLioqIEFzw60gY29tbyBxdWUgKipsb3MgcXVlIG3DoXMgZMOtYXMgbGFib3JhbGVzIHRpZW5lbiwgc29uIGxvcyBhZHVsdG9zKiogZGVzZGUgbG9zIDI3IGHDsW9zIGhhc3RhIGxvcyA2MS4NCg0KIyMjIyMgKkNsdXN0ZXIgMjogUmVsYWNpw7NuIGRlIHZhcmlhYmxlcyBkZSBFZGFkIHkgU2FsYXJpbyBEaWFyaW8uKg0KYGBge3J9DQplZGFkX3NhbGFyaW8gPC1iYWphcyAlPiUgc2VsZWN0KGdlbmVybyxlc3RhZG9fY2l2aWwsbW90aXZvX2RlX2JhamEsIHB1ZXN0bywgbm9fZGlhcywgc2FsYXJpb19kaWFyaW9faW1zcywgZWRhZCkNCg0KI05vcm1hbGl6YXIgdmFyaWFibGVzDQplZGFkX3NhbGFyaW9fbm9ybTwtc2NhbGUoZWRhZF9zYWxhcmlvWzY6N10pIA0KDQojRnVuY2nDs24gZnZpeiBwYXJhIGxhIHZpc3VhbGl6YWNpw7NuIGRlIHVuIEVsYm93IFBsb3QgeSBhc8OtIGRldGVybWluYXIgZWwgbsO6bWVybyBkZSBjbHVzdGVycy4NCmZ2aXpfbmJjbHVzdChlZGFkX3NhbGFyaW9fbm9ybSwga21lYW5zLCBtZXRob2Q9IndzcyIpKyANCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTQsIGxpbmV0eXBlPTIpKyAgICAgICAgICAgIA0KICBsYWJzKHN1YnRpdGxlID0gIkVsYm93IG1ldGhvZCIpIA0KYGBgDQoNCkNvbiBlc3RhIGdyw6FmaWNhIHBvZGVtb3MgdmlzdWFsaXphciBxdWUgZWwgKipuw7ptZXJvIMOzcHRpbW8gZGUgY2zDunN0ZXJzIHNvbiA0IChvcHRpbWl6YWNpw7NuKS4qKg0KDQpgYGB7cn0NCiNWaXN1YWxpemFyIGNsdXN0ZXJzOg0KZWRhZF9zYWxhcmlvX2NsdXN0ZXI8LWttZWFucyhlZGFkX3NhbGFyaW9fbm9ybSw0KQ0KZWRhZF9zYWxhcmlvX2NsdXN0ZXINCg0KI1Zpc3VhbGl6YXIgcmVzdWx0YWRvczoNCmZ2aXpfY2x1c3RlcihlZGFkX3NhbGFyaW9fY2x1c3RlcixkYXRhPWVkYWRfc2FsYXJpb19ub3JtKQ0KYGBgDQoNCkxhICoqZWRhZCBubyB0aWVuZSBtdWNoYSBpbmZsdWVuY2lhIGVuIGVsIHNhbGFyaW8uKiogUHVlcyBsb3MgY29sYWJvcmFkb3JlcyBxdWUgc2UgaGFuIGRhZG8gZGUgYmFqYSB0aWVuZW4gdW4gc2FsYXJpbyBtdXkgc2ltaWxhciBpbmRlcGVuZGllbnRlbWVudGUgZGUgc3UgZWRhZC4NCg0KIyMjIyMgKkNsdXN0ZXIgMzogUmVsYWNpw7NuIGRlIHZhcmlhYmxlcyBkZSBTYWxhcmlvIERpYXJpbyB5IE7Dum1lcm8gZGUgZMOtYXMuKg0KYGBge3J9DQpkaWFzX3NhbGFyaW8gPC1iYWphcyAlPiUgc2VsZWN0KGdlbmVybyxlc3RhZG9fY2l2aWwsbW90aXZvX2RlX2JhamEsIHB1ZXN0bywgZWRhZCwgbm9fZGlhcywgc2FsYXJpb19kaWFyaW9faW1zcykNCg0KI05vcm1hbGl6YXIgdmFyaWFibGVzOg0KZGlhc19zYWxhcmlvX25vcm08LXNjYWxlKGRpYXNfc2FsYXJpb1s2OjddKSANCg0KI0Z1bmNpw7NuIGZ2aXogcGFyYSBsYSB2aXN1YWxpemFjacOzbiBkZSB1biBFbGJvdyBQbG90IHkgYXPDrSBkZXRlcm1pbmFyIGVsIG7Dum1lcm8gZGUgY2x1c3RlcnMuDQpmdml6X25iY2x1c3QoZGlhc19zYWxhcmlvX25vcm0sIGttZWFucywgbWV0aG9kPSJ3c3MiKSsgDQogIGdlb21fdmxpbmUoeGludGVyY2VwdD00LCBsaW5ldHlwZT0yKSsgICAgICAgICAgICANCiAgbGFicyhzdWJ0aXRsZSA9ICJFbGJvdyBtZXRob2QiKSANCg0KYGBgDQoNCkNvbiBlc3RhIGdyw6FmaWNhIHBvZGVtb3MgdmlzdWFsaXphciBxdWUgZWwgKipuw7ptZXJvIMOzcHRpbW8gZGUgY2zDunN0ZXJzIHNvbiA0IChvcHRpbWl6YWNpw7NuKS4qKg0KDQpgYGB7cn0NCiNWaXN1YWxpemFyIGNsdXN0ZXJzOg0KZGlhc19zYWxhcmlvX2NsdXN0ZXI8LWttZWFucyhkaWFzX3NhbGFyaW9fbm9ybSw0KQ0KZGlhc19zYWxhcmlvX2NsdXN0ZXINCg0KI1Zpc3VhbGl6YXIgcmVzdWx0YWRvczoNCmZ2aXpfY2x1c3RlcihkaWFzX3NhbGFyaW9fY2x1c3RlcixkYXRhPWRpYXNfc2FsYXJpb19ub3JtKQ0KDQpwcm9tZWRpb19kaWFzIDwtIG1lYW4oYmFqYXMkbm9fZGlhcykNCnByb21lZGlvX2RpYXMNCmBgYA0KDQpFbiBlc3RlIGNsw7pzdGVyIHBvZGVtb3Mgb2JzZXJ2YXIgcXVlIHBvciBtw6FzIGFudGlnw7xlZGFkIG8gZMOtYXMgcXVlIGxhYm9yZXMgZW4gRk9STSwgKipubyBoYXkgbXVjaGEgcG9zaWJpbGlkYWQgZGUgY3JlY2ltaWVudG8gbGFib3JhbCAoZWNvbsOzbWljYW1lbnRlIGhhYmxhbmRvKSoqLCBwdWVzIHNlZ8O6biBlbCBjbHVzdGVyIHJlYWxpemFkbywgKipubyBpbmZsdXllbiBsb3MgZMOtYXMgbGFib3JhZG9zIGNvbiBlbCBzYWxhcmlvIGRpYXJpby4qKg0KDQojIyMjICoqUGFzbyA0LiBDcmVhY2nDs24gZGUgU2VnbWVudG9zIGFwYXJ0aXIgZGUgbG9zIENsw7pzdGVyczoqKg0KYGBge3J9DQojRGVjaWRpbW9zIHVzYXIgZWwgQ2x1c3RlciAyIHBhcmEgZ2VuZXJhciBsYSBjbGFzaWZpY2FjacOzbiBkZSB2YXJpYWJsZXMgeSBwb2RlciBjb21wYXJhciBjb24gZGF0b3MgY3VhbGl0YXRpdm9zLg0KDQojQcOxYWRpciBhIGxhIGJhc2UgZGUgZGF0b3MgbGEgY29sdW1uYSBkZSBDbHVzdGVycyB5IHN1IGNsYXNpZmljYWNpw7NuOg0KYmFqYXMxPC1iYWphcw0KYmFqYXMxJENsdXN0ZXJzPC1lZGFkX3NhbGFyaW9fY2x1c3RlciRjbHVzdGVyDQoNCiNJZGVudGlmaWNhbW9zIGxhIGNsYXNpZmljYWNpw7NuIGRlIGxhcyBkaXN0aW50YXMgZWRhZGVzIGRlIGxvcyBjb2xhYm9yYWRvcmVzLg0KYmFqYXMyPC1iYWphczEgJT4lIGdyb3VwX2J5KENsdXN0ZXJzKSAlPiUgc3VtbWFyaXNlKGVkYWQ9bWF4KGVkYWQpKSAlPiUgYXJyYW5nZShkZXNjKGVkYWQpKQ0KYmFqYXMxJENsdXN0ZXJfTmFtZXM8LWZhY3RvcihiYWphczEkQ2x1c3RlcnMsbGV2ZWxzID0gYygxLDIsMyw0KSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiT3V0bGllciIsICJKb3ZlbiIsICJBdmFuemFkYSIsICJBZHVsdGEiKSkNCmJhamFzMyA8LSBiYWphczEgJT4lIGdyb3VwX2J5KENsdXN0ZXJfTmFtZXMpICU+JSBzdW1tYXJpemUoZWRhZF9hw7Fvcz1tYXgoZWRhZCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbGFyaW9faW1zcz1tZWFuKHNhbGFyaW9fZGlhcmlvX2ltc3MpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvdW50PW4oKSkNCmNsdXN0ZXJzPC1hcy5kYXRhLmZyYW1lKGJhamFzMykNCmNsdXN0ZXJzDQoNCmBgYA0KDQojIyMjICoqUGFzbyA1LiBHZW5lcmFjacOzbiBkZSBncsOhZmljb3M6KioNCiMjIyMjICoqR3LDoWZpY29zIGN1YW50aXRhdGl2b3M6KioNCmBgYHtyfQ0KI1NlIHJlYWxpesOzIHVuYSBncsOhZmljYSBwYXJhIGFuYWxpemFyIGVsIG7Dum1lcm8gZGUgcmVnaXN0cm9zIHBvciBjYWRhIHNlZ21lbnRvOiANCmdncGxvdChiYWphczMsYWVzKHg9cmVvcmRlcihDbHVzdGVyX05hbWVzLENvdW50KSx5PUNvdW50LGZpbGw9Q2x1c3Rlcl9OYW1lcykpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKQ0KDQpgYGANCg0KTG9zICoqY29sYWJvcmFkb3JlcyBxdWUgbcOhcyBiYWphcyBoYW4gcHJlc2VudGFkbyoqIHNlZ8O6biBsYSBncsOhZmljYSBhbnRlcmlvciBzb24gKipqw7N2ZW5lcyoqLCBzZWd1aWRvIHBvciBsb3MgYWR1bHRvcyB5IGRlc3B1w6lzIGxvcyBjb2xhYm9yYWRvcmVzIGRlIGVkYWQgYXZhbnphZGEuDQoNCmBgYHtyfQ0KI1Zpc3VhbGl6YXIgbGEgZWRhZCBwb3IgY2FkYSBzZWdtZW50bzoNCmdncGxvdChiYWphczMsIGFlcyh4PUNsdXN0ZXJfTmFtZXMseT1lZGFkX2HDsW9zLGZpbGw9IENsdXN0ZXJfTmFtZXMsbGFiZWw9cm91bmQoZWRhZF9hw7FvcyxkaWdpdHM9MikpKSArIA0KICBnZW9tX2NvbCgpICsgDQogIGdlb21fdGV4dCgpDQpgYGANCg0KVmlzdWFsaXphY2nDs24gZGUgbG9zIG3DoXhpbW9zIGRlIGNhZGEgc2VnbWVudG86ICpKw7N2ZW5lcyAoaGFzdGEgbG9zIDI4KSwgQXZhbnphZGEgKEhhc3RhIGxvcyA2MSksIEFkdWx0YSAoSGFzdGEgbG9zIDQwKSB5IGVsIE91dGxpZXIgZGUgMzIuKg0KDQojIyMjIyAqKkdyw6FmaWNhcyBtaXh0YXMgKERhdG9zIEN1YWxpdGF0aXZvcyB5IEN1YW50aXRhdGl2b3MpOioqDQoNCiMjIyMjIEdyw6FmaWNhIGRlIGJhcnJhczogKENsdXN0ZXJzIHkgR8OpbmVybykNCmBgYHtyfQ0KZ2dwbG90KGJhamFzMSwgYWVzKGZhY3RvcihDbHVzdGVyX05hbWVzKSwgZmlsbCA9IGZhY3RvcihnZW5lcm8pKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlMihwcmVzZXJ2ZSA9ICJzaW5nbGUiKSkgDQpgYGANCg0KRXN0ZSBncsOhZmljbyBub3MgZGljZSBxdWUgZGUgY2FkYSBzZWdtZW50bywgKipoYXkgbcOhcyBtdWplcmVzIHF1ZSBzZSBoYW4gZGFkbyBkZSBiYWphLioqDQoNCiMjIyMjIEdyw6FmaWNhIGRlIGJhcnJhczogKENsdXN0ZXJzIHkgRXN0YWRvIENpdmlsKQ0KYGBge3J9DQpnZ3Bsb3QoYmFqYXMxLCBhZXMoZmFjdG9yKENsdXN0ZXJfTmFtZXMpLCBmaWxsID0gZmFjdG9yKGVzdGFkb19jaXZpbCkpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UyKHByZXNlcnZlID0gInNpbmdsZSIpKSANCmBgYA0KDQpQb2RlbW9zIHZpc3VhbGl6YXIgcXVlIGRlIGRlIGxvcyBqw7N2ZW5lcywgbGEgbWF5b3LDrWEgZXJhbiBzb2x0ZXJvcywgZGUgbG9zIGFkdWx0b3MgaGFiw61hIGxhIG1pc21hIGNhbnRpZGFkIGRlIGNhc2Fkb3MsIHNvbGVyb3MgeSBlbiB1bmnDs24gbGlicmUgeSBlbiBhdmFuemFkb3MgZXJhbiBtw6FzIHNvbHRlcm9zIHkgY2FzYWRvcy4gTcOhcyBzaW4gZW1iYXJnbywgKipoYXkgbXV5IHBvY29zIGNvbGFib3JhZG9yZXMgcXVlIHNlIGhhbiBkYWRvIGRlIGJhamEgZGl2b3JjaWFkb3MuKioNCg0KIyMjIyMgR3LDoWZpY2EgZGUgYmFycmFzOiAoQ2x1c3RlcnMgeSBNb3Rpdm8gZGUgQmFqYSkNCmBgYHtyfQ0KZ2dwbG90KGJhamFzMSwgYWVzKGZhY3RvcihDbHVzdGVyX05hbWVzKSwgZmlsbCA9IGZhY3Rvcihtb3Rpdm9fZGVfYmFqYSkpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UyKHByZXNlcnZlID0gInNpbmdsZSIpKSANCmBgYA0KDQpQb2RlbW9zIG9ic2VydmFyIHF1ZSBlbiBlbCBzZWdtZW50byBkZSBjb2xhYm9yYWRvcmVzIGpvdmVuZXMsIGFkdWx0b3MgeSBkZSBlZGFkIGF2YW56YWRhLCAqKmxhIG1heW9yIHBhcnRlIHNlIGhhIGRhZG8gZGUgYmFqYSBwb3IgZmFsdGFzLCBzaWd1aWVuZG8gYXPDrSBwb3IgcmVudW5jaWEgdm9sdW50YXJpYS4qKg0KDQojIyMjIyBHcsOhZmljYSBkZSBwYXk6IChQdWVzdG8pDQpgYGB7cn0NCnRhYmxlKGJhamFzMSRwdWVzdG8pDQpwcm9wb3JjaW9uZXMgPC0gYygyMywgMTc5LCAxMSwgMTEsIDcsIDUpDQpldGlxdWV0YXMgPC0gYygiT3Ryb3MiLCJBeXVkYW50ZSBHZW5lcmFsIiwgIkNvc3R1cmVyYSIsICJTb2xkYWRvciIsICJBeXVkYW50ZSBFbWJhcnF1ZXMiLCAiTW9udGFjYXJndWlzdGEiKQ0KcGN0IDwtIHJvdW5kKHByb3BvcmNpb25lcy9zdW0ocHJvcG9yY2lvbmVzKSoxMDApDQpldGlxdWV0YXMgPC0gcGFzdGUoZXRpcXVldGFzLCBwY3QpDQpldGlxdWV0YXMgPC0gcGFzdGUoZXRpcXVldGFzLCIlIixzZXA9IiIpDQpwaWUocHJvcG9yY2lvbmVzLGxhYmVscyA9IGV0aXF1ZXRhcywNCiAgICBjb2w9cmFpbmJvdyhsZW5ndGgoZXRpcXVldGFzKSksDQogICAgbWFpbj0iUHVlc3RvIGRlIGxvcyBFeC1Db2xhYm9yYWRvcmVzIikNCg0KYGBgDQoNCkxhICoqbWF5b3IgcGFydGUgZGUgbG9zIGV4LWNvbGFib3JhZG9yZXMgZGUgRm9ybSBlcmFuIEF5dWRhbnRlcyBnZW5lcmFsZXMgKDc2JSkuKioNCg0KDQojIyMgKiozKSBJZGVudGlmaWNhciB5IGRlc2NyaWJpciBsb3MgaGFsbGF6Z29zIGRlIGxvcyBjbMO6c3RlcnM6KioNCg0KPGRpdiBjbGFzcz10ZXh0LWp1c3RpZnk+DQoNCiMjIyMjICoqMS4gTGEgZWRhZCoqIGRlIGxvcyBjb2xhYm9yYWRvcmVzIHF1ZSBzZSBoYW4gZGFkbyBkZSBiYWphLCAqKm5vIHRpZW5lIGluZmx1ZW5jaWEgZW4gc3Ugc2FsYXJpby4qKg0KDQojIyMjIyAqKjIuIEVsIHNhbGFyaW8gaW5mbHV5ZSBtdWNobyBlbiBsYXMgYmFqYXMqKiwgcHVlcyB0b2RvcyBsb3MgcXVlIHNlIGhhbiBkYWRvIGRlIGJhamEgdGllbmVuIHVuICpzYWxhcmlvIHByb21lZGlvIG1lbm9yIGEgJDE4MCBkaWFyaW9zLiogU29sYW1lbnRlIHVuIGNvbGFib3JhZG9yIGNvbiB1biBzYWxhcmlvIG1heW9yICgkNTAwKSBzZSBoYSBkYWRvIGRlIGJhamEuDQoNCiMjIyMjICoqMy4gTG9zIGTDrWFzIGxhYm9yYWxlcyAoYW50aWfDvGVkYWQpIGRlIHVuIGNvbGFib3JhZG9yLCBubyBpbmZsdXllbiBjb24gZWwgc2FsYXJpbyoqLCBhbCBtZW5vcyBjb24gbG9zIHF1ZSBzZSBoYW4gZGFkbyBkZSBiYWphLiBMbyBxdWUgcHVlZGUgc2lnbmlmaWNhciBxdWUgKmxhIG9wb3J0dW5pZGFkIGRlIGNyZWNlciBlY29uw7NtaWNhbWVudGUgZW4gRk9STSBkZSBhY3VlcmRvIGEgdHUgYW50aWfDvGVkYWQgZXMgbcOtbmltYS4qDQoNCiMjIyMjICoqNC4gTGEgbWF5b3LDrWEgZGUgbG9zIGNvbGFib3JhZG9yZXMgcXVlIHNlIGhhbiBkYWRvIGRlIGJhamEsIG5vIGhhbiB0cmFiYWphZG8gbcOhcyBkZSAzIG1lc2VzKiogKDc5IGTDrWFzKSBlbiBGT1JNLg0KDQojIyMjIyAqKjUuIExvcyBjb2xhYm9yYWRvcmVzIHF1ZSBtw6FzIGJhamFzIGhhbiBwcmVzZW50YWRvIHNvbiBqw7N2ZW5lcyoqIChkZSBlZGFkZXMgZGUgbG9zIDE4LTI4IGHDsW9zKS4NCg0KIyMjIyMgKio2LioqIEluZGVwZW5kaWVudGVtZW50ZSBkZSBzaSBsb3MgZXgtY29sYWJvcmFkb3JlcyBzb24gasOzdmVuZXMsIGFkdWx0b3MgbyBtYXlvcmVzLCBkZSBjYWRhIHNlZ21lbnRvICoqbGFzIG11amVyZXMgc29uIGxhcyBxdWUgaGFuIHByZXNlbnRhZG8gbcOhcyBiYWphcy4qKg0KDQojIyMjIyAqKjcuIEZPUk0gaGEgZGVzcGVkaWRvIG3DoXMgY29sYWJvcmFkb3JlcyBkZSBsb3MgcXVlIGhhbiByZW51bmNpYWRvLCBzaWVuZG8gbGEgcHJpbmNpcGFsIGNhdXNhIGxhICJCYWphIHBvciBmYWx0YXMiLioqIExvIHF1ZSBwdWVkZSBzaWduaWZpY2FyIHF1ZSBzdSBwcm9jZXNvIGRlIGNvbnRyYXRhY2nDs24gbm8gZXMgZWwgbcOhcyDDs3B0aW1vIHlhIHF1ZSB0ZXJtaW5hbiBjb250cmF0YW5kbyBwZXJzb25hbCBxdWUgbm8gZXJhIGVsIGFkZWN1YWRvIHBhcmEgZWwgcHVlc3RvLg0KDQo8L2Rpdj4NCg0KIyMjICoqNCkgUmVmZXJlbmNpYXM6KioNCg0KPGRpdiBjbGFzcz10ZXh0LWp1c3RpZnk+DQoNCiMjIyMjIChMRURVKSwgRS4gRS4gKDIwMTgsIFNlcHRlbWJlciAxMikuIFVuZGVyc3RhbmRpbmcgSy1tZWFucyBjbHVzdGVyaW5nIGluIG1hY2hpbmUgbGVhcm5pbmcuIE1lZGl1bS4gUmV0cmlldmVkIE9jdG9iZXIgOCwgMjAyMiwgZnJvbSBodHRwczovL3Rvd2FyZHNkYXRhc2NpZW5jZS5jb20vdW5kZXJzdGFuZGluZy1rLW1lYW5zLWNsdXN0ZXJpbmctaW4tbWFjaGluZS1sZWFybmluZy02YTZlNjczMzZhYTEgDQoNCiMjIyMjIEstbWVhbnMgY2x1c3RlcmluZyBpbiBSIHByb2dyYW1taW5nLiBHZWVrc2ZvckdlZWtzLiAoMjAyMCwgSnVseSAyKS4gUmV0cmlldmVkIE9jdG9iZXIgOSwgMjAyMiwgZnJvbSBodHRwczovL3d3dy5nZWVrc2ZvcmdlZWtzLm9yZy9rLW1lYW5zLWNsdXN0ZXJpbmctaW4tci1wcm9ncmFtbWluZy8gDQogIA0KIyMjIyMgU3VwZXJ2aXNlZCBhbmQgdW5zdXBlcnZpc2VkIGxlYXJuaW5nIGluIFIgcHJvZ3JhbW1pbmcuIEdlZWtzZm9yR2Vla3MuICgyMDIxLCBOb3ZlbWJlciAyOSkuIFJldHJpZXZlZCBPY3RvYmVyIDksIDIwMjIsIGZyb20gaHR0cHM6Ly93d3cuZ2Vla3Nmb3JnZWVrcy5vcmcvc3VwZXJ2aXNlZC1hbmQtdW5zdXBlcnZpc2VkLWNsdXN0ZXJpbmctaW4tci1wcm9ncmFtbWluZy8gDQogIA0KIyMjIyMgU2hhZGFuLCBNLiAobi5kLikuIFVuc3VwZXJ2aXNlZCBsZWFybmluZyBpbiBSLiBSLiBSZXRyaWV2ZWQgT2N0b2JlciA5LCAyMDIyLCBmcm9tIGh0dHBzOi8vcnN0dWRpby1wdWJzLXN0YXRpYy5zMy5hbWF6b25hd3MuY29tLzI3MzEyOV80NTM2MTBjYTY5NDU0MWUxYTJjNTY2NGJmN2NjYmExYS5odG1sIA0KDQojIyMjIyBIb3cgdG8gY29tcHV0ZSB0aGUgZXVjbGlkZWFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIGFycmF5cyBpbiBSIC0uIFByb2plY3RQcm8uIChuLmQuKS4gUmV0cmlldmVkIE9jdG9iZXIgOSwgMjAyMiwgZnJvbSBodHRwczovL3d3dy5wcm9qZWN0cHJvLmlvL3JlY2lwZXMvY29tcHV0ZS1ldWNsaWRlYW4tZGlzdGFuY2UtYmV0d2Vlbi10d28tYXJyYXlzLXIgDQoNCjwvZGl2Pg0KDQoNCg0K