Desarrollo de clasificación de K Vecinos

Librerias instaladas

library(foreign)
library(dplyr)        # data manipulation 
## 
## 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)      # data visualization 
library(psych)        # functions for multivariate analysis 
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
library(corrplot)     # correlation plots
## corrplot 0.92 loaded
library(jtools)       # presentation of regression analysis 
library(lmtest)       # diagnostic checks - linear regression analysis 
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(car)          # diagnostic checks - linear regression analysis
## 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)   # provides functions to extract and visualize the output of exploratory multivariate data analyses
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(ggfortify)    # data visualization tools for statistical analysis results

Importar base de datos

summary(rh)
##  nombre_completo     fecha_nac            genero           fecha_alta       
##  Length:238         Length:238         Length:238         Length:238        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##    mot_baja          permanencia          baja              puesto         
##  Length:238         Min.   :   0.00   Length:238         Length:238        
##  Class :character   1st Qu.:   9.00   Class :character   Class :character  
##  Mode  :character   Median :  19.00   Mode  :character   Mode  :character  
##                     Mean   :  79.71                                        
##                     3rd Qu.:  49.00                                        
##                     Max.   :1966.00                                        
##                     NA's   :25                                             
##  departamento       sal_diario_imss   colonia                CP       
##  Length:238         Min.   :144.4   Length:238         Min.   :    0  
##  Class :character   1st Qu.:180.7   Class :character   1st Qu.:66645  
##  Mode  :character   Median :180.7   Mode  :character   Median :66646  
##                     Mean   :178.0                      Mean   :64816  
##                     3rd Qu.:180.7                      3rd Qu.:66649  
##                     Max.   :500.0                      Max.   :99999  
##                                                        NA's   :3      
##   municipio            estado          estado_civil           edad          
##  Length:238         Length:238         Length:238         Length:238        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
## 

Limpieza de base de datos

Remplazar los NA en “permanencia” y “edad” por la media del puesto

Observar cuantos NA´s tenemos por columna

rh_2 <- rh_1
colSums(is.na(rh_2))
## nombre_completo       fecha_nac          genero      fecha_alta        mot_baja 
##               0               1               0               1              25 
##     permanencia            baja          puesto    departamento sal_diario_imss 
##               3              15               0               0               0 
##         colonia              CP       municipio          estado    estado_civil 
##               0               3               0               0               0 
##            edad 
##               0
class(rh_2$permanencia)
## [1] "numeric"
class(rh_2$baja)
## [1] "character"
class(rh_2$edad)
## [1] "character"
class(rh_2$sal_diario_imss)
## [1] "numeric"
rh_2$baja <- as.Date(rh_2$baja)
rh_2$edad <- as.integer(rh_2$edad)
## Warning: NAs introduced by coercion
rh_2$permanencia <- as.integer(rh_2$permanencia)

Agregar columna de mes de baja

rh_3 <- rh_2
rh_3$mes_baja <- as.numeric(format(rh_3$baja, '%m'))
rh_3
## # A tibble: 238 × 17
## # Groups:   puesto [22]
##    nombre_com…¹ fecha…² genero fecha…³ mot_b…⁴ perma…⁵ baja       puesto depar…⁶
##    <chr>        <chr>   <chr>  <chr>   <chr>     <int> <date>     <chr>  <chr>  
##  1 MARIO VALDE… 1990-0… MASCU… 2020-0… RENUNC…     628 2021-11-27 DISE�O "ADMIN…
##  2 ISABEL BARR… 1986-0… FEMEN… 2021-1… RENUNC…      60 2022-01-08 AYUDA… "PRODU…
##  3 MARIA ELIZA… 1999-0… FEMEN… 2021-1… RENUNC…      59 2022-01-08 AYUDA… "STABI…
##  4 ALONDRA ABI… 2001-0… FEMEN… 2021-1… RENUNC…      59 2022-01-08 AYUDA… "CELDA…
##  5 ERIKA ROSAL… 1993-0… FEMEN… 2021-1… RENUNC…      51 2022-01-08 AYUDA… ""     
##  6 GUADALUPE S… 1976-1… FEMEN… 2021-1… BAJA P…      37 2022-01-08 AYUDA… ""     
##  7 YOANA CRIST… 1993-0… FEMEN… 2021-1… BAJA P…      37 2022-01-08 AYUDA… ""     
##  8 CESAR ANTON… 1991-0… MASCU… 2021-1… BAJA P…      31 2022-01-08 AYUDA… ""     
##  9 ROBERTO SAE… 1972-0… MASCU… 2021-1… BAJA P…      18 2022-01-08 AYUDA… ""     
## 10 JAIME DANIE… 2003-0… MASCU… 2021-0… RENUNC…     224 2022-01-10 AYUDA… "MATER…
## # … with 228 more rows, 8 more variables: sal_diario_imss <dbl>, colonia <chr>,
## #   CP <int>, municipio <chr>, estado <chr>, estado_civil <chr>, edad <int>,
## #   mes_baja <dbl>, and abbreviated variable names ¹​nombre_completo,
## #   ²​fecha_nac, ³​fecha_alta, ⁴​mot_baja, ⁵​permanencia, ⁶​departamento
class(rh_3$permanencia)
## [1] "integer"
class(rh_3$baja)
## [1] "Date"
class(rh_3$edad)
## [1] "integer"
class(rh_3$sal_diario_imss)
## [1] "numeric"
class(rh_3$mes_baja)
## [1] "numeric"
summary(rh_3)
##  nombre_completo     fecha_nac            genero           fecha_alta       
##  Length:238         Length:238         Length:238         Length:238        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##    mot_baja          permanencia           baja               puesto         
##  Length:238         Min.   :   0.00   Min.   :2021-11-27   Length:238        
##  Class :character   1st Qu.:   9.00   1st Qu.:2022-02-25   Class :character  
##  Mode  :character   Median :  21.00   Median :2022-04-29   Mode  :character  
##                     Mean   :  77.96   Mean   :2022-04-29                     
##                     3rd Qu.:  60.00   3rd Qu.:2022-06-29                     
##                     Max.   :1966.00   Max.   :2022-08-25                     
##                     NA's   :3         NA's   :15                             
##  departamento       sal_diario_imss   colonia                CP       
##  Length:238         Min.   :144.4   Length:238         Min.   :    0  
##  Class :character   1st Qu.:180.7   Class :character   1st Qu.:66645  
##  Mode  :character   Median :180.7   Mode  :character   Median :66646  
##                     Mean   :178.0                      Mean   :64816  
##                     3rd Qu.:180.7                      3rd Qu.:66649  
##                     Max.   :500.0                      Max.   :99999  
##                                                        NA's   :3      
##   municipio            estado          estado_civil            edad      
##  Length:238         Length:238         Length:238         Min.   : 0.00  
##  Class :character   Class :character   Class :character   1st Qu.:23.00  
##  Mode  :character   Mode  :character   Mode  :character   Median :28.00  
##                                                           Mean   :30.39  
##                                                           3rd Qu.:37.00  
##                                                           Max.   :61.00  
##                                                           NA's   :1      
##     mes_baja     
##  Min.   : 1.000  
##  1st Qu.: 2.000  
##  Median : 4.000  
##  Mean   : 4.475  
##  3rd Qu.: 6.000  
##  Max.   :11.000  
##  NA's   :15

Reemplazar los NA por el mes 7

rh_4 <- rh_3
rh_4$mes_baja <- replace(rh_4$mes_baja, is.na(rh_4$mes_baja), 7)

Variables que vamos a analizar en el análisis k-means

rh_alt<-rh_4 %>% select(sal_diario_imss, edad, permanencia, mes_baja)
## Adding missing grouping variables: `puesto`
rh_alt
## # A tibble: 238 × 5
## # Groups:   puesto [22]
##    puesto           sal_diario_imss  edad permanencia mes_baja
##    <chr>                      <dbl> <int>       <int>    <dbl>
##  1 DISE�O                      500     32         628       11
##  2 AYUDANTE GENERAL            152.    36          60        1
##  3 AYUDANTE GENERAL            152.    23          59        1
##  4 AYUDANTE GENERAL            152.    21          59        1
##  5 AYUDANTE GENERAL            152.    29          51        1
##  6 AYUDANTE GENERAL            152.    46          37        1
##  7 AYUDANTE GENERAL            152.    29          37        1
##  8 AYUDANTE GENERAL            152.    31          31        1
##  9 AYUDANTE GENERAL            152.    50          18        1
## 10 AYUDANTE GENERAL            177.    19         224        1
## # … with 228 more rows

Eliminar NA´s

rh_alt<-rh_alt[-c(196, 197,200),] # 
summary(rh_alt) # no missing values
##     puesto          sal_diario_imss      edad        permanencia     
##  Length:235         Min.   :144.4   Min.   : 0.00   Min.   :   0.00  
##  Class :character   1st Qu.:180.7   1st Qu.:23.00   1st Qu.:   9.00  
##  Mode  :character   Median :180.7   Median :28.00   Median :  21.00  
##                     Mean   :178.0   Mean   :30.43   Mean   :  77.96  
##                     3rd Qu.:180.7   3rd Qu.:37.00   3rd Qu.:  60.00  
##                     Max.   :500.0   Max.   :61.00   Max.   :1966.00  
##     mes_baja     
##  Min.   : 1.000  
##  1st Qu.: 3.000  
##  Median : 5.000  
##  Mean   : 4.604  
##  3rd Qu.: 7.000  
##  Max.   :11.000

Definicion de conceptos clave

En equipo describir con sus propias palabras cómo los siguientes conceptos contribuyen a la identificación de clusters usando analítica de datos:

K- Vecinos Más Cercanos y/o K-Means Clustering

El objetivo del K-Means Clustering es dividir el conjunto de datos en subpoblaciones de objetos que son similares y pertenecen dentro de un grupo específico acorde a sus características.
Además este método es probablemente el más utilizado en la ciencia de datos.

Ejemplos para aplicar K-Means: - Segmentación de clientes.
- Comunidades de redes sociales
- Geo estadística

Aprendizaje No Supervisado y/o Unsupervised Learning

La clusterización es un algoritmo de aprendizaje no supervisado.
El algoritmo de aprendizaje no supervisado sirve para explorar, describir y resumir datos, así como también a descubrir patrones y relaciones, pero sin existir una categorización o etiquetado de datos previo, por lo tanto, se agrupará según las características y similitudes.

Distancia Euclidiana / Eucliedean Distance

Se emplea para medir la disimilitud (Falta de semejanza o de parecido entre dos o más cosas) y es la más utilizada al momento de realizar K-Means clustering.
Dicha distancia mide una línea recta entre el punto de consulta y el otro punto que se mide.

Clusters

Cluster 1: Analizar que edad tiene menor permanencia que el promedio.

#Normalizar las variables  
rh_alt1 <- rh_alt
rh_alt1 <- subset(rh_alt1, permanencia>0 & permanencia<79)
rh_alt1 <- subset(rh_alt1, edad>24 & edad<38)
rh_permanencia<-scale(rh_alt1[3:4]) 
summary(rh_permanencia)
##       edad          permanencia     
##  Min.   :-1.4589   Min.   :-1.0086  
##  1st Qu.:-0.9356   1st Qu.:-0.7421  
##  Median :-0.1505   Median :-0.3598  
##  Mean   : 0.0000   Mean   : 0.0000  
##  3rd Qu.: 0.8963   3rd Qu.: 0.3470  
##  Max.   : 1.6814   Max.   : 2.5138
fviz_nbclust(rh_permanencia, kmeans, method="wss")+ # wss method considers total within sum of square
  geom_vline(xintercept=4, linetype=2)+           # optimal number of clusters is computed with the default method = "euclidean"
  labs(subtitle = "Elbow method")                 
## Registered S3 methods overwritten by 'broom':
##   method            from  
##   tidy.glht         jtools
##   tidy.summary.glht jtools

# visualize the clusters' information. Briefly, you can detect how each dataset's observation corresponds to a specific cluster. 
permanencia_cluster1<-kmeans(rh_permanencia,4)
permanencia_cluster1
## K-means clustering with 4 clusters of sizes 26, 9, 37, 8
## 
## Cluster means:
##         edad permanencia
## 1  0.9667615  -0.6075563
## 2  0.9544596   1.6177287
## 3 -0.7799570  -0.3672901
## 4 -0.6084407   1.8533297
## 
## Clustering vector:
##  [1] 2 4 3 3 2 3 3 1 1 1 3 3 3 3 3 3 3 1 3 1 4 4 1 3 3 3 1 3 3 1 1 3 1 1 3 3 1 3
## [39] 1 3 1 1 3 1 1 3 3 1 1 3 3 3 3 3 3 1 2 2 2 2 4 2 1 2 3 4 4 2 4 3 1 1 3 1 1 4
## [77] 3 3 3 1
## 
## Within cluster sum of squares by cluster:
## [1] 10.327682  3.140087 16.382860  4.559511
##  (between_SS / total_SS =  78.2 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
# visualize clustering results 
fviz_cluster(permanencia_cluster1,data=rh_permanencia)

Tabla de clusters

#lets add the estimated clusters’ information to the original dataset so we can interpret the results

rh_alt_tabla<-rh_alt1
rh_alt_tabla$Clusters<-permanencia_cluster1$cluster
#lets create a dataset so we can identify some characteristics of “permanencia” by cluster
rh_alt_tabla2<-rh_alt_tabla %>% group_by(Clusters) %>% summarise(permanencia=max(permanencia)) %>% arrange(desc(permanencia))
#group the clusters by name
rh_alt_tabla$Cluster_Names<-factor(rh_alt_tabla$Clusters,levels = c(1,2,3,4), 
                              labels=c("Antigüedad Baja", "Antigüedad Alta", "Antigüedad Moderada", "Antigüedad Avanzada"))
#group the clusters by cluster names and Summarize the Columns
rh_alt_tabla3 <- rh_alt_tabla %>% group_by(Cluster_Names) %>% summarize(permanencia_años=max(permanencia), 
                                                             edad=mean(edad),
                                                             Count=n())
clusters<-as.data.frame(rh_alt_tabla3)
clusters
##         Cluster_Names permanencia_años     edad Count
## 1     Antigüedad Baja               29 34.26923    26
## 2     Antigüedad Alta               60 34.22222     9
## 3 Antigüedad Moderada               37 27.59459    37
## 4 Antigüedad Avanzada               77 28.25000     8
#lets plot the number of data observations by clusters names
ggplot(rh_alt_tabla3,aes(x=reorder(Cluster_Names,Count),y=Count,fill=Cluster_Names)) +
  geom_bar(stat="identity")

Cluster 2: Analizar salario diario y permanencia

summary(rh_alt)
##     puesto          sal_diario_imss      edad        permanencia     
##  Length:235         Min.   :144.4   Min.   : 0.00   Min.   :   0.00  
##  Class :character   1st Qu.:180.7   1st Qu.:23.00   1st Qu.:   9.00  
##  Mode  :character   Median :180.7   Median :28.00   Median :  21.00  
##                     Mean   :178.0   Mean   :30.43   Mean   :  77.96  
##                     3rd Qu.:180.7   3rd Qu.:37.00   3rd Qu.:  60.00  
##                     Max.   :500.0   Max.   :61.00   Max.   :1966.00  
##     mes_baja     
##  Min.   : 1.000  
##  1st Qu.: 3.000  
##  Median : 5.000  
##  Mean   : 4.604  
##  3rd Qu.: 7.000  
##  Max.   :11.000
rh_salario<-scale(rh_alt2[4:5]) 

summary(rh_salario)
##  sal_diario_imss    permanencia     
##  Min.   :-2.8567   Min.   :-1.1201  
##  1st Qu.: 0.3499   1st Qu.:-0.7992  
##  Median : 0.3499   Median :-0.2643  
##  Mean   : 0.0000   Mean   : 0.0000  
##  3rd Qu.: 0.3499   3rd Qu.: 0.7518  
##  Max.   : 0.6808   Max.   : 2.5168
fviz_nbclust(rh_salario, kmeans, method="wss")+ # wss method considers total within sum of square
  geom_vline(xintercept=4, linetype=2)+           # optimal number of clusters is computed with the default method = "euclidean"
  labs(subtitle = "Elbow method")                 

# visualize the clusters' information. Briefly, you can detect how each dataset's observation corresponds to a specific cluster. 
salario_cluster1<-kmeans(rh_salario,4)
salario_cluster1
## K-means clustering with 4 clusters of sizes 15, 30, 30, 64
## 
## Cluster means:
##   sal_diario_imss permanencia
## 1      -2.8567440  0.47016757
## 2       0.3281298  0.01199211
## 3       0.3353366  1.54875184
## 4       0.3585495 -0.84179425
## 
## Clustering vector:
##   [1] 1 1 1 1 1 1 1 1 1 1 2 2 1 1 1 1 1 4 4 4 4 4 4 4 3 4 4 2 2 4 4 2 2 2 4 4 4
##  [38] 2 2 3 2 4 3 3 3 2 4 3 3 3 3 2 4 4 4 2 4 4 4 4 4 4 4 2 2 4 4 4 4 4 3 2 4 4
##  [75] 4 4 2 2 4 4 4 2 4 4 4 4 2 4 4 2 4 4 4 4 4 4 4 4 4 2 2 3 3 3 3 3 3 3 4 3 3
## [112] 4 3 3 4 3 3 3 3 3 3 3 3 4 4 4 4 4 3 2 2 2 4 2 4 4 2 2 2
## 
## Within cluster sum of squares by cluster:
## [1] 8.309523 2.567639 4.603043 2.643046
##  (between_SS / total_SS =  93.4 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
# visualize clustering results 
fviz_cluster(salario_cluster1,data=rh_salario)

Tabla de clusters

#lets add the estimated clusters’ information to the original dataset so we can interpret the results

rh_alt2_tabla<-rh_alt2
rh_alt2_tabla$Clusters<-salario_cluster1$cluster
#lets create a dataset so we can identify some characteristics of “permanencia” by cluster
rh_alt2_tabla2<-rh_alt2_tabla %>% group_by(Clusters) %>% summarise(permanencia=max(permanencia)) %>% arrange(desc(permanencia))
#group the clusters by name
rh_alt2_tabla$Cluster_Names<-factor(rh_alt2_tabla$Clusters,levels = c(1,2,3,4), 
                              labels=c("Antigüedad Alta", "Antigüedad Moderada", "Antigüedad Avanzada", "Antigüedad Baja"))
#group the clusters by cluster names and Summarize the Columns
rh_alt2_tabla3 <- rh_alt2_tabla %>% group_by(Cluster_Names) %>% summarize(permanencia_dias=max(permanencia), 
                                                             sal_diario_imss=mean(sal_diario_imss),
                                                             Count=n())
clusters<-as.data.frame(rh_alt2_tabla3)
clusters
##         Cluster_Names permanencia_dias sal_diario_imss Count
## 1     Antigüedad Alta               60        151.6100    15
## 2 Antigüedad Moderada               41        180.4827    30
## 3 Antigüedad Avanzada               77        180.5480    30
## 4     Antigüedad Baja               22        180.7584    64
#lets plot the number of data observations by clusters names
ggplot(rh_alt2_tabla3,aes(x=reorder(Cluster_Names,Count),y=Count,fill=Cluster_Names)) +
  geom_bar(stat="identity")

Cluster 3: Analizar mes_baja (1-8) y edad

summary(rh_alt)
##     puesto          sal_diario_imss      edad        permanencia     
##  Length:235         Min.   :144.4   Min.   : 0.00   Min.   :   0.00  
##  Class :character   1st Qu.:180.7   1st Qu.:23.00   1st Qu.:   9.00  
##  Mode  :character   Median :180.7   Median :28.00   Median :  21.00  
##                     Mean   :178.0   Mean   :30.43   Mean   :  77.96  
##                     3rd Qu.:180.7   3rd Qu.:37.00   3rd Qu.:  60.00  
##                     Max.   :500.0   Max.   :61.00   Max.   :1966.00  
##     mes_baja     
##  Min.   : 1.000  
##  1st Qu.: 3.000  
##  Median : 5.000  
##  Mean   : 4.604  
##  3rd Qu.: 7.000  
##  Max.   :11.000
rh_mesbaja<-scale(rh_alt3[2:3]) 

summary(rh_mesbaja)
##     mes_baja             edad        
##  Min.   :-1.68512   Min.   :-1.2349  
##  1st Qu.:-0.80017   1st Qu.:-0.8895  
##  Median : 0.08479   Median :-0.3137  
##  Mean   : 0.00000   Mean   : 0.0000  
##  3rd Qu.: 0.96974   3rd Qu.: 0.7226  
##  Max.   : 2.73964   Max.   : 3.0256
fviz_nbclust(rh_mesbaja, kmeans, method="wss")+ # wss method considers total within sum of square
  geom_vline(xintercept=4, linetype=2)+           # optimal number of clusters is computed with the default method = "euclidean"
  labs(subtitle = "Elbow method")                 

# visualize the clusters' information. Briefly, you can detect how each dataset's observation corresponds to a specific cluster. 
mesbaja_cluster1<-kmeans(rh_mesbaja,4)
mesbaja_cluster1
## K-means clustering with 4 clusters of sizes 66, 24, 49, 28
## 
## Cluster means:
##     mes_baja       edad
## 1  0.7887252 -0.4724990
## 2 -0.8923490  1.1736210
## 3 -0.9897991 -0.7085313
## 4  0.6378810  1.3477166
## 
## Clustering vector:
##   [1] 1 3 3 2 3 3 2 3 3 3 3 2 3 2 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 3 2 3 2 3 3 2 3
##  [38] 3 2 2 3 3 2 3 3 3 2 2 3 3 2 3 3 2 3 2 2 3 3 2 3 3 3 3 2 3 3 3 2 3 3 1 1 1
##  [75] 3 2 3 1 4 4 4 1 1 1 1 1 1 4 1 1 4 1 1 1 4 1 4 1 1 4 4 4 1 1 1 1 1 1 1 4 4
## [112] 1 1 4 4 4 4 1 4 1 1 1 4 1 4 1 4 1 4 4 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 1 4
## [149] 1 4 1 1 1 1 1 1 1 4 1 1 1 1 1 4 1 4 1
## 
## Within cluster sum of squares by cluster:
## [1] 35.77270 15.78750 23.85718 13.76712
##  (between_SS / total_SS =  73.1 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
# visualize clustering results 
fviz_cluster(mesbaja_cluster1,data=rh_mesbaja)

Tabla de clusters

#lets add the estimated clusters’ information to the original dataset so we can interpret the results

rh_alt3_tabla<-rh_alt3
rh_alt3_tabla$Clusters<-mesbaja_cluster1$cluster
#lets create a dataset so we can identify some characteristics of “permanencia” by cluster
rh_alt3_tabla2<-rh_alt3_tabla %>% group_by(Clusters) %>% summarise(edad=max(edad)) %>% arrange(desc(edad))
#group the clusters by name
rh_alt3_tabla$Cluster_Names<-factor(rh_alt3_tabla$Clusters,levels = c(1,2,3,4), 
                              labels=c("Adulta", "Jubilación", "Joven Adulta", "Avanzada"))
#group the clusters by cluster names and Summarize the Columns
rh_alt3_tabla3 <- rh_alt3_tabla %>% group_by(Cluster_Names) %>% summarize(edad=max(edad), 
                                                             mes_baja=mean(mes_baja),
                                                             Count=n())
clusters<-as.data.frame(rh_alt3_tabla3)
clusters
##   Cluster_Names edad mes_baja Count
## 1        Adulta   38 6.590909    66
## 2    Jubilación   61 2.791667    24
## 3  Joven Adulta   36 2.571429    49
## 4      Avanzada   57 6.250000    28
#lets plot the number of data observations by clusters names
ggplot(rh_alt3_tabla3,aes(x=reorder(Cluster_Names,Count),y=Count,fill=Cluster_Names)) +
  geom_bar(stat="identity")

Principales hallazgos

Hallazgo 1. Las personas con menos permanencia en la empresa son la principal causa de la gran catidad de bajas.

Hallazgo 2. El salario no es factor que influye en la permanencia de una persona dentro de la empresa. Se encontró que las personas que tienen el mismo salario tienen una permanencia variada al igual de los que ganan menos.

Hallazgo 3 De acuerdo al salario diario con la permanencia es contante, sin importar cuánto tiempo lleves en la empresa el salario permanece en 180 pesos diarios.

Hallazgo 4 Del grupo de edad adulta y edad avanzada el mes donde obtuvieron más bajas fue en el mes de agosto.

Hallazgo 5 Del grupo de jubilación y joven adulta el mes donde obtuvieron más bajas fue en el mes de febrero.

Referencias

Miniak-Górecka, A., Podlaski, K., & Gwizdałła, T. (2022). Using K-Means Clustering in Python with Periodic Boundary Conditions. Symmetry (20738994), 14(6), N.PAG. https://0-doi-org.biblioteca-ils.tec.mx/10.3390/sym14061237

LS0tCnRpdGxlOiAiRW50cmVnYWJsZSAyLjYgUmV0byIKYXV0aG9yOiAiRXF1aXBvIDUiCmRhdGU6ICI2LzEwLzIwMjIiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCjxpbWcgc3JjPSAiL1VzZXJzL2FuaXRhMy9EZXNrdG9wL2ZvbmRvIGNhamFzLnBuZyI+CgojIyA8c3BhbiBzdHlsZT0iY29sb3I6ICNGRjdGMjQiPiAqKkRlc2Fycm9sbG8gZGUgY2xhc2lmaWNhY2nDs24gZGUgSyBWZWNpbm9zKiogPC9zcGFuPgoKIyMjIyBMaWJyZXJpYXMgaW5zdGFsYWRhcwoKYGBge3Igd2FybmluZz1GQUxTRX0KbGlicmFyeShmb3JlaWduKQpsaWJyYXJ5KGRwbHlyKSAgICAgICAgIyBkYXRhIG1hbmlwdWxhdGlvbiAKbGlicmFyeShnZ3Bsb3QyKSAgICAgICMgZGF0YSB2aXN1YWxpemF0aW9uIApsaWJyYXJ5KHBzeWNoKSAgICAgICAgIyBmdW5jdGlvbnMgZm9yIG11bHRpdmFyaWF0ZSBhbmFseXNpcyAKbGlicmFyeShjb3JycGxvdCkgICAgICMgY29ycmVsYXRpb24gcGxvdHMKbGlicmFyeShqdG9vbHMpICAgICAgICMgcHJlc2VudGF0aW9uIG9mIHJlZ3Jlc3Npb24gYW5hbHlzaXMgCmxpYnJhcnkobG10ZXN0KSAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMgCmxpYnJhcnkoY2FyKSAgICAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMKbGlicmFyeShmYWN0b2V4dHJhKSAgICMgcHJvdmlkZXMgZnVuY3Rpb25zIHRvIGV4dHJhY3QgYW5kIHZpc3VhbGl6ZSB0aGUgb3V0cHV0IG9mIGV4cGxvcmF0b3J5IG11bHRpdmFyaWF0ZSBkYXRhIGFuYWx5c2VzCmxpYnJhcnkoZ2dmb3J0aWZ5KSAgICAjIGRhdGEgdmlzdWFsaXphdGlvbiB0b29scyBmb3Igc3RhdGlzdGljYWwgYW5hbHlzaXMgcmVzdWx0cwpgYGAKCiMjIyMgSW1wb3J0YXIgYmFzZSBkZSBkYXRvcwoKYGBge3IgaW5jbHVkZT1GQUxTRX0KcmggPC0gcmVhZC5jc3YoIi9Vc2Vycy9hbml0YTMvRG93bmxvYWRzLzViYWphc19saW1waWEgLSBudWV2YS5jc3YiKSAKYGBgCgpgYGB7cn0Kc3VtbWFyeShyaCkKYGBgCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6ICNGRjdGMjQiPiAqKkxpbXBpZXphIGRlIGJhc2UgZGUgZGF0b3MqKiA8L3NwYW4+CgoqKlJlbXBsYXphciBsb3MgTkEgZW4gInBlcm1hbmVuY2lhIiB5ICJlZGFkIiBwb3IgbGEgbWVkaWEgZGVsIHB1ZXN0byoqCmBgYHtyIGluY2x1ZGU9RkFMU0V9CnJoXzEgPC0gcmgKcmhfMSA8LSByaF8xICU+JSBncm91cF9ieShwdWVzdG8pICU+JSBtdXRhdGUocGVybWFuZW5jaWE9aWZlbHNlKGlzLm5hKHBlcm1hbmVuY2lhKSwgbWVhbihwZXJtYW5lbmNpYSxuYS5ybT1UKSwgcGVybWFuZW5jaWEpKQoKcmhfMQpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CnN1bW1hcnkocmhfMSkKYGBgCgoqKk9ic2VydmFyIGN1YW50b3MgTkHCtHMgdGVuZW1vcyBwb3IgY29sdW1uYSoqCmBgYHtyfQpyaF8yIDwtIHJoXzEKY29sU3Vtcyhpcy5uYShyaF8yKSkKYGBgCgpgYGB7cn0KY2xhc3MocmhfMiRwZXJtYW5lbmNpYSkKY2xhc3MocmhfMiRiYWphKQpjbGFzcyhyaF8yJGVkYWQpCmNsYXNzKHJoXzIkc2FsX2RpYXJpb19pbXNzKQoKYGBgCgpgYGB7cn0KcmhfMiRiYWphIDwtIGFzLkRhdGUocmhfMiRiYWphKQpyaF8yJGVkYWQgPC0gYXMuaW50ZWdlcihyaF8yJGVkYWQpCnJoXzIkcGVybWFuZW5jaWEgPC0gYXMuaW50ZWdlcihyaF8yJHBlcm1hbmVuY2lhKQpgYGAKCioqQWdyZWdhciBjb2x1bW5hIGRlIG1lcyBkZSBiYWphKioKYGBge3J9CnJoXzMgPC0gcmhfMgpyaF8zJG1lc19iYWphIDwtIGFzLm51bWVyaWMoZm9ybWF0KHJoXzMkYmFqYSwgJyVtJykpCnJoXzMKYGBgCgpgYGB7cn0KY2xhc3MocmhfMyRwZXJtYW5lbmNpYSkKY2xhc3MocmhfMyRiYWphKQpjbGFzcyhyaF8zJGVkYWQpCmNsYXNzKHJoXzMkc2FsX2RpYXJpb19pbXNzKQpjbGFzcyhyaF8zJG1lc19iYWphKQpgYGAKCmBgYHtyfQpzdW1tYXJ5KHJoXzMpCmBgYAoKKipSZWVtcGxhemFyIGxvcyBOQSBwb3IgZWwgbWVzIDcqKgpgYGB7cn0KcmhfNCA8LSByaF8zCnJoXzQkbWVzX2JhamEgPC0gcmVwbGFjZShyaF80JG1lc19iYWphLCBpcy5uYShyaF80JG1lc19iYWphKSwgNykKYGBgCgoqKlZhcmlhYmxlcyBxdWUgdmFtb3MgYSBhbmFsaXphciBlbiBlbCBhbsOhbGlzaXMgay1tZWFucyoqCmBgYHtyfQpyaF9hbHQ8LXJoXzQgJT4lIHNlbGVjdChzYWxfZGlhcmlvX2ltc3MsIGVkYWQsIHBlcm1hbmVuY2lhLCBtZXNfYmFqYSkKcmhfYWx0CmBgYAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KI2JkIGNvbiBsYSBxdWUgdHJhYmFqYXJlbW9zIGxvcyBjbHVzdGVycwpzdW1tYXJ5KHJoX2FsdCkKYGBgCgoqKkVsaW1pbmFyIE5BwrRzKioKYGBge3J9CnJoX2FsdDwtcmhfYWx0Wy1jKDE5NiwgMTk3LDIwMCksXSAjIApzdW1tYXJ5KHJoX2FsdCkgIyBubyBtaXNzaW5nIHZhbHVlcwpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogI0ZGN0YyNCI+ICoqRGVmaW5pY2lvbiBkZSBjb25jZXB0b3MgY2xhdmUqKiA8L3NwYW4+CkVuIGVxdWlwbyBkZXNjcmliaXIgY29uIHN1cyBwcm9waWFzIHBhbGFicmFzIGPDs21vIGxvcyBzaWd1aWVudGVzIGNvbmNlcHRvcyBjb250cmlidXllbiBhIGxhIGlkZW50aWZpY2FjacOzbiBkZSBjbHVzdGVycyB1c2FuZG8gYW5hbMOtdGljYSBkZSBkYXRvczoKCiMjIyBLLSBWZWNpbm9zIE3DoXMgQ2VyY2Fub3MgeS9vIEstTWVhbnMgQ2x1c3RlcmluZwpFbCBvYmpldGl2byBkZWwgSy1NZWFucyBDbHVzdGVyaW5nIGVzIGRpdmlkaXIgZWwgY29uanVudG8gZGUgZGF0b3MgZW4gc3VicG9ibGFjaW9uZXMgZGUgb2JqZXRvcyBxdWUgc29uIHNpbWlsYXJlcyB5IHBlcnRlbmVjZW4gZGVudHJvIGRlIHVuIGdydXBvIGVzcGVjw61maWNvIGFjb3JkZSBhIHN1cyBjYXJhY3RlcsOtc3RpY2FzLiAgCkFkZW3DoXMgZXN0ZSBtw6l0b2RvIGVzIHByb2JhYmxlbWVudGUgZWwgbcOhcyB1dGlsaXphZG8gZW4gbGEgY2llbmNpYSBkZSBkYXRvcy4gIAoKKipFamVtcGxvcyBwYXJhIGFwbGljYXIgSy1NZWFuczoqKgotIFNlZ21lbnRhY2nDs24gZGUgY2xpZW50ZXMuICAgCi0gQ29tdW5pZGFkZXMgZGUgcmVkZXMgc29jaWFsZXMgIAotIEdlbyBlc3RhZMOtc3RpY2EgICAKCiMjIyBBcHJlbmRpemFqZSBObyBTdXBlcnZpc2FkbyB5L28gVW5zdXBlcnZpc2VkIExlYXJuaW5nCioqTGEgY2x1c3Rlcml6YWNpw7NuIGVzIHVuIGFsZ29yaXRtbyBkZSBhcHJlbmRpemFqZSBubyBzdXBlcnZpc2Fkby4qKiAgCkVsIGFsZ29yaXRtbyBkZSBhcHJlbmRpemFqZSBubyBzdXBlcnZpc2FkbyBzaXJ2ZSBwYXJhIGV4cGxvcmFyLCBkZXNjcmliaXIgeSByZXN1bWlyIGRhdG9zLCBhc8OtIGNvbW8gdGFtYmnDqW4gYSBkZXNjdWJyaXIgcGF0cm9uZXMgeSByZWxhY2lvbmVzLCBwZXJvIHNpbiBleGlzdGlyIHVuYSBjYXRlZ29yaXphY2nDs24gbyBldGlxdWV0YWRvIGRlIGRhdG9zIHByZXZpbywgcG9yIGxvIHRhbnRvLCBzZSBhZ3J1cGFyw6Egc2Vnw7puIGxhcyBjYXJhY3RlcsOtc3RpY2FzIHkgc2ltaWxpdHVkZXMuICAgCgojIyMgRGlzdGFuY2lhIEV1Y2xpZGlhbmEgLyBFdWNsaWVkZWFuIERpc3RhbmNlClNlIGVtcGxlYSBwYXJhIG1lZGlyIGxhIGRpc2ltaWxpdHVkICgqRmFsdGEgZGUgc2VtZWphbnphIG8gZGUgcGFyZWNpZG8gZW50cmUgZG9zIG8gbcOhcyBjb3NhcyopIHkgZXMgbGEgbcOhcyB1dGlsaXphZGEgYWwgbW9tZW50byBkZSByZWFsaXphciBLLU1lYW5zIGNsdXN0ZXJpbmcuICAgCkRpY2hhIGRpc3RhbmNpYSBtaWRlIHVuYSBsw61uZWEgcmVjdGEgZW50cmUgZWwgcHVudG8gZGUgY29uc3VsdGEgeSBlbCBvdHJvIHB1bnRvIHF1ZSBzZSBtaWRlLiAgIAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiAjRkY3RjI0Ij4gKipDbHVzdGVycyoqIDwvc3Bhbj4KCiMjIyBDbHVzdGVyIDE6IEFuYWxpemFyIHF1ZSBlZGFkIHRpZW5lIG1lbm9yIHBlcm1hbmVuY2lhIHF1ZSBlbCBwcm9tZWRpby4gCmBgYHtyfQojTm9ybWFsaXphciBsYXMgdmFyaWFibGVzICAKcmhfYWx0MSA8LSByaF9hbHQKcmhfYWx0MSA8LSBzdWJzZXQocmhfYWx0MSwgcGVybWFuZW5jaWE+MCAmIHBlcm1hbmVuY2lhPDc5KQpyaF9hbHQxIDwtIHN1YnNldChyaF9hbHQxLCBlZGFkPjI0ICYgZWRhZDwzOCkKCmBgYAoKYGBge3J9CgpyaF9wZXJtYW5lbmNpYTwtc2NhbGUocmhfYWx0MVszOjRdKSAKc3VtbWFyeShyaF9wZXJtYW5lbmNpYSkKYGBgCgpgYGB7cn0KZnZpel9uYmNsdXN0KHJoX3Blcm1hbmVuY2lhLCBrbWVhbnMsIG1ldGhvZD0id3NzIikrICMgd3NzIG1ldGhvZCBjb25zaWRlcnMgdG90YWwgd2l0aGluIHN1bSBvZiBzcXVhcmUKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9NCwgbGluZXR5cGU9MikrICAgICAgICAgICAjIG9wdGltYWwgbnVtYmVyIG9mIGNsdXN0ZXJzIGlzIGNvbXB1dGVkIHdpdGggdGhlIGRlZmF1bHQgbWV0aG9kID0gImV1Y2xpZGVhbiIKICBsYWJzKHN1YnRpdGxlID0gIkVsYm93IG1ldGhvZCIpICAgICAgICAgICAgICAgICAKICAgICAgICAgICAKYGBgCgpgYGB7cn0KIyB2aXN1YWxpemUgdGhlIGNsdXN0ZXJzJyBpbmZvcm1hdGlvbi4gQnJpZWZseSwgeW91IGNhbiBkZXRlY3QgaG93IGVhY2ggZGF0YXNldCdzIG9ic2VydmF0aW9uIGNvcnJlc3BvbmRzIHRvIGEgc3BlY2lmaWMgY2x1c3Rlci4gCnBlcm1hbmVuY2lhX2NsdXN0ZXIxPC1rbWVhbnMocmhfcGVybWFuZW5jaWEsNCkKcGVybWFuZW5jaWFfY2x1c3RlcjEKYGBgCgpgYGB7cn0KIyB2aXN1YWxpemUgY2x1c3RlcmluZyByZXN1bHRzIApmdml6X2NsdXN0ZXIocGVybWFuZW5jaWFfY2x1c3RlcjEsZGF0YT1yaF9wZXJtYW5lbmNpYSkKYGBgCgojIyMjIFRhYmxhIGRlIGNsdXN0ZXJzCmBgYHtyfQojbGV0cyBhZGQgdGhlIGVzdGltYXRlZCBjbHVzdGVyc+KAmSBpbmZvcm1hdGlvbiB0byB0aGUgb3JpZ2luYWwgZGF0YXNldCBzbyB3ZSBjYW4gaW50ZXJwcmV0IHRoZSByZXN1bHRzCgpyaF9hbHRfdGFibGE8LXJoX2FsdDEKcmhfYWx0X3RhYmxhJENsdXN0ZXJzPC1wZXJtYW5lbmNpYV9jbHVzdGVyMSRjbHVzdGVyCmBgYAoKYGBge3J9CiNsZXRzIGNyZWF0ZSBhIGRhdGFzZXQgc28gd2UgY2FuIGlkZW50aWZ5IHNvbWUgY2hhcmFjdGVyaXN0aWNzIG9mIOKAnHBlcm1hbmVuY2lh4oCdIGJ5IGNsdXN0ZXIKcmhfYWx0X3RhYmxhMjwtcmhfYWx0X3RhYmxhICU+JSBncm91cF9ieShDbHVzdGVycykgJT4lIHN1bW1hcmlzZShwZXJtYW5lbmNpYT1tYXgocGVybWFuZW5jaWEpKSAlPiUgYXJyYW5nZShkZXNjKHBlcm1hbmVuY2lhKSkKYGBgCgpgYGB7cn0KI2dyb3VwIHRoZSBjbHVzdGVycyBieSBuYW1lCnJoX2FsdF90YWJsYSRDbHVzdGVyX05hbWVzPC1mYWN0b3IocmhfYWx0X3RhYmxhJENsdXN0ZXJzLGxldmVscyA9IGMoMSwyLDMsNCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiQW50aWfDvGVkYWQgQmFqYSIsICJBbnRpZ8O8ZWRhZCBBbHRhIiwgIkFudGlnw7xlZGFkIE1vZGVyYWRhIiwgIkFudGlnw7xlZGFkIEF2YW56YWRhIikpCmBgYAoKYGBge3J9CiNncm91cCB0aGUgY2x1c3RlcnMgYnkgY2x1c3RlciBuYW1lcyBhbmQgU3VtbWFyaXplIHRoZSBDb2x1bW5zCnJoX2FsdF90YWJsYTMgPC0gcmhfYWx0X3RhYmxhICU+JSBncm91cF9ieShDbHVzdGVyX05hbWVzKSAlPiUgc3VtbWFyaXplKHBlcm1hbmVuY2lhX2HDsW9zPW1heChwZXJtYW5lbmNpYSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWRhZD1tZWFuKGVkYWQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ291bnQ9bigpKQpgYGAKCmBgYHtyfQpjbHVzdGVyczwtYXMuZGF0YS5mcmFtZShyaF9hbHRfdGFibGEzKQpjbHVzdGVycwpgYGAKCmBgYHtyfQojbGV0cyBwbG90IHRoZSBudW1iZXIgb2YgZGF0YSBvYnNlcnZhdGlvbnMgYnkgY2x1c3RlcnMgbmFtZXMKZ2dwbG90KHJoX2FsdF90YWJsYTMsYWVzKHg9cmVvcmRlcihDbHVzdGVyX05hbWVzLENvdW50KSx5PUNvdW50LGZpbGw9Q2x1c3Rlcl9OYW1lcykpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpCmBgYAoKIyMjIENsdXN0ZXIgMjogQW5hbGl6YXIgc2FsYXJpbyBkaWFyaW8geSBwZXJtYW5lbmNpYQoKYGBge3J9CnN1bW1hcnkocmhfYWx0KQpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CiNOb3JtYWxpemFyIGxhcyB2YXJpYWJsZXMgIApyaF9hbHQyIDwtIHJoX2FsdApyaF9hbHQyIDwtIHJoX2FsdDIgJT4lIHNlbGVjdChtZXNfYmFqYSwgZWRhZCwgc2FsX2RpYXJpb19pbXNzLHBlcm1hbmVuY2lhKQpyaF9hbHQyIDwtIHN1YnNldChyaF9hbHQyLCBwZXJtYW5lbmNpYT44ICYgcGVybWFuZW5jaWE8ODApCnJoX2FsdDIgPC0gc3Vic2V0KHJoX2FsdDIsIHNhbF9kaWFyaW9faW1zczw0OTkpCgpgYGAKCmBgYHtyfQpyaF9zYWxhcmlvPC1zY2FsZShyaF9hbHQyWzQ6NV0pIAoKc3VtbWFyeShyaF9zYWxhcmlvKQpgYGAKCmBgYHtyfQpmdml6X25iY2x1c3Qocmhfc2FsYXJpbywga21lYW5zLCBtZXRob2Q9IndzcyIpKyAjIHdzcyBtZXRob2QgY29uc2lkZXJzIHRvdGFsIHdpdGhpbiBzdW0gb2Ygc3F1YXJlCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTQsIGxpbmV0eXBlPTIpKyAgICAgICAgICAgIyBvcHRpbWFsIG51bWJlciBvZiBjbHVzdGVycyBpcyBjb21wdXRlZCB3aXRoIHRoZSBkZWZhdWx0IG1ldGhvZCA9ICJldWNsaWRlYW4iCiAgbGFicyhzdWJ0aXRsZSA9ICJFbGJvdyBtZXRob2QiKSAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgCmBgYAoKYGBge3J9CiMgdmlzdWFsaXplIHRoZSBjbHVzdGVycycgaW5mb3JtYXRpb24uIEJyaWVmbHksIHlvdSBjYW4gZGV0ZWN0IGhvdyBlYWNoIGRhdGFzZXQncyBvYnNlcnZhdGlvbiBjb3JyZXNwb25kcyB0byBhIHNwZWNpZmljIGNsdXN0ZXIuIApzYWxhcmlvX2NsdXN0ZXIxPC1rbWVhbnMocmhfc2FsYXJpbyw0KQpzYWxhcmlvX2NsdXN0ZXIxCmBgYAoKYGBge3J9CiMgdmlzdWFsaXplIGNsdXN0ZXJpbmcgcmVzdWx0cyAKZnZpel9jbHVzdGVyKHNhbGFyaW9fY2x1c3RlcjEsZGF0YT1yaF9zYWxhcmlvKQpgYGAKCiMjIyMgVGFibGEgZGUgY2x1c3RlcnMKCmBgYHtyfQojbGV0cyBhZGQgdGhlIGVzdGltYXRlZCBjbHVzdGVyc+KAmSBpbmZvcm1hdGlvbiB0byB0aGUgb3JpZ2luYWwgZGF0YXNldCBzbyB3ZSBjYW4gaW50ZXJwcmV0IHRoZSByZXN1bHRzCgpyaF9hbHQyX3RhYmxhPC1yaF9hbHQyCnJoX2FsdDJfdGFibGEkQ2x1c3RlcnM8LXNhbGFyaW9fY2x1c3RlcjEkY2x1c3RlcgpgYGAKCmBgYHtyfQojbGV0cyBjcmVhdGUgYSBkYXRhc2V0IHNvIHdlIGNhbiBpZGVudGlmeSBzb21lIGNoYXJhY3RlcmlzdGljcyBvZiDigJxwZXJtYW5lbmNpYeKAnSBieSBjbHVzdGVyCnJoX2FsdDJfdGFibGEyPC1yaF9hbHQyX3RhYmxhICU+JSBncm91cF9ieShDbHVzdGVycykgJT4lIHN1bW1hcmlzZShwZXJtYW5lbmNpYT1tYXgocGVybWFuZW5jaWEpKSAlPiUgYXJyYW5nZShkZXNjKHBlcm1hbmVuY2lhKSkKYGBgCgpgYGB7cn0KI2dyb3VwIHRoZSBjbHVzdGVycyBieSBuYW1lCnJoX2FsdDJfdGFibGEkQ2x1c3Rlcl9OYW1lczwtZmFjdG9yKHJoX2FsdDJfdGFibGEkQ2x1c3RlcnMsbGV2ZWxzID0gYygxLDIsMyw0KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJBbnRpZ8O8ZWRhZCBBbHRhIiwgIkFudGlnw7xlZGFkIE1vZGVyYWRhIiwgIkFudGlnw7xlZGFkIEF2YW56YWRhIiwgIkFudGlnw7xlZGFkIEJhamEiKSkKYGBgCgpgYGB7cn0KI2dyb3VwIHRoZSBjbHVzdGVycyBieSBjbHVzdGVyIG5hbWVzIGFuZCBTdW1tYXJpemUgdGhlIENvbHVtbnMKcmhfYWx0Ml90YWJsYTMgPC0gcmhfYWx0Ml90YWJsYSAlPiUgZ3JvdXBfYnkoQ2x1c3Rlcl9OYW1lcykgJT4lIHN1bW1hcml6ZShwZXJtYW5lbmNpYV9kaWFzPW1heChwZXJtYW5lbmNpYSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FsX2RpYXJpb19pbXNzPW1lYW4oc2FsX2RpYXJpb19pbXNzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvdW50PW4oKSkKYGBgCgpgYGB7cn0KY2x1c3RlcnM8LWFzLmRhdGEuZnJhbWUocmhfYWx0Ml90YWJsYTMpCmNsdXN0ZXJzCmBgYAoKYGBge3J9CiNsZXRzIHBsb3QgdGhlIG51bWJlciBvZiBkYXRhIG9ic2VydmF0aW9ucyBieSBjbHVzdGVycyBuYW1lcwpnZ3Bsb3QocmhfYWx0Ml90YWJsYTMsYWVzKHg9cmVvcmRlcihDbHVzdGVyX05hbWVzLENvdW50KSx5PUNvdW50LGZpbGw9Q2x1c3Rlcl9OYW1lcykpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpCmBgYAoKIyMjIENsdXN0ZXIgMzogQW5hbGl6YXIgbWVzX2JhamEgKDEtOCkgeSBlZGFkCgpgYGB7cn0Kc3VtbWFyeShyaF9hbHQpCmBgYAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KI05vcm1hbGl6YXIgbGFzIHZhcmlhYmxlcyAgCnJoX2FsdDMgPC0gcmhfYWx0CnJoX2FsdDMgPC0gcmhfYWx0MyAlPiUgc2VsZWN0KG1lc19iYWphLCBlZGFkLCBzYWxfZGlhcmlvX2ltc3MscGVybWFuZW5jaWEpCnJoX2FsdDMgPC0gc3Vic2V0KHJoX2FsdDMsZWRhZD4yMykKCgpgYGAKCmBgYHtyfQpyaF9tZXNiYWphPC1zY2FsZShyaF9hbHQzWzI6M10pIAoKc3VtbWFyeShyaF9tZXNiYWphKQpgYGAKCmBgYHtyfQpmdml6X25iY2x1c3QocmhfbWVzYmFqYSwga21lYW5zLCBtZXRob2Q9IndzcyIpKyAjIHdzcyBtZXRob2QgY29uc2lkZXJzIHRvdGFsIHdpdGhpbiBzdW0gb2Ygc3F1YXJlCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTQsIGxpbmV0eXBlPTIpKyAgICAgICAgICAgIyBvcHRpbWFsIG51bWJlciBvZiBjbHVzdGVycyBpcyBjb21wdXRlZCB3aXRoIHRoZSBkZWZhdWx0IG1ldGhvZCA9ICJldWNsaWRlYW4iCiAgbGFicyhzdWJ0aXRsZSA9ICJFbGJvdyBtZXRob2QiKSAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgCmBgYAoKYGBge3J9CiMgdmlzdWFsaXplIHRoZSBjbHVzdGVycycgaW5mb3JtYXRpb24uIEJyaWVmbHksIHlvdSBjYW4gZGV0ZWN0IGhvdyBlYWNoIGRhdGFzZXQncyBvYnNlcnZhdGlvbiBjb3JyZXNwb25kcyB0byBhIHNwZWNpZmljIGNsdXN0ZXIuIAptZXNiYWphX2NsdXN0ZXIxPC1rbWVhbnMocmhfbWVzYmFqYSw0KQptZXNiYWphX2NsdXN0ZXIxCmBgYAoKYGBge3J9CiMgdmlzdWFsaXplIGNsdXN0ZXJpbmcgcmVzdWx0cyAKZnZpel9jbHVzdGVyKG1lc2JhamFfY2x1c3RlcjEsZGF0YT1yaF9tZXNiYWphKQpgYGAKCiMjIyMgVGFibGEgZGUgY2x1c3RlcnMKCmBgYHtyfQojbGV0cyBhZGQgdGhlIGVzdGltYXRlZCBjbHVzdGVyc+KAmSBpbmZvcm1hdGlvbiB0byB0aGUgb3JpZ2luYWwgZGF0YXNldCBzbyB3ZSBjYW4gaW50ZXJwcmV0IHRoZSByZXN1bHRzCgpyaF9hbHQzX3RhYmxhPC1yaF9hbHQzCnJoX2FsdDNfdGFibGEkQ2x1c3RlcnM8LW1lc2JhamFfY2x1c3RlcjEkY2x1c3RlcgpgYGAKCmBgYHtyfQojbGV0cyBjcmVhdGUgYSBkYXRhc2V0IHNvIHdlIGNhbiBpZGVudGlmeSBzb21lIGNoYXJhY3RlcmlzdGljcyBvZiDigJxwZXJtYW5lbmNpYeKAnSBieSBjbHVzdGVyCnJoX2FsdDNfdGFibGEyPC1yaF9hbHQzX3RhYmxhICU+JSBncm91cF9ieShDbHVzdGVycykgJT4lIHN1bW1hcmlzZShlZGFkPW1heChlZGFkKSkgJT4lIGFycmFuZ2UoZGVzYyhlZGFkKSkKYGBgCgpgYGB7cn0KI2dyb3VwIHRoZSBjbHVzdGVycyBieSBuYW1lCnJoX2FsdDNfdGFibGEkQ2x1c3Rlcl9OYW1lczwtZmFjdG9yKHJoX2FsdDNfdGFibGEkQ2x1c3RlcnMsbGV2ZWxzID0gYygxLDIsMyw0KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJBZHVsdGEiLCAiSnViaWxhY2nDs24iLCAiSm92ZW4gQWR1bHRhIiwgIkF2YW56YWRhIikpCmBgYAoKYGBge3J9CiNncm91cCB0aGUgY2x1c3RlcnMgYnkgY2x1c3RlciBuYW1lcyBhbmQgU3VtbWFyaXplIHRoZSBDb2x1bW5zCnJoX2FsdDNfdGFibGEzIDwtIHJoX2FsdDNfdGFibGEgJT4lIGdyb3VwX2J5KENsdXN0ZXJfTmFtZXMpICU+JSBzdW1tYXJpemUoZWRhZD1tYXgoZWRhZCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzX2JhamE9bWVhbihtZXNfYmFqYSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb3VudD1uKCkpCmBgYAoKYGBge3J9CmNsdXN0ZXJzPC1hcy5kYXRhLmZyYW1lKHJoX2FsdDNfdGFibGEzKQpjbHVzdGVycwpgYGAKCmBgYHtyfQojbGV0cyBwbG90IHRoZSBudW1iZXIgb2YgZGF0YSBvYnNlcnZhdGlvbnMgYnkgY2x1c3RlcnMgbmFtZXMKZ2dwbG90KHJoX2FsdDNfdGFibGEzLGFlcyh4PXJlb3JkZXIoQ2x1c3Rlcl9OYW1lcyxDb3VudCkseT1Db3VudCxmaWxsPUNsdXN0ZXJfTmFtZXMpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKQpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogI0ZGN0YyNCI+ICoqUHJpbmNpcGFsZXMgaGFsbGF6Z29zKiogPC9zcGFuPgoKKipIYWxsYXpnbyAxLioqIExhcyBwZXJzb25hcyBjb24gbWVub3MgcGVybWFuZW5jaWEgZW4gbGEgZW1wcmVzYSBzb24gbGEgcHJpbmNpcGFsIGNhdXNhIGRlIGxhIGdyYW4gY2F0aWRhZCBkZSBiYWphcy4KCioqSGFsbGF6Z28gMi4qKiBFbCBzYWxhcmlvIG5vIGVzIGZhY3RvciBxdWUgaW5mbHV5ZSBlbiBsYSBwZXJtYW5lbmNpYSBkZSB1bmEgcGVyc29uYSBkZW50cm8gZGUgbGEgZW1wcmVzYS4gU2UgZW5jb250csOzIHF1ZSBsYXMgcGVyc29uYXMgcXVlIHRpZW5lbiBlbCBtaXNtbyBzYWxhcmlvIHRpZW5lbiB1bmEgcGVybWFuZW5jaWEgdmFyaWFkYSBhbCBpZ3VhbCBkZSBsb3MgcXVlIGdhbmFuIG1lbm9zLgoKKipIYWxsYXpnbyAzKiogRGUgYWN1ZXJkbyBhbCBzYWxhcmlvIGRpYXJpbyBjb24gbGEgcGVybWFuZW5jaWEgZXMgY29udGFudGUsIHNpbiBpbXBvcnRhciBjdcOhbnRvIHRpZW1wbyBsbGV2ZXMgZW4gbGEgZW1wcmVzYSBlbCBzYWxhcmlvIHBlcm1hbmVjZSBlbiAxODAgcGVzb3MgZGlhcmlvcy4KCioqSGFsbGF6Z28gNCoqIERlbCBncnVwbyBkZSBlZGFkIGFkdWx0YSB5IGVkYWQgYXZhbnphZGEgZWwgbWVzIGRvbmRlIG9idHV2aWVyb24gbcOhcyBiYWphcyBmdWUgZW4gZWwgbWVzIGRlIGFnb3N0by4KCioqSGFsbGF6Z28gNSoqIERlbCBncnVwbyBkZSBqdWJpbGFjacOzbiB5IGpvdmVuIGFkdWx0YSBlbCBtZXMgZG9uZGUgb2J0dXZpZXJvbiBtw6FzIGJhamFzIGZ1ZSBlbiBlbCBtZXMgZGUgZmVicmVyby4KCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogI0ZGN0YyNCI+ICoqUmVmZXJlbmNpYXMqKiA8L3NwYW4+Ck1pbmlhay1Hw7NyZWNrYSwgQS4sIFBvZGxhc2tpLCBLLiwgJiBHd2l6ZGHFgsWCYSwgVC4gKDIwMjIpLiBVc2luZyBLLU1lYW5zIENsdXN0ZXJpbmcgaW4gUHl0aG9uIHdpdGggUGVyaW9kaWMgQm91bmRhcnkgQ29uZGl0aW9ucy4gU3ltbWV0cnkgKDIwNzM4OTk0KSwgMTQoNiksIE4uUEFHLiBodHRwczovLzAtZG9pLW9yZy5iaWJsaW90ZWNhLWlscy50ZWMubXgvMTAuMzM5MC9zeW0xNDA2MTIzNw==