Agrupamento de Estresse Acadêmico com K-Means
Exploração dos Dados
A base StressExp.csv contém 280 registros e 9 colunas.
As variáveis são relacionadas ao perfil acadêmico dos alunos, pressões percebidas, ambiente de estudo e hábitos.
- AcademicStage: Nível acadêmico do respondente.
- PeerPressure: Pressão dos colegas (escala 1–5).
- HomePressure: Pressão da família (escala 1–5).
- StudyEnv: Ambiente de estudo (Peaceful, Noisy, Disrupted).
- Strategy: Estratégias de enfrentamento.
- BadHabits: Maus hábitos (Sim/Não).
- AcademicComp: Competição acadêmica (escala 1–5).
- Stress: Nível de estresse (1–5). Usado apenas como validação externa.
| AcademicStage | PeerPressure | HomePressure | StudyEnv | Strategy | BadHabits | AcademicComp | Stress |
|---|---|---|---|---|---|---|---|
| undergraduate | 4 | 5 | Noisy | Analyze the situation and handle it with intellect | No | 3 | 5 |
| undergraduate | 3 | 4 | Peaceful | Analyze the situation and handle it with intellect | No | 3 | 3 |
| undergraduate | 1 | 1 | Peaceful | Social support (friends, family) | No | 2 | 4 |
| undergraduate | 3 | 2 | Peaceful | Analyze the situation and handle it with intellect | No | 4 | 3 |
| undergraduate | 3 | 3 | Peaceful | Analyze the situation and handle it with intellect | No | 4 | 5 |
Pré-processamento
- A coluna Timestamp foi removida por não agregar informação.
- A variável StudyEnv apresentava 1 valor nulo, que foi preenchido com a moda (Peaceful).
- Variáveis categóricas (AcademicStage, StudyEnv, Strategy, BadHabits) foram convertidas em valores numéricos via Label Encoding.
- A variável Stress foi removida das features para o K-Means, sendo utilizada apenas na avaliação posterior.
- As features numéricas foram padronizadas com
StandardScalerpara garantir que todas tenham a mesma escala.
Clustering K-Means
O modelo K-Means foi configurado com:
- k = 5 clusters (escolhido por corresponder à escala de estresse 1–5).
- Inicialização: k-means++.
- Máximo de 100 iterações, random_state=42, n_init=10.
Resultados do Treinamento
- Inércia (WCSS): 1218.72
- Silhouette Score: 0.19 → Indica que os clusters estão pouco separados e há sobreposição entre grupos.
Visualização (PCA 2D)
Os dados foram reduzidos para 2 dimensões com PCA apenas para visualização:
import numpy as np
import matplotlib.pyplot as plt
from io import StringIO
from sklearn.preprocessing import LabelEncoder
from sklearn.cluster import KMeans
import pandas as pd
plt.figure(figsize=(12, 10))
# Preprocess the data
def preprocess(df: pd.DataFrame) -> pd.DataFrame:
# remocao da coluna Timestamp
df = df.drop(columns=['Timestamp'])
# Tratamento de missing values
## 'Study Environment' tem 1 valor ausente -> preenchid com a moda (valor mais frequente)
df['StudyEnv'].fillna(df['StudyEnv'].mode()[0], inplace=True)
#conversao de variaveis categoricas
label_encoder = LabelEncoder()
df['AcademicStage'] = label_encoder.fit_transform(df['AcademicStage'])
df['StudyEnv'] = label_encoder.fit_transform(df['StudyEnv'])
df['Strategy'] = label_encoder.fit_transform(df['Strategy'])
df['BadHabits'] = label_encoder.fit_transform(df['BadHabits'])
# Selecao de features
features = [
'AcademicStage',
'PeerPressure',
'HomePressure',
'StudyEnv',
'Strategy',
'BadHabits',
'AcademicComp'
]
return df[features]
# Carregar base
df = pd.read_csv('https://raw.githubusercontent.com/tigasparzin/Machine-Learning/refs/heads/main/data/StressExp.csv')
X = preprocess(df)
#run Kmeans
kmeans = KMeans(n_clusters=5, init='k-means++', max_iter=100, random_state=42)
labels = kmeans.fit_predict(X)
#Plot
plt.scatter(X.iloc[:, 0], X.iloc[:, 1], c=labels, cmap='viridis', s=50)
cent = kmeans.cluster_centers_
plt.scatter(cent[:, 0], cent[:, 1], c='red', marker='*', s=200, label='Centroids')
plt.title('K-Means Clustering Results')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.legend()
# # Print centroids and inertia
# print("Final centroids:", kmeans.cluster_centers_)
# print("Inertia (WCSS):", kmeans.inertia_)
# # Display the plot
buffer = StringIO()
plt.savefig(buffer, format="svg", transparent=True)
print(buffer.getvalue())
Avaliação dos Clusters
A variável Stress foi usada para verificar como os clusters se alinham com os níveis reais de estresse.
Tabela cruzada (Stress x Cluster):
| Stress | Cluster 0 | Cluster 1 | Cluster 2 | Cluster 3 | Cluster 4 |
|---|---|---|---|---|---|
| 1 | 13 | 6 | 9 | 7 | 21 |
| 2 | 11 | 7 | 19 | 5 | 14 |
| 3 | 3 | 26 | 8 | 15 | 4 |
| 4 | 3 | 33 | 8 | 11 | 1 |
| 5 | 9 | 30 | 3 | 13 | 1 |
Observa-se que os clusters não correspondem diretamente aos níveis de estresse, com forte sobreposição entre as classes.
Conclusão
- O K-Means não conseguiu separar claramente os grupos de alunos de acordo com o nível de estresse.
- O Silhouette Score baixo (0.19) confirma que os clusters são pouco distintos.
- Cada cluster mistura diferentes valores de estresse, mostrando que o algoritmo está agrupando mais por perfil geral (estágio acadêmico, hábitos, ambiente) do que pelo nível de estresse em si.
- A análise é válida para identificar padrões de perfis semelhantes, mas não substitui modelos supervisionados como o KNN.
Recomendações
- Testar diferentes valores de k (método do cotovelo, silhouette).
- Normalizar e/ou reduzir dimensionalidade antes do clustering (ex.: PCA completo).
- Usar
Stressapenas como validação externa, não como feature no clustering. - Considerar outras técnicas de clusterização (ex.: DBSCAN, Agglomerative Clustering) para comparação.