Agrupamento Hierárquico com Scikit-Learn

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Neste laboratório, utilizaremos a biblioteca scikit-learn do Python para realizar agrupamento hierárquico em alguns conjuntos de dados de exemplo. O agrupamento hierárquico é um método de agrupamento onde se constrói uma hierarquia de clusters, de forma ascendente ou descendente. O objetivo do agrupamento hierárquico é encontrar grupos de pontos que são semelhantes entre si e diferentes dos pontos em outros grupos.

Dicas da Máquina Virtual

Após o arranque da máquina virtual, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante o aprendizado, não hesite em contactar o Labby. Forneça feedback após a sessão e resolveremos o problema rapidamente para si.

Importar Bibliotecas e Carregar Dados

Começaremos importando as bibliotecas necessárias e carregando os conjuntos de dados de exemplo que usaremos nos nossos exemplos de agrupamento hierárquico.

import time
import warnings

import numpy as np
import matplotlib.pyplot as plt

from sklearn import cluster, datasets
from sklearn.preprocessing import StandardScaler
from itertools import cycle, islice

np.random.seed(0)

## %%
## Gerar conjuntos de dados. Escolhemos um tamanho suficientemente grande para ver a escalabilidade dos algoritmos, mas não muito grande para evitar tempos de execução demasiado longos

n_samples = 1500
noisy_circles = datasets.make_circles(n_samples=n_samples, factor=0.5, noise=0.05)
noisy_moons = datasets.make_moons(n_samples=n_samples, noise=0.05)
blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)
no_structure = np.random.rand(n_samples, 2), None

## Dados distribuídos anisotrópica
random_state = 170
X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)
transformation = [[0.6, -0.6], [-0.4, 0.8]]
X_aniso = np.dot(X, transformation)
aniso = (X_aniso, y)

## Blobs com variâncias variadas
varied = datasets.make_blobs(
    n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state
)

Realizar Agrupamento Hierárquico

Agora, realizaremos agrupamento hierárquico nos conjuntos de dados de exemplo carregados na etapa 1. Usaremos diferentes métodos de ligação, como single, average, complete e ward, para construir os nossos clusters.

## Configurar parâmetros do cluster
plt.figure(figsize=(9 * 1.3 + 2, 14.5))
plt.subplots_adjust(
    left=0.02, right=0.98, bottom=0.001, top=0.96, wspace=0.05, hspace=0.01
)

plot_num = 1

default_base = {"n_neighbors": 10, "n_clusters": 3}

datasets = [
    (noisy_circles, {"n_clusters": 2}),
    (noisy_moons, {"n_clusters": 2}),
    (varied, {"n_neighbors": 2}),
    (aniso, {"n_neighbors": 2}),
    (blobs, {}),
    (no_structure, {}),
]

for i_dataset, (dataset, algo_params) in enumerate(datasets):
    ## atualizar parâmetros com valores específicos do conjunto de dados
    params = default_base.copy()
    params.update(algo_params)

    X, y = dataset

    ## normalizar o conjunto de dados para uma seleção de parâmetros mais fácil
    X = StandardScaler().fit_transform(X)

    ## ============
    ## Criar objetos de cluster
    ## ============
    ward = cluster.AgglomerativeClustering(
        n_clusters=params["n_clusters"], linkage="ward"
    )
    complete = cluster.AgglomerativeClustering(
        n_clusters=params["n_clusters"], linkage="complete"
    )
    average = cluster.AgglomerativeClustering(
        n_clusters=params["n_clusters"], linkage="average"
    )
    single = cluster.AgglomerativeClustering(
        n_clusters=params["n_clusters"], linkage="single"
    )

    clustering_algorithms = (
        ("Single Linkage", single),
        ("Average Linkage", average),
        ("Complete Linkage", complete),
        ("Ward Linkage", ward),
    )

    for name, algorithm in clustering_algorithms:
        t0 = time.time()

        ## capturar avisos relacionados com kneighbors_graph
        with warnings.catch_warnings():
            warnings.filterwarnings(
                "ignore",
                message="the number of connected components of the "
                + "connectivity matrix is [0-9]{1,2}"
                + " > 1. Completing it to avoid stopping the tree early.",
                category=UserWarning,
            )
            algorithm.fit(X)

        t1 = time.time()
        if hasattr(algorithm, "labels_"):
            y_pred = algorithm.labels_.astype(int)
        else:
            y_pred = algorithm.predict(X)

        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)
        if i_dataset == 0:
            plt.title(name, size=18)

        colors = np.array(
            list(
                islice(
                    cycle(
                        [
                            "#377eb8",
                            "#ff7f00",
                            "#4daf4a",
                            "#f781bf",
                            "#a65628",
                            "#984ea3",
                            "#999999",
                            "#e41a1c",
                            "#dede00",
                        ]
                    ),
                    int(max(y_pred) + 1),
                )
            )
        )
        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])

        plt.xlim(-2.5, 2.5)
        plt.ylim(-2.5, 2.5)
        plt.xticks(())
        plt.yticks(())
        plt.text(
            0.99,
            0.01,
            ("%.2fs" % (t1 - t0)).lstrip("0"),
            transform=plt.gca().transAxes,
            size=15,
            horizontalalignment="right",
        )
        plot_num += 1

plt.show()

Analisar os Resultados

Agora, analisaremos os resultados do nosso agrupamento hierárquico. Com base nos conjuntos de dados de exemplo utilizados, podemos fazer as seguintes observações:

  • A ligação única é rápida e pode ter bom desempenho em dados não globulares, mas tem um desempenho fraco na presença de ruído.
  • A ligação média e completa têm bom desempenho em clusters globulares claramente separados, mas têm resultados mistos caso contrário.
  • Ward é o método mais eficaz para dados ruidosos.

É importante notar que, embora estas observações nos forneçam alguma intuição sobre os algoritmos, esta intuição pode não se aplicar a dados de alta dimensionalidade.

Resumo

Neste laboratório, aprendemos a realizar agrupamento hierárquico utilizando a biblioteca scikit-learn do Python. Usamos diferentes métodos de ligação, como single, average, complete e ward, para construir nossos clusters e analisamos os resultados com base em alguns conjuntos de dados de exemplo. O agrupamento hierárquico é uma técnica poderosa que pode ser usada para identificar clusters de pontos de dados semelhantes e pode ser útil em diversas áreas, como biologia, marketing e finanças.