<jupyter_start><jupyter_text>Desafio Lumini Para este desafio, faremos uma análise exploratória de dados de uma amostra de inscrições no ENEM de 2016, seguindo recomendações que estão no repositório e podem ser vistas abaixo: ![image.png](attachment:image.png)  Importação das bibliotecas<jupyter_code>import pandas as pd
import warnings
import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style="white", context="talk")
warnings.filterwarnings('ignore')<jupyter_output><empty_output><jupyter_text>Carregamento de arquivos e primeiras análises Vamos primeiramente abrir o arquivo csv contendo os dados:<jupyter_code>micro_enem = pd.read_csv("Microdados_Enem_2016.csv")<jupyter_output><empty_output><jupyter_text>O dicionário presente também é importante para trazer uma explicaçã para as colunas presentes no texto. Vamos ver uma amostra dos dados carregados<jupyter_code>micro_enem.head()<jupyter_output><empty_output><jupyter_text>Toda a lista de colunas contém as classes:<jupyter_code>micro_enem.columns.tolist()<jupyter_output><empty_output><jupyter_text>Check de consistência e criação de nova informação de notas Vamos analisar o ano de realização da prova para consistência da análise:<jupyter_code>micro_enem["NU_ANO"].unique()<jupyter_output><empty_output><jupyter_text>Todos fizeram a prova no mesmo ano, logo, comparar notas aqui faz sentido . Vamos separar as notas e descartar os casos faltantes para calcular uma média de nota por aluno. A partir de agora, não consideraremos as notas de alunos que não realizaram todas as provas do enem sem perder nenhum dia.<jupyter_code>micro_enem = micro_enem.dropna(subset=['NU_NOTA_CN','NU_NOTA_CH', 'NU_NOTA_LC', 'NU_NOTA_MT', 'NU_NOTA_REDACAO'])
micro_enem
notas_alunos = micro_enem[['NU_NOTA_CN','NU_NOTA_CH', 'NU_NOTA_LC', 'NU_NOTA_MT', 'NU_NOTA_REDACAO']].dropna()<jupyter_output><empty_output><jupyter_text>Podemos agora calcular a média por matéria por curiosidade e a média por aluno:<jupyter_code>notas_alunos.mean(axis=0)
nota_alunos = notas_alunos.mean(axis=1)
micro_enem['nota_final']=nota_alunos<jupyter_output><empty_output><jupyter_text>Nesse momento, temos uma nota final média por aluno como nova variável. Usaremos ela em análises  Análise de estados Vamos realizar agora uma primeira exploração associando o estado do aluno com sua respectiva nota. Vamos listar de ordem decrescente para analisarmos os piores estados e melhores<jupyter_code>uf_nota = micro_enem[['SG_UF_RESIDENCIA','nota_final']]<jupyter_output><empty_output><jupyter_text>Piores Estados por nota:<jupyter_code>uf_nota.groupby('SG_UF_RESIDENCIA').mean().sort_values('nota_final')[:5]<jupyter_output><empty_output><jupyter_text>Melhores Estados por nota:<jupyter_code>uf_nota.groupby('SG_UF_RESIDENCIA').mean().sort_values('nota_final')[-5:]<jupyter_output><empty_output><jupyter_text>Antes de tomar conclusões, é importante analisarmos também quantos elementos participam de cada grupo. Por exemplo, pode-se ver que o estados que estão em melhor posição são estados pouco populosos na listagem. Também vamos olhar o desvio padrão, para entendermos se temos um dado com pouca variação, mesmo com uma população pouco representativa<jupyter_code>uf_nota.groupby('SG_UF_RESIDENCIA').agg(['mean', 'std', 'count']).sort_values(('nota_final','mean'))<jupyter_output><empty_output><jupyter_text>A amostra é bem pequena comparando-se o número total de inscritos no ENEM, porém de certa forma representativa. Dos 5 piores estados, 3 são da região norte e 2 da região nordeste. Possivelmente, a região norte ou nordeste são as com pior desempenho. Vamos verificar isso a seguir  Análise de região do país Podemos fazer essa divisão também por região, já que o código do município, contém a região como primeiro dígito identificador<jupyter_code>regiao_nota = micro_enem[['CO_MUNICIPIO_RESIDENCIA','nota_final']]
regiao_nota['região'] = regiao_nota['CO_MUNICIPIO_RESIDENCIA'].astype("str").apply(lambda x:x[0])
del regiao_nota['CO_MUNICIPIO_RESIDENCIA']<jupyter_output><empty_output><jupyter_text>vamos pegar uma amostra da UF só para conseguirmos identificar o que é cada número de região:<jupyter_code>pd.concat([uf_nota[:5],regiao_nota['região'][:5]], axis=1)<jupyter_output><empty_output><jupyter_text>podemos então ver que 1 é norte, 2 é nordeste, 3 é sudeste, 4 é sul, e 5 é centro-oeste (único não representado na amostra). Vamos criar um mapa para localizar as regiões por nome:<jupyter_code>map_region = {'1':'norte', '2':'nordeste', '3':'sudeste', '4':'sul', '5':'centro-oeste'}<jupyter_output><empty_output><jupyter_text>Vamos agora agrupar as métricas por região, usando também a média, desvio e contagem de elementos para avaliarmos:<jupyter_code>regiao_nota = regiao_nota.groupby('região').agg(['mean', 'std', 'count']).sort_values(('nota_final','mean'))
regiao_nota<jupyter_output><empty_output><jupyter_text>Trocando os nomes pelo nome da região e plotando:<jupyter_code>regiao_nota['região'] = regiao_nota.index.to_series().apply(lambda x:map_region[x])
grades = regiao_nota[('nota_final','mean')].tolist()
regions = regiao_nota['região'].tolist()
# PLOT

f, ax1 = plt.subplots(1, figsize=(8, 8))#, sharex=True)
sns.barplot(x=regions, y=grades, data=regiao_nota, palette="deep", ax=ax1)
ax1.axhline(0, color="k", clip_on=False)
ax1.set_ylabel("Nota média do Enem")<jupyter_output><empty_output><jupyter_text>Apesar das notas  estarem próximas, as menores notas **dessa amostra** são do nordeste e norte, com índices quase iguais. Essa divisão, é similar à encontrada aqui: https://www.leiaja.com/carreiras/2019/07/02/veja-regioes-com-maior-e-menor-media-na-redacao-do-enem/. Apesar de serem de anos distintos, espera-se que o comportamento não tenha tanta variação de um ano para outro. Outro detalhe é que aqui estamos analisando uma amostra apenas do conjunto inteiro de dados  Análise de Idade Vamos realizar agora uma análise a partir da idade dos candidatos<jupyter_code>age_grades = micro_enem[['NU_IDADE','nota_final']]
ages_grade = age_grades.groupby('NU_IDADE').agg(['mean', 'std', 'count'])
print(ages_grade.shape)
ages_grade.head()<jupyter_output><empty_output><jupyter_text>Como tivemos 53 possíveis idades aqui, a contagem dela deve ser bem variada. Vamos filtrar apenas idades com pelo menos 10 amostras para remoção de outliers<jupyter_code>ages_grade = ages_grade[ages_grade[('nota_final','count')]>10]
ages = ages_grade.index.tolist()
grades = ages_grade[('nota_final','mean')].tolist()
df = ages_grade[('nota_final','mean')]

ages_grade['ages'] = ages_grade.index
ages_grade['value'] = ages_grade[('nota_final','mean')]

ages_grade = ages_grade[['ages', 'value']]<jupyter_output><empty_output><jupyter_text>O gráfico abaixo relaciona a nota a idade dos participantes. É possível identificar que participantes mais jovens possuem melhores notas, o que poderá ser justificado na próxima análise<jupyter_code>sns.set(style="darkgrid")
g = sns.lmplot(x="ages", y="value", data=ages_grade, ci=None, palette="muted", height=10, 
           scatter_kws={"s": 50, "alpha": 1}, truncate=False)

g.set_ylabels("Nota média do Enem")
g.set_xlabels("Idade")

fig = g.fig 
fig.suptitle("Nota Enem x Idade. Reta de regressão também plotada.", fontsize=12)<jupyter_output><empty_output><jupyter_text>Vamos analisar agora a idade média das pessoas que trabalham e não trabalham<jupyter_code>trabalho = micro_enem[['NU_IDADE', 'Q026']]
trabalho_map = {"A":"Nunca Trabalhei", "B": "Já Trabalhei", "C":"Trabalho"}
trabalho['trabalho']=trabalho['Q026'].apply(lambda x:trabalho_map[x])<jupyter_output><empty_output><jupyter_text>Plotando a média de idade dos que trabalham e não trabalham<jupyter_code>g = sns.catplot(x="trabalho", y="NU_IDADE", data=trabalho,
                height=6, kind="bar", palette="muted")
g.set_ylabels("Idade Média")
g.set_xlabels("Situação de Trabalho")<jupyter_output><empty_output><jupyter_text>Ao analisar a idade média dos participantes que trabalham, é possível notar que participantes que trabalham ou já trabalharam (possívelmente desempregados) possuem idade média maior, e também são os que tendem a possuir menor média no Enem (após os 20 anos). Logo, o fator de gastar tempo trabalhando ao invés de estudar, é um possível motivo pelo qual as notas de pessoas com idade superior à 20 anos são mais baixas que a de jovens.  Análise Etnias Vamos analisar as notas por etnias declaradas no enem<jupyter_code>ethnic = micro_enem[['TP_COR_RACA','nota_final']]
ethnic = ethnic.groupby('TP_COR_RACA').agg(['mean', 'std', 'count'])

etnics_map = {0:'Não Declar.',1:'Branca', 2:'Preto', 3:'Pardo', 4:'Amarelo', 5:'Indígena'}
ethnic['cor'] = ethnic.index.to_series().apply(lambda x:etnics_map[x])

grades = ethnic[('nota_final','mean')].tolist()
color = ethnic['cor'].tolist()<jupyter_output><empty_output><jupyter_text>O gráfico abaixo relaciona o grupo étnico declarado pelo participante com sua nota. É possivel identificar que o grupo étnico "branco" possui maiores médias, enquanto o "indígena", piores. Novamente, devido a pequena quantidade de dados, a análise não pode ser tida como final:<jupyter_code>f, ax1 = plt.subplots(1, figsize=(8, 8))#, sharex=True)
sns.barplot(x=color, y=grades, palette="deep", ax=ax1)
ax1.axhline(0, color="k", clip_on=False)
ax1.set_ylabel("Nota média do Enem")<jupyter_output><empty_output><jupyter_text>Análise Tipo de Escola<jupyter_code>school_type = micro_enem[['TP_ESCOLA','nota_final']]
school_type = school_type.groupby('TP_ESCOLA').agg(['mean', 'std', 'count'])#.sort_values(('nota_final','mean'))
school_type<jupyter_output><empty_output><jupyter_text>Como é possível ver,a maioria dos estudantes do subconjunto não declarou o tipo de escola. Dos declarados, a maioria é de escola pública, com uma 569 indivíduos de escola particular. Como no exterior só possui um aluno, vamos retirá-lo da análise.<jupyter_code>school_type = school_type[:3]
school_map = {1:'Não Declar.', 2:'Pública', 3:'Privada', 4:'Exterior'}
school_type['escola'] = school_type.index.to_series().apply(lambda x:school_map[x])
grades = school_type[('nota_final','mean')].tolist()
school = school_type['escola'].tolist()
f, ax1 = plt.subplots(1, figsize=(8, 8))#, sharex=True)
sns.barplot(x=school, y=grades, palette="rocket", ax=ax1)
ax1.axhline(0, color="k", clip_on=False)
ax1.set_ylabel("Nota média do Enem")<jupyter_output><empty_output><jupyter_text>Ainda que a maior parte dos estudantes venha de escolas públicas, as melhores notas se encontram em alunos provenientes de escolas particulares  Relação Tipos de Escolas e Tipos de Etnias Aqui, realizaremos uma análise do tipo de escola e tipos de etnias para entendermos a relação de ambas<jupyter_code>school_ethnic = micro_enem[['TP_ESCOLA', 'TP_COR_RACA', 'nota_final']]
school_ethnic['TP_COR_RACA'] = school_ethnic['TP_COR_RACA'].apply(lambda x:etnics_map[x])
school_ethnic['Tipo Escola'] = school_ethnic['TP_ESCOLA'].apply(lambda x:school_map[x])
del school_ethnic['TP_ESCOLA']<jupyter_output><empty_output><jupyter_text>Faremos a análise em cima apenas do número de estudantes de escolas pública e privada:<jupyter_code>school_ethnic = school_ethnic[(school_ethnic['Tipo Escola']=="Pública") | (school_ethnic['Tipo Escola']=="Privada")]<jupyter_output><empty_output><jupyter_text>Agora, relacionando grupo étnico e escola de origem com as notas, pode-se ver que independente do grupo étnico,as notas de alunos provenientes de escolas públicas são mais baixas que notas de alunos provenientes de escolas particulares:<jupyter_code>g = sns.catplot(x="TP_COR_RACA", y="nota_final", hue="Tipo Escola", data=school_ethnic,
                height=8, kind="bar", palette="muted")
g.despine(left=True)
g.set_ylabels("Nota média do Enem")
g.set_xlabels("Etnia")<jupyter_output><empty_output><jupyter_text>Os Negros (Pretos e Pardos) tendem a ter um resultado inferior aos Brancos e amarelos nas escolas privadas. Além do tipo de escola, é importante analisar como as etnias se comportam com relação à renda familiar. Isso pode ajudar a evidenciar o fato de que em escolas particulares, ainda existe uma grande distinção entre escolas mais caras e mais baratas. Logicamente, se os negros possuem menos renda, mesmo estudando em escola particular eles estudarão em escolas com menor desempenho. Vamos à análise para ver se confirma nossa hipótese:<jupyter_code>color_income = micro_enem[['TP_ESCOLA', 'TP_COR_RACA', 'Q006']]
etnics_map = {0:'Não Declar.',1:'Branca', 2:'Preto', 3:'Pardo', 4:'Amarelo', 5:'Indígena'}
color_income['cor'] = color_income['TP_COR_RACA'].apply(lambda x:etnics_map[x])
del color_income['TP_ESCOLA']
del color_income['TP_COR_RACA']

brancos = color_income[color_income['cor']=='Branca']
negros = color_income[(color_income['cor']=='Preto') | (color_income['cor']=='Pardo')]<jupyter_output><empty_output><jupyter_text>Nos gráficos a seguir, analisaremos apenas os casos de negros e brancos por terem mais relevância estatística. Vamos analisar as diferentes classes sociais, sendo que **A** equivale a nenhuma renda familiar, **B** equivale a renda de até 880,00 reais, **C** de 880,01 até 1320,00 reais, até **Q** que é mais de 17.600,00 reais.<jupyter_code>g_negros = negros.groupby("Q006").count()
g_brancos = brancos.groupby("Q006").count()

f, (ax1, ax2) = plt.subplots(2,1, figsize=(8, 15))#, sharex=True)
sns.barplot(x=g_negros.index, y=g_negros['cor'], palette="rocket", ax=ax1)
ax1.axhline(0, color="k", clip_on=False)
ax1.set_ylabel("Número de Indivíduos")
ax1.set_xlabel("Renda Média (A menor, Q Maior)")
ax1.set_title("Renda Média de Negros")

sns.barplot(x=g_brancos.index, y=g_brancos['cor'], palette="rocket", ax=ax2)
ax2.axhline(0, color="k", clip_on=False)
ax2.set_ylabel("Número de Indivíduos")
ax2.set_xlabel("Renda Média (A menor, Q Maior)")
ax2.set_title("Renda Média de Brancos")<jupyter_output><empty_output><jupyter_text>Percebe-se no gráfico acima que negros possuem renda inferior à renda de brancos. Isso está diretamente ligado ao desempenho escolar, que pode ser justificado pelos negros terem desempenho inferior tanto em escolas públicas como em escolas privadas   Análise de gênero Aqui, vamos fazer uma seleção dos gêneros pela nota do Enem<jupyter_code>gender = micro_enem[['TP_SEXO','nota_final']]
f, ax1 = plt.subplots(1, figsize=(7, 7))#, sharex=True)
sns.boxplot(x="TP_SEXO", y="nota_final", data=gender, palette="rocket", ax=ax1)
ax1.axhline(0, color="k", clip_on=False)
ax1.set_ylabel("Nota média do Enem")
ax1.set_xlabel("Sexos Masculino (M) e Feminino (F)")

ax1.set_title("Distribuição de notas por gênero")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11698839046506836, 'fraction_numerical': 0.011472143985711341, 'mean_word_length': 7.727817745803358, 'pattern_counts': {'":': 5, '<': 125, '<?xml version=': 0, '>': 126, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '31', 'dir': 'jupyter-structured-clean-dedup', 'id': '307626', 'license': 'MIT', 'n_tokens_mistral': 5730, 'n_tokens_neox': 5557, 'n_words': 1366, 'path': 'notebooks/Alexandre_Desafio.ipynb', 'repo_name': 'alexandre469/lumini-hire-test', 'size': '14557'}