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é se llama “regresión” lineal?

Un nombre que suena a retroceso… pero que usamos para predecir el futuro: la regresión…

3 horas ago

Guía definitiva para trabajar con JSON en SQL Server

El formato JSON (JavaScript Object Notation) se ha convertido en el estándar de facto para…

2 días ago

Cómo crear un Data Lake en Azure paso a paso

El volumen de datos que las organizaciones generan y deben manejar crece día a día:…

1 semana ago

¿Por qué el azar no es tan aleatorio como parece?

Cuando escuchamos la palabra “azar”, pensamos en lo impredecible: una moneda que gira en el…

1 semana ago

Detectan vulnerabilidad crítica en MLflow que permite ejecución remota de código

Una nueva vulnerabilidad crítica ha sido detectada en MLflow, la popular plataforma de código abierto…

1 semana ago

Curiosidad: ¿Por qué los datos “raros” son tan valiosos?

En estadística, los valores atípicos —también llamados outliers— son esos datos que se alejan “demasiado”…

2 semanas ago

This website uses cookies.