Introdução ao Pré-Processamento: Arrumando a casa para a festa

01 — Adequação dos tipos de Dados (int, float, str…)
02 — Trabalhando com Dados Missing

01 — Adequação dos tipos de Dados (int, float, str…)

Nem sempre nós vamos receber uma amostra (dataset) toda pronta e bonitinha para trabalhar. As vezes é preciso adequar os dados para só depois trabalhar com eles.

Vamos começar com uma amostra (dataset) disponibilizada pelo Kaggle referente ao consumo de energia de alguns prêdios (SEA Building Energy Benchmarking).

Ok, depois de baixado vamos fazer alguns passos iniciais com a nossa amostra (dataset):

NOTE:
Bem, eu não vou deixar aqui saída porque vão ser muitas colunas (42 como nós configuramos), mas você pode testar no seu computador.

Mas como eu posso ver os tipos de dados de cada coluna da minha amostra de dados? Simples, basta utilizar o atributo dtypes do Pandas:

OUTPUT:

OSEBuildingID int64
DataYear int64
BuildingType object
PrimaryPropertyType object
PropertyName object
TaxParcelIdentificationNumber object
Location object
CouncilDistrictCode int64
Neighborhood object
YearBuilt int64
NumberofBuildings int64
NumberofFloors float64
PropertyGFATotal int64
PropertyGFAParking int64
PropertyGFABuilding(s) int64
ListOfAllPropertyUseTypes object
LargestPropertyUseType object
LargestPropertyUseTypeGFA float64
SecondLargestPropertyUseType object
SecondLargestPropertyUseTypeGFA float64
ThirdLargestPropertyUseType object
ThirdLargestPropertyUseTypeGFA float64
YearsENERGYSTARCertified object
ENERGYSTARScore float64
SiteEUI(kBtu/sf) float64
SiteEUIWN(kBtu/sf) float64
SourceEUI(kBtu/sf) float64
SourceEUIWN(kBtu/sf) float64
SiteEnergyUse(kBtu) float64
SiteEnergyUseWN(kBtu) float64
SteamUse(kBtu) float64
Electricity(kWh) float64
Electricity(kBtu) float64
NaturalGas(therms) float64
NaturalGas(kBtu) float64
OtherFuelUse(kBtu) float64
GHGEmissions(MetricTonsCO2e) float64
GHGEmissionsIntensity(kgCO2e/ft2) float64
DefaultData object
Comment object
ComplianceStatus object
Outlier object
2010 Census Tracts float64
Seattle Police Department Micro Community Policing Plan Areas float64
City Council Districts float64
SPD Beats float64
Zip Codes int64

NOTE:
Para a nossa sorte os tipos de dados da nossa amostra estão quase da maneira que nós queremos. Mas só para praticar suponha que nós queremos trocar o tipo da coluna “DataYear” que está em int64 para object como faríamos?

Simples basta utilizar a função astype() do pandas.DataFrame:

OUTPUT:

OSEBuildingID int64
DataYear object ←
BuildingType object
PrimaryPropertyType object
PropertyName object
TaxParcelIdentificationNumber object
Location object
CouncilDistrictCode int64
Neighborhood object
YearBuilt int64
NumberofBuildings int64
NumberofFloors float64
PropertyGFATotal int64
PropertyGFAParking int64
PropertyGFABuilding(s) int64
ListOfAllPropertyUseTypes object
LargestPropertyUseType object
LargestPropertyUseTypeGFA float64
SecondLargestPropertyUseType object
SecondLargestPropertyUseTypeGFA float64
ThirdLargestPropertyUseType object
ThirdLargestPropertyUseTypeGFA float64
YearsENERGYSTARCertified object
ENERGYSTARScore float64
SiteEUI(kBtu/sf) float64
SiteEUIWN(kBtu/sf) float64
SourceEUI(kBtu/sf) float64
SourceEUIWN(kBtu/sf) float64
SiteEnergyUse(kBtu) float64
SiteEnergyUseWN(kBtu) float64
SteamUse(kBtu) float64
Electricity(kWh) float64
Electricity(kBtu) float64
NaturalGas(therms) float64
NaturalGas(kBtu) float64
OtherFuelUse(kBtu) float64
GHGEmissions(MetricTonsCO2e) float64
GHGEmissionsIntensity(kgCO2e/ft2) float64
DefaultData object
Comment object
ComplianceStatus object
Outlier object
2010 Census Tracts float64
Seattle Police Department Micro Community Policing Plan Areas float64
City Council Districts float64
SPD Beats float64
Zip Codes int64
dtype: object

NOTE:
Veja que agora a coluna “DataYear” está do tipo object.

02 — Trabalhando com Dados Missing

Para esse exemplo de dados missing em uma amostra de dados vamos trabalhar com o dataset 120 years of Olympic history referente a história de 120 anos de jogos olímpicos. Essa amostra de dados contém 15 colunas:

OUTPUT:

ID Name Sex Age Height Weight Team \
0 1 A Dijiang M 24.0 180.0 80.0 China
1 2 A Lamusi M 23.0 170.0 60.0 China
2 3 Gunnar Nielsen Aaby M 24.0 NaN NaN Denmark
3 4 Edgar Lindenau Aabye M 34.0 NaN NaN Denmark/Sweden
4 5 Christine Jacoba Aaftink F 21.0 185.0 82.0 Netherlands

NOC Games Year Season City Sport \
0 CHN 1992 Summer 1992 Summer Barcelona Basketball
1 CHN 2012 Summer 2012 Summer London Judo
2 DEN 1920 Summer 1920 Summer Antwerpen Football
3 DEN 1900 Summer 1900 Summer Paris Tug-Of-War
4 NED 1988 Winter 1988 Winter Calgary Speed Skating

Event Medal
0 Basketball Men’s Basketball NaN
1 Judo Men’s Extra-Lightweight NaN
2 Football Men’s Football NaN
3 Tug-Of-War Men’s Tug-Of-War Gold
4 Speed Skating Women’s 500 metres NaN

ID int64
Name object
Sex object
Age float64
Height float64
Weight float64
Team object
NOC object
Games object
Year int64
Season object
City object
Sport object
Event object
Medal object
dtype: objec

NOTE:
Essa saída não ficou das melhores e eu recomendo que você veja ela em um jupyter notebook para ficar mais legível.

Voltando para o nosso dataset… Se você prestou bem atenção vai ver que na nossa amostra de dados existem valores NaN.

Esse “NaN” é particular do Python que resumidamente significa que os dados estão faltando (ou podem ser zero).

Ok, se se eu quiser excluir todas as linhas que contém valores NaN?
Então, para isso o Pandas tem a função dropna():

OUTPUT:

ID Name Sex Age Height Weight Team NOC \
40 16 Juhamatti Tapio Aaltonen M 28.0 184.0 85.0 Finland FIN
41 17 Paavo Johannes Aaltonen M 28.0 175.0 64.0 Finland FIN
42 17 Paavo Johannes Aaltonen M 28.0 175.0 64.0 Finland FIN
44 17 Paavo Johannes Aaltonen M 28.0 175.0 64.0 Finland FIN
48 17 Paavo Johannes Aaltonen M 28.0 175.0 64.0 Finland FIN

Games Year Season City Sport \
40 2014 Winter 2014 Winter Sochi Ice Hockey
41 1948 Summer 1948 Summer London Gymnastics
42 1948 Summer 1948 Summer London Gymnastics
44 1948 Summer 1948 Summer London Gymnastics
48 1948 Summer 1948 Summer London Gymnastics

Event Medal
40 Ice Hockey Men’s Ice Hockey Bronze
41 Gymnastics Men’s Individual All-Around Bronze
42 Gymnastics Men’s Team All-Around Gold
44 Gymnastics Men’s Horse Vault Gold
48 Gymnastics Men’s Pommelled Horse Gold

NOTE:
Veja que agora não temos nenhum valor NaN.

E se eu quiser saber quantas colunas e amostras (linhas) tem meu dataset? Uma maneira muito simples é utilizar o atributo shape():

OUTPUT:

Veja que acima nós exibimos 2 exemplos:

  • Amostra completa;
  • Amostra sem dados NaN.

Agora se eu quiser diferenciar as colunas em “True” ou “False” na minha amostra tem como?

Sim, muito simples, basta utilizar a função isnull():

OUTPUT:

ID Name Sex Age Height Weight Team NOC Games \
0 False False False False False False False False False
1 False False False False False False False False False
2 False False False False True True False False False
3 False False False False True True False False False
4 False False False False False False False False False
… … … … … … … … … …
271111 False False False False False False False False False
271112 False False False False False False False False False
271113 False False False False False False False False False
271114 False False False False False False False False False
271115 False False False False False False False False False

Year Season City Sport Event Medal
0 False False False False False True
1 False False False False False True
2 False False False False False True
3 False False False False False False
4 False False False False False True
… … … … … … …
271111 False False False False False True
271112 False False False False False True
271113 False False False False False True
271114 False False False False False True
271115 False False False False False True

Veja que agora o nosso retorno foi:

  • False = Quando os valores NÃO são nulos;
  • True = Quando os valores são nulos.

NOTE:
E se eu quiser saber o total de dados faltantes por coluna? Bem, agora nós vamos precisar fazer alguns malabarismo com Python e Pandas, mas não é nenhum bixo de sete cabeças:

OUTPUT:

Veja como foi simples, apenas adicionamos a função sum().

NOTE:
Ta, mas se eu quiser saber quanto porcento % representa esses dados faltantes por coluna? Mais uma vez vamos fazer aquele malabarismo com Python e Pandas para conseguir aplicar isso:

OUTPUT:

Olhando para o resultado acima nós temos que:

  • A coluna “age” tem 3% dos dados missing;
  • A coluna “Height” tem 22% dos dados;
  • A coluna “Weight” tem 23% dos dados missing;
  • E por fim, a coluna “Medal” tem 85% dos dados missing.

Mas como isso foi feito na prática?

  • Primeiro, nós somamos os dados missing por coluna — data.isnull().sum();
  • Depois, dividimos cada coluna pelo o tamanho da nossa amostra — len(data[‘ID’]);
  • E por fim, multiplicamos por 100, ou seja, 100% dos dados.

Ok, tudo lindo… Mas se eu quiser preencher esses valores missing? Por exemplo, na medalha eu desejo trocar os valors NaN por “Nenhuma”.

Para isso é muito simples, basta utilizar a função fillna():

OUTPUT:

Agora, vamos pensar um pouco diferente, que tal preencher os valores NaN pelo a média ou mediana daquela coluna?

Ok, vamos lá… Primeiro, vamos pegar as colunas Height e Weight e substituir os valores NaN pelo a média da respectiva coluna:

OUTPUT:

Vejam como foi simples, nós substituímos valores NaN pelo as médias de cada coluna Height e Weight.

NOTE:
Para substituir pelo a mediana é muito simples, bata seguir a mesma lógica, porém, utilizando a função median().

Ok, agora vamos avançar para alguns conceitos importantes quando se fala de dados missing. Como nós vimos acima é possível ver quanto porcento & de cada coluna está missing - NaN.

Existem várias pesquisas sobre dados missing e o que fazer em cada ocasião. Nós não vamos ver todas, mas vou deixar abaixo algumas dicas importantes:

  • Quando os dados missing estão abaixo de 5% talvez seja irrelevante:
  • Agora quando os dados missing estão acima de 30% já é considero uma quantidade alta de dados faltantes.
  • Agora se por acado os dados missing estão acima de 60% já é algo que deve ser tomada alguma atitude:
  • Porque se você tem mais de 60% dos dados faltando talvez essa variável no nosso modelo seja quase nula.

NOTE:
Lembrando que esses exemplos acima são só observações e dicas. Tudo vai depender da variável e quão importante ela é. Por exemplo, na previsão de uma casa, quais variáveis tem mais relevância? Números de quartos? A cor da casa?

Existem Cientistas de Dados que dizem que todos os dados são relevantes, ou seja, nós nunca devemos excluir nenhuma variável (coluna).

NOTE:
Mas se pensarmos bem, uma variável (coluna) que tem 60% dos dados faltando e nós substituímos esses valores pelo a média ou mediana, nós estamos apenas criando dados artificiais e isso pode gerar uma certa poluição no nosso modelo, podendo gerar um resultado não verídico. Isso porque os dados não foram realmente coletados de fato, e sim nós estamos manipulando artificialmente.

Agora vamos voltar a nossa amostra (dataset) referente ao consumo de energia de prêdios (SEA Building Energy Benchmarking) e aplicar um Pré-Processamento bem simples. vai ser o seguinte:

  • 1ª) — Vamos tirar a média de dados missing (NaN) em cada coluna do nosso Dataset e depois exibir essas médias;
  • 2ª) — Depois vamos trocar os dados missing (NaN) pelo a mediana na coluna - ENERGYSTARScore;
  • 3ª) — Por fim, vamos tirar a média dos dados missing (NaN) de cada coluna do nosso Dataset novamente e depois exibir essas médias.

Vamos ver como fica essa bruxaria em Python?

OUTPUT:

OSEBuildingID 0.000000
DataYear 0.000000
BuildingType 0.000000
PrimaryPropertyType 0.000000
PropertyName 0.000000
TaxParcelIdentificationNumber 0.059880
Location 0.000000
CouncilDistrictCode 0.000000
Neighborhood 0.000000
YearBuilt 0.000000
NumberofBuildings 0.000000
NumberofFloors 0.239521
PropertyGFATotal 0.000000
PropertyGFAParking 0.000000
PropertyGFABuilding(s) 0.000000
ListOfAllPropertyUseTypes 3.802395
LargestPropertyUseType 4.071856
LargestPropertyUseTypeGFA 4.071856
SecondLargestPropertyUseType 53.323353
SecondLargestPropertyUseTypeGFA 53.323353
ThirdLargestPropertyUseType 83.233533
ThirdLargestPropertyUseTypeGFA 83.233533
YearsENERGYSTARCertified 96.706587
ENERGYSTARScore 23.353293 ←
SiteEUI(kBtu/sf) 0.299401
SiteEUIWN(kBtu/sf) 0.299401
SourceEUI(kBtu/sf) 0.299401
SourceEUIWN(kBtu/sf) 0.299401
SiteEnergyUse(kBtu) 0.299401
SiteEnergyUseWN(kBtu) 0.299401
SteamUse(kBtu) 0.299401
Electricity(kWh) 0.299401
Electricity(kBtu) 0.299401
NaturalGas(therms) 0.299401
NaturalGas(kBtu) 0.299401
OtherFuelUse(kBtu) 0.299401
GHGEmissions(MetricTonsCO2e) 0.299401
GHGEmissionsIntensity(kgCO2e/ft2) 0.299401
DefaultData 0.029940
Comment 99.610778
ComplianceStatus 0.000000
Outlier 97.485030
2010 Census Tracts 93.293413
Seattle Police Department Micro Community Policing Plan Areas 0.059880
City Council Districts 93.622754
SPD Beats 0.059880
Zip Codes 0.000000
dtype: float64

OSEBuildingID 0.000000
DataYear 0.000000
BuildingType 0.000000
PrimaryPropertyType 0.000000
PropertyName 0.000000
TaxParcelIdentificationNumber 0.059880
Location 0.000000
CouncilDistrictCode 0.000000
Neighborhood 0.000000
YearBuilt 0.000000
NumberofBuildings 0.000000
NumberofFloors 0.239521
PropertyGFATotal 0.000000
PropertyGFAParking 0.000000
PropertyGFABuilding(s) 0.000000
ListOfAllPropertyUseTypes 3.802395
LargestPropertyUseType 4.071856
LargestPropertyUseTypeGFA 4.071856
SecondLargestPropertyUseType 53.323353
SecondLargestPropertyUseTypeGFA 53.323353
ThirdLargestPropertyUseType 83.233533
ThirdLargestPropertyUseTypeGFA 83.233533
YearsENERGYSTARCertified 96.706587
ENERGYSTARScore 0.000000 ←ENERGYSTARScore
SiteEUI(kBtu/sf) 0.299401
SiteEUIWN(kBtu/sf) 0.299401
SourceEUI(kBtu/sf) 0.299401
SourceEUIWN(kBtu/sf) 0.299401
SiteEnergyUse(kBtu) 0.299401
SiteEnergyUseWN(kBtu) 0.299401
SteamUse(kBtu) 0.299401
Electricity(kWh) 0.299401
Electricity(kBtu) 0.299401
NaturalGas(therms) 0.299401
NaturalGas(kBtu) 0.299401
OtherFuelUse(kBtu) 0.299401
GHGEmissions(MetricTonsCO2e) 0.299401
GHGEmissionsIntensity(kgCO2e/ft2) 0.299401
DefaultData 0.029940
Comment 99.610778
ComplianceStatus 0.000000
Outlier 97.485030
2010 Census Tracts 93.293413
Seattle Police Department Micro Community Policing Plan Areas 0.059880
City Council Districts 93.622754
SPD Beats 0.059880
Zip Codes 0.000000
dtype: float64

NOTE:
Veja que na variável (coluna) “ENERGYSTARScore” depois que nós substituímos os valores nulos (NaN) pelo a mediana nossa saída foi de 0% de dados nulos nessa coluna.

REFERENCES:
Didatica Tech : MÓDULO — I

Rodrigo Leite, Software Engineer

I like to understand how things work and my hobby is to solve real-world problems through A.I, Algorithms, Math, and programming. https://drigols.github.io/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store