K-Means
Introdução
O algoritmo K-Means foi aplicado com o objetivo de identificar padrões e agrupar os candidatos ao MBA em clusters com características semelhantes. Diferente dos métodos supervisionados, como a árvore de decisão e o KNN, o K-Means é um algoritmo de aprendizado não supervisionado, que organiza os dados em grupos de acordo com a proximidade entre seus atributos, sem utilizar diretamente a variável de admissão como guia. Dessa forma, é possível verificar se os agrupamentos formados se aproximam das categorias reais de admissão (Admit, Waitlist e Deny), oferecendo uma perspectiva complementar sobre como os perfis acadêmicos e profissionais dos candidatos se distribuem na base de dados.
Base de dados
A base utilizada é composta por dados sintéticos criados a partir das estatísticas da turma de 2025 do MBA de Wharton. Ela reúne informações demográficas, acadêmicas e profissionais de candidatos, como gênero, nacionalidade, área de formação, desempenho no GPA e no GMAT, além de experiência de trabalho e setor de atuação. Esses atributos foram relacionados ao status final da candidatura, categorizado como admitido, em lista de espera ou negado. Por se tratar de um conjunto de dados diversificado, é possível observar tanto os aspectos objetivos ligados ao desempenho acadêmico e profissional quanto elementos contextuais que podem influenciar o resultado do processo seletivo. Essa combinação torna o dataset especialmente relevante para análises exploratórias e para o desenvolvimento de modelos preditivos que buscam compreender os critérios implícitos de seleção em admissões de MBA.
A variável gênero apresenta uma diferença significativa na quantidade de aplicações. Observa-se uma predominância de candidatos do sexo masculino em comparação às candidatas do sexo feminino, o que indica uma distribuição desigual nesse aspecto. Essa discrepância pode refletir tendências do mercado de MBA ou características específicas da base gerada. Além disso, é um fator importante a ser considerado no modelo, já que possíveis vieses de gênero podem influenciar tanto a análise quanto as previsões de admissão.
A variável alunos internacionais mostra que a maior parte das aplicações é de candidatos domésticos (não internacionais), enquanto os estudantes internacionais representam uma parcela menor do total. Essa diferença pode indicar que os programas de MBA ainda têm maior procura local, embora o número de aplicações internacionais seja relevante para demonstrar a diversidade e a atratividade global da instituição. Essa característica pode influenciar o modelo de predição, visto que fatores como origem do aluno podem estar relacionados às taxas de aceitação.
A variável GPA apresenta distribuição concentrada em torno de valores relativamente altos, entre 3.1 e 3.3, o que indica que a maior parte dos candidatos possui desempenho acadêmico consistente. A mediana situa-se pouco acima de 3.2, reforçando esse padrão. Observa-se ainda a presença de alguns valores atípicos, tanto abaixo de 2.8 quanto acima de 3.6, que representam candidatos com desempenho fora do perfil predominante. Esses outliers, embora pouco frequentes, podem influenciar a análise estatística e devem ser considerados no pré-processamento ou na interpretação dos resultados do modelo. De forma geral, a distribuição do GPA sugere que a base é composta majoritariamente por candidatos academicamente fortes, o que pode ser um dos critérios determinantes no processo de admissão.
A variável major, que representa a área de formação acadêmica dos candidatos, apresenta distribuição relativamente equilibrada entre as categorias, mas com destaque para Humanidades, que concentra o maior número de aplicações. As áreas de STEM e Business aparecem em proporções semelhantes, ambas com menor participação em relação a Humanidades. Essa diferença pode refletir o perfil da amostra, indicando maior procura de candidatos oriundos de cursos de Humanidades pelos programas de MBA. A análise dessa variável é relevante para verificar se determinadas formações acadêmicas têm maior representatividade ou desempenham papel diferenciado nos resultados de admissão.
A variável raça apresenta distribuição diversificada entre os candidatos, com destaque para a categoria de pessoas que preferiram não se identificar, seguida pelo grupo White. Em seguida aparecem Asian, Black e Hispanic, enquanto a categoria Other concentra a menor quantidade de aplicações. Essa composição evidencia tanto a representatividade de diferentes origens raciais quanto a limitação do campo para candidatos internacionais. A análise dessa variável é importante para compreender a diversidade do conjunto de dados e avaliar se há possíveis diferenças de perfil que podem influenciar nos resultados de admissão.
A variável GMAT apresenta uma distribuição concentrada entre 600 e 700 pontos, faixa onde se encontra a maior parte dos candidatos. O pico de frequência ocorre próximo de 650 pontos, o que sugere que esse valor é representativo do desempenho médio dos aplicantes. Apesar dessa concentração, também há candidatos com pontuações mais baixas, em torno de 570, bem como outros que alcançam notas elevadas acima de 750, embora em menor quantidade. Essa distribuição indica que, em geral, os candidatos possuem desempenho sólido no exame, mas com variação suficiente para permitir que o modelo identifique padrões relacionados ao status de admissão.
A variável experiência profissional apresenta distribuição concentrada entre 4 e 6 anos de atuação no mercado, com destaque para os candidatos que possuem 5 anos de experiência, que representam a maior parte das aplicações. Os extremos da distribuição, com candidatos que possuem apenas 1 ou 2 anos de experiência e aqueles com mais de 7 anos, aparecem em menor número, configurando perfis menos frequentes na amostra. Esse padrão sugere que a base de dados está composta principalmente por profissionais em estágio intermediário de carreira, o que reflete o perfil típico de aplicantes a programas de MBA. Essa variável é particularmente relevante, pois pode influenciar diretamente nas chances de admissão, uma vez que a experiência prática é um critério valorizado nas seleções.
A variável setor de experiência profissional revela que a maior parte dos candidatos possui trajetória em Consultoria, que se destaca amplamente em relação aos demais setores. Em seguida aparecem PE/VC (Private Equity e Venture Capital), Tecnologia e setores ligados ao serviço público ou organizações sem fins lucrativos, todos com participação significativa. Áreas tradicionais como Investment Banking e Financial Services também se mostram relevantes, mas em menor proporção. Já setores como Saúde, Bens de Consumo (CPG), Mídia/Entretenimento, Varejo, Imobiliário e Energia aparecem de forma mais restrita, representando nichos específicos da amostra. Essa distribuição indica que o MBA atrai predominantemente profissionais de consultoria e finanças, mas também apresenta diversidade ao incluir candidatos de áreas emergentes e de setores menos tradicionais.
Pré-Processamento
Com base na análise exploratória realizada, foram definidos e aplicados procedimentos de pré-processamento a fim de adequar os dados para a etapa de modelagem. As principais etapas conduzidas incluem:
- Tratamento de valores ausentes:na variável admission, valores nulos foram interpretados como recusa e substituídos por Deny. Já na variável race, os valores ausentes foram preenchidos como Unknown, garantindo a consistência da base.
- Codificação de variáveis categóricas: colunas como gender, international, major, race, work_industry e admission foram convertidas em variáveis numéricas por meio do método LabelEncoder, possibilitando sua utilização pelo modelo de árvore de decisão.
- Imputação em variáveis numéricas: atributos como gpa, gmat e work_exp tiveram seus valores ausentes substituídos pela mediana, minimizando a influência de outliers e preservando a distribuição original dos dados.
- Seleção de variáveis: foram mantidas no conjunto de treino apenas as colunas relevantes para a análise preditiva, enquanto identificadores como application_id foram descartados por não possuírem valor analítico.
- Separação entre features e target: as variáveis explicativas (X) foram definidas a partir das características acadêmicas, demográficas e profissionais dos candidatos, enquanto a variável alvo (y) corresponde ao status de admission.
- Divisão em treino e teste: o conjunto de dados foi dividido em duas partes, com 80% para treino e 20% para teste, garantindo estratificação da variável alvo para preservar a proporção entre as classes.
| application_id | gender | international | gpa | major | race | gmat | work_exp | work_industry | admission |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Female | False | 3.3 | Business | Asian | 620 | 3 | Financial Services | Admit |
| 2 | Male | False | 3.28 | Humanities | Black | 680 | 5 | Investment Management | nan |
| 3 | Female | True | 3.3 | Business | nan | 710 | 5 | Technology | Admit |
| 4 | Male | False | 3.47 | STEM | Black | 690 | 6 | Technology | nan |
| 5 | Male | False | 3.35 | STEM | Hispanic | 590 | 5 | Consulting | nan |
| 6 | Male | False | 3.18 | Business | White | 610 | 6 | Consulting | nan |
| 7 | Female | False | 2.93 | STEM | Other | 590 | 3 | Technology | Admit |
| 8 | Male | True | 3.02 | Business | nan | 630 | 6 | Financial Services | nan |
| 9 | Male | False | 3.24 | Business | White | 590 | 2 | Nonprofit/Gov | nan |
| 10 | Male | False | 3.27 | Humanities | Asian | 690 | 3 | Consulting | nan |
| 11 | Male | False | 3.05 | Humanities | White | 580 | 5 | Technology | nan |
| 12 | Male | True | 2.85 | Humanities | nan | 580 | 4 | PE/VC | nan |
| 13 | Female | False | 3.24 | Humanities | Hispanic | 640 | 6 | PE/VC | Waitlist |
| 14 | Female | False | 3.39 | Business | Black | 690 | 4 | Nonprofit/Gov | nan |
| 15 | Female | False | 3.03 | STEM | White | 600 | 5 | Technology | Admit |
| 16 | Female | True | 3.05 | Humanities | nan | 710 | 4 | Consulting | Admit |
| 17 | Female | False | 3.32 | Business | Asian | 710 | 5 | PE/VC | Admit |
| 18 | Male | False | 3.23 | Humanities | Black | 700 | 4 | Health Care | nan |
| 19 | Male | False | 3.13 | Humanities | White | 630 | 6 | Financial Services | nan |
| 20 | Male | True | 3.09 | Business | nan | 670 | 8 | Consulting | nan |
| gender | international | gpa | major | race | gmat | work_exp | work_industry | admission |
|---|---|---|---|---|---|---|---|---|
| 1 | 0 | 3.48 | 1 | 5 | 630 | 5 | 8 | 0 |
| 1 | 0 | 3.27 | 0 | 5 | 610 | 6 | 10 | 0 |
| 1 | 0 | 3.31 | 2 | 0 | 670 | 6 | 8 | 0 |
| 1 | 1 | 3.29 | 1 | 4 | 660 | 5 | 10 | 0 |
| 1 | 1 | 3.02 | 2 | 4 | 570 | 3 | 10 | 0 |
| 1 | 0 | 3.4 | 1 | 0 | 710 | 4 | 13 | 0 |
| 0 | 0 | 3.23 | 0 | 0 | 670 | 7 | 9 | 0 |
| 1 | 0 | 3.36 | 2 | 1 | 700 | 5 | 10 | 2 |
| 0 | 0 | 3.36 | 1 | 1 | 670 | 4 | 6 | 2 |
| 1 | 0 | 3.29 | 0 | 5 | 620 | 6 | 1 | 0 |
| 1 | 1 | 3.4 | 2 | 4 | 580 | 5 | 1 | 0 |
| 0 | 0 | 3.21 | 1 | 2 | 580 | 5 | 1 | 0 |
| 1 | 1 | 3.06 | 0 | 4 | 640 | 4 | 1 | 0 |
| 0 | 0 | 3.2 | 1 | 2 | 630 | 6 | 1 | 0 |
| 1 | 0 | 3.25 | 2 | 0 | 610 | 5 | 6 | 0 |
| 1 | 0 | 3.27 | 2 | 1 | 630 | 6 | 1 | 0 |
| 1 | 1 | 3.01 | 0 | 4 | 610 | 6 | 13 | 0 |
| 1 | 1 | 3.15 | 0 | 4 | 620 | 6 | 10 | 0 |
| 0 | 0 | 2.93 | 1 | 2 | 580 | 5 | 0 | 0 |
| 1 | 1 | 3.25 | 0 | 4 | 570 | 6 | 8 | 0 |
Divisão dos Dados
Diferentemente dos modelos supervisionados, em que é necessário separar os dados em conjuntos de treino e teste, o algoritmo K-Means segue uma abordagem não supervisionada. Isso significa que ele não utiliza diretamente a variável-alvo admission durante o processo de agrupamento, mas sim apenas as variáveis explicativas (gpa, gmat, work_exp, gender, international, major, race, work_industry).
Nesse contexto, todos os dados disponíveis foram utilizados para a aplicação do K-Means, de forma a identificar agrupamentos naturais dentro da base. A variável admission foi mantida apenas como referência, sendo utilizada posteriormente para comparar os clusters formados pelo modelo com as categorias reais de decisão (Admit, Waitlist e Deny). Essa estratégia permite avaliar se os grupos encontrados refletem, ao menos parcialmente, os padrões de admissão presentes no conjunto de candidatos.
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score, adjusted_rand_score
df = pd.read_csv("./src/MBA.csv")
df["admission"] = df["admission"].fillna("Deny")
y = df["admission"].map({"Deny":0, "Waitlist":1, "Admit":2}).astype(int)
df["race"] = df["race"].fillna("Unknown")
num_cols = ["gpa", "gmat", "work_exp"]
for c in num_cols:
df[c] = pd.to_numeric(df[c], errors="coerce").fillna(df[c].median())
cat_cols = ["gender","international","major","race","work_industry"]
X_cat = pd.get_dummies(df[cat_cols].astype(str).apply(lambda s: s.str.strip()),
drop_first=False, dtype=int)
X_num = df[num_cols].copy()
scaler = StandardScaler()
X_num[num_cols] = scaler.fit_transform(X_num[num_cols])
X = pd.concat([X_num, X_cat], axis=1).values
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
sil = silhouette_score(X, labels)
ari = adjusted_rand_score(y, labels)
print(f"Silhouette: {sil:.3f} | ARI: {ari:.3f}")
Treinamento do Modelo
Silhouette Score: 0.1321 Inertia (WCSS): 29246.49 Variância explicada PCA por componente: [0.25495582 0.16156017] Variância explicada acumulada (PCA 2D): 0.4165 [SALVO] Artefatos K-Means em docs/k-means/artifacts/kmeans_artifacts.pkl
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from io import StringIO
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score # <-- métrica adicionada
plt.figure(figsize=(12, 10))
# --- Carregar e preparar a base ---
df = pd.read_csv("./src/MBA.csv")
df["admission"] = df["admission"].fillna("Deny")
df["race"] = df["race"].fillna("Unknown")
adm_map = {"Deny": 0, "Waitlist": 1, "Admit": 2}
y = df["admission"].map(adm_map).astype(int)
num_cols = ["gpa", "gmat", "work_exp"]
for c in num_cols:
df[c] = pd.to_numeric(df[c], errors="coerce").fillna(df[c].median())
cat_cols = ["gender", "international", "major", "race", "work_industry"]
X_cat = pd.get_dummies(
df[cat_cols].astype(str).apply(lambda s: s.str.strip()),
drop_first=False, dtype=int
)
scaler = StandardScaler()
X_num = df[num_cols].copy()
X_num[num_cols] = scaler.fit_transform(X_num[num_cols])
X = pd.concat([X_num, X_cat], axis=1).values
# --- Treinamento do K-Means ---
kmeans = KMeans(n_clusters=3, init='k-means++', max_iter=100,
random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
# --- Métricas de avaliação (sem rótulos verdadeiros) ---
# 1) Silhouette Score (quanto maior, melhor; faixa [-1, 1])
sil_score = silhouette_score(X, labels)
# 2) Inertia (WCSS) - soma das distâncias quadráticas aos centróides (quanto menor, melhor)
inertia = kmeans.inertia_
# --- PCA apenas para visualização em 2D ---
pca = PCA(n_components=2, random_state=42)
X_2d = pca.fit_transform(X)
# Variância explicada pelo PCA (útil para relatar quanta info o 2D preserva)
explained = pca.explained_variance_ratio_
explained_total = explained.sum()
# Projetar centróides para o espaço 2D do PCA
centers_2d = pca.transform(kmeans.cluster_centers_)
# --- Gráfico ---
plt.scatter(X_2d[:, 0], X_2d[:, 1], c=labels, cmap='viridis', s=50)
plt.scatter(centers_2d[:, 0], centers_2d[:, 1],
c='red', marker='*', s=200, label='Centroids (PCA proj.)')
plt.title('K-Means Clustering (MBA Dataset)')
plt.xlabel(f'PCA 1 ({explained[0]*100:.1f}% var.)')
plt.ylabel(f'PCA 2 ({explained[1]*100:.1f}% var.)')
plt.legend()
# --- Impressões das métricas ---
print(f"Silhouette Score: {sil_score:.4f}")
print(f"Inertia (WCSS): {inertia:.2f}")
print(f"Variância explicada PCA por componente: {explained}")
print(f"Variância explicada acumulada (PCA 2D): {explained_total:.4f}")
# Exportar o SVG do gráfico (para embutir em página)
buffer = StringIO()
plt.savefig(buffer, format="svg", transparent=True)
print(buffer.getvalue())
# --- Fim do código ---
labels = kmeans.fit_predict(X)
# (se usar treino/teste, troque X por X_train / y por y_train)
# --- salvar artefatos do K-Means ---
import os, joblib
ART = "docs/k-means/artifacts"
os.makedirs(ART, exist_ok=True)
joblib.dump(
{
"kmeans": kmeans,
"X": X,
"y": y, # rótulo "admission" codificado (0/1/2)
"labels": labels,
"silhouette": sil_score,
"inertia": inertia,
"pca_2d": X_2d,
"centers_2d": centers_2d,
"explained": explained,
},
f"{ART}/kmeans_artifacts.pkl"
)
print(f"[SALVO] Artefatos K-Means em {ART}/kmeans_artifacts.pkl")
Avaliação do Modelo
O modelo K-Means foi avaliado a partir de métricas internas e da projeção bidimensional via PCA. O Silhouette Score obtido foi de 0,1321, valor considerado baixo, o que indica que os clusters apresentam pouca coesão interna e significativa sobreposição entre si. Esse resultado sugere que o algoritmo não conseguiu separar os candidatos em grupos bem distintos, o que é esperado em bases com variáveis heterogêneas (numéricas e categóricas transformadas).
A inércia (WCSS) resultou em 29.246,49, medida que representa a soma das distâncias quadráticas dos pontos aos centróides de seus clusters. Embora esse valor seja elevado, ele é útil principalmente para comparação em diferentes valores de k (método do cotovelo), a fim de identificar se a escolha de três clusters (correspondente às categorias Admit, Waitlist e Deny) é adequada ou se um número alternativo de grupos produziria melhor ajuste.
Na projeção em duas dimensões por meio do PCA, os dois primeiros componentes explicaram apenas 41,65% da variância total dos dados, evidenciando que o gráfico utilizado para visualização perde mais da metade da informação original da base. Isso significa que a separação observada nos clusters no plano bidimensional não reflete plenamente a estrutura em alta dimensão.
De modo geral, os resultados sugerem que, embora o K-Means consiga estruturar a base em agrupamentos, a definição dos clusters é fraca, o que limita sua capacidade de representar com precisão as categorias reais de admissão. Ainda assim, o modelo oferece uma visão exploratória útil, especialmente se complementado por testes com outros valores de k e pela comparação com métodos supervisionados.
Conclusão
A aplicação do algoritmo K-Means na base MBA permitiu identificar padrões e agrupar candidatos de acordo com suas características acadêmicas e profissionais. Apesar da sobreposição entre alguns clusters, a análise mostrou que o modelo conseguiu segmentar o conjunto de dados em grupos distintos, oferecendo uma visão exploratória útil sobre os perfis existentes. Dessa forma, o K-Means se mostrou uma ferramenta complementar para entender melhor a estrutura dos dados e apoiar futuras análises preditivas.