Laptop cheat sheet za brzu prethodnu obradu podataka

Često ljudi koji ulaze u polje nauke o podacima imaju manje od realnih očekivanja o tome šta ih čeka. Mnogi ljudi misle da će sada pisati cool neuronske mreže, kreirati glasovnog asistenta iz Iron Mana ili pobijediti sve na finansijskim tržištima.
Ali posao podaci Naučnici su vođeni podacima, a jedan od najvažnijih i dugotrajnih aspekata je obrada podataka prije nego što se unesu u neuronsku mrežu ili analiziraju na određeni način.

U ovom članku naš tim će opisati kako možete brzo i jednostavno obraditi podatke pomoću detaljnih uputstava i koda. Pokušali smo učiniti kod prilično fleksibilnim i mogao bi se koristiti za različite skupove podataka.

Mnogi profesionalci možda neće pronaći ništa neobično u ovom članku, ali početnici će moći naučiti nešto novo, a svako ko već dugo sanja da napravi zasebnu bilježnicu za brzu i strukturiranu obradu podataka može kopirati kod i formatirati ga za sebe, ili preuzmite gotovu bilježnicu sa Github-a.

Dobili smo skup podataka. Šta dalje?

Dakle, standard: moramo razumjeti sa čime imamo posla, cjelokupnu sliku. Da bismo to učinili, koristimo pande da jednostavno definiramo različite tipove podataka.

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

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

Laptop cheat sheet za brzu prethodnu obradu podataka

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

Laptop cheat sheet za brzu prethodnu obradu podataka

Pogledajmo vrijednosti stupaca:

  1. Da li broj redova u svakoj koloni odgovara ukupnom broju redova?
  2. Koja je suština podataka u svakoj koloni?
  3. Koju kolonu želimo ciljati da bismo za nju napravili predviđanja?

Odgovori na ova pitanja će vam omogućiti da analizirate skup podataka i grubo nacrtate plan za svoje sljedeće akcije.

Također, za dublji pogled na vrijednosti u svakoj koloni, možemo koristiti funkciju pandas describe(). Međutim, nedostatak ove funkcije je što ne daje informacije o stupcima sa vrijednostima niza. Pozabavićemo se njima kasnije.

df.describe()

Laptop cheat sheet za brzu prethodnu obradu podataka

Magična vizualizacija

Pogledajmo gdje uopće nemamo vrijednosti:

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

Laptop cheat sheet za brzu prethodnu obradu podataka

Ovo je bio kratak pogled odozgo, sada ćemo preći na zanimljivije stvari

Pokušajmo pronaći i, ako je moguće, ukloniti stupce koji imaju samo jednu vrijednost u svim redovima (ni na koji način neće utjecati na rezultat):

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

Sada štitimo sebe i uspjeh našeg projekta od duplih linija (redova koji sadrže iste informacije istim redoslijedom kao i jedan od postojećih redova):

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

Skup podataka dijelimo na dva: jedan s kvalitativnim vrijednostima, a drugi s kvantitativnim

Ovdje moramo napraviti malo pojašnjenje: ako linije s nedostajućim podacima u kvalitativnim i kvantitativnim podacima nisu jako povezane jedna s drugom, onda ćemo morati odlučiti šta ćemo žrtvovati - sve linije s podacima koji nedostaju, samo dio njih, ili određene kolone. Ako su linije u korelaciji, onda imamo puno pravo podijeliti skup podataka na dva. U suprotnom, prvo ćete se morati pozabaviti linijama koje ne povezuju podatke koji nedostaju u kvalitativnom i kvantitativnom smislu, a tek onda podijeliti skup podataka na dva.

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

To radimo kako bismo sebi olakšali obradu ove dvije različite vrste podataka – kasnije ćemo shvatiti koliko nam to čini život lakšim.

Radimo sa kvantitativnim podacima

Prvo što treba da uradimo je da utvrdimo da li u kvantitativnim podacima postoje „špijunske kolone“. Ove kolone nazivamo tako jer se predstavljaju kao kvantitativni podaci, ali djeluju kao kvalitativni podaci.

Kako ih možemo identificirati? Naravno, sve ovisi o prirodi podataka koje analizirate, ali općenito takve kolone mogu imati malo jedinstvenih podataka (u području od 3-10 jedinstvenih vrijednosti).

print(df_numerical.nunique())

Nakon što identificiramo špijunske kolone, premjestit ćemo ih iz kvantitativnih podataka u 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']) #добавляем третью колонку-шпион в качественные данные

Konačno, potpuno smo razdvojili kvantitativne podatke od kvalitativnih i sada možemo pravilno raditi s njima. Prva stvar je razumjeti gdje imamo prazne vrijednosti (NaN, au nekim slučajevima 0 će biti prihvaćeno kao prazne vrijednosti).

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

U ovom trenutku, važno je razumjeti u kojim kolonama nule mogu ukazivati ​​na vrijednosti koje nedostaju: da li je to zbog načina na koji su podaci prikupljeni? Ili bi to moglo biti povezano s vrijednostima podataka? Na ova pitanja se mora odgovoriti od slučaja do slučaja.

Dakle, ako ipak odlučimo da nam možda nedostaju podaci gdje postoje nule, trebali bismo zamijeniti nule s NaN kako bismo kasnije olakšali rad s ovim izgubljenim podacima:

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

Sada da vidimo gdje nam nedostaju podaci:

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

Laptop cheat sheet za brzu prethodnu obradu podataka

Ovdje one vrijednosti unutar kolona koje nedostaju trebaju biti označene žutom bojom. A sada počinje zabava – kako se nositi s tim vrijednostima? Da li da izbrišem redove sa ovim vrednostima ili kolone? Ili popunite ove prazne vrijednosti nekim drugim?

Evo približnog dijagrama koji vam može pomoći da odlučite šta se, u principu, može učiniti s praznim vrijednostima:

Laptop cheat sheet za brzu prethodnu obradu podataka

0. Uklonite nepotrebne kolone

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

1. Da li je broj praznih vrijednosti u ovoj koloni veći 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 linije sa praznim vrijednostima

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

3.1. Umetanje nasumične vrijednosti

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

3.2. Umetanje konstantne vrijednosti

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. Unesite prosječnu ili najčešću vrijednost

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. Unesite vrijednost izračunatu drugim modelom

Ponekad se vrijednosti mogu izračunati korištenjem regresijskih modela koristeći modele iz sklearn biblioteke ili drugih sličnih biblioteka. Naš tim će posvetiti poseban članak o tome kako se to može učiniti u bliskoj budućnosti.

Dakle, za sada ćemo prekinuti narativ o kvantitativnim podacima, jer postoje mnoge druge nijanse o tome kako bolje napraviti pripremu i pretprocesu podataka za različite zadatke, a osnovne stvari za kvantitativne podatke uzete su u obzir u ovom članku, a sada je vrijeme da se vratimo na kvalitativne podatke koje smo odvojili nekoliko koraka unazad od kvantitativnih. Ovu bilježnicu možete mijenjati kako želite, prilagođavajući je različitim zadacima, tako da prethodna obrada podataka ide vrlo brzo!

Kvalitativni podaci

U osnovi, za kvalitativne podatke, metoda One-hot-encoding se koristi kako bi se formatirali iz niza (ili objekta) u broj. Prije nego što pređemo na ovu tačku, koristimo dijagram i kod iznad da se pozabavimo praznim vrijednostima.

df_categorical.nunique()

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

Laptop cheat sheet za brzu prethodnu obradu podataka

0. Uklonite nepotrebne kolone

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

1. Da li je broj praznih vrijednosti u ovoj koloni veći 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 linije sa praznim vrijednostima

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

3.1. Umetanje nasumične vrijednosti

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

3.2. Umetanje konstantne vrijednosti

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)

Dakle, konačno smo dobili kontrolu nad nultima u kvalitativnim podacima. Sada je vrijeme da izvršite jednokratno kodiranje na vrijednostima koje se nalaze u vašoj bazi podataka. Ova metoda se vrlo često koristi kako bi se osiguralo da vaš algoritam može učiti iz visokokvalitetnih podataka.

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))

Dakle, konačno smo završili obradu odvojenih kvalitativnih i kvantitativnih podataka - vrijeme je da ih ponovo spojimo

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

Nakon što smo spojili skupove podataka u jedan, konačno možemo koristiti transformaciju podataka koristeći MinMaxScaler iz sklearn biblioteke. Ovo će naše vrijednosti postaviti između 0 i 1, što će pomoći prilikom obuke modela u budućnosti.

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

Ovi podaci su sada spremni za sve - neuronske mreže, standardne ML algoritme, itd.!

U ovom članku nismo uzeli u obzir rad s podacima vremenskih serija, jer bi za takve podatke trebali koristiti nešto drugačije tehnike obrade, ovisno o zadatku. Ubuduće će naš tim ovoj temi posvetiti poseban članak i nadamo se da će moći unijeti nešto zanimljivo, novo i korisno u vaš život, baš poput ovog.

izvor: www.habr.com

Dodajte komentar