Prevendo nota de matemática do ENEM de 2016

 · 8 mins read

Todos sabemos que o Exame Nacional do Ensino Médio (ENEM) é uma prova muito concorrida e que muitos candidatos tem a oportunidade de estudar em uma boa instituição devido a pontuação que obteve.

*Neste notebook está toda minha análise e os tratamentos realizados. Aqui deixo para consulta o deploy da aplicação APLICAÇÃO

Vamos realizar a análise da base do ENEM de 2016, fazer a previsão da nota de matemática dos candidados e tentar saber como que se saíram, qual foi o estado com mais participantes e qual foi a melhor pontuação e mais. Então vamos lá!

Para iniciar fiz a importação da base de treino e de teste.

train = pd.read_csv('https://dl.dropbox.com/s/1dcc81bthwmw47r/train.csv?dl=0', index_col=0)
test = pd.read_csv('https://dl.dropbox.com/s/ycp6it0mmndajco/test.csv?dl=0')

A base está distribuida da seguinte forma:

Treino: 13730 linhas e 166 colunas (features)
Teste: 4576 linhas e 47 colunas (features)

Analisando a base

Conseguimos identificar que o estado de São Paulo teve o maior número de participantes, seguido por Ceará e Minas Gerais

participantes

Fazendo a verificação por sexo, conseguimos observar que as mulheres tiveram uma maior participação na prova.

quantidade por sexo

Muitos dos candidatos que realizam esse exame são aqueles que estão concluindo o ensino médio, sendo assim, temos uma grande concentração da idade entre 17 e 18 anos. A probabilidade de termos um candidato com idade menor ou igual a 25 anos é de 69%.

histograma idade

Na prova e na redação a maior pontuação é de mil pontos. Na distribuição abaixo observamos que nas provas há uma concentração das notas próximo de 500, já na redação está próximo de 600. A probabilidade dos candidatos obterem uma nota maior ou igual a 600 na prova é de 6,22%, já para a redação a probabilidade é de obterem nota maior ou igual a 700 é de 13,25%.

notas

Na redação temos alguns pontos que são observados no caso de fugir ao tema, for anulada, entre outros. A tabela abaixo nos mostra como que ficaram essas situações. obs.: Não incluí em gráfico pois ficaria difícil visualizar os valores menores

SituaçãoQuantidade
Sem problemas13195
Em branco133
Fuga ao tema105
Parte desconectada29
Cópia texto motivador17
Texto insuficiente12
Fere direitos autorais9
Não atendimento ao tipo7
Anulada3

Mostramos como ficaram as notas de toda a base de dados, agora vamos verificar como ficaram as notas das provas distribuídas por estado. Há uma boa quantidade de outliers (valores fora do comum), mas nossa mediana está bem próximo de 500, conforme citamos anteriormente no histograma.

notas por estado

Quando fazemos a inscrição no ENEM, há um questionário socioeconómico para respondermos. Baseando nisso, vamos observar se dependendo da resposta os candidatos podem se sair melhor que os outros. Uma das perguntas é “Até que série seu pai, ou o homem responsável por você, estudou?”. Podemos inferir que quanto maior o grau de escolaridade do pai, mais provável que o candidato obtenha boa nota no exame.

questionario q001

Isso vale também em relação a renda mensal da família. Quanto maior a renda, maior a possibilidade do canditato ter uma melhor nota.

questionario q006

Tratando os dados e realizando a previsão

Depois dessas análises, chegou a hora de prepar os dados para nossa previsão. Primeiro realizei o tratamento imputando o valor 0 (zero) na prova daqueles candidatos que estavam com com status diferente de “1 = Presente na prova”.

train_df.loc[train_df['TP_PRESENCA_CH'] != 1, 'NU_NOTA_CH'] = train_df.loc[train_df['TP_PRESENCA_CH'] != 1, 'NU_NOTA_CH'].fillna(0)
train_df.loc[train_df['TP_PRESENCA_CN'] != 1, 'NU_NOTA_CN'] = train_df.loc[train_df['TP_PRESENCA_CN'] != 1, 'NU_NOTA_CN'].fillna(0)
train_df.loc[train_df['TP_PRESENCA_MT'] != 1, 'NU_NOTA_MT'] = train_df.loc[train_df['TP_PRESENCA_MT'] != 1, 'NU_NOTA_MT'].fillna(0)
train_df.loc[train_df['TP_PRESENCA_LC'] != 1, 'NU_NOTA_LC'] = train_df.loc[train_df['TP_PRESENCA_LC'] != 1, 'NU_NOTA_LC'].fillna(0)
train_df.loc[train_df['TP_PRESENCA_LC'] != 1, 'NU_NOTA_REDACAO'] = train_df.loc[train_df['TP_PRESENCA_LC'] != 1, 'NU_NOTA_REDACAO'].fillna(0)
...

Como os modelos de Machine Learning não aceitam dados categóricos alterei as informações do sexo de ‘F’ e ‘M’ para 0 e 1, respectivamente.

train_df['TP_SEXO'] = train_df['TP_SEXO'].map({'F': 0, 'M': 1})

Utilizei também o Label Encoder para alterarmos o tipo das respostas referente ao questionário socioeconômico. Por exemplo: na coluna que havia as respostas A, B, C e D passarão a ser 1, 2, 3 e 4. O Label Encoder se encarrega de fazer essa alteração.

train_df['Q001'] = label_encoder.fit_transform(train_df['Q001'])
train_df['Q002'] = label_encoder.fit_transform(train_df['Q002'])
train_df['Q006'] = label_encoder.fit_transform(train_df['Q006'])
train_df['Q025'] = label_encoder.fit_transform(train_df['Q025'])
train_df['Q047'] = label_encoder.fit_transform(train_df['Q047'])

Para o treino foram utilizados dois modelos de aprendizado supervisionado baseado em regressão, que foram Random Forest e Linear Regression, regressão pois estamos querendo realizar a previsão da nota de matemática e supervisionado porque estamos passando a feature de resposta para realizar o treinamento. A outros modelos que poderiamos ter utilizado, mas vamos trabalhar apenas com esses.

Como no desafio tive que submeter um arquivo csv com os dados, vou fazer aqui uma separação dos dados de treino para realizarmos a validação dos dados e verificar como está o desempenho do nosso modelo.

target = train['NU_NOTA_MT']
train.drop(['NU_NOTA_MT', 'TP_PRESENCA_MT'], axis=1, inplace=True)
X_train, X_test, y_train, y_test = train_test_split(train, target, test_size=0.25, random_state=42)
lr = LinearRegression()
lr_model = lr.fit(X_train, y_train)
y_pred = lr_model.predict(X_test)

print(f'Acurácia do modelo: {round(lr_model.score(X_test, y_test), 3)}%')

Acurácia do modelo: 0.917%

rf = RandomForestRegressor(n_jobs=-1)
rf_model = rf.fit(X_train, y_train)
y_pred_rf = rf_model.predict(X_test)

print(f'Acurácia do modelo: {round(rf_model.score(X_test, y_test), 3)}%')

Acurácia do modelo: 0.925%

O modelo Random Forest ficou com o score melhor que o Linear Regression, então quer dizer que o primeiro é melhor que o segundo? Não, isso quer dizer apenas que o primeiro melhor se adequou a nossa base e por tanto teve a melhor acurácia.

Nunca podemos dizer que um modelo é melhor, mas sim que um se adequa melhor que o outro para o que foi proposto.

Então é isso pessoal, espero que tenham gostado e até a próxima.