Listado de Librerias que se usaran durante el tema de K-Means Clustering:

library(openxlsx)
library(cluster)
library(factoextra)
library(plotly)
library(tidyverse)
library(dplyr)

K-Means Clustering

El algoritmo K-Means es un método de agrupamiento que divide un conjunto de datos en k grupos o clusters. Los datos se segmentan de tal manera que los puntos en el mismo cluster sean más similares entre sí que los puntos en otros clusters.

Es utilizado en Machine Learning, y es del tipo No Supervisado y se basa en la suma de las distancias euclidianas.

Ejercicio 1

Definamos un grupo de 16 Alumnos para casos prácticos, el objetivo es agruparlo por el perfil según sus calificaciones en 4 áreas de aprendizaje impartidas.

El grupo de 16 Alumnos se lista a continuacíon.

Para el caso se enlistan los Nombres de los Alumnos, con el nombre de la matería y su calificación, se definen 5 vectores y los unimos a un data frame.

#Carga de Datos
# Definición de los 5 vectores
Alumno = c("Glo", "Leo", "Oli", "Rio", "Ian", "Art", "Alan", "Min", "Lux", "Onx", "Mich", "Ozzy", "Rain", "Erin", "Neon", "Alfa")
CExactas = c(85,60,90,60,75,78,92,100,64,72,67,83,92,74,75,76)
Artisticas = c(72,67,83,92,66,76,60,90,60,75,78,93,77,55,87,89)
Humanisticas = c(67,83,92,74,100,83,72,67,83,92,74,100,93,71,84,62)
CNaturales = c(95,100,64,72,67,83,92,74,60,90,60,75,78,66,93,90)

# Unimos los vectores a un data frame
DFAlumno <- data.frame(Alumno, CExactas, Artisticas, Humanisticas, CNaturales)

#El algoritmo es sensible a la falta de datos, limpiamos el Data Frame.
DFAlumnos <- na.omit(DFAlumno)

# Desplegamos los datos del data frame de Alumnos
DFAlumnos
##    Alumno CExactas Artisticas Humanisticas CNaturales
## 1     Glo       85         72           67         95
## 2     Leo       60         67           83        100
## 3     Oli       90         83           92         64
## 4     Rio       60         92           74         72
## 5     Ian       75         66          100         67
## 6     Art       78         76           83         83
## 7    Alan       92         60           72         92
## 8     Min      100         90           67         74
## 9     Lux       64         60           83         60
## 10    Onx       72         75           92         90
## 11   Mich       67         78           74         60
## 12   Ozzy       83         93          100         75
## 13   Rain       92         77           93         78
## 14   Erin       74         55           71         66
## 15   Neon       75         87           84         93
## 16   Alfa       76         89           62         90
#Analizamos el tipo de variables del data frame
glimpse(DFAlumnos)
## Rows: 16
## Columns: 5
## $ Alumno       <chr> "Glo", "Leo", "Oli", "Rio", "Ian", "Art", "Alan", "Min", …
## $ CExactas     <dbl> 85, 60, 90, 60, 75, 78, 92, 100, 64, 72, 67, 83, 92, 74, …
## $ Artisticas   <dbl> 72, 67, 83, 92, 66, 76, 60, 90, 60, 75, 78, 93, 77, 55, 8…
## $ Humanisticas <dbl> 67, 83, 92, 74, 100, 83, 72, 67, 83, 92, 74, 100, 93, 71,…
## $ CNaturales   <dbl> 95, 100, 64, 72, 67, 83, 92, 74, 60, 90, 60, 75, 78, 66, …

El algoritmo de K-Means es sensible a los outliers o a los valores atípicos.

summary(DFAlumnos)
##     Alumno             CExactas        Artisticas     Humanisticas   
##  Length:16          Min.   : 60.00   Min.   :55.00   Min.   : 62.00  
##  Class :character   1st Qu.: 70.75   1st Qu.:66.75   1st Qu.: 71.75  
##  Mode  :character   Median : 75.50   Median :76.50   Median : 83.00  
##                     Mean   : 77.69   Mean   :76.25   Mean   : 81.06  
##                     3rd Qu.: 86.25   3rd Qu.:87.50   3rd Qu.: 92.00  
##                     Max.   :100.00   Max.   :93.00   Max.   :100.00  
##    CNaturales    
##  Min.   : 60.00  
##  1st Qu.: 66.75  
##  Median : 76.50  
##  Mean   : 78.69  
##  3rd Qu.: 90.50  
##  Max.   :100.00
# Outliers o valores atípicos. [,-1] Nos sirve para remover la columna de Alumno, al no ser númerico. [Renglón,Columna]
boxplot(DFAlumnos[,-1])

Elaboremos una agrupación para el área de Ciencias Exactas.

Vamos a definir 4 grupos, en este caso decidimos agrupar según las calificaciones. De la mínima aprobatoria como 60 hasta 100 como la máxima calificación, por lo tanto tenemos 4 posibles grupos.

El modelo de K-Means, tiene varios parámetros, en este caso tomamos arbitrariamente 4 centros o grupos (existen métodos para obtener el valor óptimo de k clusters).

El parámetro iter.max es el valor de las iteraciones que el algoritmo ejecutara, el parámetro nstart es para definir los puntos de inicialización.

# Definimos el set.seed que nos ayuda a la generación de números aleatorios
set.seed(1234)

#Definimos el Cluster en Km.CE
km.CE <- kmeans(DFAlumnos$CExactas, centers = 4, iter.max = 10, nstart = 25)

#Diagrama de Dispersión del Cluster generado"
plot(DFAlumnos$CExactas, col = km.CE$cluster)

#Observamos los datos del Cluster
km.CE$cluster
##  [1] 4 2 3 2 1 1 3 3 2 1 2 4 3 1 1 1
# El tamaño del Cluster
km.CE$size
## [1] 6 4 4 2
#Datos del Cluster
print(km.CE)
## K-means clustering with 4 clusters of sizes 6, 4, 4, 2
## 
## Cluster means:
##    [,1]
## 1 75.00
## 2 62.75
## 3 93.50
## 4 84.00
## 
## Clustering vector:
##  [1] 4 2 3 2 1 1 3 3 2 1 2 4 3 1 1 1
## 
## Within cluster sum of squares by cluster:
## [1] 20.00 34.75 59.00  2.00
##  (between_SS / total_SS =  94.6 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
#Graficamos el Cluster
fviz_cluster(km.CE, DFAlumnos[,-1], repel = TRUE)

#Uniendo los datos y Visualizando los datos del Cluster en un data frame
DF3CE <- data.frame(DFAlumnos$Alumno, DFAlumnos$CExactas ,km.CE$cluster)
DF3CE
##    DFAlumnos.Alumno DFAlumnos.CExactas km.CE.cluster
## 1               Glo                 85             4
## 2               Leo                 60             2
## 3               Oli                 90             3
## 4               Rio                 60             2
## 5               Ian                 75             1
## 6               Art                 78             1
## 7              Alan                 92             3
## 8               Min                100             3
## 9               Lux                 64             2
## 10              Onx                 72             1
## 11             Mich                 67             2
## 12             Ozzy                 83             4
## 13             Rain                 92             3
## 14             Erin                 74             1
## 15             Neon                 75             1
## 16             Alfa                 76             1

De los datos obtenidos, observamos que se generan 4 agrupaciones, una agrupación de 4 elementos, una de dos, de 6 y 4. En el DF3 generamos los nombres de los Alumnos sus calificaciones y a que Cluster pertenece.

Continuamos y vamos a generar la misma información para la área del conocimiento de Ciencias Humanisticas.

set.seed(1234)

#Definimos el Cluster en Km.CH
km.CH <- kmeans(DFAlumnos$Humanisticas, centers = 4, iter.max = 10, nstart = 25)

#Diagrama de Dispersión del Cluster generado"
plot(DFAlumnos$Humanisticas, col = km.CH$cluster)

#Observamos los datos del Cluster
km.CH$cluster
##  [1] 1 4 3 2 3 4 2 1 4 3 2 3 3 2 4 1
# El tamaño del Cluster
km.CH$size
## [1] 3 4 5 4
#Datos del Cluster
print(km.CH)
## K-means clustering with 4 clusters of sizes 3, 4, 5, 4
## 
## Cluster means:
##       [,1]
## 1 65.33333
## 2 72.75000
## 3 95.40000
## 4 83.25000
## 
## Clustering vector:
##  [1] 1 4 3 2 3 4 2 1 4 3 2 3 3 2 4 1
## 
## Within cluster sum of squares by cluster:
## [1] 16.66667  6.75000 71.20000  0.75000
##  (between_SS / total_SS =  95.6 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
#Graficamos el Cluster
fviz_cluster(km.CH, DFAlumnos[,-1], ellipse = TRUE, ellipse.type = "convex", repel = TRUE)

fviz_cluster(km.CH, data = DFAlumnos[,-1],
             palette = c("#FF0000", "#00913F", "#000000", "#FF20FF"),
             ellipse.type = "euclid", 
             star.plot = TRUE, 
             repel = TRUE,
             ggtheme = theme_classic())
## Too few points to calculate an ellipse

#Visualizando los datos del Cluster en un data frame

DF4CH <- data.frame(DFAlumnos$Alumno, DFAlumnos$Humanisticas ,km.CH$cluster)
DF4CH
##    DFAlumnos.Alumno DFAlumnos.Humanisticas km.CH.cluster
## 1               Glo                     67             1
## 2               Leo                     83             4
## 3               Oli                     92             3
## 4               Rio                     74             2
## 5               Ian                    100             3
## 6               Art                     83             4
## 7              Alan                     72             2
## 8               Min                     67             1
## 9               Lux                     83             4
## 10              Onx                     92             3
## 11             Mich                     74             2
## 12             Ozzy                    100             3
## 13             Rain                     93             3
## 14             Erin                     71             2
## 15             Neon                     84             4
## 16             Alfa                     62             1

Ahora juntemos las 4 áreas del conocimiento, y para este ejercicio nos están pidiendo que hagamos 4 equipos de 4 personas, para hacer un trabajo final dónde vamos a balancear los talentos para que el aprendizaje sea más nutritivo o tal vez en la institución educativa van a aplicar EduScrum.

set.seed(1234)

#Definimos el Cluster en Km.all
km.all <- kmeans(DFAlumnos[,-1], centers = 4, iter.max = 10, nstart = 25)

#Diagrama de Dispersión del Cluster generado"
plot(DFAlumnos, col = km.all$cluster)

#Observamos los datos del Cluster
km.all$cluster
##  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 
##  3  2  1  4  1  2  3  3  4  2  4  1  1  4  2  3
# El tamaño del Cluster
km.all$size
## [1] 4 4 4 4
#Datos del Cluster
print(km.all)
## K-means clustering with 4 clusters of sizes 4, 4, 4, 4
## 
## Cluster means:
##   CExactas Artisticas Humanisticas CNaturales
## 1    85.00      79.75        96.25      71.00
## 2    71.25      76.25        85.50      91.50
## 3    88.25      77.75        67.00      87.75
## 4    66.25      71.25        75.50      64.50
## 
## Clustering vector:
##  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 
##  3  2  1  4  1  2  3  3  4  2  4  1  1  4  2  3 
## 
## Within cluster sum of squares by cluster:
## [1]  747.50  595.50 1252.25 1151.50
##  (between_SS / total_SS =  59.3 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
#Graficamos el Cluster
fviz_cluster(km.all, DFAlumnos[,-1], repel = TRUE)

#Visualizando los datos del Cluster en un data frame

DF5CAll <- data.frame(DFAlumnos$Alumno, km.all$cluster)
DF5CAll
##    DFAlumnos.Alumno km.all.cluster
## 1               Glo              3
## 2               Leo              2
## 3               Oli              1
## 4               Rio              4
## 5               Ian              1
## 6               Art              2
## 7              Alan              3
## 8               Min              3
## 9               Lux              4
## 10              Onx              2
## 11             Mich              4
## 12             Ozzy              1
## 13             Rain              1
## 14             Erin              4
## 15             Neon              2
## 16             Alfa              3
# Otra manera de desplegar los datos del Cluster
DFDD5 <- cbind(DFAlumnos$Alumno, km.all$cluster)
head(DFDD5)
##   [,1]  [,2]
## 1 "Glo" "3" 
## 2 "Leo" "2" 
## 3 "Oli" "1" 
## 4 "Rio" "4" 
## 5 "Ian" "1" 
## 6 "Art" "2"

Al observar los datos del data frame DF5All, observamos que tenemos las agrupaciones afines o que cuentan con las mismas habilidades:

Cluster 1: Glo, Alan, Min, Alfa.

Cluster 2: Leo, Art, Onx, Neon.

Cluster 3: Oli, Ian, Ozzy, Rainn.

Cluster 4: Rio, Lux, Mich, Erin

Al hacer los grupos de trabajo para el EduScrum, tomaremos un miembro de cada cluster para tener un grupo balanceado:

Podria quedar de la siguiente manera:

Grupo1: Glo, Leo, Oli,Rio.

Grupo2: Alan, Art, Ian, Lux.

Grupo3: Min, Onx, Ozzy, Mich.

Grupo4: Alfa, Neon, Rain, Erin

En el caso anterior tomamos arbitrariamente el valor de 4, pero existen métodos en los cuales nos da el valor óptimo del tamaño del cluster.

A continuación se enlista los 3 más usados, el valor del tamaño del cluster es dónde se hace “un codo” o dónde cambia la pendiente de la gráfica, el valor de k es visual.

# Metodo del Codo
# WSS
fviz_nbclust(DFAlumnos[,-1], kmeans, method = "wss")

#Silhouette
fviz_nbclust(DFAlumnos[,-1], kmeans, method = "silhouette")

#gap_stat
fviz_nbclust(DFAlumnos[,-1], kmeans, method = "gap_stat")

Como se observa el tamaño óptimo del Cluster es con k = 5

# Buscando el valor óptimo del Cluster
varwss = 10000000
wss = 0
for (i in 1:15) {
  # Ajustar en modelo en km.out
  km.out <- kmeans(DFAlumnos[,-1], centers = i, nstart = 25)
  # Guardar el valor de la suma de los cuadrados
    if (varwss > km.out$tot.withinss) {
      km.out$tot.withinss
      wss[i] <- km.out$tot.withinss
      print(i)
      varwss <- km.out$tot.withinss
      print(varwss)}
}
## [1] 1
## [1] 9196.812
## [1] 2
## [1] 6835.125
## [1] 3
## [1] 4862.536
## [1] 4
## [1] 3746.75
## [1] 5
## [1] 2942.25
## [1] 6
## [1] 2232.5
## [1] 7
## [1] 1803.5
## [1] 8
## [1] 1378
## [1] 9
## [1] 990.5
## [1] 10
## [1] 787
## [1] 11
## [1] 592.5
## [1] 12
## [1] 440
## [1] 13
## [1] 315.5
## [1] 14
## [1] 197
## [1] 15
## [1] 83.5

Cabe mencionar que el mejor metodo para este algoritmo es normalizar los valores para que estén en la misma escala. Para esto usaremos el scale ya que ésto nos ayuda a colocar a todos los valores de las observaciones en las mismas escalas.

dfScaled <- scale(DFAlumnos[,-1])

head(dfScaled, n= 4)
##     CExactas Artisticas Humanisticas CNaturales
## 1  0.6134444 -0.3481736   -1.1716208  1.2228024
## 2 -1.4838014 -0.7577895    0.1614233  1.5976077
## 3  1.0328936  0.5529815    0.9112606 -1.1009906
## 4 -1.4838014  1.2902903   -0.5884140 -0.5013021
set.seed(1234)

#Definimos el Cluster en Km.allScaled
km.allScaled <- kmeans(dfScaled[,-1], centers = 4, iter.max = 10, nstart = 25)

#Diagrama de Dispersión del Cluster generado"
plot(dfScaled, col = km.allScaled$cluster)

#Observamos los datos del Cluster
km.allScaled$cluster
##  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 
##  2  2  1  3  1  2  2  3  4  2  4  1  1  4  2  3
# El tamaño del Cluster
km.allScaled$size
## [1] 4 6 3 3
#Datos del Cluster
print(km.allScaled)
## K-means clustering with 4 clusters of sizes 4, 6, 3, 3
## 
## Cluster means:
##   Artisticas Humanisticas   CNaturales
## 1  0.2867312   1.26535043 -0.576263191
## 2 -0.2799042  -0.07463658  1.010412695
## 3  1.1537516  -1.11607727 -0.001561689
## 4 -0.9762514  -0.42178348 -1.250912780
## 
## Clustering vector:
##  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 
##  2  2  1  3  1  2  2  3  4  2  4  1  1  4  2  3 
## 
## Within cluster sum of squares by cluster:
## [1] 3.693209 6.528398 1.629594 2.640497
##  (between_SS / total_SS =  67.8 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
#Graficamos el Cluster
fviz_cluster(km.allScaled, dfScaled, repel = TRUE)

#Visualizando los datos del Cluster en un data frame

DF5CAllScaled <- data.frame(DFAlumnos$Alumno, km.allScaled$cluster)
DF5CAllScaled
##    DFAlumnos.Alumno km.allScaled.cluster
## 1               Glo                    2
## 2               Leo                    2
## 3               Oli                    1
## 4               Rio                    3
## 5               Ian                    1
## 6               Art                    2
## 7              Alan                    2
## 8               Min                    3
## 9               Lux                    4
## 10              Onx                    2
## 11             Mich                    4
## 12             Ozzy                    1
## 13             Rain                    1
## 14             Erin                    4
## 15             Neon                    2
## 16             Alfa                    3
DFDD5Scaled <- cbind(DFAlumnos$Alumno, km.allScaled$cluster)
head(DFDD5Scaled)
##   [,1]  [,2]
## 1 "Glo" "2" 
## 2 "Leo" "2" 
## 3 "Oli" "1" 
## 4 "Rio" "3" 
## 5 "Ian" "1" 
## 6 "Art" "2"

Buscando el valor óptimo del cluster en el data frame “scaled”.

# Metodo del Codo
# WSS
fviz_nbclust(dfScaled[,-1], kmeans, method = "wss")

#Silhouette
fviz_nbclust(dfScaled[,-1], kmeans, method = "silhouette")

#gap_stat
fviz_nbclust(dfScaled[,-1], kmeans, method = "gap_stat")

Conclución:

El tamaño del Cluster puede ser definido arbitrariamente o emplear los métodos para obtener un valor óptimo de k, se recomienda usar varios valores de k, así como varias las iteraciones y el parámetro de inicialización. Todo depende del tamaño de datos a analizar, o las necesidades de cada caso.

Ejercicio 2

Ahora agruparemos a una lista de empleados de acuerdo a una matriz de habilidades.

#Empleados
Empleados = c("Claudia", "Lalo", "Alain", "Ulises", "Dan", "Iram", "Arn", "Will", "Ivon", "Ness")
RCA =c("Excelente", "Bueno", "Regular", "Malo", "Excelente", "Bueno", "Regular", "Malo","Excelente", "Bueno")
Kaizen =c("Malo", "Excelente", "Bueno", "Regular", "Malo","Excelente", "Bueno", "Excelente", "Bueno", "Regular")
Creatividad =c("Regular", "Malo","Excelente", "Bueno", "Excelente", "Bueno", "Regular","Malo", "Excelente", "Bueno")
Liderazgo =c("Bueno", "Excelente", "Bueno", "Regular","Malo", "Excelente", "Bueno","Regular", "Malo","Excelente")

# Anexamos los vectores a un data frame y visualizamos de que tipo son.
DFEmpleados <- data.frame(Empleados, RCA, Kaizen, Creatividad, Liderazgo)
glimpse(DFEmpleados)
## Rows: 10
## Columns: 5
## $ Empleados   <chr> "Claudia", "Lalo", "Alain", "Ulises", "Dan", "Iram", "Arn"…
## $ RCA         <chr> "Excelente", "Bueno", "Regular", "Malo", "Excelente", "Bue…
## $ Kaizen      <chr> "Malo", "Excelente", "Bueno", "Regular", "Malo", "Excelent…
## $ Creatividad <chr> "Regular", "Malo", "Excelente", "Bueno", "Excelente", "Bue…
## $ Liderazgo   <chr> "Bueno", "Excelente", "Bueno", "Regular", "Malo", "Excelen…
#Mapeando  a valores númericos el texto.
# Aplicando método de asignacíon de valores, ésta asignación puede ser más practica y rapida.
# Definimos las habilidades en Root Cause Analysis
RCA =c("Excelente", "Bueno", "Regular", "Malo", "Excelente", "Bueno", "Regular", "Malo","Excelente", "Bueno")

# En Data Frame
RCA <- data.frame(RCA)
# Mapeamos los valores a los atributos
mapping <- c("Excelente" = 8, "Bueno" =5, "Regular" = 3, "Malo" = 1, "Excelente" =8, "Bueno" =5, "Regular" = 3, "Malo" = 2,"Excelente" = 8, "Bueno"= 5)
# Asignamos los valores
RCA$value <- mapping[RCA[,1]]

# Kaizen
Kaizen =c("Malo", "Excelente", "Bueno", "Regular", "Malo","Excelente", "Bueno", "Excelente", "Bueno", "Regular")
# En Data Frame
Kaizen <- data.frame(Kaizen)
# Mapeamos los valores a los atributos
mapping <- c("Excelente" = 8, "Bueno" =5, "Regular" = 3, "Malo" = 1, "Excelente" =8, "Bueno" =5, "Regular" = 3, "Malo" = 2,"Excelente" = 8, "Bueno"= 5)
# Asignamos los valores
Kaizen$value <- mapping[Kaizen[,1]]

# Creatividad
Creatividad =c("Regular", "Malo","Excelente", "Bueno", "Excelente", "Bueno", "Regular","Malo", "Excelente", "Bueno")
# En Data Frame
Creatividad <- data.frame(Creatividad)
# Mapeamos los valores a los atributos
mapping <- c("Excelente" = 8, "Bueno" =5, "Regular" = 3, "Malo" = 1, "Excelente" =8, "Bueno" =5, "Regular" = 3, "Malo" = 2,"Excelente" = 8, "Bueno"= 5)
# Asignamos los valores
Creatividad$value <- mapping[Creatividad[,1]]

# Liderazgo
Liderazgo =c("Bueno", "Excelente", "Bueno", "Regular","Malo", "Excelente", "Bueno","Regular", "Malo","Excelente")
# En Data Frame
Liderazgo <- data.frame(Liderazgo)
# Mapeamos los valores a los atributos
mapping <- c("Excelente" = 8, "Bueno" =5, "Regular" = 3, "Malo" = 1, "Excelente" =8, "Bueno" =5, "Regular" = 3, "Malo" = 2,"Excelente" = 8, "Bueno"= 5)
# Asignamos los valores
Liderazgo$value <- mapping[Liderazgo[,1]]

#Creamos el data frame del mapeo.
DFEmpleadosmap <- data.frame(Empleados, RCA, Kaizen, Creatividad, Liderazgo)

# Definimos el data frame con los valores asignados.
DFEmpleadosvalues <- data.frame(Empleados, RCA$value, Kaizen$value, Creatividad$value, Liderazgo$value)
glimpse(DFEmpleadosvalues)
## Rows: 10
## Columns: 5
## $ Empleados         <chr> "Claudia", "Lalo", "Alain", "Ulises", "Dan", "Iram",…
## $ RCA.value         <dbl> 8, 5, 3, 1, 8, 5, 3, 1, 8, 5
## $ Kaizen.value      <dbl> 1, 8, 5, 3, 1, 8, 5, 8, 5, 3
## $ Creatividad.value <dbl> 3, 1, 8, 5, 8, 5, 3, 1, 8, 5
## $ Liderazgo.value   <dbl> 5, 8, 5, 3, 1, 8, 5, 3, 1, 8
DFEmpleadosvaluesS <- data.frame(RCA$value, Kaizen$value, Creatividad$value, Liderazgo$value)

# Eliminamos aquellos registros con falta de datos,
DFEValores <- na.omit(DFEmpleadosvalues)
DFEValores
##    Empleados RCA.value Kaizen.value Creatividad.value Liderazgo.value
## 1    Claudia         8            1                 3               5
## 2       Lalo         5            8                 1               8
## 3      Alain         3            5                 8               5
## 4     Ulises         1            3                 5               3
## 5        Dan         8            1                 8               1
## 6       Iram         5            8                 5               8
## 7        Arn         3            5                 3               5
## 8       Will         1            8                 1               3
## 9       Ivon         8            5                 8               1
## 10      Ness         5            3                 5               8

Ejecutamos un boxplot para observar si hay valores atípicos u Outliers.

# Outliers o valores atípicos
boxplot(DFEValores[,-1])

No se observan Outliers o valores atípicos.

Analizamos la habilidad de RCA (Root Cause Analysis)

set.seed(1234)

#Definimos el Cluster en Km.RCA
km.RCA <- kmeans(DFEValores$RCA.value, centers = 4, iter.max = 10, nstart = 25)

#Diagrama de Dispersión del Cluster generado
plot(DFEValores$RCA.value, col = km.RCA$cluster)

#Observamos los datos del Cluster
km.RCA$cluster
##  [1] 4 2 3 1 4 2 3 1 4 2
# El tamañcomparison of these types is not implementedo del Cluster
km.RCA$size
## [1] 2 3 2 3
#Datos del Cluster
print(km.RCA)
## K-means clustering with 4 clusters of sizes 2, 3, 2, 3
## 
## Cluster means:
##   [,1]
## 1    1
## 2    5
## 3    3
## 4    8
## 
## Clustering vector:
##  [1] 4 2 3 1 4 2 3 1 4 2
## 
## Within cluster sum of squares by cluster:
## [1] 0 0 0 0
##  (between_SS / total_SS = 100.0 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
#Graficamos el Cluster
fviz_cluster(km.RCA, DFEValores[,-1], repel = TRUE)

#Visualizando los datos del Cluster en un data frame
DF6EL <- data.frame(DFEValores$Empleados, km.RCA$cluster, DFEValores$RCA.value)
DF6EL
##    DFEValores.Empleados km.RCA.cluster DFEValores.RCA.value
## 1               Claudia              4                    8
## 2                  Lalo              2                    5
## 3                 Alain              3                    3
## 4                Ulises              1                    1
## 5                   Dan              4                    8
## 6                  Iram              2                    5
## 7                   Arn              3                    3
## 8                  Will              1                    1
## 9                  Ivon              4                    8
## 10                 Ness              2                    5

Ahora usaremos todos los datos de la matriz de habilidades, para agrupar o segmentar a los empleados, en el caso anterior notamos que varios Empleados necesitan reforzar ciertas habilidades y tambíen podemos observar cuales de ellos pueden ser capacitadores hacia sus compañeros

Vamos a definir el tamaño del cluster a través de las funciones siguentes:

# Metodo del Codo
# WSS
fviz_nbclust(DFEValores[,-1], kmeans, k.max = 4, method = "wss")

#Silhouette
fviz_nbclust(DFEValores[,-1], kmeans, k.max = 4, method = "silhouette")

#gap_stat
fviz_nbclust(DFEValores[,-1], kmeans, k.max = 4, method = "gap_stat")

En base lo observado el tamaño del cluster es de 3

set.seed(1234)
# Num de Clusters
k = 3

#Definimos el Cluster en Km.HAll
km.Hall <- kmeans(DFEValores[,-1], centers = k, iter.max = 15, nstart = 50)

#Diagrama de Dispersión del Cluster generado
plot(DFEValores[,-1], col = km.Hall$cluster)

#Observamos los datos del Cluster
km.Hall$cluster
##  1  2  3  4  5  6  7  8  9 10 
##  1  3  2  2  1  3  2  2  1  3
# El tamañcomparison of these types is not implementedo del Cluster
km.Hall$size
## [1] 3 4 3
#Datos del Cluster
print(km.Hall)
## K-means clustering with 3 clusters of sizes 3, 4, 3
## 
## Cluster means:
##   RCA.value Kaizen.value Creatividad.value Liderazgo.value
## 1         8     2.333333          6.333333        2.333333
## 2         2     5.250000          4.250000        4.000000
## 3         5     6.333333          3.666667        8.000000
## 
## Clustering vector:
##  1  2  3  4  5  6  7  8  9 10 
##  1  3  2  2  1  3  2  2  1  3 
## 
## Within cluster sum of squares by cluster:
## [1] 38.00000 47.50000 27.33333
##  (between_SS / total_SS =  57.3 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
#Graficamos el Cluster
fviz_cluster(km.Hall, DFEValores[,-1], repel = TRUE)

#Visualizando los datos del Cluster en un data frame

# Sumamos las habilidades
Sumas <- DFEValores$RCA.value + DFEValores$Kaizen.value + DFEValores$Creatividad.value + DFEValores$Liderazgo.value
DF7Hall <- data.frame(DFEValores$Empleados, km.Hall$cluster, Sumas)
DF7Hall
##    DFEValores.Empleados km.Hall.cluster Sumas
## 1               Claudia               1    17
## 2                  Lalo               3    22
## 3                 Alain               2    21
## 4                Ulises               2    12
## 5                   Dan               1    18
## 6                  Iram               3    26
## 7                   Arn               2    16
## 8                  Will               2    13
## 9                  Ivon               1    22
## 10                 Ness               3    21

Conclusión:

Es necesario correr el K-Means con varios valores de inicialización. Borrar datos faltantes en la fuente de datos a analizar, Revisar valores atípicos y usar scale para poner todos los valores en la misma escala.

Ejercicio adicional, en el Ejemplo 2, cambia los valores con scale. ¿Se obtienen los mismos resultados?


This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.

Referencias:

https://www.iebschool.com/blog/algoritmo-k-means-que-es-y-como-funciona-big-data/

https://www.datanovia.com/en/lessons/k-means-clustering-in-r-algorith-and-practical-examples/

https://www.datacamp.com/tutorial/k-means-clustering-r

https://www.statology.org/k-means-clustering-in-r/

https://rpubs.com/Dariel1102/1046632

https://uc-r.github.io/kmeans_clustering

https://rpubs.com/farhaadf777/1151698

Otros trabajos

https://rpubs.com/Cpepi/832141

https://rpubs.com/Cpepi/RegresionLinealSimple

K cpepi

cpepi@yahoo.com

Versión 1.5, Revisión 26.05.2024.mx

May 26, 2024