Agrupación jerárquica con Python y Scikit-Learn

    El agrupamiento jerárquico es un tipo de algoritmo de Machine Learning no supervisado que se utiliza para agrupar puntos de datos sin etiquetar. Al igual que el agrupamiento de K-medias, el agrupamiento jerárquico también agrupa los puntos de datos con características similares. En algunos casos, el resultado de la agrupación jerárquica y de K-Means puede ser similar. Antes de implementar agrupación jerárquica utilizando Scikit-Learn, primero comprendamos la teoría detrás de la agrupación jerárquica.

    Teoría de la agrupación jerárquica

    Hay dos tipos de agrupamiento jerárquico: aglomerativo y divisivo. En el primero, los puntos de datos se agrupan utilizando un enfoque ascendente que comienza con puntos de datos individuales, mientras que en el segundo se sigue un enfoque descendente en el que todos los puntos de datos se tratan como un gran grupo y el proceso de agrupamiento implica dividir el único gran agruparse en varios grupos pequeños.

    En este artículo nos centraremos en la agrupación aglomerativa que implica el enfoque de abajo hacia arriba.

    Pasos para realizar agrupaciones jerárquicas

    Los siguientes son los pasos involucrados en la agrupación aglomerativa:

    • Al principio, trate cada punto de datos como un grupo. Por lo tanto, el número de conglomerados al inicio será K, mientras que K es un número entero que representa el número de puntos de datos.
    • Forme un grupo uniendo los dos puntos de datos más cercanos que resulten en grupos K-1.
    • Forme más grupos uniendo los dos grupos más cercanos que resulten en grupos K-2.
    • Repita los tres pasos anteriores hasta que se forme un gran grupo.
    • Una vez que se forma un solo grupo, dendrogramas se utilizan para dividirse en varios grupos según el problema. Estudiaremos el concepto de dendrograma en detalle en una próxima sección.

    Hay diferentes formas de encontrar la distancia entre los grupos. La distancia en sí puede ser euclidiana o distancia de Manhattan. A continuación, se muestran algunas de las opciones para medir la distancia entre dos grupos:

    • Mida la distancia entre los puntos de cierre de dos grupos.
    • Mida la distancia entre los puntos más lejanos de dos grupos.
    • Mide la distancia entre los centroides de dos grupos.
    • Mida la distancia entre todas las combinaciones posibles de puntos entre los dos grupos y obtenga la media.

    Papel de los dendrogramas para la agrupación jerárquica

    En la última sección, dijimos que una vez que se forma un grupo grande mediante la combinación de grupos pequeños, los dendrogramas del grupo se utilizan para dividir el grupo en múltiples grupos de puntos de datos relacionados. Veamos cómo se hace realmente.

    Supongamos que tenemos una colección de puntos de datos representados por un numpy matriz de la siguiente manera:

    import numpy as np
    
    X = np.array([[5,3],
        [10,15],
        [15,12],
        [24,10],
        [30,30],
        [85,70],
        [71,80],
        [60,78],
        [70,55],
        [80,91],])
    

    Tracemos los puntos de datos anteriores. Para hacerlo, ejecute el siguiente código:

    import matplotlib.pyplot as plt
    
    labels = range(1, 11)
    plt.figure(figsize=(10, 7))
    plt.subplots_adjust(bottom=0.1)
    plt.scatter(X[:,0],X[:,1], label="True Position")
    
    for label, x, y in zip(labels, X[:, 0], X[:, 1]):
        plt.annotate(
            label,
            xy=(x, y), xytext=(-3, 3),
            textcoords="offset points", ha="right", va="bottom")
    plt.show()
    

    El script anterior dibuja los puntos de datos en el X numpy puntos de datos de matriz y etiqueta de 1 a 10. En la imagen a continuación, verá que el gráfico que se genera a partir de este código:

    Nombramos el gráfico anterior como Graph1. Se puede ver a simple vista que los puntos de datos forman dos grupos: el primero en la parte inferior izquierda que consta de los puntos 1-5 y el segundo en la parte superior derecha que consta de los puntos 6-10.

    Sin embargo, en el mundo real, podemos tener miles de puntos de datos en muchas más de 2 dimensiones. En ese caso, no sería posible detectar grupos a simple vista. Por eso se han desarrollado algoritmos de agrupamiento.

    Volviendo al uso de dendrogramas en agrupaciones jerárquicas, dibujemos los dendrogramas para nuestros puntos de datos. Usaremos el scipy biblioteca para ese propósito. Ejecute el siguiente script:

    from scipy.cluster.hierarchy import dendrogram, linkage
    from matplotlib import pyplot as plt
    
    linked = linkage(X, 'single')
    
    labelList = range(1, 11)
    
    plt.figure(figsize=(10, 7))
    dendrogram(linked,
                orientation='top',
                labels=labelList,
                distance_sort="descending",
                show_leaf_counts=True)
    plt.show()
    

    El gráfico de salida se parece al siguiente. Llamemos a esta gráfica Graph2.

    El algoritmo comienza por encontrar los dos puntos más cercanos entre sí sobre la base de la distancia euclidiana. Si miramos hacia atrás en Graph1, podemos ver que los puntos 2 y 3 están más cerca entre sí, mientras que los puntos 7 y 8 están cerca entre sí. Por lo tanto, primero se formará un grupo entre estos dos puntos. En Graph2, puede ver que los dendogramas se han creado uniendo los puntos 2 con 3 y 8 con 7. La altura vertical del dendograma muestra las distancias euclidianas entre puntos. En el Gráfico 2, se puede ver que la distancia euclidiana entre los puntos 8 y 7 es mayor que la distancia entre los puntos 2 y 3.

    El siguiente paso es unir el grupo formado al unir dos puntos al siguiente grupo o punto más cercano que a su vez da como resultado otro grupo. Si observa Graph1, el punto 4 es el más cercano al grupo de los puntos 2 y 3, por lo tanto, en Graph2 el dendrograma se genera uniendo el punto 4 con el dendrograma de los puntos 2 y 3. Este proceso continúa hasta que todos los puntos se unen para formar un gran racimo.

    Una vez que se forma un gran grupo, se selecciona la distancia vertical más larga sin ninguna línea horizontal que lo atraviese y se traza una línea horizontal a través de él. El número de líneas verticales que pasa esta línea horizontal recién creada es igual al número de grupos. Eche un vistazo a la siguiente trama:

    Podemos ver que la mayor distancia vertical sin ninguna línea horizontal que la atraviese está representada por una línea azul. Entonces dibujamos una nueva línea roja horizontal que pasa a través de la línea azul. Dado que cruza la línea azul en dos puntos, el número de grupos será 2.

    Básicamente, la línea horizontal es un umbral, que define la distancia mínima requerida para ser un grupo separado. Si trazamos una línea más abajo, el umbral requerido para ser un nuevo clúster disminuirá y se formarán más clústeres como se ve en la imagen a continuación:

    En el gráfico anterior, la línea horizontal pasa por cuatro líneas verticales que dan como resultado cuatro grupos: grupo de puntos 6, 7, 8 y 10, grupo de puntos 3,2,4 y los puntos 9 y 5 se tratarán como grupos de un solo punto.

    Agrupación jerárquica mediante Scikit-Learn

    Suficiente de teoría, ahora implementemos la agrupación jerárquica usando la biblioteca Scikit-Learn de Python.

    Ejemplo 1

    En nuestro primer ejemplo agruparemos el X numpy matriz de puntos de datos que creamos en la sección anterior.

    El proceso de agrupación en clústeres es similar a cualquier otro algoritmo de Machine Learning no supervisado. Comenzamos importando las bibliotecas requeridas:

    import matplotlib.pyplot as plt
    import pandas as pd
    %matplotlib inline
    import numpy as np
    

    El siguiente paso es importar o crear el conjunto de datos. En este ejemplo, usaremos los siguientes datos de ejemplo:

    X = np.array([[5,3],
        [10,15],
        [15,12],
        [24,10],
        [30,30],
        [85,70],
        [71,80],
        [60,78],
        [70,55],
        [80,91],])
    

    El siguiente paso es importar la clase para agrupar y llamar a su fit_predict método para predecir los clústeres a los que pertenece cada punto de datos.

    Eche un vistazo al siguiente guión:

    from sklearn.cluster import AgglomerativeClustering
    
    cluster = AgglomerativeClustering(n_clusters=2, affinity='euclidean', linkage="ward")
    cluster.fit_predict(X)
    

    En el código anterior importamos el AgglomerativeClustering clase de la biblioteca “sklearn.cluster”. El número de parámetros se establece en 2 utilizando el n_clusters parámetro mientras el affinity se establece en “euclidiana” (distancia entre los puntos de datos). Finalmente linkage El parámetro se establece en “ward”, lo que minimiza la variante entre los grupos.

    A continuación llamamos al fit_predict método del AgglomerativeClustering variable de clase cluster. Este método devuelve los nombres de los clústeres a los que pertenece cada punto de datos. Ejecute el siguiente script para ver cómo se han agrupado los puntos de datos.

    print(cluster.labels_)
    

    La salida es una matriz unidimensional de 10 elementos correspondientes a los grupos asignados a nuestros 10 puntos de datos.

    [1 1 1 1 1 0 0 0 0]
    

    Como se esperaba, los primeros cinco puntos se han agrupado, mientras que los últimos cinco puntos se han agrupado. Es importante mencionar aquí que estos unos y ceros son simplemente etiquetas asignadas a los grupos y no tienen implicaciones matemáticas.

    Finalmente, tracemos nuestros clústeres. Para hacerlo, ejecute el siguiente código:

    plt.scatter(X[:,0],X[:,1], c=cluster.labels_, cmap='rainbow')
    

    Puede ver puntos en dos grupos donde los primeros cinco puntos se agruparon y los últimos cinco puntos se agruparon.

    Ejemplo 2

    En la última sección, realizamos un agrupamiento jerárquico de datos ficticios. En este ejemplo, realizaremos un agrupamiento jerárquico en datos del mundo real y veremos cómo se puede usar para resolver un problema real.

    El problema que vamos a solucionar en este apartado es segmentar a los clientes en diferentes grupos en función de sus tendencias de compra.

    El conjunto de datos de este problema se puede descargar desde el siguiente enlace:

    shopping-data.csv

    Coloque el archivo “shopping-data.csv” descargado en la carpeta “Conjuntos de datos” del directorio “D”. Para agrupar estos datos en grupos, seguiremos los mismos pasos que realizamos en el apartado anterior.

    Ejecute el siguiente script para importar las bibliotecas deseadas:

    import matplotlib.pyplot as plt
    import pandas as pd
    %matplotlib inline
    import numpy as np
    

    A continuación, para importar el conjunto de datos de este ejemplo, ejecute el siguiente código:

    customer_data = pd.read_csv('D:Datasetsshopping-data.csv')
    

    Exploremos un poco nuestro conjunto de datos. Para verificar la cantidad de registros y atributos, ejecute el siguiente script:

    customer_data.shape
    

    El script anterior volverá (200, 5) lo que significa que el conjunto de datos contiene 200 registros y 5 atributos.

    Para observar el conjunto de datos, ejecute el head() función del marco de datos. Eche un vistazo al siguiente guión:

    customer_data.head()
    

    La salida se verá así:

    CustomerID Género Edad Ingreso anual (k $) Puntuación de gasto (1-100)

    01Masculino191539
    12Masculino211581
    23Hembra20dieciséis6
    34Hembra23dieciséis77
    45Hembra311740

    Nuestro conjunto de datos tiene cinco columnas: CustomerID, Genre, Age, Annual Income y Spending Score. Para ver los resultados en un espacio de características bidimensional, solo conservaremos dos de estas cinco columnas. Podemos eliminar la columna CustomerID, Genre y Age. Conservaremos las columnas Ingresos anuales (en miles de dólares) y Puntuación de gastos (1-100). La columna Spending Score indica la frecuencia con la que una persona gasta dinero en un centro comercial en una escala del 1 al 100, siendo 100 el que más gasta. Ejecute el siguiente script para filtrar las primeras tres columnas de nuestro conjunto de datos:

    data = customer_data.iloc[:, 3:5].values
    

    A continuación, necesitamos saber los clústeres en los que queremos que se dividan nuestros datos. Usaremos nuevamente el scipy biblioteca para crear los dendrogramas para nuestro conjunto de datos. Ejecute el siguiente script para hacerlo:

    import scipy.cluster.hierarchy as shc
    
    plt.figure(figsize=(10, 7))
    plt.title("Customer Dendograms")
    dend = shc.dendrogram(shc.linkage(data, method='ward'))
    

    En el script anterior importamos la clase de jerarquía del scipy.cluster biblioteca como shc. La clase de jerarquía tiene un dendrogram método que toma el valor devuelto por el linkage método de la misma clase. los linkage El método toma el conjunto de datos y el método para minimizar las distancias como parámetros. Usamos ‘ward’ como el method ya que minimiza entonces las variantes de distancias entre los conglomerados.

    La salida del script anterior se ve así:

    Si dibujamos una línea horizontal que atraviesa la distancia más larga sin una línea horizontal, obtenemos 5 grupos como se muestra en la siguiente figura:

    Ahora que sabemos la cantidad de clústeres para nuestro conjunto de datos, el siguiente paso es agrupar los puntos de datos en estos cinco clústeres. Para hacerlo, usaremos nuevamente el AgglomerativeClustering clase de la sklearn.cluster biblioteca. Eche un vistazo al siguiente guión:

    from sklearn.cluster import AgglomerativeClustering
    
    cluster = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage="ward")
    cluster.fit_predict(data)
    

    La salida del script anterior se ve así:

    array([4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4,
           3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 1, 4, 1,
           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 0, 2, 0, 2, 1, 2, 0, 2, 0, 2,
           0, 2, 0, 2, 1, 2, 0, 2, 1, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 2, 0, 2, 1,
           2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,
           0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2], dtype=int64)
    

    Puede ver las etiquetas del clúster de todos sus puntos de datos. Como teníamos cinco clústeres, tenemos cinco etiquetas en la salida, es decir, de 0 a 4.

    Como paso final, tracemos los clústeres para ver cómo se han agrupado realmente nuestros datos:

    plt.figure(figsize=(10, 7))
    plt.scatter(data[:,0], data[:,1], c=cluster.labels_, cmap='rainbow')
    

    La salida del código anterior se ve así:

    Puede ver los puntos de datos en forma de cinco grupos. Los puntos de datos en la parte inferior derecha pertenecen a los clientes con salarios altos pero gastos bajos. Estos son los clientes que gastan su dinero con cuidado. Del mismo modo, los clientes en la parte superior derecha (puntos de datos verdes), estos son los clientes con altos salarios y altos gastos. Estos son el tipo de clientes a los que se dirigen las empresas. Los clientes en el medio (puntos de datos azules) son los que tienen ingresos medios y salarios medios. El mayor número de clientes pertenece a esta categoría. Las empresas también pueden dirigirse a estos clientes dado que son grandes cantidades, etc.

    Recursos

    Entre todos los diferentes paquetes de Python (pandas, matplotlib, numpyy sklearn) hay mucha información en este artículo que puede ser difícil de seguir, por lo que recomendamos consultar algunos recursos más detallados sobre cómo realizar tareas de ciencia de datos con Python, como un curso en línea:

    Hemos descubierto que estos recursos son lo suficientemente buenos como para que usted obtenga un conocimiento sólido de cómo usarlos en su propio trabajo.

    Conclusión

    La técnica de agrupación en clústeres puede ser muy útil cuando se trata de datos sin etiquetar. Dado que la mayoría de los datos en el mundo real no están etiquetados y anotar los datos tiene costos más altos, se pueden usar técnicas de agrupamiento para etiquetar los datos no etiquetados.

    En este artículo explicamos el agrupamiento jerárquico con la ayuda de dos ejemplos. Para obtener más artículos sobre Machine Learning y ciencia de datos, siga visitando este sitio. ¡Feliz codificación!

     

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *