KÀepÀrane mÀrkmeraamat kiireks andmete eeltöötluseks

Tihti inimesed, kes siseneb andmete teaduse valdkonda, omavad ebatavalisi ootusi selle kohta, mis neid ees ootab. Paljud arvavad, et nad hakkavad kohe kirjutama keerulisi nÀrvivÔrke, looma raudmehe hÀÀlabilisi vÔi vÔidavad kÔiki finantsturgudel.
Kuid töö Andmed teadlasena on seotud andmetega, ning ĂŒks olulisemaid ja kĂ”ige ajakulukamaid hetki on andmete töötlemine enne nende sisestamist nĂ€rvivĂ”rku vĂ”i enne kindlal viisil analĂŒĂŒsimist.

Selles artiklis kirjeldab meie meeskond, kuidas andmeid lihtsalt ja kiiresti töödelda, et jĂ€lgida samm-sammult juhiseid ja koode. Oleme pĂŒĂŒdnud, et kood oleks piisavalt paindlik ja seda saaks kasutada erinevate andmekogumite jaoks.

Paljud spetsialistid ei pruugi selle artikli sisu leida midagi erakordset, kuid algajad saavad kindlasti midagi uut ja igaĂŒks, kes on pikka aega soovinud luua enda jaoks eraldi mĂ€rkmiku kiireks ja struktureeritud andmete töötlemiseks, saab koode kopeerida ja kohandada endale sobivaks, vĂ”i laadida valmis mĂ€rkmiku Githubist.

Olete saanud andmekogumi. Mida edasi teha?

Seega, standart: tuleb mĂ”ista, millega meil tegu on, ĂŒldpilti. Selleks kasutame pandas't, et lihtsalt mÀÀrata erinevaid andmetĂŒĂŒpe.

import pandas as pd #impordime pandas
import numpy as np  #impordime numpy
df = pd.read_csv("AB_NYC_2019.csv") #loeme andmestiku ja salvestame muutuja df

df.head(3) #vaatame kolme esimese rida, et mÔista, kuidas vÀÀrtused vÀlja nÀevad

KÀepÀrane mÀrkmeraamat kiireks andmete eeltöötluseks

df.info() #Kuvame teavet veergude kohta

KÀepÀrane mÀrkmeraamat kiireks andmete eeltöötluseks

Vaatame veergude vÀÀrtuseid:

  1. Kas iga veeru ridade arv vastab koguarvule ridadele?
  2. Mis on iga veeru andmete olemus?
  3. Millist veergu soovime teha sihiks, et teha ennustusi selle kohta?

Nendele kĂŒsimustele vastamine vĂ”imaldab analĂŒĂŒsida andmestikku ning koostada lĂŒhiajaline tegevuskava.

Samuti, et sĂŒgavamalt vaadata iga veeru vÀÀrtusi, saame kasutada pandas'i funktsiooni describe(). Kahjuks ei paku see funktsioon teavet string-vÀÀrtustega veergude kohta. Nendega tegeleme hiljem.

df.describe()

KÀepÀrane mÀrkmeraamat kiireks andmete eeltöötluseks

Mugav visualiseerimine

Vaatame, kus meil puuduvad vÀÀrtused tÀielikult:

import seaborn as sns
sns.heatmap(df.isnull(), yticklabels=False, cbar=False, cmap='viridis')

KÀepÀrane mÀrkmeraamat kiireks andmete eeltöötluseks

See oli vĂ€ike ĂŒlevaade, nĂŒĂŒd liikume huvitavamate asjade juurde

PĂŒĂŒame leida ja vĂ”imalusel eemaldada veerud, milles on ainult ĂŒks vÀÀrtus kĂ”igis ridades (need ei mĂ”juta tulemust):

df = df[[c for c
        in list(df)
        if len(df[c].unique()) > 1]] #Uuendame andmestikku, jĂ€ttes alles vaid need veerud, kus on rohkem kui ĂŒks unikaalne vÀÀrtus

Kaitseme end ja meie projekti edu duplikaatridade eest (ridade ees, mis sisaldavad sama teavet samas jÀrjekorras nagu juba olemasolevad read):

df.drop_duplicates(inplace=True) #Teeme seda, kui peame seda vajalikuks.
                                 #MÔnes projektis ei ole otstarbekas selliseid andmeid alguses eemaldada.

Jagame andmestiku kaheks: ĂŒks kvaliteetsete vÀÀrtuste jaoks ja teine kvantitatiivsete vÀÀrtuste jaoks

Siin on vajalik vĂ€ike tĂ€psustus: kui ridade vahel, kus on puudu andmeid kvalitatiivsete ja kvantitatiivsete andmete osas, ei ole tugev seos, siis tuleb otsustada, millest loobume — kas kĂ”igist puuduvate andmetega ridadest, ainult osast neist vĂ”i teatud veergudest. Kui read omavahel seonduvad, siis on meil tĂ€ielik Ă”igus jagada andmestiku kahte osa. Vastasel juhul tuleb esmalt lahendada read, kus kvalitatiivsetes ja kvantitatiivsetes andmetes puuduvad andmed ei seondu, ja alles seejĂ€rel jagada andmestik kahte osa.

df_numerical = df.select_dtypes(include = [np.number])
df_categorical = df.select_dtypes(exclude = [np.number])

Teeme seda, et oleks kergem töötada nende kahe erineva andmeliigiga — hiljem mĂ”istame, kui palju see meie elu lihtsustab.

Töötame kvantitatiivsete andmetega

Esimene asi, mida peaksime teema, on mÀÀrata, kas kvantitatiivsetes andmetes on „nuhi-veerge“. Me nimetame neid veerge nii, kuna nad annavad end vĂ€lja kvantitatiivsete andmetena, kuid töötavad tegelikult nagu kvaliteedilised.

Kuidas me need mÀÀratleme? Loomulikult sĂ”ltub kĂ”ik analĂŒĂŒsitavate andmete iseloomust, kuid peamiselt vĂ”ivad sellised veerud omada vĂ€he unikaalseid andmeid (umbes 3-10 unikaalset vÀÀrtust).

print(df_numerical.nunique())

PÀrast seda, kui oleme mÀÀratlenud nuhkveerud, liigutame need kvantitatiivsetest andmetest kvalitatiivsetesse:

spy_columns = df_numerical[['veeru1', 'veeru2', 'veeru3']]#valime nuhkveerud ja salvestame need eraldi dataframe'iks
df_numerical.drop(labels=['veeru1', 'veeru2', 'veeru3'], axis=1, inplace=True)#kustutame need veerud kvantitatiivsetest andmetest
df_categorical.insert(1, 'veeru1', spy_columns['veeru1']) #lisame esimese nuhkveeru kvalitatiivsetesse andmetesse
df_categorical.insert(1, 'veeru2', spy_columns['veeru2']) #lisame teise nuhkveeru kvalitatiivsetesse andmetesse
df_categorical.insert(1, 'veeru3', spy_columns['veeru3']) #lisame kolmanda nuhkveeru kvalitatiivsetesse andmetesse

Saime lĂ”puks tĂ€ielikult eraldada kvantitatiivsed andmed kvalitatiivsetest ning nĂŒĂŒd saame nendega korralikult töötada. Esiteks — tuleb mĂ”ista, kus meil on tĂŒhjad vÀÀrtused (NaN, ja mĂ”nel juhul tunneme 0 tĂŒhjade vÀÀrtustena).

for i in df_numerical.columns:
    print(i, df[i][df[i]==0].count())

Selles etapis on oluline mĂ”ista, millistes veergudes nullid vĂ”ivad tĂ€hendada puuduvaid vÀÀrtusi: kas see on seotud andmete kogumisega? VĂ”i vĂ”ivad need olla seotud andmete vÀÀrtustega? Neile kĂŒsimustele tuleb vastata igas eraldi juhus.

Nii et kui me oleme ikka jÔudnud jÀreldusele, et andmed vÔivad puududa seal, kus on nullid, tuleks nullid asendada NaN-iga, et oleks hiljem lihtsam töötada nende kadunud andmetega:

df_numerical[["veerg 1", "veerg 2"]] = df_numerical[["veerg 1", "veerg 2"]].replace(0, nan)

NĂŒĂŒd vaatame, kus meil on puuduvad andmed:

sns.heatmap(df_numerical.isnull(), yticklabels=False, cbar=False, cmap='viridis') # Samuti saab kasutada df_numerical.info()

KÀepÀrane mÀrkmeraamat kiireks andmete eeltöötluseks

Siin peaksid kollase vĂ€rviga olema mĂ€rgitud need vÀÀrtused veergudes, mis puuduvad. Ja nĂŒĂŒd algab kĂ”ige huvitavam osa — kuidas nende vÀÀrtustega kĂ€ituda? Kustutada need ridadega vĂ”i veergudega? VĂ”i tĂ€ita need tĂŒhjad vÀÀrtused millegagi?

Siin on ligikaudne skeem, mis vĂ”ib aidata teil otsustada, mida pĂ”himĂ”tteliselt teha tĂŒhjade vÀÀrtustega:

KÀepÀrane mÀrkmeraamat kiireks andmete eeltöötluseks

0. Kustutame mittevajalikud veerud

df_numerical.drop(labels=["veerg1", "veerg2"], axis=1, inplace=True)

1. Kas selle veeru tĂŒhjade vÀÀrtuste arv ĂŒletab 50%?

print(df_numerical.isnull().sum() / df_numerical.shape[0] * 100)

df_numerical.drop(labels=["veerg1", "veerg2"], axis=1, inplace=True) # Eemaldame, kui mĂ”nes veerus on rohkem kui 50 tĂŒhja vÀÀrtust

2. Eemaldame tĂŒhjad vÀÀrtused ridadest

df_numerical.dropna(inplace=True) # Eemaldame tĂŒhjad vÀÀrtused ridadest, kui jÀÀb piisavalt andmeid koolituseks

3.1. Sisestame juhusliku vÀÀrtuse

import random # impordime random
df_numerical["veerg"].fillna(lambda x: random.choice(df[df[column] != np.nan]["veerg"]), inplace=True) # sisestame juhuslikud vÀÀrtused tĂŒhjadesse lahtritesse

3.2. Sisestame konstantsed vÀÀrtused

from sklearn.impute import SimpleImputer # impordime SimpleImputeri, mis aitab sisestada vÀÀrtusi
imputer = SimpleImputer(strategy='constant', fill_value="") # sisestame kindla vÀÀrtuse SimpleImputeriga
df_numerical[["uus_veerg1", 'uus_veerg2', 'uus_veerg3']] = imputer.fit_transform(df_numerical[['veerg1', 'veerg2', 'veerg3']]) # Rakendame seda meie tabelisse
df_numerical.drop(labels=["veerg1", "veerg2", "veerg3"], axis=1, inplace=True) # Eemaldame veerud vanade vÀÀrtustega

3.3. Sisestame keskmise vÔi kÔige sagedasema vÀÀrtuse

from sklearn.impute import SimpleImputer # teiste vÀÀrtuste tÀitmiseks vajalik SimpleImputer imporditakse
imputer = SimpleImputer(strategy='mean', missing_values = np.nan) # mean'i asemel vÔib kasutada ka most_frequent
df_numerical[["uus_kategooria1", 'uus_kategooria2', 'uus_kategooria3']] = imputer.fit_transform(df_numerical[['kategooria1', 'kategooria2', 'kategooria3']]) # rakendame seda meie tabelis
df_numerical.drop(labels = ["kategooria1", "kategooria2", "kategooria3"], axis = 1, inplace = True) # eemaldame vanad vÀÀrtused

3.4. Sisestame vÀÀrtuse, mille teine mudel on arvutanud

MĂ”nikord saab vÀÀrtusi arvutada regressioonimudelite abil, kasutades sklearn'i vĂ”i teiste sarnaste teekide mudeleid. Meie meeskond pĂŒhendab sellele teemale eraldi artikli lĂ€hitulevikus.

Nii et, kuigi kvantitatiivsete andmete jutustus katkeb, kuna on palju muid nĂŒansse, kuidas andmete ettevalmistamist ja eeltöötlemist erinevate ĂŒlesannete jaoks paremini teha, ja baasasjad kvantitatiivsete andmete jaoks on selles artiklis arvesse vĂ”etud, on nĂŒĂŒd Ă”ige aeg naasta kvalitatiivsete andmete juurde, mille me mĂ”ni samm tagasi kvantitatiivsetest eraldasime. Te saate seda notebook'i muuta nii, nagu soovite, kohandades seda erinevate ĂŒlesannete jaoks, et andmete eeltöötlemine toimuks vĂ€ga kiiresti!

Kvalitatiivsed andmed

Kvalitatiivsete andmete puhul kasutatakse peamiselt meetodit One-hot-encoding, et vormindada need string'idest (vĂ”i objektidest) numbriteks. Enne selle punkti juurde liikumist kasuta ĂŒleval olevat skeemi ja koodi, et tegeleda puuduva vÀÀrtusega.

df_categorical.nunique()

sns.heatmap(df_categorical.isnull(), yticklabels=False, cbar=False, cmap='viridis')

KÀepÀrane mÀrkmeraamat kiireks andmete eeltöötluseks

0. Kustutame mittevajalikud veerud

df_categorical.drop(labels=["ĐșĐŸĐ»ĐŸĐœĐșа1", "ĐșĐŸĐ»ĐŸĐœĐșа2"], axis=1, inplace=True)

1. Kas selle veeru tĂŒhjade vÀÀrtuste arv ĂŒletab 50%?

print(df_categorical.isnull().sum() / df_numerical.shape[0] * 100)

df_categorical.drop(labels=["ĐșĐŸĐ»ĐŸĐœĐșа1", "ĐșĐŸĐ»ĐŸĐœĐșа2"], axis=1, inplace=True) # Eemaldame, kui mĂ”nes tulbas on rohkem kui 50% tĂŒhje vÀÀrtusi

2. Eemaldame tĂŒhjad vÀÀrtused ridadest

df_categorical.dropna(inplace=True)#Eemame tĂŒhjad read, 
                                   #kui jÀÀb piisavalt andmeid Ôppimiseks

3.1. Sisestame juhusliku vÀÀrtuse

import random
df_categorical["veerg"].fillna(lambda x: random.choice(df[df[column] != np.nan]["veerg"]), inplace=True)

3.2. Sisestame konstantsed vÀÀrtused

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='constant', fill_value="")
df_categorical[["uus_veerg1", 'uus_veerg2', 'uus_veerg3']] = imputer.fit_transform(df_categorical[['veerg1', 'veerg2', 'veerg3']])
df_categorical.drop(labels=["veerg1", "veerg2", "veerg3"], axis=1, inplace=True)

Nii, lĂ”puks oleme saanud aru, kuidas tegeleda tĂŒhjade vÀÀrtustega kvalitatiivsetes andmetes. NĂŒĂŒd on aeg teostada one-hot-encoding vÀÀrtuste jaoks, mis teie andmebaasis on. See meetod on ÀÀrmisel sagedasel kasutusel, et teie algoritm saaks Ă”ppida kvalitatiivsete andmete arvestamisel.

def encode_and_bind(original_dataframe, feature_to_encode):
    dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
    res = pd.concat([original_dataframe, dummies], axis=1)
    res = res.drop([feature_to_encode], axis=1)
    return(res)

features_to_encode = ["veerg1", "veerg2", "veerg3"]
for feature in features_to_encode:
    df_categorical = encode_and_bind(df_categorical, feature)

Nii, lĂ”puks oleme lĂ”petanud kvalitatiivsete ja kvantitatiivsete andmete töötlemise – aeg on need jĂ€lle kokku viia.

new_df = pd.concat([df_numerical,df_categorical], axis=1)

PĂ€rast andmestike ĂŒhendamist ĂŒhte saab me kasutada andmete teisendamist MinMaxScaler abil, mis on saadaval sklearn raamatukogus. See aitab hoida meie vÀÀrtusi vahemikus 0 kuni 1, mis on kasulik mudeli koolitamiseks tulevikus.

from sklearn.preprocessing import MinMaxScaler
min_max_scaler = MinMaxScaler()
new_df = min_max_scaler.fit_transform(new_df)

Need andmed on nĂŒĂŒd valmis kĂ”ikideks — nĂ€rvivĂ”rkude, standardsete ML algoritmide jne jaoks!

Selles artiklis ei ole me arvesse vĂ”tnud ajaseeriatega seotud andmete töötlemist, kuna selliste andmete korral tuleks kasutada veidi teisi töötlustehnikaid, sĂ”ltuvalt teie ĂŒlesandest. Tulevikus pĂŒhendab meie meeskond sellele teemale eraldi artikli, lootes, et see toob teie ellu midagi huvitavat, uut ja kasulikku, just nagu see.

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster