-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Este projeto foi desenvolvido com o objetivo de responder à pergunta: Qual será a classificação de nota (GradeClass) de um aluno novo, dado seu perfil (por exemplo, idade, tempo de estudo semanal, faltas, etc.)? Utilizando um modelo de classificação. Os dados foram retirados da plataforma Kaggle, um repositório popular de datasets para análise de dados e aprendizado de máquina.
Variaveis presentes no dataset:
-
StudentID(EstudantesID): Indentificador exclusivo para cada aluno (1001 a 3392)
-
Detalhes demograficos
- Age/IDADE: A idade dos alunos variam de 15 a 18 anos
- Gender/Genero: Masculino e Feminino
- Ethnicity/Etinia: Tipos de etinia: Caucasian, African American, Asian, Other
- ParentalEducation/nivelEscolaridadePais: Nível de escolaridade dos pais, codificado da seguinte forma:
- None/nao tem
- High School/Ensino medio
- Some College/Alguma faculdade
- Bachelor's/Bacharelado
- Higher/Mais alto
-
Habitos de estudo
- StudyTimeWeekly: tempo de estudo semanal em horas
- Absences: Número de faltas durante o ano letivo, variando de 0 a 30.
- Tutoring: Status da tutoria, onde 0 indica Não e 1 indica Sim.
-
Envolvimento Parental
- ParentalSupport: nivel de apoio da familia
- Nenhum
- Baixo
- Moderado
- Alto
- Muito Alto
- ParentalSupport: nivel de apoio da familia
-
Atividades extrcurriculares
- Extracurricular: Participação em atividades extracurriculares
- Sports: participação em esportes
- Music: participação em atividades musicais
- Volunteering: possui particiação voluntária
-
Performance academica
- GPA: media de pontuação em uma escala de 2,0 a 4,0, influenciada por hábitos de estudo, envolvimento dos pais e atividades extracurriculares.
-
Variável alvo: classe de notas(GradeClass)
-
GradeClass: Classificação das notas dos alunos com base no GPA:
- 0: 'A' (GPA >= 3,5)
- 1: 'B' (3,0 <= GPA <3,5)
- 2: 'C' (2,5 <= GPA <3,0)
- 3: 'D' (2,0 <= GPA <2,5)
- 4: 'F' (GPA <2,0)
A pergunta que buscamos responder neste projeto é: Qual será a classificação de nota (GradeClass) de um aluno novo, dado seu perfil (por exemplo, idade, tempo de estudo semanal, faltas, etc.)?
Para fazer a instalação das bibliotecas foi necessário utilizar os seguintes comandos:
install.packages("class")
install.packages("corrplot")
install.packages("caret")
install.packages("C50")
install.packages("e1071")
install.packages("kernlab")
install.packages("mlbench")
Utilização das bibliotecas:
library(ggplot2) # visualização dos dados
library(dplyr) # Usado para as funções de filtro e tratamento de dados
library(reshape2) # Converter a matriz de correlação em um data frame
library(caret) # Usada para usar a função createDataPartition (partição dos dados)
library(corrplot) # Visualizar as variaveis correlacionadas
library(C50) # pacote para arvore de binaria (classificação)
library(class)# pacote para modelo KNN
library(e1071) # pacote para modelo naiveBayes
library(kernlab) # pacote para modelo SVM
library(mlbench) # pacote para modelo SVM
1) Coleta de Dados: Carregando os dados do arquivo do excel.
tabela = read.table("Student_performance_data.csv", sep = ";", dec = ",", header = TRUE)
2) Análise Exploratória dos Dados (EDA):
- Resumo estatisticos dos dados
summary(tabela)
- Visualização dos dados
Através do resumo estatístico é possível perceber que:
- idade: apesar de os alunos estarem entre 15 e 18 anos a média é 16
- A média do nível de educação dos pais é 1.74. Isso significa que todos possui ensino médio.
- A mediana é 2 que significa que os pais possuem também alguma faculdade. É possível perceber também que mais de 75% possui alguma faculdade, pois o nível 2 esta concentrado no terceiro quartil.
- As variáveis StudyTimeWeekly, GPA e GradeClass possuem valores muito discrepantes. O que pode ser necessário uma normalização das variáveis
- A variável Absences possui muitos números aleatórios. Isso poderia ser resolvido com uma escala de notas.
- A média de faltas é muita alta. Pois, 75% dos alunos tiveram 22 faltas
3) Pré-processamento dos Dados:
Para entender melhor a distribuição dos dados. Alguns passos serão seguidos nessa etapa.
- Identificar as variáveis numéricas e categóricas na base de dados
str(tabela)
É possível perceber que as variaveis: StudyTimeWeekly, GPA e GradeClass são do tipo caracter e as demais são do tipo inteiros
- Transformar as variáveis de caracteres para numéricas.
2.1) StudyTimeWeekly
Verificando valores únicos para entender melhor a natureza dos dados e identificar padrões de formatação ou possíveis erros nos dados. Utilizaremos a função unique.
unique(tabela$StudyTimeWeekly)
Limpeza dos dados
Remover pontos e transformar para numéricos.
tabela$StudyTimeWeekly <- gsub("\\.", "", tabela$StudyTimeWeekly) # Remove os pontos
tabela$StudyTimeWeekly <- as.numeric(tabela$StudyTimeWeekly) # Converte para numérico
Verificar e validar os dados
Verificar se a conversão foi bem sucedida
summary(tabela$StudyTimeWeekly) # Resumo estatístico da variavel
Observando o resultado é possível observar que os valores são extremamente grandes. Sendo assim, será necessário fazer uma normalização para ajustar os valores para um intervalo especifico. Neste caso será feito um Escalamento Logarítmico pois os dados seguem uma distribuição exponencial que pode ser útil para reduzir a dispersão.
Aplicar escalamento logarítmico à coluna StudyTimeWeekly
tabela$StudyTimeWeekly_log_scaled <- log(tabela$StudyTimeWeekly)
Visualizando o boxplot da variavel StudyTimeWeekly
ggplot(tabela, aes(y = StudyTimeWeekly_log_scaled)) +
geom_boxplot() +
labs(title = "StudyTimeWeekly", y = "") +
theme(plot.title = element_text(hjust = 0.5))
2.2) GPA
Verificando valores únicos
unique(tabela$GPA)
Limpeza dos dados
Remover pontos e transformar para numéricos
tabela$GPA <- gsub("\\.", "", tabela$GPA) # Remove os pontos
tabela$GPA <- as.numeric(tabela$GPA) # Converte para numérico
Verificar e validar os dados
Verificar se a conversão foi bem sucedida
summary(tabela$GPA) # Resumo estatístico da variavel
Aplicar escalamento logarítmico à coluna GPA
tabela$GPA_log_scaled <- log(tabela$GPA)
Visualizando o boxplot da variavel GPA
ggplot(tabela, aes(y = GPA_log_scaled)) +
geom_boxplot() +
labs(title = "GPA", y = "") +
theme(plot.title = element_text(hjust = 0.5))
Verificar resumo dos valores de GPA
summary(tabela$GPA_log_scaled)
É possível perceber que a média apresentou valor -inf. Isso significa que a presença desses valores afetou o calculo da media.
Resolver o Problema com Valores -Inf
Identificar os índices onde os valores são -Inf
indices_inf <- which(is.infinite(tabela$GPA_log_scaled))
Exibir os índices ou valores problemáticos
tabela$GPA_log_scaled[indices_inf]
Filtrando os valores -Inf
tabela_inf <- tabela %>%
filter(is.infinite(GPA_log_scaled))
Exibir o resultado
print(tabela_inf)
É possível perceber que somente 16 linhas contem o valor -Inf. Sendo assim, será necessário excluir esses valores.
Remover valores -Inf na coluna GPA_log_scaled
tabela_filtrada <- tabela %>%
filter(!is.infinite(GPA_log_scaled))
Removendo a coluna GPA
nova_tabela <- tabela_filtrada %>%
select(-GPA)
Removendo a coluna StudyTimeWeekly
nova_tabela <- nova_tabela %>%
select(-StudyTimeWeekly)
Renomeando variavel GPA_log_scaled
nova_tabela <- nova_tabela %>%
rename(GPA = GPA_log_scaled)
Renomeando variável StudyTimeWeekly
nova_tabela <- nova_tabela %>%
rename(StudyTimeWeekly = StudyTimeWeekly_log_scaled)
Como não vamos precisar do ID dos estudantes, também será removido da base de dados
Removendo a coluna StudentID
nova_tabela <- nova_tabela %>%
select(-StudentID)
2.3) GradeClass
Convertendo a coluna GradeClass para formato numérico
nova_tabela$GradeClass <- as.numeric(nova_tabela$GradeClass)
Verificar quantos valores foram convertidos para NA
sum(is.na(nova_tabela$GradeClass))
Verificar estatísticas descritivas
summary(nova_tabela$GradeClass)
- Análise de Correlação.
Verificar as variáveis correlacionada
correlation_matrix <- cor(nova_tabela)
Converter a matriz de correlação em um data frame
melted_correlation_matrix <- melt(correlation_matrix)
Transformar em formato de dados para visualização
melted_cor_matrix <- melt(cor_matrix)
Visualização de correlação entre as variáveis
library(ggplot2) # utilização da biblioteca de visualização
ggplot(data = melted_cor_matrix, aes(x = Var1, y = Var2, fill = value)) +
geom_tile() +
scale_fill_gradient2(low = "blue", high = "red", mid = "white", midpoint = 0,
limit = c(-1, 1), name = "Correlação") +
labs(title = "Matriz de Correlação") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1, margin = margin(t = 0.6, r = 0, b = 0, l = 0)),
axis.text.y = element_text(margin = margin(t = 0.6, r = 0, b = 0, l = 0))) +
coord_fixed()
Como podemos observar no gráfico acima, podemos observar que a variavel GradeClass é a mais correlacionada com o GPA em relação a outras variáveis.
4) Modelagem e Treinamento:
Divisão dos dados em conjuntos de treino e teste
Definindo a proporção de divisão
set.seed(123) # Definindo uma seed para reprodutibilidade
proporcao_treino <- 0.8
Criando uma partição estratégica
indice_treino <- createDataPartition(nova_tabela$GradeClass, p = proporcao_treino, list = FALSE)
Criando conjuntos de treinamento e teste
dados_treino <- nova_tabela[indice_treino, ]
dados_teste <- nova_tabela[-indice_treino, ]
Nessa próxima etapa é importante utilizar mais de um modelo de classificação para fazer a comparação. Sendo assim, foi escolhido os seguintes modelos: Árvore de classificação, KNN (K-Nearest Neighbours), Bayes (Naïve Bayes), SVM (Support Vector Machine)
4.1) Classificação
Separar as variáveis preditoras e a variável de resposta
Identificar o índice da coluna de resposta
response_col_index <- which(colnames(nova_tabela) == "GradeClass")
Separar as variáveis preditoras e a variável de resposta para os dados de treino
train_target <- dados_treino[, response_col_index] # Variável de resposta
train_features <- dados_treino[, -response_col_index] # Variáveis preditoras
Separar as variáveis preditoras e a variável de resposta para os dados de teste
test_target <- dados_teste[, response_col_index] # Variável de resposta
test_features <- dados_teste[, -response_col_index] # Variáveis preditoras
No R, um fator é usado para representar variáveis categóricas. Sendo assim, é necessario garantir que a variável de resposta seja tratada como um fator.
Convertendo a variável de resposta para fator
train_target <- factor(dados_treino[, response_col_index])
test_target <- factor(dados_teste[, response_col_index])
Criar o modelo de Árvore de classificação
c50_model <- C5.0(train_features, train_target)
Fazer previsões nos dados de teste
predictions_c50 <- predict(c50_model, test_features)
Avaliar o modelo Árvore binária
# Avaliar o desempenho
confusion_matrix_c50 <- table(predictions_c50, test_target)
# Convertendo a matriz de confusão para um data frame no formato long
confusion_df_matrix_c50 <- as.data.frame(as.table(confusion_matrix_c50))
# Renomeando as colunas
colnames(confusion_df_matrix_c50) <- c("Predicted", "Actual", "Count")
# Visualização matriz confusão
ggplot(confusion_df_matrix_c50, aes(x = Actual, y = Predicted, fill = Count)) +
geom_tile() +
scale_fill_gradient(low = "white", high = "blue") +
geom_text(aes(label = Count), color = "black") +
labs(title = "Matriz confusão Arvore binaria", x = "Actual", y = "Predicted") +
theme_minimal()
accuracy_c50 <- sum(diag(confusion_matrix_c50)) / sum(confusion_matrix_c50)
print(paste("Acurácia arvore:", accuracy_c50 * 100))
4.2) KNN (K-Nearest Neighbours)
Separar as características (features) e o alvo (target)
train_x <- dados_treino[, -response_col_index] # Todas as colunas exceto GradeClass
train_y <- dados_treino$GradeClass # Apenas a coluna GradeClass
test_x <- dados_teste[, -response_col_index] # Todas as colunas exceto GradeClass
test_y <- dados_teste$GradeClass # Apenas a coluna GradeClass
Ajustar o modelo KNN
k <- 5
predict_knn <- knn(train = train_x, test = test_x, cl = train_y, k = k)
Avaliar o modelo
# Avaliar o modelo
confusion_matrix_knn <- table(Predicted = predict_knn, Actual = test_y)
# Convertendo a matriz de confusão para um data frame no formato long
confusion_df_matrix_knn <- as.data.frame(as.table(confusion_matrix_knn))
# Renomeando as colunas
colnames(confusion_df_matrix_knn) <- c("Predicted", "Actual", "Count")
# Visualização matriz confusão
ggplot(confusion_df_matrix_knn, aes(x = Actual, y = Predicted, fill = Count)) +
geom_tile() +
scale_fill_gradient(low = "white", high = "blue") +
geom_text(aes(label = Count), color = "black") +
labs(title = "Matriz confusão KNN", x = "Actual", y = "Predicted") +
theme_minimal()
# Acuracia modelo KNN
accuracy_knn <- sum(diag(confusion_matrix_knn)) / sum(confusion_matrix_knn)
print(paste("Acurácia:", accuracy_knn * 100))
4.3) Bayes (Naïve Bayes)
Ajustar o modelo Naive Bayes
model <- naiveBayes(GradeClass ~ ., data = dados_treino)
Fazer previsões
predictions_bayes <- predict(model, dados_teste)
Avaliar o modelo
# Avaliar o modelo
confusion_matrix_bayes <- table(dados_teste$GradeClass, predictions_bayes)
# Convertendo a matriz de confusão para um data frame no formato long
confusion_df_matrix_bayes <- as.data.frame(as.table(confusion_matrix_bayes))
# Renomeando as colunas
colnames(confusion_df_matrix_bayes) <- c("Predicted", "Actual", "Count")
# Visualização matriz confusão
ggplot(confusion_df_matrix_bayes, aes(x = Actual, y = Predicted, fill = Count)) +
geom_tile() +
scale_fill_gradient(low = "white", high = "blue") +
geom_text(aes(label = Count), color = "black") +
labs(title = "Matriz confusão Bayes", x = "Actual", y = "Predicted") +
theme_minimal()
#Acuracia bayes
accuracy_bayes <- sum(diag(confusion_matrix_bayes)) / sum(confusion_matrix_bayes)
print(paste("Acurácia bayes:", accuracy_bayes * 100))
5) Avaliação do Modelo:
É possível perceber, segundo o gráfico, que o modelo de Árvore Binária apresentou a melhor acurácia, com um desempenho significativamente superior aos modelos k-NN e Bayes. Enquanto a Árvore Binária atingiu uma acurácia de aproximadamente 91,79%, os modelos k-NN e Bayes tiveram acurácias consideravelmente menores, em torno de 65,47% e 64,84%, respectivamente. Isso indica que, para este conjunto de dados, a Árvore Binária é a abordagem mais eficaz para a tarefa de classificação
- O modelo de classificação atingiu uma acurácia de 94% no conjunto de teste.
- Observando a acurácia é possivel perceber que a proporção de previsões corretas feitas pelo modelo em relação ao total de previsões foi de quase 100%.
- Ao inserir novos dados de novos alunos podemos concluir que o modelo será capaz de prever a classificação de alunos em grupos com 94% de acerto.
Para melhorar ainda mais este projeto, futuras análises podem incluir:
- Outras métrica como precisão, Precisão, Recall, F1-Score, entre outras.