Pré-processamento de dados: lidando com valores extremos e valores ausentes

No contexto de ciência de dados, é comum ter que lidar com problemas nos dados de um modelo preditivo, tais como valores extremos (outliers) ou valores ausentes (missing data). Em muitos casos, é preciso aplicar pré-processamentos para validar e utilizar um modelo, ao mesmo tempo que é necessário evitar o vazamento de dados (data leakage). Abordamos estes desafios neste artigo mostrando exemplos com dados reais em aplicações nas linguagens de programação R e Python.

Para aprender mais e ter acesso a códigos confira o curso de Modelagem e Previsão usando Python ou comece do zero em análise de dados com a formação Do Zero à Análise de Dados com Python.

Vazamento de dados (data leakage)

Vazamento de dados, do inglês data leakage, é um termo utilizado em ciência de dados para se referir a quando acontece, em um processo de validação de um modelo (simulação), a exposição de informações que não estariam disponíveis para o modelo em ambiente de produção (fora da simulação). Em outras palavras, o modelo é estimado/treinado com informações que ele não teria acesso na prática, ou seja, com dados não vistos/futuros. O termo pode ser confuso (em geral, as pessoas pensam em vazamento de emails, dados financeiros, etc.), então um exemplo talvez clarifique a ideia.

Por exemplo: você quer prever as vendas mensais usando a tendência e outras métricas como variáveis explicativas. Você calcula a tendência temporal das vendas usando o conjunto de dados completo, então separa-o em amostras de treino e teste e usa a amostra de treino para estimar/treinar um modelo. Percebeu o problema? A variável tendência, na amostra de treino, possui informações sobre o futuro (da amostra de teste) que na prática não estarão disponíveis no momento de previsão “fora da amostra”.

Quando acontece vazamento de dados, as estimativas do modelo não são confiáveis e é provável que as previsões não sejam acuradas. Dessa forma, é extremamente importante tomar todas as precauções necessárias para evitar, durante o treinamento de um modelo, que aconteça vazamento de dados. Essa é uma tarefa difícil e complexa e que até mesmo as principais referências na área de ciência de dados acabam cometendo “deslizes” vez ou outra (veja o caso “famoso” de Andrew Ng em Rajpurkar et al. (2017)).

Tudo isso para dizer que a etapa de pré-processamento de dados é bastante suscetível a vazamento de dados. A seguir, vamos abordar alguns casos de pré-processamento de dados e maneiras de evitar o vazamento de dados.

Valores extremos (outliers)

Modelos estatísticos, econométricos e de aprendizado de máquina são, em geral, sensíveis à distribuição e intervalo dos dados. Eventos raros, valores extremos, outliers, etc., podem gerar estimativas e previsões viesadas por influência desses valores, além de dificultar ou impossibilitar a convergência de algoritmos.

Por exemplo: imagine que você tenha um modelo que prevê a média de uma variável alvo qualquer. Em um determinado dia acontece um evento raro (i.e., pandemia) e sua variável alvo é afetada com o registro de um valor extremo. Dessa forma, as próximas previsões do seu modelo serão deslocadas para uma faixa de valores na direção do valor extremo, pois a média é uma estatística sensível a esses grandes números, mesmo que o evento raro tenha acontecido somente uma vez e tudo tenha voltado ao “normal” após o evento.

Existem pelo menos três abordagens para lidar com valores extremos em modelos preditivos:

  • Remoção: é o processo de identificar, baseado em alguma regra, os valores extremos na distribuição de dados e remover, seja a variável ou apenas a observação.
  • Substituição: é o processo de identificar, baseado em alguma regra, os valores extremos na distribuição de dados e substituir a observação por outro valor usando alguma estatística dos dados, ou método de proximidade, ou valor discricionário, ou outros.
  • Dummy: é o processo de identificar, baseado em alguma regra, os valores extremos na distribuição de dados e adicionar, no modelo preditivo, uma dummy que assume valor 1 para a observação extrema e 0 caso contrário.

Não existe abordagem geral para todos os cenários e casos de uso. A recomendação é analisar o valor extremo, investigar a fonte do mesmo e, então, decidir o que fazer (se algo deve ser feito) com o mesmo em um modelo preditivo.

Como evitar vazamento de dados: sempre separe as amostras de treino e teste primeiro e, somente após isso, aplique os pré-processamentos que julgar necessários individualmente nas amostras.

Valores ausentes (missing data)

Valores ausentes são dados que não estão preenchidos em uma dada observação de uma variável, geralmente codificados como NANaN ou outras codificações. É um “buraco” muito comum em conjuntos de dados reais que pode ser oriundo de diversas causas (i.e., feriado, não obrigatoriedade de preenchimento, problemas de infraestrutura técnica, etc.). Para grande parte dos modelos preditivos, os valores ausentes são um problema que o cientista/analista precisa lidar, pois os estimadores supõem que todos os valores de um vetor sejam numéricos.

Existem pelo menos duas abordagens para lidar com valores ausentes em modelos preditivos:

  • Exclusão: é o processo de identificar, baseado em alguma codificação, os valores ausentes na distribuição de dados, avaliar a proporção de valores ausentes em relação ao total de linhas e decidir entre a exclusão da variável (coluna) ou da observação (linha).
  • Imputação: é o processo de identificar, baseado em alguma codificação, os valores ausentes na distribuição de dados e substituir por alguma estatística, valor discricionário, valor próximo, método de proximidade ou outros.

Não existe abordagem geral para todos os cenários e casos de uso. A recomendação é analisar os valores ausentes, sua proporção, investigar a fonte do mesmo e, então, decidir o que fazer (se algo deve ser feito) com o mesmo em um modelo preditivo.

Como evitar vazamento de dados: sempre separe as amostras de treino e teste primeiro e, somente após isso, aplique os pré-processamentos que julgar necessários individualmente nas amostras.

Exemplo prático com dados econômicos

Agora vamos demonstrar como aplicar alguns pré-processamentos em um conjunto de dados econômicos. Uma tabela interessante de se trabalhar é a Pesquisa Nacional por Amostra de Domicílios Contínua (PNAD-C) do IBGE, que disponibiliza os microdados da pesquisa trazendo informações sobre renda, educação e outros. Por ser uma pesquisa, com pessoas/domicílios, a PNAD-C costuma ter diversos valores ausentes e extremos, o que é excelente para praticar as abordagens.

Abaixo apresentamos as primeiras linhas da tabela da PNAD-C (ano 2022, trimestre 4):

R

Código
# A tibble: 6 × 421
    Ano Trimestre    UF Capital RM_RIDE      UPA Estrato V1008 V1014 V1016 V1022
  <dbl>     <dbl> <dbl>   <dbl>   <dbl>    <dbl>   <dbl> <chr> <chr> <dbl> <dbl>
1  2022         4    11      11      NA   1.10e8 1110011 01    10        1     1
2  2022         4    11      11      NA   1.10e8 1110011 01    10        1     1
3  2022         4    11      11      NA   1.10e8 1110011 02    10        1     1
4  2022         4    11      11      NA   1.10e8 1110011 03    10        1     1
5  2022         4    11      11      NA   1.10e8 1110011 03    10        1     1
6  2022         4    11      11      NA   1.10e8 1110011 04    10        1     1
# ℹ 410 more variables: V1023 <dbl>, V1027 <dbl>, V1028 <dbl>, V1029 <dbl>,
#   V1033 <dbl>, posest <dbl>, posest_sxi <dbl>, V2001 <dbl>, V2003 <chr>,
#   V2005 <chr>, V2007 <dbl>, V2008 <chr>, V20081 <chr>, V20082 <dbl>,
#   V2009 <dbl>, V2010 <dbl>, V3001 <dbl>, V3002 <dbl>, V3002A <dbl>,
#   V3003 <lgl>, V3003A <chr>, V3004 <lgl>, V3005 <lgl>, V3005A <dbl>,
#   V3006 <chr>, V3006A <lgl>, V3007 <dbl>, V3008 <dbl>, V3009 <lgl>,
#   V3009A <chr>, V3010 <dbl>, V3011 <lgl>, V3011A <dbl>, V3012 <dbl>, …

Python

Código
    Ano  Trimestre  UF  ...    V1028199  V1028200   ID_DOMICILIO
0  2022          4  11  ...  298.760783       0.0  1100000160110
1  2022          4  11  ...  298.760783       0.0  1100000160110
2  2022          4  11  ...  158.839984       0.0  1100000160210
3  2022          4  11  ...  281.073395       0.0  1100000160310
4  2022          4  11  ...  281.073395       0.0  1100000160310

[5 rows x 421 columns]
Nota

Os dados da PNAD-C são amostrais, sendo necessário considerar o plano amostral para obter estimativas estatísticas. Nesse artigo ignoramos isso e focamos apenas em demonstrar as técnicas de pré-processamentos.

Agora vamos separar os dados dessa tabela, um corte transversal, em amostras de treino e teste por amostragem aleatória simples, visando evitar o vazamento de dados durante (não demonstraremos os procedimentos de modelagem preditiva aqui, mas seria isso que deveria ser feito para não contaminar a amostra de treinamento). Abaixo apresentamos as linhas finais da amostra de treino e as linhas iniciais da amostra de teste:

R

Código
# A tibble: 6 × 421
    Ano Trimestre    UF Capital RM_RIDE      UPA Estrato V1008 V1014 V1016 V1022
  <dbl>     <dbl> <dbl>   <dbl>   <dbl>    <dbl>   <dbl> <chr> <chr> <dbl> <dbl>
1  2022         4    53      53      NA   5.30e8 5310111 09    10        4     1
2  2022         4    53      53      NA   5.30e8 5310111 10    10        4     1
3  2022         4    53      53      NA   5.30e8 5310111 11    10        4     1
4  2022         4    53      53      NA   5.30e8 5310111 11    10        4     1
5  2022         4    53      53      NA   5.30e8 5310111 13    10        4     1
6  2022         4    53      53      NA   5.30e8 5310111 14    10        4     1
# ℹ 410 more variables: V1023 <dbl>, V1027 <dbl>, V1028 <dbl>, V1029 <dbl>,
#   V1033 <dbl>, posest <dbl>, posest_sxi <dbl>, V2001 <dbl>, V2003 <chr>,
#   V2005 <chr>, V2007 <dbl>, V2008 <chr>, V20081 <chr>, V20082 <dbl>,
#   V2009 <dbl>, V2010 <dbl>, V3001 <dbl>, V3002 <dbl>, V3002A <dbl>,
#   V3003 <lgl>, V3003A <chr>, V3004 <lgl>, V3005 <lgl>, V3005A <dbl>,
#   V3006 <chr>, V3006A <lgl>, V3007 <dbl>, V3008 <dbl>, V3009 <lgl>,
#   V3009A <chr>, V3010 <dbl>, V3011 <lgl>, V3011A <dbl>, V3012 <dbl>, …
Código
# A tibble: 6 × 421
    Ano Trimestre    UF Capital RM_RIDE      UPA Estrato V1008 V1014 V1016 V1022
  <dbl>     <dbl> <dbl>   <dbl>   <dbl>    <dbl>   <dbl> <chr> <chr> <dbl> <dbl>
1  2022         4    11      11      NA   1.10e8 1110011 02    10        1     1
2  2022         4    11      11      NA   1.10e8 1110011 03    10        1     1
3  2022         4    11      11      NA   1.10e8 1110011 04    10        1     1
4  2022         4    11      11      NA   1.10e8 1110011 05    10        1     1
5  2022         4    11      11      NA   1.10e8 1110011 10    10        1     1
6  2022         4    11      11      NA   1.10e8 1110011 02    10        4     1
# ℹ 410 more variables: V1023 <dbl>, V1027 <dbl>, V1028 <dbl>, V1029 <dbl>,
#   V1033 <dbl>, posest <dbl>, posest_sxi <dbl>, V2001 <dbl>, V2003 <chr>,
#   V2005 <chr>, V2007 <dbl>, V2008 <chr>, V20081 <chr>, V20082 <dbl>,
#   V2009 <dbl>, V2010 <dbl>, V3001 <dbl>, V3002 <dbl>, V3002A <dbl>,
#   V3003 <lgl>, V3003A <chr>, V3004 <lgl>, V3005 <lgl>, V3005A <dbl>,
#   V3006 <chr>, V3006A <lgl>, V3007 <dbl>, V3008 <dbl>, V3009 <lgl>,
#   V3009A <chr>, V3010 <dbl>, V3011 <lgl>, V3011A <dbl>, V3012 <dbl>, …

Python

Código
         Ano  Trimestre  UF  ...    V1028199    V1028200   ID_DOMICILIO
75545   2022          4  21  ...    0.000000  223.698358  2100318690710
132851  2022          4  23  ...    0.000000  152.367255  2302107720910
169727  2022          4  26  ...  270.943490    0.000000  2601321061010
292463  2022          4  33  ...  245.477555    0.000000  3301556250710
381148  2022          4  42  ...  467.428530    0.000000  4200233090210

[5 rows x 421 columns]
Código
         Ano  Trimestre  UF  ...     V1028199     V1028200   ID_DOMICILIO
234236  2022          4  31  ...     0.000000   106.282648  3100936730310
22234   2022          4  13  ...  1492.279455     0.000000  1300294160510
100414  2022          4  22  ...   214.927316     0.000000  2200072031010
417074  2022          4  43  ...   701.293670  1053.547610  4301070841010
13711   2022          4  12  ...    94.998281    96.767922  1200079700510

[5 rows x 421 columns]
Código

Com os dados preparados, vamos verificar se a amostra de treino possui valores extremos, tomando como exemplo a variável quantitativa “Horas efetivamente trabalhadas na semana de referência em todos os trabalhos para pessoas de 14 anos ou mais de idade” (VD4035). Isso pode ser feito de diversas formas: uma das maneiras mais simples é através de ferramentas de visualização de dados, como um boxplot.

R

Código

Python

Código

Como pode ser visto, essa variável é cheia de valores extremos (desigualdade social?). Uma vez que esses valores tenham sido identificados, você pode querer aplicar um pré-processamento. Vamos supor que para o objetivo do estudo faça sentido remover essas observações (linhas). Abaixo plotamos o boxplot novamente após este pré-processamento na tabela de treino (utilizando a regra do IQR, conforme Hyndman e Athanasopoulos (2021)), sendo que o mesmo deve ser feito na tabela de teste:

R

Código

Python

Código

Nota-se uma grande redução do intervalo da distribuição da variável, mas com uma “nova” distribuição podem haver novos valores extremos para essa distribuição, mesmo que ela seja mais “comportada” em relação a distribuição anterior.

Agora vamos mudar o foco para os valores ausentes que podem haver na variável. Um primeiro procedimento interessante é identificar e computar a quantidade de valores ausentes, preferencialmente em relação ao total de valores. Abaixo apresentamos esse cálculo:

R

Código
# A tibble: 1 × 1
  prop_na
    <dbl>
1   0.569

Python

Código
0.5682223610019632

Uma vez que esses valores tenham sido identificados, você pode querer aplicar um pré-processamento. Vamos supor que para o objetivo do estudo faça sentido imputar os valores ausentes com a média amostral. Abaixo reportamos as estatísticas descritivas da amostra de treino, somente para a variável em análise, antes e depois da imputação nos valores ausentes:

R

Código
     VD4035      
 Min.   :  0.00  
 1st Qu.: 30.00  
 Median : 40.00  
 Mean   : 37.82  
 3rd Qu.: 44.00  
 Max.   :120.00  
 NA's   :190488  
Código
     VD4035      
 Min.   :  0.00  
 1st Qu.: 37.82  
 Median : 37.82  
 Mean   : 37.82  
 3rd Qu.: 40.00  
 Max.   :120.00  

Python

Código
count    144500.000000
mean         37.855751
std          13.917319
min           0.000000
25%          30.000000
50%          40.000000
75%          44.000000
max         120.000000
Name: VD4035, dtype: float64
Código
count    334663.000000
mean         37.855751
std           9.145023
min           0.000000
25%          37.855751
50%          37.855751
75%          40.000000
max         120.000000
Name: VD4035, dtype: float64

Nota-se que a distribuição mudou com esse pré-processamento e é preciso ter isso em mente em um modelo preditivo.

Conclusão

No contexto de ciência de dados, é comum ter que lidar com problemas nos dados de um modelo preditivo, tais como valores extremos (outliers) ou valores ausentes (missing data). Em muitos casos, é preciso aplicar pré-processamentos para validar e utilizar um modelo, ao mesmo tempo que é necessário evitar o vazamento de dados (data leakage). Abordamos estes desafios neste artigo mostrando exemplos com dados reais em aplicações nas linguagens de programação R e Python.

Saiba mais

Se você se interessa por análise e ciência de dados e quiser adquirir os conhecimentos e habilidades destacados neste artigo, dê uma olhadinha nessa formação especial que a Análise Macro preparou:

E para obter os códigos completos deste exercício e de vários outros, dê uma olhada no Clube AM da Análise Macro, onde publicamos exercícios de ciência de dados toda semana em R e Python.

Referências

Hyndman, R. J., & Athanasopoulos, G. (2021) Forecasting: principles and practice, 3rd edition, OTexts: Melbourne, Australia. OTexts.com/fpp3. Accessed on 2023-07-13.

Pedregosa, F., Varoquaux, G., Gramfort, A., Michel, V., Thirion, B., Grisel, O., … & Duchesnay, É. (2011). Scikit-learn: Machine learning in Python. the Journal of machine Learning research, 12, 2825-2830.

Rajpurkar, P., Irvin, J., Zhu, K., Yang, B., Mehta, H., Duan, T., ... & Ng, A. Y. (2017). Chexnet: Radiologist-level pneumonia detection on chest x-rays with deep learning. arXiv preprint arXiv:1711.05225.

Compartilhe esse artigo

Facebook
Twitter
LinkedIn
WhatsApp
Telegram
Email
Print

Comente o que achou desse artigo

Outros artigos relacionados

Retropolando a série do desemprego no Brasil

Nosso objetivo neste exercício será estender a taxa de desemprego fornecida pela Pesquisa de Nacional por Amostra de Domicílios Contínua (PNAD Contínua) através daquela fornecida pela Pesquisa Mensal de Emprego (PME). Serão construídas duas séries: uma normal, outra dessazonalizada. Faremos todo o exercício utilizando o Python.

Variáveis Instrumentais no R: qual o impacto do gasto de segurança no crime?

Diversos métodos econométricos têm como principal finalidade melhorar o processo de investigar o efeito de uma variável sobre a outra, e um importante método encontra-se no uso de Variáveis Instrumentais na análise de regressão linear. Mas como podemos utilizar essa ferramenta para auxiliar no estudo da avaliação de impacto?

Neste post, oferecemos uma breve introdução a esse importante método da área de inferência causal, acompanhado de um estudo de caso para uma compreensão mais aprofundada de sua aplicação. Os resultados foram obtidos por meio da implementação em R, como parte integrante do nosso curso sobre Avaliação de Políticas Públicas utilizando esta linguagem de programação.

Análise regional do mercado de trabalho com dados do CAGED usando Python

Os microdados dos CAGED fornecem informações detalhadas a nível de cidade, sexo, raça, nível de instrução, idade, salário e outras sobre os trabalhadores formais do Brasil, possibilitando ricas análises regionais de dados. Neste artigo mostramos como acessar, processar e analisar estes dados utilizando o Python.

como podemos ajudar?

Preencha os seus dados abaixo e fale conosco no WhatsApp

Boletim AM

Preencha o formulário abaixo para receber nossos boletins semanais diretamente em seu e-mail.