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)
  • Lendo os dados
  • 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")

    1 - Conhecendo os dados

    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:

    1. -matricula
    2. -ano_evasao
    3. -periodo_evasao
    4. -cod_disciplina
    5. -disciplina
    6. -creditos
    7. -media

    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:

    1. Criando Modelos
    2. Comparar os resultados de cada modelo
    3. Verificar a importância das veriáveis
    4. Realizar predição
    5. Utilizar o melhor modelo para prever o meu próprio desempenho

    2 - Criando Modelos

    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:

    1. GBM (Gradient Boosting Algorithm)
    2. Random Forest/
    3. Deep Learning

    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
                 )

    3 - Comparando os modelos

    # 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.

    Compotamento dos modelos

  • Random Forest
  • Podemos observar o gráfico de evolução do treino (linha azul) e da validação (linha laranja) que com 10 árvores nosso modelo Random Forest começar a ter uma certa estabilidade, e depois da árvore de número 45 o modelo vai se tornando cada vez mais estável.
  • GBM
  • O Gradient Boosting Algorithm necessita de menos árvores para chegar ao ponto de estabilidade, a partir da árvore 8 o modelo começa a se estabilizar.
  • Deep Learning Model
  • 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.

    4 - Importância das Variáveis

  • Random Forest
  • GBM
  • Deep Learning Model
  • 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.

    5 - Realizando predição

    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.

    6 - Prevendo Desempenho Próprio

    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

    7 - Conclusões

    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.