Análise da prova P1

Esta análise foi feita no ambiente computacional IPython Notebook com a linguagem Python 2.7 e as bibliotecas Numpy (computação científica), Pandas (análise de dados) e Matplotlib (gráficos):

In [24]:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

%matplotlib inline
pd.options.display.mpl_style = 'default'

Começamos a análise carregando o arquivo com as notas, tomando o cuidado de descartar os alunos que não participaram da prova (neste caso, cada nota associada a esse aluno deve ser "NaN", de "Not a number"). Altere o nome do arquivo conforme a sua necessidade.

In [25]:
data = pd.read_csv("notas_p1_raw.csv").dropna()

Nesse arquivo ("notas_p1_raw.csv"), cada linha corresponde a um aluno e cada coluna, a um item de exercício: "1a" para o item a do exercício 1, "3b" para o item b do exercício 3 e assim por diante. Por exemplo, abaixo estão apresentadas as primeiras linhas do arquivo de notas. Note que a primeira linha contém os itens de exercícios. Neste caso, há quatro exercícios (de 1 a 4) e cada exercício tem 4 ou 5 itens (de "a" até "e").

In [26]:
data.head()
Out[26]:
1a 1b 1c 1d 2a 2b 2c 2d 2e 3a 3b 3c 3d 4a 4b 4c 4d 4e
0 0.5 0.75 0.55 0.75 0.50 0.50 1.0 0.5 0.5 0.5 0.25 0.15 0.4 0.30 0.1 0.00 0.40 0.0
1 0.5 0.75 0.65 0.00 0.50 0.50 0.4 0.0 0.5 0.0 0.00 0.25 0.0 0.30 0.2 0.00 0.00 0.0
2 0.5 0.75 0.75 0.00 0.00 0.17 0.0 0.5 0.5 0.5 0.00 0.40 0.4 0.45 0.0 0.00 0.00 0.0
3 0.4 0.75 0.65 0.90 0.00 0.50 0.4 0.5 0.5 0.5 0.00 0.50 0.3 0.50 0.5 0.25 0.00 0.0
4 0.5 0.75 0.65 1.00 0.25 0.50 0.4 0.0 0.5 0.4 0.25 0.50 0.4 0.45 0.5 0.50 0.25 0.5

obs.: a coluna mais à esquerda, com os índices, não fazem parte do arquivo. Essa numeração das linhas é feita automaticamente pelo Pandas.

Cada item de exercício tem uma pontuação máxima, listada abaixo na mesma sequência em que aparece no arquivo acima (altere-a conforme a sua necessidade):

In [27]:
pontuacao_maxima = np.array([0.5, 0.75, 0.75, 1, 0.5, 0.5, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1])

Ou seja, a pontuação de cada item de exercício é a seguinte (aproveite para conferir a configuração):

In [28]:
print np.vstack((data.columns.values, pontuacao_maxima)).transpose()
[['1a' 0.5]
 ['1b' 0.75]
 ['1c' 0.75]
 ['1d' 1.0]
 ['2a' 0.5]
 ['2b' 0.5]
 ['2c' 1.0]
 ['2d' 0.5]
 ['2e' 0.5]
 ['3a' 0.5]
 ['3b' 0.5]
 ['3c' 0.5]
 ['3d' 0.5]
 ['4a' 0.5]
 ['4b' 0.5]
 ['4c' 0.5]
 ['4d' 0.5]
 ['4e' 1.0]]

Histograma de notas

Para montar o histograma de notas, precisamos somar as pontuações em cada item, varrendo as colunas (axis=1), para compor a nota de cada aluno. Em seguida, com o vetor de notas resultante, fazemos o histograma:

In [29]:
pd.DataFrame(data).sum(axis=1).hist(bins=np.arange(11))
Out[29]:
<matplotlib.axes.AxesSubplot at 0x3db2650>

Desempenho médio em cada item de exercício

O desempenho médio em cada item de exercício dá uma ideia sobre a dificuldade de cada item. Com ele é possível ter uma visão geral sobre quais itens foram mais difíceis e, por isso, precisam de revisão. Para calculá-lo, o primeiro passo é determinar a pontuação média em cada item de exercício (ie, em valores absolutos):

In [30]:
pontuacao_media = pd.DataFrame(data).mean(axis=0)

Desempenho médio (0-100%) em cada item de exercício:

In [31]:
desempenho_medio = pontuacao_media.div(pontuacao_maxima)

Gráfico de desempenho médio em cada item de exercício:

In [32]:
# Abscissa
dx = 1
x = np.arange(0, 18, dx)

# Gráfico de barras verticais
bar_width = 0.8
bar_pos = x + (dx - bar_width) / 2
plt.bar(bar_pos, desempenho_medio, width=bar_width)

# Rótulos personalizados: "1a", "1b" etc
label_pos = x# + dx / 2
plt.xticks(label_pos, data.columns.values)

# Desenha o gráfico
plt.show()

Histograma de desempenho em cada item de exercício

O histograma de desempenho em cada item de exercício é uma visão ainda mais pormenorizada, pois mostra claramente quantos alunos conseguiram resolver um determinado item: quanto mais barras houver à direita (próximo da pontuação máxima de cada item), melhor terá sido o desempenho da turma, e vice-versa. Idealmente, cada histograma deveria apresentar uma única barra na extrema direita.

A função abaixo desenha o conjunto de histogramas associados aos itens de exercício (segundo parâmetro):

In [52]:
def plot_histogram(notas, itens):
    n_itens = len(itens)
    exercicio = pd.DataFrame(notas, columns=itens)
    figura, eixos = plt.subplots(nrows=1, ncols=n_itens, figsize=(3*n_itens,3))
    for i in range(n_itens):
        item = itens[i]
        i_p_max = np.where(data.columns.values == item)[0][0] # Índice do item de exercício
        p_max = pontuacao_maxima[i_p_max] # Pontuação máxima do item de exercício
        exercicio[item].hist(ax=eixos[i])#,bins=np.arange(0,p_max, 0.1))
        eixos[i].set_title(item + ": " + str(p_max) + " pontos")

Exercício 1

Para desenhar os histogramas dos itens do exercício 1, indique os itens que o compõe: ["1a", "1b", ...].

In [53]:
plot_histogram(data, ["1a", "1b", "1c", "1d"])

Exercício 2

In [54]:
plot_histogram(data, ["2a", "2b", "2c", "2d", "2e"])

Exercício 3

In [55]:
plot_histogram(data, ["3a", "3b", "3c", "3d"])

Exercício 4

In [56]:
plot_histogram(data, ["4a", "4b", "4c", "4d", "4e"])

Créditos e licença

Criado por I. R. Pagnossin (irpagnossin.edu at usp.br) e distribuído para uso segundo os termos da licença Creative Commons 3.0 CC-BY. Isso significa que você pode utilizá-lo livremente, inclusive para fins comerciais, desde que cite a fonte.

Caso você encontre um problema ou tenha alguma sugestão de melhoria, sinta-se à vontade para entrar em contato.

In [37]: