Nessa análise construíremos modelos preditivos de regressão para predição do CRA (Coeficiente de Rendimento Acadêmico) baseado nas notas obtidas nas disciplinas do primeiro e do segundo período dos alunos de Ciência da Computação - UFCG.
Bibliotecas utilizadas
library(dplyr)
library(reshape2)
library(ggplot2)
library(corrplot)
library(caret)
library(leaps)
library(h2o)
Recebemos os dataset já separados em treino e test.
graduados.train <- read.csv("dados/graduados_treino.csv")
graduados.validation <- read.csv("dados/graduados_teste.csv")
graduados.test <- read.csv("dados/test.csv")
Um preprocessamento nos dados foi necessário, antes de iniciarmos nossa análise. Foi preciso calcular o CRA dos alunos e selecionar apenas as disciplinas referentes ao primeiro e segundo perído do curso. Após o processamento nossos dados ficaram no seguinte formato:
Após processarmos os dados tivemos que fazer mais algumas alterações para os dados ficassem no formato necessário para criar os modelos. Os atributos dos dados ficaram sendo as disciplinas e a última coluna como sendo a variável alvo. As linhas são as notas dos alunos, a matrícula foi removida devido a confidencialidade dos dados.
head(train)
## matricula C1 Vetorial LPT P1 IC
## 1 002b348d3bc88b68aa6ebd24cfc9d6a0 8.700000 8.000000 8.400000 5.600000 7.5
## 2 007961bf3929ae353c8585e6c09df369 7.600000 7.100000 7.700000 6.700000 8.5
## 3 00960ff73dd29b59f4432072c2219c04 8.500000 7.300000 7.500000 7.000000 5.6
## 4 00b6f55e3639c9d3b835751a39ca6309 7.766667 7.766667 7.766667 7.766667 7.3
## 5 00eb58fa89c562efda118e64efab77a5 6.300000 6.800000 8.600000 5.500000 7.0
## 6 01fc383ae2c2cb3e69d844272a5ecac0 8.800000 9.100000 9.500000 6.600000 5.9
## LP1 C2 Discreta P2 Grafos Fisica LP2 CRA
## 1 9.100000 8.109877 9.200000 7.700000 7.200000 9.600000 8.600000 8.109877
## 2 8.600000 6.975824 5.000000 5.700000 7.000000 7.800000 8.000000 6.975824
## 3 6.500000 6.057282 5.300000 5.600000 7.900000 7.000000 8.100000 6.057282
## 4 7.766667 7.200000 7.766667 7.766667 7.766667 7.766667 7.766667 7.766667
## 5 7.400000 7.693827 6.700000 7.900000 6.100000 7.100000 9.000000 7.693827
## 6 8.300000 6.722892 6.100000 6.800000 5.300000 7.300000 9.000000 6.722892
Antes de iniciarmos nossa análise vamos observar a correlação das variáveis em relação a variável alvo.
#calculando matriz de correlação
correlationMatrix <- cor(train %>% select(-matricula))
#utlizamos a bibliota corrplot para montar o gráfico com as correlações
corrplot(correlationMatrix, method="circle", type="lower", order="hclust", addCoef.col = "black")
Vemos que a disciplina de cálculo 2, LPT e matemática discreta são as disciplinas que possuem correlação mais alta com o CRA do aluno.
Vamos agora para nossa análise preditiva, para isso vamos seguir os passos descritos abaixo:
Para a criação do modelo utilizei o pacote h2o, por se tratar de um open-source software para big-data analysis. O h2o é bastante rápido e flexível, podendo assim ser possível carregar uma grande quantidade de dados. Faz parte de uma comunidade que vem crescendo cada dia mais.
Inicialmente iremos criar 3 modelos básicos onde cada modelo será de um algoritmo diferente. Iremos utilizar:
O nosso objetivo nessa etapa é encontrar o melhor modelo para o nosso problema sem utilizar nenhum tipo de pre processamento, transformação, criação de features. Depois de encontrado o melhor modelo iremos aplicar todo o pre processamento já feito, transformação de variáveis, etc. Com o objetivo final de deixar o modelo ainda melhor.
Vamos inicialmente trabalhar com os modelos GBM, Random Florest e Deep Learning. O ideal seria inicialmente rodar todos os modelos com um grande número de árvores, grande profundidade e uma taxa de aprendizado pequena por interação.
conn <- h2o.init(nthreads = -1)
dados.treino <- h2o.importFile("dados/dados_treino.csv")
dados.validacao <- h2o.importFile("dados/dados_validacao.csv")
dados.teste <- h2o.importFile("dados/test.csv")
# Coluna que se deseja prever
myY <- "CRA"
# Coluna que deve ser ignorada pelo modelo
ignored_columns <- c("CRA", "matricula")
myX <- setdiff(setdiff(names(dados.treino), myY), ignored_columns)
# GBM
gbm <- h2o.gbm(x = myX, build_tree_one_node = T,
y = myY,
training_frame = dados.treino,
validation_frame = dados.validacao,
ntrees = 50,
max_depth = 6,
learn_rate = 0.1)
# DRF
drf <- h2o.randomForest(x = myX,
y = myY,
training_frame = dados.treino,
validation_frame = dados.validacao,
ntrees = 50,
max_depth = 30)
# Deep Learning
dlearning.model <- h2o.deeplearning(
x = myX,
y = myY,
training_frame = dados.treino,
validation_frame = dados.validacao,
epoch = 60,
hidden = c(100,100),
activation = "Rectifier",
seed = 1122
)
# Score de cada modelo
trainr2.gbm <- h2o.r2(gbm)
testr2.gbm <- h2o.r2(gbm, valid = TRUE)
trainr2.drf <- h2o.r2(drf)
testr2.drf <- h2o.r2(drf, valid = TRUE)
trainr2.dlearning.model <- h2o.r2(dlearning.model)
testr2.dlearning.model <- h2o.r2(dlearning.model, valid = TRUE)
toPlot <- data.frame(Rsquared = c(trainr2.gbm, testr2.gbm, trainr2.drf, testr2.drf, trainr2.dlearning.model, testr2.dlearning.model),
tipo = c("treino", "validacao", "treino", "validacao", "treino", "validacao"),
modelo = c("GBM","GBM","RF", "RF","DL", "DL"))
Para verificar qual dos 3 modelos é o melhor, utilizamos a métrica Rsquared, onde o valor do Rsquared (entre 0 e 1) é o percentual de variância explicada pelo o modelo. Na regressão, o Rsquared é uma medida estatística de quão bem a linha de regressão aproxima os pontos de dados reais. Um Rsquared igual a 1 indica que a linha de regressão encaixa perfeitamente os dados. Quanto maior foi o Rsquared melhor é o modelo.
ggplot(data=toPlot, aes(x = modelo, y = Rsquared, fill = tipo)) +
geom_bar(stat="identity", position=position_dodge()) +
theme_classic() +
labs(title = "Comparando os modelos") +
theme(axis.ticks = element_blank())
É possível notar que o DL (Deep Learning Model) teve um melhor resultado do que os outros modelos, obtendo assim um Rsquared maior. Por esse motivo optamos por escolher o modelo DL para realizar a predição. Porém antes de realizar a predição vamos tentar melhorar ainda mais esse modelo utilizando várias estratégias.
Ao analisar o gráfico de evolução do treino (linha azul) e da validação (linha laranja), percebemos que entre as épocas 45 e 50 o modelo começa ter um comportamento inverso, a validação começa a ter um melhor resultado que o treino, concluímos que a partir da época 47 o modelo apresenta uma taxa de aprendizagem melhor.
Como o DL é uma rede neural a capacidade de extrair características fortes para o modelo fica limitada, com o pacote H2O é possível extrair a importância das variáveis do modelo. Nosso trashold para selecionar as variáveis mais importantes para o modelo, foi seu valor na escala de importância que os modelos nos fornecem, o valor foi > 0.9. Portanto, comparando os resultados dos Random Forest, GBM e DL as variáveis mais importantes para o modelo são: C2, LPT, IC, P1 e C1.
Depois de escolhido o modelo vamos prepara os dados do teste.
# Realizando a predição
predicao = h2o.predict(object = dlearning.model, newdata = dados.teste)
h2o.exportFile(predicao, path = "dados/predicao2.csv", force = TRUE)
# Editando o arquivo de predição
predicao2 <- read.csv("dados/predicao2.csv")
predicao2$predict <- as.character(predicao2$predict)
predicao2$predict <- gsub(",", ".", predicao2$predict)
predicao2$predict <- as.numeric(predicao2$predict)
write.csv2(predicao2$predict, file = 'dados/predicao.csv', row.names = FALSE)
hist(predicao2$predict, main="Histograma Predição CRA",
xlab= "CRA")
hist(train$CRA, main="Histograma Treino CRA",
xlab= "CRA")
Após realizar a predição com os dados de teste, podemos comparar nossos resultados observados os histogramas plotados com os valores da nossa predição e com os dos dados de teste. O comportamento dos gráficos se comparam a uma distribuição normal, o que é um bom sinal para o nosso modelo.
notas = data.frame(LPT = 7.9, P1 = 9.3, IC = 6.6, Vetorial = 5.6, Discreta = 7.6, P2 = 8.2, LP2 = 8.2, Grafos = 8.3, C1 = 7.0, LP1 = 9.3, C2 = 5.0, Fisica = 7.5)
write.csv(notas,"dados/minhas_notas.csv", row.names = F)
# Editando o arquivo de predição
minhas.notas <- h2o.importFile("dados/minhas_notas.csv")
predict(drf, minhas.notas)
Passamos como parâmetro para a predição um vetor com as minhas notas do primeiro e do segundo período, e o resultado foi bastante semelhante com o real. Hoje meu CRA é 7.25
Após todo o estudo inicial sobre as melhores técnicas para encontrar padrões em dados conseguimos formular um background teórico para propormos descobrir qual melhor modelo para realizar a predição do desempenho do aluno. Apresentamos três modelos de regressão, dois utilizando árvores de decisão e um redes neurais artificiais, concluímos que tanto os modelos utilizaram praticamente as mesmas variáveis para realizar a predição, porém a rede neural utilizada se mostrou mais adequada para a solução desse problema.
Dentre os três modelos o escolhido foi o Deep Learning (que utiliza uma rede neural), que obteve o maior R², ou seja, o que explica a variância do modelo.
Concluindo nosso relatório, vários fatores externos podem influenciar o desempenho acadêmico de um aluno no decorrer de sua graduação em Ciência da Computação, nosso modelo apontou que se ele se dedicar mais nas disciplinas C2, LPT, IC, P1 e C1, essa dedicação poderá ocasionar um excelente resultado no final do seu curso.