Teoría

Agrupamiento o clustering es una técnica de aprendizaje automático no supervisado que agrupa datos en función de su similitud.

Algunos usos típicos de esta técnica son:

  • Segmentación de clientes
  • Detección de anormalidades
  • Categorización de documentos

Paso 1. Instalar paquetes y llamar librerías

# install.packages("cluster") # Análisis de Agrupamiento
library(cluster) 
# install.packages("ggplot2") # Graficar
library(ggplot2)
# install.packages("data.table") # Manejo de muchos datos
library(data.table)
# install.packages("factoextra") # Gráfica optimización de número de clusters
library(factoextra)

Paso 2. Obtener los datos

df1 <- data.frame(x=c(2,2,8,5,6,7,1,4),y=c(10,5,4,8,5,4,2,9))

Paso 3. Entender los datos

summary(df1)
##        x               y         
##  Min.   :1.000   Min.   : 2.000  
##  1st Qu.:2.000   1st Qu.: 4.000  
##  Median :4.500   Median : 5.000  
##  Mean   :4.375   Mean   : 5.875  
##  3rd Qu.:6.250   3rd Qu.: 8.250  
##  Max.   :8.000   Max.   :10.000
str(df1)
## 'data.frame':    8 obs. of  2 variables:
##  $ x: num  2 2 8 5 6 7 1 4
##  $ y: num  10 5 4 8 5 4 2 9

Paso 4. Escalar los datos

# Solo si los datos no están en la misma escala.
# datos_escalados <- scale(datos_originales)

Paso 5. Determinar el número de grupos

# Siempre es un valor inicial "cualquiera", luego se optimiza.
plot(df1$x,df1$y)

grupos1 <- 3

Paso 6. Generar los grupos

set.seed(123)
clusters1 <- kmeans(df1,grupos1)
clusters1
## K-means clustering with 3 clusters of sizes 2, 3, 3
## 
## Cluster means:
##          x        y
## 1 1.500000 3.500000
## 2 3.666667 9.000000
## 3 7.000000 4.333333
## 
## Clustering vector:
## [1] 2 1 3 2 3 3 1 2
## 
## Within cluster sum of squares by cluster:
## [1] 5.000000 6.666667 2.666667
##  (between_SS / total_SS =  85.8 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Paso 7. Optimizar el número de grupos

optimizacion1 <- clusGap(df1, FUN=kmeans, nstart =1, K.max=7)
# El k.max normalmente es 10, en este ejercicio al ser 8 datos se dejó en 7.
plot(optimizacion1, xlab="Número de clusters k" ,main="Optimización de clusters")

# Se selecciona como óptimo el primer punto más alto.

Paso 8. Graficar los grupos

fviz_cluster(clusters1, data=df1)

Paso 9. Agregar Clusters a la base de Datos

df1_clusters <- cbind(df1,cluster = clusters1$cluster)
head(df1_clusters)
##   x  y cluster
## 1 2 10       2
## 2 2  5       1
## 3 8  4       3
## 4 5  8       2
## 5 6  5       3
## 6 7  4       3

Conclusiones

La técnica de clustering permite identificar patrones o grupos naturales en los datos sin necesidad de etiquetas previas.

LS0tDQp0aXRsZTogIjggUHVudG9zIg0KYXV0aG9yOiAiTHVpcyBEw6F2aWxhIC0gQTAxMjg1NTIxIg0KZGF0ZTogIjIwMjUtMDgtMTgiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUNCiAgICB0aGVtZTogeWV0aQ0KLS0tDQoNCiFbXShodHRwczovL2kwLndwLmNvbS9jZXNhcnF1ZXphZGFiLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAyMS8wNy9kYnNjYW4ucG5nP3Jlc2l6ZT02NDAlMkM0ODAmc3NsPTEpDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij4gVGVvcsOtYSA8L3NwYW4+ICANCg0KKipBZ3J1cGFtaWVudG8qKiBvICpjbHVzdGVyaW5nKiBlcyB1bmEgdMOpY25pY2EgZGUgYXByZW5kaXphamUgYXV0b23DoXRpY28gbm8gc3VwZXJ2aXNhZG8gcXVlIGFncnVwYSBkYXRvcyBlbiBmdW5jacOzbiBkZSBzdSBzaW1pbGl0dWQuICAgDQoNCkFsZ3Vub3MgdXNvcyB0w61waWNvcyBkZSBlc3RhIHTDqWNuaWNhIHNvbjogICANCg0KKiBTZWdtZW50YWNpw7NuIGRlIGNsaWVudGVzDQoqIERldGVjY2nDs24gZGUgYW5vcm1hbGlkYWRlcw0KKiBDYXRlZ29yaXphY2nDs24gZGUgZG9jdW1lbnRvcw0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IFBhc28gMS4gSW5zdGFsYXIgcGFxdWV0ZXMgeSBsbGFtYXIgbGlicmVyw61hcyA8L3NwYW4+DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIGluc3RhbGwucGFja2FnZXMoImNsdXN0ZXIiKSAjIEFuw6FsaXNpcyBkZSBBZ3J1cGFtaWVudG8NCmxpYnJhcnkoY2x1c3RlcikgDQojIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKSAjIEdyYWZpY2FyDQpsaWJyYXJ5KGdncGxvdDIpDQojIGluc3RhbGwucGFja2FnZXMoImRhdGEudGFibGUiKSAjIE1hbmVqbyBkZSBtdWNob3MgZGF0b3MNCmxpYnJhcnkoZGF0YS50YWJsZSkNCiMgaW5zdGFsbC5wYWNrYWdlcygiZmFjdG9leHRyYSIpICMgR3LDoWZpY2Egb3B0aW1pemFjacOzbiBkZSBuw7ptZXJvIGRlIGNsdXN0ZXJzDQpsaWJyYXJ5KGZhY3RvZXh0cmEpDQpgYGANCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPiBQYXNvIDIuIE9idGVuZXIgbG9zIGRhdG9zIDwvc3Bhbj4NCmBgYHtyfQ0KZGYxIDwtIGRhdGEuZnJhbWUoeD1jKDIsMiw4LDUsNiw3LDEsNCkseT1jKDEwLDUsNCw4LDUsNCwyLDkpKQ0KYGBgDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij4gUGFzbyAzLiBFbnRlbmRlciBsb3MgZGF0b3MgPC9zcGFuPg0KYGBge3J9DQpzdW1tYXJ5KGRmMSkNCnN0cihkZjEpDQpgYGANCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPiBQYXNvIDQuIEVzY2FsYXIgbG9zIGRhdG9zIDwvc3Bhbj4NCmBgYHtyfQ0KIyBTb2xvIHNpIGxvcyBkYXRvcyBubyBlc3TDoW4gZW4gbGEgbWlzbWEgZXNjYWxhLg0KIyBkYXRvc19lc2NhbGFkb3MgPC0gc2NhbGUoZGF0b3Nfb3JpZ2luYWxlcykNCmBgYA0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IFBhc28gNS4gRGV0ZXJtaW5hciBlbCBuw7ptZXJvIGRlIGdydXBvcyA8L3NwYW4+DQpgYGB7cn0NCiMgU2llbXByZSBlcyB1biB2YWxvciBpbmljaWFsICJjdWFscXVpZXJhIiwgbHVlZ28gc2Ugb3B0aW1pemEuDQpwbG90KGRmMSR4LGRmMSR5KQ0KZ3J1cG9zMSA8LSAzDQpgYGANCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPiBQYXNvIDYuIEdlbmVyYXIgbG9zIGdydXBvcyA8L3NwYW4+DQpgYGB7cn0NCnNldC5zZWVkKDEyMykNCmNsdXN0ZXJzMSA8LSBrbWVhbnMoZGYxLGdydXBvczEpDQpjbHVzdGVyczENCmBgYA0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IFBhc28gNy4gT3B0aW1pemFyIGVsIG7Dum1lcm8gZGUgZ3J1cG9zIDwvc3Bhbj4NCmBgYHtyfQ0Kb3B0aW1pemFjaW9uMSA8LSBjbHVzR2FwKGRmMSwgRlVOPWttZWFucywgbnN0YXJ0ID0xLCBLLm1heD03KQ0KIyBFbCBrLm1heCBub3JtYWxtZW50ZSBlcyAxMCwgZW4gZXN0ZSBlamVyY2ljaW8gYWwgc2VyIDggZGF0b3Mgc2UgZGVqw7MgZW4gNy4NCnBsb3Qob3B0aW1pemFjaW9uMSwgeGxhYj0iTsO6bWVybyBkZSBjbHVzdGVycyBrIiAsbWFpbj0iT3B0aW1pemFjacOzbiBkZSBjbHVzdGVycyIpDQojIFNlIHNlbGVjY2lvbmEgY29tbyDDs3B0aW1vIGVsIHByaW1lciBwdW50byBtw6FzIGFsdG8uDQpgYGANCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPiBQYXNvIDguIEdyYWZpY2FyIGxvcyBncnVwb3MgPC9zcGFuPg0KYGBge3J9DQpmdml6X2NsdXN0ZXIoY2x1c3RlcnMxLCBkYXRhPWRmMSkNCmBgYA0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IFBhc28gOS4gQWdyZWdhciBDbHVzdGVycyBhIGxhIGJhc2UgZGUgRGF0b3MgPC9zcGFuPg0KYGBge3J9DQpkZjFfY2x1c3RlcnMgPC0gY2JpbmQoZGYxLGNsdXN0ZXIgPSBjbHVzdGVyczEkY2x1c3RlcikNCmhlYWQoZGYxX2NsdXN0ZXJzKQ0KYGBgDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij4gQ29uY2x1c2lvbmVzIDwvc3Bhbj4gICAgDQpMYSB0w6ljbmljYSBkZSAqY2x1c3RlcmluZyogcGVybWl0ZSBpZGVudGlmaWNhciBwYXRyb25lcyBvIGdydXBvcyBuYXR1cmFsZXMgZW4gbG9zIGRhdG9zIHNpbiBuZWNlc2lkYWQgZGUgZXRpcXVldGFzIHByZXZpYXMuICAgDQo=