1
resposta

[Projeto] otimizando o resultado dos agrupamentos

import pandas as pd
import matplotlib.pyplot as plt
import joblib
import matplotlib.cm as cm
import numpy as np

from sklearn.preprocessing import OneHotEncoder, MinMaxScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score, silhouette_samples

1. Carregar e preparar os dados

url = 'https://raw.githubusercontent.com/alura-cursos/Clusterizacao-dados-sem-rotulo/main/Dados/dados_mkt.csv'
df = pd.read_csv(url)

encoder = OneHotEncoder(categories=[['F','M','NE']], sparse_output=False)
sexo = encoder.fit_transform(df[['sexo']])
sexo_df = pd.DataFrame(sexo, columns=encoder.get_feature_names_out(['sexo']))
dados = pd.concat([df, sexo_df], axis=1).drop('sexo', axis=1)

print(dados.describe())

2. Escalonar dados

scaler = MinMaxScaler()
dados_escalados = scaler.fit_transform(dados)
dados_escalados = pd.DataFrame(dados_escalados, columns=dados.columns)

print(dados_escalados.describe())

3. Salvar scaler

joblib.dump(scaler, 'scaler.pkl')

4. Função de avaliação

def avaliacao(dados):
inercia, silhueta = [], []
for k in range(2, 21):
modelo = KMeans(n_clusters=k, random_state=45, n_init='auto')
pred = modelo.fit_predict(dados)
inercia.append(modelo.inertia_)
silhueta.append(silhouette_score(dados, pred))
return silhueta, inercia

5. Gráfico de silhueta

def graf_silhueta(n_clusters, dados):
modelo = KMeans(n_clusters=n_clusters, random_state=45, n_init='auto')
pred = modelo.fit_predict(dados)
media = silhouette_score(dados, pred)
amostras = silhouette_samples(dados, pred)

fig, ax = plt.subplots(figsize=(8, 6))
ax.set_xlim([-0.1, 1])
ax.set_ylim([0, len(dados) + (n_clusters + 1) * 10])

y_lower = 10
for i in range(n_clusters):
    vals = amostras[pred == i]
    vals.sort()
    tam = vals.shape[0]
    y_upper = y_lower + tam
    cor = cm.nipy_spectral(float(i) / n_clusters)
    ax.fill_betweenx(np.arange(y_lower, y_upper), 0, vals, facecolor=cor, edgecolor=cor, alpha=0.7)
    ax.text(-0.05, y_lower + 0.5 * tam, str(i))
    y_lower = y_upper + 10

ax.axvline(x=media, color='red', linestyle='--')
ax.set_title(f'Silhueta para {n_clusters} clusters')
ax.set_xlabel('Coeficiente de silhueta')
ax.set_ylabel('Cluster')
ax.set_yticks([])
plt.show()

6. Método do cotovelo

def plot_cotovelo(inercia):
plt.figure(figsize=(8,4))
plt.plot(range(2, 21), inercia, 'bo-')
plt.xlabel('Número de clusters')
plt.ylabel('Inércia')
plt.title('Método do Cotovelo')
plt.show()

7. Avaliar dados escalados

silhueta, inercia = avaliacao(dados_escalados)
for k, s in enumerate(silhueta, start=2):
print(f'k={k} - silhueta={s:.4f}')

graf_silhueta(3, dados_escalados)
plot_cotovelo(inercia)

8. Treinar modelo final com k=3

modelo_kmeans = KMeans(n_clusters=3, random_state=45, n_init='auto')
modelo_kmeans.fit(dados_escalados)

9. Salvar modelo

joblib.dump(modelo_kmeans, 'kmeans.pkl')

print('Modelo e scaler salvos com sucesso.')

1 resposta

Olá, Moacir! Como vai?

Parabéns pela resolução da atividade!

Observei que você explorou o uso do MinMaxScaler para normalizar os dados com Python, utilizou muito bem o KMeans para realizar a clusterização e ainda compreendeu a importância das métricas como silhouette score e o método do cotovelo para avaliar a qualidade dos agrupamentos.

Continue postando as suas soluções, com certeza isso ajudará outros estudantes e tem grande relevância para o fórum.

Sugestão de conteúdo para você mergulhar ainda mais no tema:

Alguns materiais estão em inglês, mas é possível compreendê-los usando o recurso de tradução de páginas do próprio navegador.

Fico à disposição! E se precisar, conte sempre com o apoio do fórum.

Abraço e bons estudos!

AluraConte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!