Descubra as melhores notas de matemática do ENEM 2016

Leonardo Caldeira
5 min readApr 6, 2020

--

Que tal prevermos quais serão as notas de matemática dos participantes do ENEM 2016?

Olá cientista, tudo bem com você? Tenho andado meio sumido, né? São muitas coisas a fazer nas poucas 24 horas diárias que tenho.

De qualquer forma, tive uma hora para participar do Desafio da CodeNation que estava ativo até 05/04/20 e gerei um Notebook e um passo a passo pra você dar uma olhada em como descobrir as notas de matemática do ENEM 2016.

Para quem é ligado no mundo do desenvolvimento de aplicações web, desktop e até ciência de dados, fique ligado nas acelerações que o pessoal disponibiliza porque servem, inclusive, para você poder testar um pouco o seu conhecimento.

Todos os arquivos e informações estão disponíveis no meu repositório: https://github.com/lpcaldeira/codenation-data-science

Sem mais delongas, vamos ao que interessa: A Ciência.

A empresa liberou 4 arquivos para o desafio:
- train.csv
- test.csv
- Dicionario_Microdados_Enem_2016.xlsx
- Dicionario_Microdados_Enem_2016.ods

Os dois últimos arquivos são de suporte para que possamos entender o que são os campos que iremos trabalhar.

O desafio obrigava o participante a obter nota superior a 90% para entrar na aceleração. Neste passo a passo, foi atingida a nota de 93% de forma bem simples.

Vamos aos passos.

Parte 1: Visão geral dos dados

Primeiro, temos que importar os datasets de treino (train.csv) e teste (teste.csv).

Importando os datasets para df_train e df_test.
Importando os datasets para df_train e df_test.

Em seguida, utilizo a função .corr() para identificar quais as colunas (features) que mais possuem correlação com meu target (NU_NOTA_MT).

Identificando a correção com a coluna alvo.
Identificando a correção com a coluna alvo.

Destes resultados, separamos outras 3 notas para usar como base para alguns gráficos e melhores visualizações dos nossos tratamentos de dados. São elas:
- NU_NOTA_LC
- NU_NOTA_CN
- NU_NOTA_CH

Parte 2: Gráficos e tratamentos de nulos/NaN

Após importar as libs matplotlib e seaborn, vamos plotar o primeiro gráfico:

Antes de tratar dados nulos/NaN.
Antes de tratar dados nulos/NaN.

Depois de aplicar a opção .fillna(0) no dataset de treino (cor vermelha), vamos ver como ficou o gráfico novamente:

A coluna com valor zerado aumentou significativamente.
A coluna com valor zerado aumentou significativamente.

Percebemos então que tinhamos muitos valores errados que agora foram setados para ZERO.

Seguindo o baile, vamos fazer o mesmo para o dataset de teste (cor azul):

Após utilizar a opção .fillna(0) no dataset de teste, os valores com zero cresceram.
Após utilizar a opção .fillna(0) no dataset de teste, os valores com zero cresceram.

Finalizamos nossa parte introdutória de conhecimento dos dados.

Parte 3: Separando e tratando os dados

Para começar, vamos alterar os formatos dos dados que estão em object para float para conseguirmos trabalhar com eles nos nossos modelos.

Identificando os campos object:

Identificando os campos object nos dois datasets.
Identificando os campos object nos dois datasets.

Agora, separamos os valores de cada dataset e os campos que vamos utilizar.

Separando valores.
Separando valores.

A variável colunas possuem todas as colunas que existem no dataset de treino, removendo apenas a inscrição.

Depois, podemos usar, por exemplo, o LabelEncoder para tratar cada campo do tipo objeto:

Aplicando encoder e transformando object para float.
Aplicando encoder e transformando object para float.

Prontinho, dados alterados. Agora sim podemos começar a melhor parte.

Parte 4: Criando os modelos de regressões

Estou utilizando aqui o conceito de Pipeline com RandomizedSearchCV (você pode aplicar o GridSearchCV se quiser) para realizar vários testes de regressão e identificar os melhores parâmetros para o meu modelo alcançar ou chegar o mais próximo de 100%.

O primeiro a ser testado será o AdaBoost.

AdaBoostRegressor.
AdaBoostRegressor.

O conceito de Pipeline nos permite enviar diversos parâmetros para esta função e ela se encarrega de aplicar todas as variações possíveis, nos devolvendo a melhor parametrização e o percentual de acerto atingido.

O retorno é algo assim:

Retorno do método RandomizedSearchCV.
Retorno do método RandomizedSearchCV.

Consegue ver o valor 0.92 alguma coisa? Isso quer dizer que o modelo atingir 92% de acerto utilizando os parâmetros informados logo abaixo onde está escrito AdaBoostRegressor.

Então podemos simplesmente pegar este retorno e aplicar algo assim:

Modelo de regressão com AdaBoost após RandomizedSearchCV.
Modelo de regressão com AdaBoost após RandomizedSearchCV.

O que estou fazendo acima é utilizar o retorno para criar o meu modelo de regressão, para depois aplicar o .fit que aplica o modelo nos dados, o .predict que retorna um array/lista com todas as notas preditas e, a partir disso, posso criar meu dataset final com as notas que chamei de answer_ada.csv com os campos NU_INSCRICAO e as notas.

Fim.

Viram, não disse que era fácil e rápido?

Este foi apenas um desafio visando treinar pessoas que já possuem um prévio conhecimento em Ciência de Dados, mesmo que básico.

Espero que tenha gostado e ficado claro para você.

Recomendo que baixe o arquivo .ipynb que está no meu repositório e o execute passo a passo para ver o que as programações estão fazendo.

Além do AdaBoostRegressor, utilizei DecisionTreeRegressor e RandomForestRegressor nos testes e deixei outros modelos dentro do arquivo para que você aplique e identifique as diferenças, buscando entender o seu funcionamento e, quem sabe, até alcançar os 100% de acerto.

O arquivo e demais informações estão no meu repositório e o link está bem no topo desta publicação.

Não esqueça de seguir minha página no Insta e saber das novidades em tempo real!

Um grande abraço.

--

--