Introducción

El campo del aprendizaje automático se centra en la capacidad de los sistemas informáticos para aprender y mejorar automáticamente a partir de datos, permitiendo hacer predicciones y tomar decisiones sin una programación explícita. Uno de sus objetivos principales es la clasificación automática de objetos o datos.

Existen diversos tipos de algoritmos en el aprendizaje automático que se utilizan para la clasificación. Estos algoritmos se pueden agrupar en tres categorías principales:

K-means es un algoritmo de clasificación no supervisada (clusterización).

Algoritmos de aprendizaje no supervisado

A diferencia del aprendizaje supervisado, estos algoritmos se utilizan cuando los datos no están etiquetados y el sistema tiene que encontrar patrones o estructuras por sí mismo. Ejemplos de algoritmos no supervisados son el clustering (agrupamiento), como el algoritmo K-means, y el análisis de componentes principales (PCA).

K-Means

K-means es un algoritmo o método de clasificación cuyo objetivo es agrupar objetos u observaciones bastante similares en k conjuntos, también conocidos como clústeres, con el propósito de identificar patrones entre estos, pero esas observaciones deben ser diferentes a los otros grupos. Teniendo en cuenta lo anterior, se puede decir que el método K-means busca maximizar la variación inter-cluster (entre los k grupos formados) y minimizar la variación intra-cluster (entre las observaciones que se encuentran dentro de cada grupo).

Este algoritmo presenta ventajas y desventajas, entre las cuales podemos encontrar las siguientes:

Ventajas

  • Es uno de los métodos de clustering más utilizados por la rapidez y sencillez de su algoritmo.

Desventajas

  • Se debe ir probando el número de clúster y para esto es necesario identificar potenciales valores óptimos de K.

Aplicación del algoritmo K-Means

  1. Inicialización: una vez escogido el número de grupos, k, se establecen k centroides en el espacio de los datos, por ejemplo, escogiéndolos aleatoriamente.

  2. Asignación objetos a los centroides: cada objeto de los datos es asignado a su centroide más cercano.

  3. Actualización centroides: se actualiza la posición del centroide de cada grupo tomando como nuevo centroide la posición del promedio de los objetos pertenecientes a dicho grupo.

# Carga del conjunto de datos mtcars
library(caret)
## Warning: package 'caret' was built under R version 4.3.2
## Loading required package: ggplot2
## Loading required package: lattice
data(mtcars)

# Selección de las columnas que se utilizarán para el clustering
# En este caso, se seleccionarán 'mpg' y 'hp'
datos <- mtcars[, c('mpg', 'hp')]

# Calcular la suma de los cuadrados dentro de los clusters para diferentes valores de k
wss <- sapply(1:15, function(k){
  kmeans(datos, centers = k)$tot.withinss
})

# Gráfico del codo (Elbow Method)
plot(1:15, wss, type = 'b', pch = 19, frame = FALSE, 
     xlab = 'Número de clusters (k)', ylab = 'Suma de cuadrados dentro de los clusters')

# Determinar el punto de codo (Elbow)
elbow <- elbow <- elbow <- data.frame(K=1:15, WSS=wss)
elbow$Diff <- c(0, diff(elbow$WSS))
elbow$PercentReduction <- (1 - elbow$WSS / max(elbow$WSS)) * 100

# Encontrar el punto de codo
elbow_point <- elbow[which.min(elbow$Diff), "K"]

# Dibujar línea para señalar el punto de codo
abline(v = elbow_point, col = "red", lty = 2)
text(elbow_point, elbow[elbow$K == elbow_point, "WSS"], 
     paste("Optimal k =", elbow_point), pos = 3, col = "red")

# Número de clusters deseados
k <- 2

# Fijar la semilla para reproducibilidad
set.seed(123)  # Puedes usar cualquier número como semilla

# Aplicación del algoritmo K-Means
kmeans_result <- kmeans(datos, centers = k)

# Mostrar resultados
print(kmeans_result)
## K-means clustering with 2 clusters of sizes 7, 25
## 
## Cluster means:
##        mpg       hp
## 1 13.41429 248.4286
## 2 21.96000 118.2000
## 
## Clustering vector:
##           Mazda RX4       Mazda RX4 Wag          Datsun 710      Hornet 4 Drive 
##                   2                   2                   2                   2 
##   Hornet Sportabout             Valiant          Duster 360           Merc 240D 
##                   2                   2                   1                   2 
##            Merc 230            Merc 280           Merc 280C          Merc 450SE 
##                   2                   2                   2                   2 
##          Merc 450SL         Merc 450SLC  Cadillac Fleetwood Lincoln Continental 
##                   2                   2                   1                   1 
##   Chrysler Imperial            Fiat 128         Honda Civic      Toyota Corolla 
##                   1                   2                   2                   2 
##       Toyota Corona    Dodge Challenger         AMC Javelin          Camaro Z28 
##                   2                   2                   2                   1 
##    Pontiac Firebird           Fiat X1-9       Porsche 914-2        Lotus Europa 
##                   2                   2                   2                   2 
##      Ford Pantera L        Ferrari Dino       Maserati Bora          Volvo 142E 
##                   1                   2                   1                   2 
## 
## Within cluster sum of squares by cluster:
## [1] 11132.54 42573.84
##  (between_SS / total_SS =  63.4 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
# Crear un gráfico más detallado
library(ggplot2)

# Convertir datos a un marco de datos para ggplot
df <- data.frame(datos)
df$cluster <- as.factor(kmeans_result$cluster)

# Función para encontrar los puntos que pertenecen a un cluster específico
find_cluster_points <- function(df, cluster_number) {
  return(df[df$cluster == cluster_number, c("mpg", "hp")])
}

# Crear un polígono que rodee los puntos de cada cluster
cluster_polygons <- lapply(unique(df$cluster), function(cluster_num) {
  cluster_points <- find_cluster_points(df, cluster_num)
  chull_points <- chull(cluster_points)
  return(cluster_points[c(chull_points, chull_points[1]), ])
})

# Crear un dataframe para almacenar los polígonos
polygons_df <- do.call(rbind, cluster_polygons)
polygons_df$cluster <- factor(rep(unique(df$cluster), sapply(cluster_polygons, nrow)))


# Gráfico de dispersión con polígonos alrededor de los clusters y colores modificados
ggplot(df, aes(x = mpg, y = hp, color = cluster)) +
  geom_point(size = 3) +
  geom_polygon(data = polygons_df, aes(x = mpg, y = hp, group = cluster),
               color = "black", fill = NA, size = 1.5) +
  geom_point(data = as.data.frame(kmeans_result$centers), aes(x = mpg, y = hp),
             color = "black", size = 5, shape = 4) +
  labs(title = "Clusters generados por K-Means",
       x = "MPG",
       y = "HP") +
  scale_color_brewer(palette = "Set1") +  # Cambiar la paleta de colores (puedes usar otras paletas)
  theme_minimal() 
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

# Cargar el conjunto de datos mtcars (si aún no está cargado)
data(mtcars)

# Seleccionar las variables a utilizar en el análisis
datos <- mtcars[, c("mpg", "hp")]  # Seleccionar las columnas "mpg" y "hp"

# Establecer el número de clusters (k)
k <- 2  # Por ejemplo, vamos a definir k=2 clusters

# Fijar la semilla para reproducibilidad
set.seed(123)  # Puedes usar cualquier número como semilla

# Aplicar el algoritmo K-Means
kmeans_result <- kmeans(datos, centers = k)

# Mostrar los resultados del clustering
print(kmeans_result)
## K-means clustering with 2 clusters of sizes 7, 25
## 
## Cluster means:
##        mpg       hp
## 1 13.41429 248.4286
## 2 21.96000 118.2000
## 
## Clustering vector:
##           Mazda RX4       Mazda RX4 Wag          Datsun 710      Hornet 4 Drive 
##                   2                   2                   2                   2 
##   Hornet Sportabout             Valiant          Duster 360           Merc 240D 
##                   2                   2                   1                   2 
##            Merc 230            Merc 280           Merc 280C          Merc 450SE 
##                   2                   2                   2                   2 
##          Merc 450SL         Merc 450SLC  Cadillac Fleetwood Lincoln Continental 
##                   2                   2                   1                   1 
##   Chrysler Imperial            Fiat 128         Honda Civic      Toyota Corolla 
##                   1                   2                   2                   2 
##       Toyota Corona    Dodge Challenger         AMC Javelin          Camaro Z28 
##                   2                   2                   2                   1 
##    Pontiac Firebird           Fiat X1-9       Porsche 914-2        Lotus Europa 
##                   2                   2                   2                   2 
##      Ford Pantera L        Ferrari Dino       Maserati Bora          Volvo 142E 
##                   1                   2                   1                   2 
## 
## Within cluster sum of squares by cluster:
## [1] 11132.54 42573.84
##  (between_SS / total_SS =  63.4 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Resultados

Con la base de datos de mtcars procederemos a realizar el algoritmo K-Means para agrupar los diferentes modelos de autos en grupos/clusters basados en sus atributos o características. Por ejemplo, podrías estar interesado en agrupar los autos en función de su rendimiento en millas por galón (mpg), caballos de fuerza (hp).