Cheat sheet na notebook pro rychlé předzpracování dat

Lidé vstupující do oboru Data Science mají často méně než realistická očekávání toho, co je čeká. Mnoho lidí si myslí, že teď napíšou skvělé neuronové sítě, vytvoří hlasového asistenta z Iron Mana nebo porazí všechny na finančních trzích.
Ale práce Data Vědec je řízen daty a jedním z nejdůležitějších a časově náročných aspektů je zpracování dat před jejich vložením do neuronové sítě nebo jejich analýzou určitým způsobem.

V tomto článku náš tým popíše, jak můžete rychle a snadno zpracovat data pomocí podrobných pokynů a kódu. Snažili jsme se, aby byl kód docela flexibilní a mohl být použit pro různé datové sady.

Mnoho profesionálů možná v tomto článku nenajde nic mimořádného, ​​ale začátečníci se budou moci naučit něco nového a každý, kdo dlouho snil o výrobě samostatného notebooku pro rychlé a strukturované zpracování dat, si může kód zkopírovat a naformátovat pro sebe, popř. stáhněte si hotový notebook z Github.

Obdrželi jsme datovou sadu. Co dělat dál?

Takže standard: musíme pochopit, s čím máme co do činění, celkový obraz. K tomu používáme pandy k jednoduché definici různých datových typů.

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

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

Cheat sheet na notebook pro rychlé předzpracování dat

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

Cheat sheet na notebook pro rychlé předzpracování dat

Podívejme se na hodnoty sloupců:

  1. Odpovídá počet řádků v každém sloupci celkovému počtu řádků?
  2. Jaká je podstata dat v každém sloupci?
  3. Na který sloupec chceme cílit, abychom pro něj mohli předpovídat?

Odpovědi na tyto otázky vám umožní analyzovat datovou sadu a zhruba nakreslit plán vašich dalších akcí.

Pro hlubší pohled na hodnoty v každém sloupci také můžeme použít funkci pandas description(). Nevýhodou této funkce však je, že neposkytuje informace o sloupcích s řetězcovými hodnotami. Budeme se jimi zabývat později.

df.describe()

Cheat sheet na notebook pro rychlé předzpracování dat

Magická vizualizace

Podívejme se, kde nemáme vůbec žádné hodnoty:

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

Cheat sheet na notebook pro rychlé předzpracování dat

Toto byl krátký pohled shora, nyní přejdeme k zajímavějším věcem

Pokusme se najít a pokud možno odstranit sloupce, které mají ve všech řádcích pouze jednu hodnotu (výsledek nijak neovlivní):

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

Nyní chráníme sebe a úspěch našeho projektu před duplicitními řádky (řádky, které obsahují stejné informace ve stejném pořadí jako jeden z existujících řádků):

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

Soubor dat rozdělíme na dva: jeden s kvalitativními hodnotami a druhý s kvantitativními hodnotami

Zde si musíme udělat malé upřesnění: pokud řádky s chybějícími údaji v kvalitativních a kvantitativních údajích spolu příliš nekorelují, pak se budeme muset rozhodnout, co obětujeme – všechny řádky s chybějícími údaji, jen část z nich, nebo určité sloupce. Pokud jsou řádky korelované, pak máme plné právo rozdělit datovou sadu na dvě. V opačném případě se budete muset nejprve vypořádat s řádky, které nekorelují chybějící data kvalitativně a kvantitativně, a teprve poté rozdělit datovou sadu na dvě.

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

Děláme to proto, abychom si usnadnili zpracování těchto dvou různých typů dat – později pochopíme, o kolik nám to usnadňuje život.

Pracujeme s kvantitativními daty

První věc, kterou bychom měli udělat, je určit, zda v kvantitativních datech existují „špionážní sloupce“. Tyto sloupce tak nazýváme, protože se prezentují jako kvantitativní data, ale fungují jako kvalitativní data.

Jak je můžeme identifikovat? Vše samozřejmě závisí na povaze dat, která analyzujete, ale obecně mohou mít tyto sloupce málo jedinečných dat (v oblasti 3–10 jedinečných hodnot).

print(df_numerical.nunique())

Jakmile identifikujeme špionážní sloupce, přesuneme je z kvantitativních dat na kvalitativní data:

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']) #добавляем третью колонку-шпион в качественные данные

Konečně jsme zcela oddělili kvantitativní data od kvalitativních a nyní s nimi můžeme správně pracovat. První věcí je pochopit, kde máme prázdné hodnoty (NaN a v některých případech 0 budou akceptovány jako prázdné hodnoty).

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

V tomto okamžiku je důležité pochopit, ve kterých sloupcích mohou nuly označovat chybějící hodnoty: je to způsobeno tím, jak byla data shromážděna? Nebo by to mohlo souviset s hodnotami dat? Tyto otázky je třeba zodpovědět případ od případu.

Pokud se tedy přesto rozhodneme, že nám mohou chybět data tam, kde jsou nuly, měli bychom nuly nahradit NaN, abychom si později usnadnili práci s těmito ztracenými daty:

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

Nyní se podívejme, kde nám chybí data:

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

Cheat sheet na notebook pro rychlé předzpracování dat

Zde by hodnoty uvnitř sloupců, které chybí, měly být označeny žlutě. A teď začíná zábava – jak s těmito hodnotami naložit? Mám smazat řádky s těmito hodnotami nebo sloupci? Nebo vyplnit tyto prázdné hodnoty nějakými jinými?

Zde je přibližný diagram, který vám může pomoci rozhodnout, co lze v zásadě udělat s prázdnými hodnotami:

Cheat sheet na notebook pro rychlé předzpracování dat

0. Odstraňte nepotřebné sloupce

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

1. Je počet prázdných hodnot v tomto sloupci větší než 50 %?

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

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

2. Odstraňte řádky s prázdnými hodnotami

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

3.1. Vložení náhodné hodnoty

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

3.2. Vložení konstantní hodnoty

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. Zadejte průměrnou nebo nejčastější hodnotu

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. Vložte hodnotu vypočítanou jiným modelem

Někdy lze hodnoty vypočítat pomocí regresních modelů pomocí modelů z knihovny sklearn nebo jiných podobných knihoven. Náš tým bude v blízké budoucnosti věnovat samostatný článek, jak toho lze dosáhnout.

Takže prozatím bude vyprávění o kvantitativních datech přerušeno, protože existuje mnoho dalších nuancí, jak lépe provádět přípravu a předzpracování dat pro různé úkoly, a základní věci pro kvantitativní data byly v tomto článku zohledněny a nyní je čas vrátit se ke kvalitativním datům, která jsme od těch kvantitativních oddělili o několik kroků zpět. Tento notebook můžete libovolně měnit, přizpůsobovat jej různým úkolům, takže předzpracování dat jde velmi rychle!

Kvalitativní údaje

V zásadě se pro kvalitativní data používá metoda One-hot-encoding za účelem jejich formátování z řetězce (nebo objektu) na číslo. Než přejdeme k tomuto bodu, použijme výše uvedený diagram a kód k řešení prázdných hodnot.

df_categorical.nunique()

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

Cheat sheet na notebook pro rychlé předzpracování dat

0. Odstraňte nepotřebné sloupce

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

1. Je počet prázdných hodnot v tomto sloupci větší než 50 %?

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

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

2. Odstraňte řádky s prázdnými hodnotami

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

3.1. Vložení náhodné hodnoty

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

3.2. Vložení konstantní hodnoty

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)

Takže konečně máme přehled o nulách v kvalitativních datech. Nyní je čas provést jednorázové kódování hodnot, které jsou ve vaší databázi. Tato metoda se velmi často používá k zajištění toho, aby se váš algoritmus mohl učit z vysoce kvalitních dat.

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

Takže jsme konečně dokončili zpracování oddělených kvalitativních a kvantitativních dat – čas je zpětně spojit

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

Poté, co jsme datové sady spojili do jedné, můžeme konečně použít transformaci dat pomocí MinMaxScaler z knihovny sklearn. Díky tomu budou naše hodnoty mezi 0 a 1, což pomůže při trénování modelu v budoucnu.

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

Tato data jsou nyní připravena na cokoliv – neuronové sítě, standardní ML algoritmy atd.!

V tomto článku jsme nebrali v úvahu práci s daty časových řad, protože pro taková data byste měli použít mírně odlišné techniky zpracování v závislosti na vašem úkolu. V budoucnu se tomuto tématu bude náš tým věnovat samostatný článek a doufáme, že se mu podaří přinést do vašeho života něco zajímavého, nového a užitečného, ​​jako je tento.

Zdroj: www.habr.com

Přidat komentář