Herramientas de usuario

Herramientas del sitio


clase:ia:saa:8_ml_no_supervisado:clustering

02 - Clustering

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.

K-Medias (K-Means)

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:

  • Si tenemos una idea general de dónde deberían estar los centroides, podemos establecer el hiperparámetro init como una matriz NumPy que contanga la lista de dentroides y configurar n_init como 1.
  • Podemos ejecutar el algoritmo varias veces con inicializadores aleatorios diferentes y mantener la mejor solución. Para saber cuál es la mejor solución, sklearn utiliza una métrica llamada inercia, que es la distancia cuadrática media entre cada instancia y su centroide más cercano.

K-Medias en Sklearn

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)

No hay que confundir los valores anteriores con las etiquetas de clase en la clasificación. Recuerda que el agrupamiento es una tarea de aprendizaje no supervisado

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

Escoger el número de grupos óptimo

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.

clase/ia/saa/8_ml_no_supervisado/clustering.txt · Última modificación: 2022/05/26 18:46 por cesguiro