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.')