ANÁLISE SOBRE SUBMISSÕES DE QUESTÕES DOS ALUNOS DE PROGRAMAÇÃO 1 DE COMPUTAÇÂO - UFCG

Sobre o Dataset.

A amostra utilizada é referente a submissões dos alunos da disciplina de programação 1 do curso de Ciência da Computação da Universidade Federal de Campina Grande, no período de 2014.2. A ideia é traçar uma análise para todos os alunos de programação 1 a partir da amostra fornecida. O dataset é composto de 15148 observações, com 5 variáveis a serem analisadas. São elas:

  • date - representa o timestamp de uma submissão.
  • question - o nome da questão submetida.
  • attempt - a tentativa da submissão em questão (zero significa que o aluno acessou a questão).
  • result - se a solução submetida está correta.
  • student - id do aluno.
summary(students)
##       date                               question        attempt     
##  Min.   :2.014e+13   quant_par_impar         :  283   Min.   :0.000  
##  1st Qu.:2.014e+13   produto_em_pg           :  204   1st Qu.:1.000  
##  Median :2.014e+13   percentagem_de_aprovados:  192   Median :1.000  
##  Mean   :2.015e+13   privilegia_letra        :  163   Mean   :1.748  
##  3rd Qu.:2.015e+13   vida_collatz            :  158   3rd Qu.:2.000  
##  Max.   :2.015e+13   fila_por_altura         :  157   Max.   :9.000  
##                      (Other)                 :13991                  
##    result                                 student     
##  False:8721   4ecd18724debfbfd6c612eece8e37c0e:  487  
##  True :6427   e166ee85c09b56436f986246349104d6:  477  
##               35050953e093d858af587762687855a9:  473  
##               d2016baba4c4505be57b953413df9500:  439  
##               9c9e265373951fa18e7a81aba1ce2738:  430  
##               597d5c78cef692572494ac2f8462b94a:  367  
##               (Other)                         :12475

Taxa de acerto das Questões.

Pensando em avaliar o grau de dificuldade das questões em relação aos alunos da disciplina, foi analisado a taxa de acerto das questões submetidas.

library(dplyr, quietly=TRUE)

questions <- group_by(students, question)  %>% count(question,result)

questionsTrue <- filter(questions, result == "True") %>% select(resTrue = n)
questionsFalse <- filter(questions, result == "False") %>% select(resFalse = n)

questions <- merge(questionsTrue, questionsFalse) %>% group_by(question, resTrue,resFalse) %>% 
            summarise(resTotal = resTrue + resFalse) %>% 
            group_by(question) %>% summarise(taxaAcerto = resTrue / resTotal) %>% arrange(desc(taxaAcerto)) #calcula taxa de acerto


summary(questions)
##                      question     taxaAcerto     
##  abaixo_acima_media_lista:  1   Min.   :0.01695  
##  abaixo_da_media         :  1   1st Qu.:0.25000  
##  acima_de                :  1   Median :0.45000  
##  acima_media_matriz      :  1   Mean   :0.44899  
##  adivinhe_o_numero       :  1   3rd Qu.:0.61111  
##  agenda_ordenada         :  1   Max.   :0.97500  
##  (Other)                 :403

Após analisar a taxa de acerto, uma curiosidade é que não há ocorrências de questões com 100% de acerto (máxima taxa de acerto é de 97.5% e a menor é de aproximadamente 1.7%). A média de acerto das questões encontra-se abaixo de 50%.

mean(questions$taxaAcerto)
## [1] 0.4489864
library(ggplot2, quietly = TRUE)

ggplot(questions, aes(x = 1:nrow(questions), y = taxaAcerto)) + stat_summary(fun.y = mean, geom = "point")

Os pontos do gráfico acima são referente às questões (409 observações) distribuídas ao longo do eiro x e com suas respectivas taxas de acerto no eixo vertical. Por conter vários pontos e estes estarem muito sobrepostos, as questões foram categorizadas nos níveis: FÁCIL, MÉDIA, DIFÍCIL e MUITO DIFÍCIL.

questions$dificuldade <- ""

questions_easy <- filter(questions, taxaAcerto >= 0.75) 
questions_easy$dificuldade <- "FACIL"

questions_medium <- filter(questions,  taxaAcerto < 0.75 & taxaAcerto >= 0.5)
questions_medium$dificuldade <- "MEDIO"

questions_hard <- filter(questions,  taxaAcerto < 0.5 & taxaAcerto >= 0.25)
questions_hard$dificuldade <- "DIFICIL"

questions_very_hard <- filter(questions,  taxaAcerto < 0.25)
questions_very_hard$dificuldade <- "MUITO DIFICIL"

questions <- rbind(questions_easy, questions_medium, questions_hard, questions_very_hard)

O gráfico abaixo mostra as médias para cada categoria de questão.

ggplot(questions, aes(x = dificuldade, y = taxaAcerto)) + stat_summary(fun.y = mean, geom = "point") + theme_bw()

É interessante notar o número de observações em cada tipo de categoria. Questões do tipo FÁCIL possuem um número de observações bem abaixo das outras categorias, enquanto estas possuem entre 100 e 135 observações.

nrow(questions_easy)
## [1] 54
nrow(questions_medium)
## [1] 120
nrow(questions_hard)
## [1] 135
nrow(questions_very_hard)
## [1] 100

Verificanao o Intervalo de Confiança para da amostra

Foi calculado o Intervalo de Confiança afim para as médias categorizadas anteriormente, afim de analisar um intervalo de variação confiável para a população os alunos de programação 1 do curso.

library("Rmisc", quietly = TRUE)
## Warning: package 'Rmisc' was built under R version 3.1.2
## -------------------------------------------------------------------------
## You have loaded plyr after dplyr - this is likely to cause problems.
## If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
## library(plyr); library(dplyr)
## -------------------------------------------------------------------------
## 
## Attaching package: 'plyr'
## 
## The following objects are masked from 'package:dplyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
cis <- data.frame(upper = c(), mean = c(), lower = c())


interval_easy <- CI(questions_easy$taxaAcerto, ci = 0.95)
interval_medium <- CI(questions_medium$taxaAcerto, ci = 0.95)
interval_hard <- CI(questions_hard$taxaAcerto, ci = 0.95)
interval_very_hard <- CI(questions_very_hard$taxaAcerto, ci = 0.95)

cis <- rbind(interval_easy,interval_medium, interval_hard, interval_very_hard)
cis <- data.frame(cis)

Através dos valores abaixo e do gráfico, podemos verificar uma pequena variação no intervalo para as 4 médias calculadas. É interessante notar que o ponto que possui a maior variação é o que diz respeito a média de questões fáceis. Isso ocorre devido ao número de observações na categoria fácil (54), sendo este um valor bem inferior ao número de observações nas demais categorias (que são valores bem similares, girando em torno de 115 observações), e assim, mostrando que quanto menos observações para calcular o IC, maior será o intervalo de confiança.

cis
##                        upper      mean     lower
## interval_easy      0.8713111 0.8521695 0.8330279
## interval_medium    0.6078029 0.5935379 0.5792729
## interval_hard      0.3904877 0.3784750 0.3664623
## interval_very_hard 0.1649084 0.1529962 0.1410839
ggplot(cis, aes(x = 1:nrow(cis), y = mean)) + 
  geom_point() + 
  geom_errorbar(aes(ymin = lower, ymax = upper)) + 
  geom_hline(aes(yintercept=mean(mean(questions$taxaAcerto)))) + 
  theme_bw()