Ciencia de datos

Número óptimo de clústeres con Silhouette e implementación en Python

La Silhouette es una métrica que permite evaluar la calidad de los clústeres generados mediante algoritmos de clustering basados en la distancia euclídea. Como es el caso de k-means. Cuantificando la relación que existe entre la separación de los diferentes clústeres y la similitud entre los puntos de un mismo clúster en un valor que varía entre -1 y 1. Los valores cercanos a 1 indican la mejor separación de los clústeres y los cercanos a -1 la peor. Información que se puede utilizar para seleccionar el número óptimo de clústeres en k-means. Siendo una alternativa a otros métodos como el del codo (elbow method), gap statistics o Calinski-Harabasz.

Definición de la Silhouette

La fórmula para calcular el coeficiente de Silhouette (Silhouette Coefficient) se define de la siguiente manera s_i = \frac{b_i - a_i}{\max(a_i, b_i)}, donde a_i es la distancia promedio entre el punto i y todos los demás puntos dentro del mismo cluster y b_i es la distancia promedio entre el punto i y todos los puntos en el cluster más cercano (diferente al que pertenece i).

El coeficiente de la Silhouette solamente puede tomar valores entre -1 y 1. Cuando los clústeres están completamente agrupados, el valor de a_i tiendo a cero y, por lo tanto, el valor de la métrica tiende a 1. Por otro lado, cuando b_i tiende a cero, los clústeres están completamente juntos y el valor de la Silhouette tiende a -1. En el caso de obtener un valor cercano a cero indica que los puntos de un un clúster están en el límite de los dos.

El coeficiente de la Silhouette (s_i) se define para cada clúster. Cuando se dispone de más de dos clústeres se calcula el valor promedio de la Silhouette (Average Silhouette) para disponer de una medida de la calidad de los clústeres.

Estimar la cantidad óptima de clústeres mediante la Silhouette

El valor de la Silhouette promedio se puede utilizar para seleccionar el número óptimo de clústeres en los algoritmos de clustering como k-means. La idea es calcular el valor de la Silhouette para diferente número de clústeres (k) y usar el valor que maximice la métrica. Lo que se puede hacer iterando sobre un rango de valores que va de 2 (la métrica solamente está definida a partir de dos clústeres) a un máximo definido.

Dado que en Scikit-learn existe la función silhouette_score() que implementa el cálculo de la Silhouette, implementar esta algoritmos en Python es extremadamente sencillo. Por ejemplo, se puede hacer con la siguiente función que solamente necesita un conjunto de datos para obtener una estimación del número óptimo de clústeres.

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

def silhouette(data, max_clusters=10):
    """
    Función para seleccionar el número óptimo de clusters utilizando el coeficiente de Silhouette.

    Parámetros:
    -----------
    data : matriz o matriz dispersa, forma (n_samples, n_features)
        Los datos de entrada.

    max_clusters : int, opcional (por defecto=10)
        El número máximo de clusters a considerar.

    Retorna:
    -------
    best_k : int
        El número óptimo de clusters seleccionado por el método de Silhouette
    """

    silhouette_scores = []  # Lista para almacenar los coeficientes de Silhouette

    # Iterar sobre los valores de k
    for k in range(2, max_clusters + 1):
        # Crear un modelo de KMeans con el número de clusters k
        kmeans = KMeans(n_clusters=k)

        # Ajustar el modelo a los datos y obtener las etiquetas de los clusters
        labels = kmeans.fit_predict(data)

        # Calcular el coeficiente de Silhouette para el modelo
        silhouette_avg = silhouette_score(data, labels)

        # Agregar el coeficiente a la lista
        silhouette_scores.append(silhouette_avg)

    # Encontrar el valor de k con el coeficiente de Silhouette más alto
    best_k = 2 + silhouette_scores.index(max(silhouette_scores))

    return best_k

Función que se puede probar con un conjunto de datos sintéticos generado mediante make_blobs() que se puede usar para evaluar los resultados.

from sklearn.datasets import make_blobs

# Genera un conjunto de datos de ejemplo con 4 clusters
data, _ = make_blobs(n_samples=500, centers=4, n_features=2, random_state=42)

silhouette(data)
4

En este caso, como era de esperar, el método devuelve el número de clústeres indicados a la hora de crear los datos.

Conclusiones

El método de la Silhouette es un algoritmo fácil de entender e implementar para seleccionar el número óptimo de clústeres. Por lo que es uno de los más utilizados junto al método del codo (elbow method). Aunque, debido a que generalmente ofrece unos resultados más fáciles de interpretar que este, suele ser una mejor elección cuando solamente se desea emplear un método.

Imagen de Cindy Lever en Pixabay

¿Te ha parecido de utilidad el contenido?

Daniel Rodríguez

Share
Published by
Daniel Rodríguez

Recent Posts

Curiosidad: ¿Por qué usamos p < 0.05? Un umbral que cambió la historia de la ciencia

En casi cualquier análisis estadístico —ya sea en medicina, psicología, economía o ciencia de datos—…

4 días ago

¿Está concentrado el MSCI World? Un análisis con Gini, Lorenz y leyes de potencia

El MSCI World Index suele presentarse como “la ventana al mundo” para quienes invierten en…

6 días ago

Curiosidad: La maldición de la dimensionalidad, o por qué añadir más datos puede empeorar tu modelo

En el mundo del análisis de datos solemos escuchar una idea poderosa: cuantos más datos,…

2 semanas ago

Error npm ERR! code EACCES al instalar paquetes en Node.js: Cómo solucionarlo paso a paso

¿Te has encontrado con este error al intentar instalar paquetes con npm? npm ERR! code…

2 semanas ago

Curiosidad: La Paradoja de Simpson, o por qué no siempre debes fiarte de los promedios

En ciencia de datos y estadística, los promedios y porcentajes son herramientas fundamentales para resumir…

3 semanas ago

Copias de seguridad automáticas en SQL Server con rotación de archivos

Las bases de datos son el corazón de casi cualquier sistema de información moderno. Ya…

3 semanas ago

This website uses cookies.