Beležnica-goljufalica za hitro predhodno obdelavo podatkov

Ljudje, ki vstopajo na področje podatkovne znanosti, pogosto nimajo realnih pričakovanj o tem, kaj jih čaka. Mnogi mislijo, da bodo zdaj pisali kul nevronske mreže, ustvarili glasovnega pomočnika iz Iron Mana ali premagali vse na finančnih trgih.
Ampak delo datum Znanstvenik temelji na podatkih in eden najpomembnejših in dolgotrajnejših vidikov je obdelava podatkov, preden se vnesejo v nevronsko mrežo ali analizirajo na določen način.

V tem članku bo naša ekipa opisala, kako lahko hitro in enostavno obdelate podatke z navodili po korakih in kodo. Poskušali smo narediti kodo precej prilagodljivo in jo je bilo mogoče uporabiti za različne nabore podatkov.

Mnogi strokovnjaki v tem članku morda ne bodo našli nič nenavadnega, začetniki pa se bodo lahko naučili nekaj novega, vsi, ki že dolgo sanjajo o izdelavi ločenega zvezka za hitro in strukturirano obdelavo podatkov, pa lahko kopirajo kodo in jo oblikujejo zase ali prenesite končni zvezek iz Githuba.

Prejeli smo nabor podatkov. Kaj storiti naprej?

Torej, standard: razumeti moramo, s čim imamo opravka, celotno sliko. Da bi to naredili, uporabljamo pande za preprosto definiranje različnih tipov podatkov.

import pandas as pd #импортируем pandas
import numpy as np  #импортируем numpy
df = pd.read_csv("AB_NYC_2019.csv") #читаем датасет и записываем в переменную df

df.head(3) #смотрим на первые 3 строчки, чтобы понять, как выглядят значения

Beležnica-goljufalica za hitro predhodno obdelavo podatkov

df.info() #Демонстрируем информацию о колонках

Beležnica-goljufalica za hitro predhodno obdelavo podatkov

Poglejmo vrednosti stolpcev:

  1. Ali število vrstic v vsakem stolpcu ustreza skupnemu številu vrstic?
  2. Kaj je bistvo podatkov v posameznem stolpcu?
  3. Na kateri stolpec želimo ciljati, da bomo zanj lahko predvidevali?

Odgovori na ta vprašanja vam bodo omogočili analizo nabora podatkov in grobo sestavo načrta za vaša naslednja dejanja.

Za globlji vpogled v vrednosti v vsakem stolpcu lahko uporabimo tudi funkcijo pandas describe(). Vendar pa je pomanjkljivost te funkcije ta, da ne zagotavlja informacij o stolpcih z vrednostmi nizov. Z njimi se bomo ukvarjali kasneje.

df.describe()

Beležnica-goljufalica za hitro predhodno obdelavo podatkov

Čarobna vizualizacija

Poglejmo, kje sploh nimamo nobenih vrednot:

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

Beležnica-goljufalica za hitro predhodno obdelavo podatkov

To je bil kratek pogled od zgoraj, zdaj pa gremo na bolj zanimive stvari

Poskusimo najti in, če je mogoče, odstraniti stolpce, ki imajo samo eno vrednost v vseh vrsticah (na noben način ne bodo vplivali na rezultat):

df = df[[c for c
        in list(df)
        if len(df[c].unique()) > 1]] #Перезаписываем датасет, оставляя только те колонки, в которых больше одного уникального значения

Sedaj zaščitimo sebe in uspeh našega projekta pred podvojenimi vrsticami (vrsticami, ki vsebujejo iste informacije v istem vrstnem redu kot ena od obstoječih vrstic):

df.drop_duplicates(inplace=True) #Делаем это, если считаем нужным.
                                 #В некоторых проектах удалять такие данные с самого начала не стоит.

Nabor podatkov razdelimo na dva dela: enega s kvalitativnimi vrednostmi in drugega s kvantitativnimi.

Tu moramo narediti majhno pojasnilo: če vrstice z manjkajočimi podatki v kvalitativnih in kvantitativnih podatkih med seboj niso zelo povezane, se bomo morali odločiti, kaj bomo žrtvovali - vse vrstice z manjkajočimi podatki, le del njih, ali določene stolpce. Če sta vrstici povezani, imamo vso pravico razdeliti nabor podatkov na dva dela. V nasprotnem primeru boste morali najprej obravnavati vrstice, ki manjkajočih podatkov ne povezujejo kvalitativno in kvantitativno, in šele nato nabor podatkov razdeliti na dva dela.

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

To počnemo, da bi nam olajšali obdelavo teh dveh različnih vrst podatkov – kasneje bomo razumeli, koliko nam to olajša življenje.

Delamo s kvantitativnimi podatki

Prva stvar, ki jo moramo storiti, je ugotoviti, ali so v kvantitativnih podatkih "vohunski stolpci". Te stolpce tako imenujemo, ker se predstavljajo kot kvantitativni podatki, delujejo pa kot kvalitativni podatki.

Kako jih lahko prepoznamo? Seveda je vse odvisno od narave podatkov, ki jih analizirate, vendar imajo lahko takšni stolpci na splošno malo edinstvenih podatkov (v območju 3–10 edinstvenih vrednosti).

print(df_numerical.nunique())

Ko bomo identificirali vohunske stolpce, jih bomo premaknili iz kvantitativnih podatkov v kvalitativne podatke:

spy_columns = df_numerical[['колонка1', 'колока2', 'колонка3']]#выделяем колонки-шпионы и записываем в отдельную dataframe
df_numerical.drop(labels=['колонка1', 'колока2', 'колонка3'], axis=1, inplace = True)#вырезаем эти колонки из количественных данных
df_categorical.insert(1, 'колонка1', spy_columns['колонка1']) #добавляем первую колонку-шпион в качественные данные
df_categorical.insert(1, 'колонка2', spy_columns['колонка2']) #добавляем вторую колонку-шпион в качественные данные
df_categorical.insert(1, 'колонка3', spy_columns['колонка3']) #добавляем третью колонку-шпион в качественные данные

Končno smo popolnoma ločili kvantitativne podatke od kvalitativnih podatkov in zdaj lahko z njimi pravilno delamo. Prva stvar je razumeti, kje imamo prazne vrednosti (NaN in v nekaterih primerih 0 bodo sprejete kot prazne vrednosti).

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

Na tej točki je pomembno razumeti, v katerih stolpcih lahko ničle označujejo manjkajoče vrednosti: ali je to posledica načina zbiranja podatkov? Ali pa je to lahko povezano z vrednostmi podatkov? Na ta vprašanja je treba odgovoriti od primera do primera.

Torej, če se še vedno odločimo, da morda manjkajo podatki tam, kjer so ničle, bi morali zamenjati ničle z NaN, da bi kasneje olajšali delo s temi izgubljenimi podatki:

df_numerical[["колонка 1", "колонка 2"]] = df_numerical[["колонка 1", "колонка 2"]].replace(0, nan)

Zdaj pa poglejmo, kje nam manjkajo podatki:

sns.heatmap(df_numerical.isnull(),yticklabels=False,cbar=False,cmap='viridis') # Можно также воспользоваться df_numerical.info()

Beležnica-goljufalica za hitro predhodno obdelavo podatkov

Tukaj morajo biti tiste vrednosti v stolpcih, ki manjkajo, označene z rumeno. In zdaj se začne zabava – kako ravnati s temi vrednotami? Ali naj izbrišem vrstice s temi vrednostmi ali stolpce? Ali pa te prazne vrednosti zapolnite z drugimi?

Tukaj je približen diagram, ki vam lahko pomaga pri odločitvi, kaj je načeloma mogoče narediti s praznimi vrednostmi:

Beležnica-goljufalica za hitro predhodno obdelavo podatkov

0. Odstranite nepotrebne stolpce

df_numerical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)

1. Ali je število praznih vrednosti v tem stolpcu večje od 50%?

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

df_numerical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)#Удаляем, если какая-то колонка имеет больше 50 пустых значений

2. Izbrišite vrstice s praznimi vrednostmi

df_numerical.dropna(inplace=True)#Удаляем строчки с пустыми значениями, если потом останется достаточно данных для обучения

3.1. Vstavljanje naključne vrednosti

import random #импортируем random
df_numerical["колонка"].fillna(lambda x: random.choice(df[df[column] != np.nan]["колонка"]), inplace=True) #вставляем рандомные значения в пустые клетки таблицы

3.2. Vstavljanje konstantne vrednosti

from sklearn.impute import SimpleImputer #импортируем SimpleImputer, который поможет вставить значения
imputer = SimpleImputer(strategy='constant', fill_value="<Ваше значение здесь>") #вставляем определенное значение с помощью SimpleImputer
df_numerical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_numerical[['колонка1', 'колонка2', 'колонка3']]) #Применяем это для нашей таблицы
df_numerical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True) #Убираем колонки со старыми значениями

3.3. Vnesite povprečno ali najpogostejšo vrednost

from sklearn.impute import SimpleImputer #импортируем SimpleImputer, который поможет вставить значения
imputer = SimpleImputer(strategy='mean', missing_values = np.nan) #вместо mean можно также использовать most_frequent
df_numerical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_numerical[['колонка1', 'колонка2', 'колонка3']]) #Применяем это для нашей таблицы
df_numerical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True) #Убираем колонки со старыми значениями

3.4. Vstavite vrednost, izračunano z drugim modelom

Včasih je mogoče vrednosti izračunati z uporabo regresijskih modelov z uporabo modelov iz knjižnice sklearn ali drugih podobnih knjižnic. Naša ekipa bo v bližnji prihodnosti posvetila ločen članek o tem, kako je to mogoče storiti.

Torej, zaenkrat bo pripoved o kvantitativnih podatkih prekinjena, ker obstaja veliko drugih nians o tem, kako bolje narediti pripravo in predprocesiranje podatkov za različne naloge, in osnovne stvari za kvantitativne podatke so bile upoštevane v tem članku in zdaj je čas, da se vrnemo h kvalitativnim podatkom, ki smo jih ločili nekaj korakov nazaj od kvantitativnih. Ta zvezek lahko poljubno spreminjate in ga prilagajate različnim opravilom, tako da predobdelava podatkov poteka zelo hitro!

Kvalitativni podatki

V bistvu se za kvalitativne podatke uporablja metoda One-hot-encoding, da se formatirajo iz niza (ali predmeta) v število. Preden preidemo na to točko, uporabimo zgornji diagram in kodo za obravnavo praznih vrednosti.

df_categorical.nunique()

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

Beležnica-goljufalica za hitro predhodno obdelavo podatkov

0. Odstranite nepotrebne stolpce

df_categorical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)

1. Ali je število praznih vrednosti v tem stolpcu večje od 50%?

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

df_categorical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True) #Удаляем, если какая-то колонка 
                                                                          #имеет больше 50% пустых значений

2. Izbrišite vrstice s praznimi vrednostmi

df_categorical.dropna(inplace=True)#Удаляем строчки с пустыми значениями, 
                                   #если потом останется достаточно данных для обучения

3.1. Vstavljanje naključne vrednosti

import random
df_categorical["колонка"].fillna(lambda x: random.choice(df[df[column] != np.nan]["колонка"]), inplace=True)

3.2. Vstavljanje konstantne vrednosti

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='constant', fill_value="<Ваше значение здесь>")
df_categorical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_categorical[['колонка1', 'колонка2', 'колонка3']])
df_categorical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True)

Torej, končno smo se spopadli z ničelnimi vrednostmi v kvalitativnih podatkih. Zdaj je čas, da izvedete enkratno kodiranje vrednosti, ki so v vaši bazi podatkov. Ta metoda se zelo pogosto uporablja za zagotovitev, da se lahko vaš algoritem uči iz visokokakovostnih podatkov.

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 = ["колонка1","колонка2","колонка3"]
for feature in features_to_encode:
    df_categorical = encode_and_bind(df_categorical, feature))

Tako smo končno končali obdelavo ločenih kvalitativnih in kvantitativnih podatkov – čas je, da jih ponovno združimo

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

Ko smo nabore podatkov združili v enega, lahko končno uporabimo transformacijo podatkov z uporabo MinMaxScaler iz knjižnice sklearn. S tem bodo naše vrednosti med 0 in 1, kar bo v pomoč pri urjenju modela v prihodnosti.

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

Ti podatki so zdaj pripravljeni za vse – nevronske mreže, standardne algoritme ML itd.!

V tem članku nismo upoštevali dela s podatki časovnih vrst, saj bi morali za take podatke uporabiti nekoliko drugačne tehnike obdelave, odvisno od vaše naloge. V prihodnosti bo naša ekipa tej temi posvetila poseben članek in upamo, da bo lahko v vaše življenje prinesel nekaj zanimivega, novega in uporabnega, tako kot je ta.

Vir: www.habr.com

Dodaj komentar