El agrupamiento (clustering) es la tarea de identificar instancias similares y asignarlas a grupos de instancias similares.
Al contrario que la clasificación, el agrupamiento es una tarea no supervisada. Si nos fijamos en la imagen siguiente sobre el conjunto de datos iris, en el gráfico de la izquierda cada tipo de flor se representa con un marcador diferente, lo que quiere decir que las instancias están etiquetadas. En el gráfico de la derecha no hay grupos definidos (las instancias no están etiquetadas), con lo que será el modelo de agrupamiento el que se encargue de crear esos grupos:
No existe una definición universal de lo que es un grupo. Dependiendo de los algoritmos utilizados, éstos crearan diferentes tipos de grupos. Algunos algoritmos buscan instancias centradas alrededor de un grupo concreto (centroide). Otros, buscan regiones continuas de instancias abarrotadas. Algunos algoritmos son jerárquicos y buscan grupos de grupos.
Vamos a ver uno de los algoritmo de agrupamiento más populas: K-Medias.
Vamos a partir del siguiente conjunto de datos sin etiquetar:
El funcionamiento del algoritmo K-Medias es bastante sencillo. Lo primero que hace es elegir tantos centroides (puntos) aleatorios como grupos queramos. Una vez tenemos los centroides, el algoritmo va asignando cada instancia al grupo representado por el centroide más cercano. Una vez ha terminado de asignar todas las instancias, actualiza los centroides (centrandolos según las instancias del grupo) y vuelve a repetir el proceso hasta que los centroides dejen de moverse.
Aunque está garantizado que el algoritmo convergerá en un número finito de pasos, puede que no converja en la solución óptima; que lo haga o no dependerá de la incialización de los centroides:
Para reducir este riesgo, podemos usar diferentes métodos de inicialización de centroides:
Para crear un modelo con el algoritmo K-Medias usamos la clase Kmeans. Esta clase tiene, entre otros hiperparámetros (como init o n_init que hemos visto antes) el hiperparámetro n_cluster, donde puedes indicar el número de grupos a crear:
from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=5) y_pred = kmeans.fit_predict(X)
Si mostramos y_pred, vemos los grupos a los que KMeans ha asignado a cada instancia:
y_pred
array([4, 0, 1, ..., 2, 1, 0], dtype=int32)
También podemos ver los centroides que ha encontrado el algoritmo con el atributo cluster_centers_:
kmeans.cluster_centers_
array([[-2.80389616, 1.80117999], [ 0.20876306, 2.25551336], [-2.79290307, 2.79641063], [-1.46679593, 2.28585348], [-2.80037642, 1.30082566]])
Una vez entrenado el modelo, podemos asignar nuevas instancias a los grupos encontrados con el método predict:
X_new = np.array([[0,2], [3,2], [-3,3], [-3,2.5]]) kmeans.predict(X_new)
array([1, 1, 2, 2], dtype=int32)
Sklearn usa el segundo método de incialización de centroides que hemos visto antes. Ejecuta por defecto 10 veces el algoritmo cuando llamamos al método fit() (el hiperparámetro n_init es, por defecto, igual a 10). Si queremos ver la inercia del mejor modelo escogido, usamos el parámetro inertia_:
kmeans.inertia_
211.5985372581683
En los ejemplos anteriores hemos establecido 5 como número de grupos, ya que, viendo los datos, era evidente que ese era el número correcto. El problema es que, en general, no es tan fácil saber de antemano que número de grupos es el ideal. Por ejemplo, si hubiésemos elegido 3 u 8, el modelo habría agrupado los datos de forma diferente:
Por lo tanto, necesitamos alguna forma de saber qué número de grupos es el óptimo (o, por lo menos, uno cercano al óptimo).
Aunque podríamos pensar que la inercia podría ser un buen indicativo, no es así. Si nos fijamos en la inercia para k=3, es mayor que la calculada anteriormente (k=5):
print(kmeans_k3.inertia_) print(kmeans_k8.inertia_)
653.2167190021556 119.11983416102888
Si trazamos la gráfica de la inercia en función del número de grupos, vemos que ésta siempre baja cuando aumentamos el número de grupos:
Viendo el gráfico, podemos pensar que k=4 es una buena opción, ya que es “codo” de la función (y se acerca bastante a la solución óptima).
Otra forma mejor de seleccionar el número de grupos es utilizar la puntuación de la silueta, que es el coeficiente medio de la silueta sobre todas las instancias. El coeficiente de la silueta de una instancia es:
$\displaystyle s= \frac{b - a}{max(a,b)}$
Donde a es la distancia media a las otras instancias en el mismo grupo y b es la distancia media al grupo más cercano (excluyendo el propio grupo de la instancia).
El coeficiente de silueta tiene un rango entre -1 y +1. Un coeficiente cercano a +1 indica que la instancia está muy metida en su propio grupo y lejos de otros, mientras que un coeficiente cercano a 0 significa que está cerca del límite de un grupo. Por último, un coeficiente cercano a -1 significa que la instancia puede haberse asignado al grupo equivocado.
Para calcular la puntuación de la silueta, podemos utilizar la función silhouette_score() pasándole todas las instancias del conjunto de datos y las etiquetas que se les han asignado (almacenadas en la variable labels_):
from sklearn.metrics import silhouette_score silhouette_score(X, kmeans.labels_)
0.655517642572828
Vamos a comparar las puntuaciones de silueta para diferentes número de grupos:
Como vemos, esta visualización nos da más información que la anterior. Aunque confirma que k=4 es una opción muy buena, también subraya el hecho de que k=5 es también bastante buena y mucho mejor que el resto.
Podemos obtener un gráfico más informativa si sacamos un diagrama de silueta. Este diagrama muestra el coeficiente de silueta de cada instancia, ordenado por el grupo al que se asigna y por el valor del coeficiente. Cada diagrama tiene forma de cuchillo por grupo. La altura de la forma indica el número de instancias de cada grupo y la anchura representa los coeficientes de silueta ordenados de las instancias en cada grupo. La línea discontinua indica el coeficiente de silueta medio.
Cuando la mayoría de las intancias de un grupo tienen un coeficiente más bajo que la línea discontinua, entonces el grupo es bastante malo (ya que la mayoría de sus instancias están cerca de otros grupos). Como vemos, con k=3 y k=6 obtenemos grupos bastante malos. Con k=4 y k=5 obtenemos grupos bastante buenos, pero con k=4 obtenemos un grupo bastante grande (el tercero) en comparación con los demás, mientras que con k=5 el tamaño de los grupos es más homogéneo.
Por tanto, aunque la puntuación de la silueta global de k=4 es mejor, parece buena idea utilizar k=5, ya que obtenemos grupos de tamaños similares.