Machine Learning — Regressão RandomForest para prever nota de Matemática do Enem 2016

Gabi Viana
Ensina.AI
Published in
8 min readJan 8, 2019

Introdução

Como exercício e treinamento de meus estudos em Machine Learning desenvolvi o modelo preditivo a ser mostrado nesse notebook proposto pelo site de desafios Codenation e obtive a pontuação de 67.75% de acerto.

O modelo ainda está em testes e poderá ser aprimorado/atualizado em um próximo artigo.

Página oficial do desafio: https://www.codenation.com.br/journey/data-science/challenge/enem-2.html

O desafio consiste em estimar a nota de matemática referente ao enem 2016 através da leitura de dois datasets fornecidos nos arquivos test.csv e train.csv. Para realizar esse desafio com suas devidas instruções e arquivos e obter a pontuação, basta acessar o link oficial citado acima e seguir as instruções fornecidas pelo autor.

Esse exercício foi realizado utilizando alguns exemplos, conceitos e técnicas aplicadas em um estudo sobre a aplicação de Machine Learning para classificar vinhos feito pela EliteDataScience.

Desenvolvimento

Inicialmente vamos importar as bibliotecas a serem utilizadas:

Faremos então a leitura e importação dos dados de treino e teste:

Análise Exploratória Simplificada

Faremos agora uma análise exploratória mais básica, analisando somente as features mais importantes a serem utilizadas nesse modelo, pois esse dataset contém diversas colunas e somente os valores que influenciarem mais na nota serão relevantes:

1º Passo — Verificar se o dataset de teste fornecido faz parte do dataset de treino

Ok! Os dados foram validados, agora podemos salvar o número de inscrição que usaremos só no arquivo de resposta final:

Para a regressão, utiliza-se somente valores numéricos. Para verificar a correlação desses valores e verificar quais variáveis serão usadas nesse estudo, iremos selecionar somente os valores numéricos do dataframe de teste:

Agora vamos verificar qual a correlação das variáveis para decidir quais serão usadas no modelo:

Correlação das notas com a idade e se o aluno é treineiro ou não

Após a verificação da correlação dos dados, foram selecionadas para a criação do modelo preditivo somente as features NU_NOTA_CN (nota da prova de Ciências Naturais), NU_NOTA_CH (nota da prova de Ciências Humanas), NU_NOTA_LC (nota da prova de Linguagens e Códigos) e a NU_NOTA_REDACAO (nota final da redação).

Podemos representar a correlação dessas variáveis de forma gráfica para visualizar melhor:

Correlação das notas de provas

Validação e tratamento dos dados

Na correlação das variáveis do dataset, pode-se observar que há registros em que todas as colunas se encontram vazias. Em registros nos quais todas as provas (NU_NOTA_CN,NU_NOTA_CH,NU_NOTA_LC,NU_NOTA_REDACAO) tenham as notas como nulas, pode-se estimar que esse aluno não foi realizar as provas, portanto devemos remover essas linhas do dataset de treino:

Após a remoção desses registros, percebe-se que há registros dos dataframes de teste com notas de algumas provas faltantes, o que sugere que possa ter ocorrido um erro durante a extração de algumas notas para o arquivo csv. Trabalhar com os dados dessa forma não é bom para o modelo preditivo:

Contabilização de notas de provas vazias

Esse problema pode ser solucionado através das seguintes opções:

Exclusão das notas: O que não é uma solução viável, pois irá excluir registros de pessoas que fizeram todas as provas, mas pode ter corrompido uma de suas notas durante a extração dos dados, por exemplo;
Preenchimento com zeros: Após a realização de testes em modelos de regressão anteriores, essa opção não gerou bons resultados, reduzindo drasticamente o valor final das notas estimadas;
Preenchimento das notas faltantes com a média da coluna das notas encontradas: Será a opção mais viável no momento, utilizada nesse estudo.

Preenchimento dos valores nulos das notas com a média dos valores das provas:

Separação dos dados de treino (features) e da classe

Classe: O que queremos descobrir nesse estudo? A nota de matemática dos alunos que fizeram o enem 2016, que será usada para validar os dados/treinar o algoritmo

Features: Somente os dados numéricos considerados relevantes para o treinamento, no caso as variáveis definidas anteriormente: [‘NU_NOTA_CN’,’NU_NOTA_CH’,’NU_NOTA_LC’,’NU_NOTA_REDACAO’]

Para melhorar a performance e a previsão do modelo, usaremos um pré-processamento para a padronização dos dados que se encontram em escalas diferentes usando o StandardScaler.

A padronização é o processo de subtrair os meios de cada recurso e, em seguida, dividir pelos desvios padrão do recurso.
Trata-se de um requisito comum para tarefas de aprendizado de máquina. Muitos algoritmos assumem que todos os recursos estão centralizados em torno de zero e têm aproximadamente a mesma variação.

Usaremos um recurso no Scikit-Learn chamado API de transformação. Segundo o blog EliteDataScience, esse recurso permite que você “ajuste” uma etapa de pré-processamento usando os dados de treinamento da mesma maneira que você ajustaria um modelo e, em seguida, use a mesma transformação em conjuntos de dados futuros.

Como funciona esse processo:

  • Ajuste o transformador ao conjunto de treinamento (salvando as médias e os desvios padrão)
  • Aplique o transformador ao conjunto de treinamento (dimensionando os dados de treinamento)
  • Aplique o transformador ao conjunto de teste (usando as mesmas médias e desvios padrão)

Isso torna sua estimativa final do desempenho do modelo mais realista e permite inserir suas etapas de pré-processamento em um pipeline de validação cruzada.

Configuramos o objeto scaler com as médias e desvios padrão salvos para cada recurso no conjunto de treinamento. Vamos testar aplicando aos dados de treinamento:

Vamos selecionar os dados de teste contendo somente as features necessárias a análise:

Configuraremos agora o pipeline para realizar a validação cruzada mais a frente simplesmente declarando o objeto de classe da seguinte forma: Criando um um pipeline de modelagem que primeiro transforma e normaliza os dados usando o StandardScaler() e depois se ajusta a um modelo usando um regressor de floresta aleatório.

Declaração de hiperparâmetros para ajustar o modelo: Segundo o tutorial do EliteDataScience, existem dois tipos de parâmetros com os quais precisamos nos preocupar: parâmetros de modelo e hiperparâmetros . Os parâmetros dos modelos podem ser aprendidos diretamente dos dados (isto é, coeficientes de regressão), enquanto os hiperparâmetros não podem.

Os hiperparâmetros expressam informações estruturais “de nível superior” sobre o modelo e são normalmente definidos antes do treinamento do modelo.

Exemplo: hiperparâmetros de floresta aleatórios

Como exemplo, vamos pegar nossa floresta aleatória para regressão: Dentro de cada árvore de decisão, o computador pode decidir empiricamente onde criar ramificações com base no erro de média quadrática (MSE) ou no erro médio absoluto (MAE). Portanto, as localizações das filiais reais são parâmetros do modelo .

No entanto, o algoritmo não sabe qual dos dois critérios, MSE ou MAE, deve usar. O algoritmo também não pode decidir quantas árvores incluir na floresta. Estes são exemplos de hiperparâmetros que o usuário deve definir.

O formato deve ser um dicionário Python (estrutura de dados para pares de valores-chave) em que as chaves são os nomes e valores do hiperparâmetro e as listas de configurações a serem experimentadas.
Nesse exemplo serão considerados somente esses parâmetros, porém há outras configurações que podem ser utilizadas/estudadas para melhorar o modelo RandomForest Hyperparameters.

Ajustando o modelo através de Validação Cruzada

A validação cruzada é uma das habilidades mais importantes em todos os aprendizados de máquina, pois ajuda a maximizar o desempenho do modelo, reduzindo a chance de gerar modelos ineficazes de predição.
A validação cruzada é um processo para estimar com confiabilidade o desempenho de um método para construir um modelo treinando e avaliando seu modelo várias vezes usando o mesmo método.

Na prática, esse “método” é simplesmente um conjunto de hiperparâmetros nesse contexto.

Estas são as etapas para a validação:

- Divida seus dados em k partes iguais ou "dobra" (normalmente k = 10).
- Treine seu modelo em dobras de k-1 (por exemplo, as primeiras 9 dobras).
- Avalie-o na dobra "hold-out" restante (por exemplo, a 10ª dobra).
- Realize os passos (2) e (3) k vezes, cada vez usando uma dobra diferente.
- Agregue o desempenho em todas as dobras k . Esta é a sua métrica de desempenho.

Ok, mas porque usar a validação cruzada? Vamos dizer que você quer treinar um regressor florestal aleatório. Um dos hiperparâmetros que você deve ajustar é a profundidade máxima permitida para cada árvore de decisão em sua floresta. Como você pode decidir?

É aí que entra a validação cruzada. Usando apenas o seu conjunto de treinamento, você pode usar o CV para avaliar diferentes parâmetros e estimar sua eficácia.

Mas o que é o pipeline de validação cruzada?

A melhor prática ao executar a validação cruzada é incluir as etapas de pré-processamento de dados dentro do loop da prórpia validação. Isso evita que suas dobras de treinamento sejam acidentalmente afetadas por dados influentes da dobra de teste.

Veja como o pipeline de validação cruzada inclui as etapas de pré-processamento:

 - Divida seus dados em k partes iguais ou "dobra" (normalmente k = 10).
- Pré-processar k -1 dobras de treinamento.
- Treine seu modelo nas mesmas dobras de k -1.
- Pré-processar a dobra de retenção usando as mesmas transformações da etapa (2).
- Avalie seu modelo na mesma dobra de espera.
- Realize os passos (2) - (5) k vezes, cada vez utilizando uma dobra diferente.
- Agregue o desempenho em todas as dobras k . Esta é a sua métrica de desempenho.

Felizmente, o Scikit-Learn torna isso estupidamente simples:

O GridSearchCV essencialmente realiza a validação cruzada em toda a “grade” (todas as permutações possíveis) dos hiperparâmetros. Ele leva em seu modelo (neste caso, estamos usando um pipeline de modelo), os hiperparâmetros que você deseja ajustar e o número de dobras a serem criadas.

Podemos visualizar também quais parametros foram selecionados os melhores para o modelo em questão:

Agora testaremos a previsão das notas usando o modelo criado:

Vamos salvar os resultados encontrados no dataframe de respostas:

Podemos visualizar um exemplo de notas estimados pelo modelo:

Gerando o arquivo de respostas com a inscrição do aluno e a nota de matemática predita:

Para enviar a solução do desafio do Codenation para validação deve-se enviar um arquivo csv com os campos NU_INSCRICAO e NU_NOTA_MT, que já contém as notas preditas via comando no terminal.

Podemos também salvar o modelo preditivo criado e usá-lo posteriormente usando esses códigos:

O notebook com o código completo encontra-se disponível no meu repositório: RandomForest para previsão das notas de matemática

--

--

Gabi Viana
Ensina.AI

27 anos, Ciência e Análise de Dados, Computação, Jogos e um Café por favor!! ☕👩‍💻