W3docs

Agrupamento Hierárquico

Aprenda agrupamento hierárquico em Python com scikit-learn e SciPy: métodos de ligação, dendrogramas e quando usá-lo no lugar do K-Means.

O agrupamento hierárquico é um algoritmo de aprendizado de máquina não supervisionado que organiza pontos de dados em uma árvore de clusters aninhados — sem exigir que você especifique o número de clusters previamente. Esta página explica como o algoritmo funciona, a diferença entre as abordagens aglomerativa e divisiva, como escolher um método de ligação e como implementar e visualizar o agrupamento hierárquico em Python usando scikit-learn e SciPy.

O que é Agrupamento Hierárquico?

O agrupamento hierárquico constrói uma hierarquia de clusters mesclando ou dividindo iterativamente grupos de pontos de dados com base em uma medida de distância (ou similaridade). O resultado é representado como um dendrograma — um diagrama em forma de árvore onde o eixo y mostra a distância em que os clusters são mesclados e as folhas representam pontos de dados individuais.

Ao contrário do K-Means, o agrupamento hierárquico não exige que você escolha o número de clusters antes de executar o algoritmo. Você executa o algoritmo uma vez e depois "corta" o dendrograma em um limiar de distância escolhido para produzir qualquer número de clusters.

Quando usar o agrupamento hierárquico

Use o agrupamento hierárquico quando:

  • Você não sabe o número de clusters com antecedência e deseja explorar várias opções a partir de uma única execução.
  • Seu conjunto de dados é de pequeno a médio porte (milhares de linhas, não milhões) — o custo de memória O(n²) do algoritmo o torna impraticável para conjuntos de dados muito grandes.
  • Você precisa de relações de cluster interpretáveis (o dendrograma revela o histórico de mesclagens claramente).
  • Seus clusters podem não ser esféricos — métodos hierárquicos com ligação completa ou média lidam melhor com formas não globulares do que o K-Means.

Agrupamento Aglomerativo vs Divisivo

Existem duas estratégias principais:

EstratégiaDireçãoComo funciona
Aglomerativo (de baixo para cima)Começa com cada ponto como seu próprio cluster e, em seguida, mescla repetidamente os dois clusters mais próximos.Mais comum; usado pelo AgglomerativeClustering do scikit-learn e pelo linkage do SciPy.
Divisivo (de cima para baixo)Começa com todos os pontos em um único cluster e, em seguida, divide recursivamente o maior cluster.Raramente usado na prática; computacionalmente caro.

Esta página foca no agrupamento aglomerativo, que é o que a maioria dos profissionais quer dizer quando fala em "agrupamento hierárquico".

Como o Algoritmo Funciona

O agrupamento aglomerativo segue estas etapas:

  1. Trate cada um dos n pontos de dados como seu próprio cluster (n clusters no total).
  2. Calcule a matriz de distâncias — as distâncias par a par entre todos os clusters.
  3. Mescle os dois clusters com a menor distância em um novo cluster.
  4. Atualize a matriz de distâncias para refletir o novo cluster.
  5. Repita as etapas 3–4 até que reste apenas um cluster.

A saída final é um dendrograma que codifica todas as n-1 etapas de mesclagem.

Métodos de Ligação

O método de ligação controla como a distância entre dois clusters é calculada em cada etapa de mesclagem. A escolha afeta significativamente a forma e a qualidade dos clusters.

MétodoDistância entre os clusters A e BMelhor para
WardAumento na variância total intra-cluster após a mesclagemClusters compactos e de tamanho aproximadamente igual (escolha padrão)
CompletoDistância máxima entre qualquer ponto de A e qualquer ponto de BClusters compactos; evita encadeamento
MédioDistância média entre todos os pares (um de A, um de B)Equilíbrio entre ligação simples e completa
SimplesDistância mínima entre qualquer ponto de A e qualquer ponto de BDetecção de clusters alongados ou de formas irregulares; propenso a "encadeamento"

A ligação Ward é o ponto de partida mais amplamente utilizado. Se seus clusters forem alongados ou não convexos, experimente a ligação média ou simples.

Escalonamento de Recursos Antes do Agrupamento

Como o agrupamento hierárquico depende de cálculos de distância, recursos com grandes intervalos numéricos dominam a matriz de distâncias e distorcem os resultados. Sempre escalone seus recursos primeiro.

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

O StandardScaler centraliza cada recurso para média 0 e variância unitária. Consulte o capítulo sobre escalonamento para alternativas como MinMaxScaler e RobustScaler.

Implementando Agrupamento Hierárquico com scikit-learn

A classe AgglomerativeClustering no scikit-learn ajusta o modelo e atribui rótulos de cluster em uma única etapa. Ela não produz um dendrograma — use o SciPy (mostrado na próxima seção) para isso.

Passo 1 — Gerar e escalonar os dados

from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler

# 150 points in 3 natural clusters
X, y_true = make_blobs(n_samples=150, centers=3, cluster_std=0.6, random_state=42)

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

O make_blobs cria um conjunto de dados sintético reproduzível, portanto este exemplo roda sem nenhum arquivo CSV.

Passo 2 — Ajustar o agrupamento aglomerativo

from sklearn.cluster import AgglomerativeClustering

hc = AgglomerativeClustering(n_clusters=3, linkage='ward')
labels = hc.fit_predict(X_scaled)

print(labels[:10])
# e.g. [2 2 0 1 0 1 2 2 0 1]

O fit_predict ajusta o modelo e retorna o rótulo do cluster (0, 1 ou 2) para cada ponto de dados em uma única chamada.

Passo 3 — Visualizar os clusters

import matplotlib.pyplot as plt

colors = ['red', 'blue', 'green']
for cluster_id in range(3):
    mask = labels == cluster_id
    plt.scatter(X_scaled[mask, 0], X_scaled[mask, 1],
                s=60, label=f'Cluster {cluster_id + 1}')

plt.title('Agglomerative Clustering (Ward linkage, k=3)')
plt.xlabel('Feature 1 (scaled)')
plt.ylabel('Feature 2 (scaled)')
plt.legend()
plt.tight_layout()
plt.show()

Dendrogramas com SciPy

O dendrograma é a saída mais distintiva do agrupamento hierárquico. Ele permite que você escolha visualmente o número de clusters cortando a árvore em diferentes alturas. O módulo scipy.cluster.hierarchy do SciPy fornece tanto o linkage (para construir a árvore) quanto o dendrogram (para plotá-lo).

Construindo e plotando um dendrograma

from scipy.cluster.hierarchy import dendrogram, linkage
from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

# Use a smaller dataset so the dendrogram is readable
X, _ = make_blobs(n_samples=30, centers=3, cluster_std=0.6, random_state=42)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Build the linkage matrix
Z = linkage(X_scaled, method='ward')

# Plot
plt.figure(figsize=(12, 5))
dendrogram(Z, leaf_rotation=90, leaf_font_size=8)
plt.title('Dendrogram (Ward linkage)')
plt.xlabel('Sample index')
plt.ylabel('Merge distance')
plt.tight_layout()
plt.show()

Lendo o dendrograma

  • Folhas (parte inferior) representam pontos de dados individuais.
  • Linhas horizontais representam mesclagens. A altura de uma linha é igual à distância entre os dois clusters sendo mesclados.
  • Cortar a árvore em uma determinada altura fornece o número de clusters abaixo desse corte.

Para escolher k, procure a linha vertical mais alta que não seja cruzada por uma linha horizontal — essa lacuna sugere o número mais natural de clusters.

Cortando o dendrograma para atribuir rótulos

Após construir a matriz de ligação Z, use fcluster para cortar a árvore no número desejado de clusters:

from scipy.cluster.hierarchy import linkage, fcluster
from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler
import numpy as np

X, _ = make_blobs(n_samples=150, centers=3, cluster_std=0.6, random_state=42)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

Z = linkage(X_scaled, method='ward')

# Cut the tree to get exactly 3 clusters
labels = fcluster(Z, t=3, criterion='maxclust')

print('Unique cluster IDs:', np.unique(labels))   # [1 2 3]  (1-indexed)
print('Sizes:', np.bincount(labels[labels > 0]))   # [50 50 50]

Observe que os rótulos do fcluster são indexados a partir de 1 (começam em 1), ao contrário dos rótulos indexados a partir de 0 do scikit-learn.

Comparando Métodos de Ligação

O método de ligação altera significativamente as formas e tamanhos dos clusters. Veja como comparar todos os quatro métodos no mesmo conjunto de dados:

from sklearn.cluster import AgglomerativeClustering
from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import numpy as np

X, _ = make_blobs(n_samples=150, centers=3, cluster_std=0.6, random_state=42)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

methods = ['ward', 'complete', 'average', 'single']
fig, axes = plt.subplots(1, 4, figsize=(16, 4))

for ax, method in zip(axes, methods):
    hc = AgglomerativeClustering(n_clusters=3, linkage=method)
    labels = hc.fit_predict(X_scaled)
    ax.scatter(X_scaled[:, 0], X_scaled[:, 1], c=labels, cmap='Set1', s=30)
    ax.set_title(f'{method.capitalize()} linkage')
    ax.set_xticks([])
    ax.set_yticks([])

plt.suptitle('Linkage method comparison (k=3)', y=1.02)
plt.tight_layout()
plt.show()

Agrupamento Hierárquico vs K-Means

CaracterísticaAgrupamento hierárquicoK-Means
Número de clustersEscolhido após a execução (inspecionar o dendrograma)Deve ser especificado antes da execução
EscalabilidadeEspaço O(n²) — tem dificuldades acima de ~10.000 linhasO(n·k·i) — escala para milhões
DeterminismoTotalmente determinísticoDepende da inicialização aleatória
Formas dos clustersFlexível (especialmente com ligação simples/média)Assume clusters esféricos
InterpretabilidadeO dendrograma mostra o histórico completo de mesclagensCentróides são facilmente interpretáveis

Use o agrupamento hierárquico para análise exploratória em conjuntos de dados menores; mude para K-Means (ou DBSCAN) quando tiver milhões de linhas ou já souber o número de clusters.

Armadilhas Comuns

Esquecer de escalonar os recursos. Sem o escalonamento de recursos, um recurso medido em milhares (por exemplo, renda) domina um medido em dígitos simples (por exemplo, classificação etária), produzindo clusters enganosos.

Usar ligação Ward com distâncias não euclidianas. A ligação Ward só é válida com distância euclidiana. Para outras métricas de distância (por exemplo, cosseno, Manhattan), use ligação completa ou média e passe metric= explicitamente.

Interpretar dendrogramas em conjuntos de dados muito grandes. Um dendrograma com 10.000 folhas é ilegível. Use p= e truncate_mode='lastp' no dendrogram() do SciPy para mostrar apenas as últimas p mesclagens.

Tratar IDs de cluster como estáveis. IDs de cluster (0, 1, 2) são rótulos arbitrários. Ao comparar duas execuções, combine os clusters pelo conteúdo, não pelo número.

Conclusão

O agrupamento hierárquico é um algoritmo flexível e interpretável que não requer a escolha de k previamente. Você constrói o dendrograma completo uma vez e, em seguida, corta-o em qualquer nível. A ligação Ward com pré-processamento StandardScaler é o padrão mais seguro. Para conjuntos de dados muito grandes, prefira o K-Means por desempenho.

Capítulos relacionados:

  • Scale — por que e como padronizar recursos antes do agrupamento
  • K-Means — a alternativa de agrupamento plano para grandes conjuntos de dados
  • SciPy Tutorial — mais sobre a biblioteca de computação científica SciPy
  • Scatter Plot — visualizando dados multidimensionais com Matplotlib
Was this page helpful?