Trilha 19 · Machine Learning

Agrupamento com k-means

Até aqui os dados tinham rótulos. E quando não têm? O aprendizado não-supervisionado encontra estrutura sozinho — e o k-means é o algoritmo de agrupamento mais usado para isso.

① Intuição

Encontrar grupos sem ninguém dizer quais são

Imagine espalhar moradores num mapa e querer abrir k lojas de forma que cada pessoa fique perto de uma. Você chuta k locais, manda cada pessoa à loja mais próxima, e então move cada loja para o centro dos seus clientes. Repetindo, as lojas migram até pousarem no coração dos aglomerados naturais de gente.

É exatamente o k-means. Não há rótulos "certos" — o algoritmo descobre os grupos a partir da geometria dos dados, alternando dois passos: atribuir cada ponto ao centroide mais próximo e mover cada centroide para a média dos seus pontos.

Supervisionado vs. não-supervisionado: no supervisionado (regressão, perceptron, árvores) aprendemos de pares entrada→rótulo. No não-supervisionado só temos as entradas — o objetivo é revelar estrutura escondida: grupos (clustering), dimensões importantes (PCA) ou anomalias. Sem gabarito, avaliar a qualidade é mais sutil.
② Visualização interativa

Atribuir e mover, até convergir

Os centroides (marcadores grandes) começam amontoados no centro. Cada passo reatribui os pontos por cor e desloca os centroides para o centro dos seus grupos. A inércia só cai — até estabilizar. Mude o k e veja como agrupamentos com k errado ficam estranhos.

Número de clusters (k)
iteração: 0
inércia: 1.891

Cada passo faz duas coisas: (1) atribui cada ponto ao centroide mais próximo e (2) move cada centroide para o centro dos seus pontos. A inércia (soma das distâncias²) só cai — até estabilizar. Note que k errado agrupa de forma estranha.

③ Explicação técnica

O algoritmo de Lloyd

// k-means: agrupar sem rótulos (aprendizado não-supervisionado)

def kmeans(pontos, k, iteracoes=100):
    centroides = escolher_k_aleatorios(pontos, k)
    for _ in range(iteracoes):
        // PASSO 1 — atribuir: cada ponto vai ao centroide mais próximo
        grupos = [[] for _ in range(k)]
        for p in pontos:
            i = argmin(dist(p, c) for c in centroides)
            grupos[i].append(p)

        // PASSO 2 — atualizar: cada centroide vai ao centro do seu grupo
        novos = [media(grupo) for grupo in grupos]

        if novos == centroides: break   // convergiu
        centroides = novos
    return centroides, grupos

// Garante reduzir a INÉRCIA (soma das distâncias² ao centroide)
// a cada passo — até estabilizar num mínimo local.

Escolhendo k e evitando mínimos ruins

// Dois problemas práticos do k-means

// 1. Como escolher k? — Método do cotovelo (elbow)
// Rode k-means para k = 1,2,3,... e plote a inércia:
//   inércia
//    │\
//    │ \___        ← o "cotovelo" (aqui k=3) é o bom valor:
//    │     \____      depois dele, aumentar k quase não ajuda
//    └──────────── k

// 2. Inicialização ruim → mínimo local ruim
// Solução: k-means++ escolhe sementes iniciais bem espalhadas,
// e roda várias vezes guardando o melhor (menor inércia).

// Limitações: assume grupos esféricos e de tamanho parecido;
// sensível à escala das features (normalize antes!).
k-means não dá garantia de ótimo global: ele converge para um mínimo local da inércia, que depende da inicialização. Por isso, na prática roda-se várias vezes com sementes diferentes (k-means++) e guarda-se o melhor resultado. Também é importante normalizar as features — caso contrário, a feature de maior escala domina o cálculo de distância.
④ Projeto para programar

Agrupando dados de verdade

Mini projeto: implemente k-means do zero em Python/NumPy (atribuir + mover) e aplique a pontos 2D gerados em blobs (sklearn.datasets.make_blobs). Plote os grupos e os centroides a cada iteração e confirme que a inércia decresce monotonicamente.

Projeto principal: use k-means para compressão de imagem por quantização de cores: trate cada pixel como um ponto RGB (3D), agrupe em k=16 cores e substitua cada pixel pela cor do seu centroide. Compare a imagem com 16 cores vs. as originais 16 milhões — visualmente quase idêntica, com fração do tamanho. Plote a imagem reconstruída para k = 2, 4, 8, 16, 32.

Desafio extra: implemente o método do cotovelo automaticamente: rode k de 1 a 10, registre a inércia e detecte o "cotovelo" (maior variação de curvatura). Compare com o silhouette score, outra métrica de qualidade de cluster. Os dois concordam sobre o melhor k no seu dataset?

⑤ Exercícios rápidos

Teste sua intuição

Por que k-means é um algoritmo não-supervisionado?
Quais são os dois passos que o k-means alterna?
O que o resultado do k-means tem a ver com a inicialização?
⑥ Aplicações no mundo real

Onde você encontra isso

🎯

Segmentação de clientes

Empresas agrupam clientes por comportamento de compra (frequência, valor, recência) para personalizar marketing. Sem rótulos prévios, o k-means revela segmentos como "compradores frequentes de baixo valor" ou "esporádicos de alto valor", guiando campanhas distintas para cada grupo.

🖼️

Compressão e quantização de cores

Reduzir uma imagem de milhões de cores para uma paleta de k cores (formato GIF, por exemplo) é literalmente k-means no espaço RGB. Cada pixel é trocado pela cor do centroide do seu grupo — economia enorme de espaço com perda visual mínima.

🚨

Detecção de anomalias

Pontos que ficam longe de qualquer centroide (alta distância ao cluster mais próximo) são candidatos a anomalia: uma transação fraudulenta, um sensor com defeito, tráfego de rede suspeito. Clustering vira uma forma barata de sinalizar "isto não se parece com o normal".

← Anterior: Árvores de decisão Próxima: Redes neurais →