Poznámkový blok - cheat na rýchle predbežné spracovanie údajov

Ľudia, ktorí vstupujú do oblasti Data Science, majú často menej než realistické očakávania toho, čo ich čaká. Mnoho ľudí si myslí, že teraz napíšu skvelé neurónové siete, vytvoria hlasového asistenta z Iron Mana alebo porazia každého na finančných trhoch.
Ale práca dátum Vedec je riadený údajmi a jedným z najdôležitejších a časovo náročných aspektov je spracovanie údajov pred ich vložením do neurónovej siete alebo ich analýzou určitým spôsobom.

V tomto článku náš tím opíše, ako môžete rýchlo a jednoducho spracovať údaje pomocou podrobných pokynov a kódu. Snažili sme sa, aby bol kód dosť flexibilný a mohol byť použitý pre rôzne množiny údajov.

Mnoho profesionálov možno v tomto článku nenájde nič výnimočné, no začiatočníci sa budú môcť naučiť niečo nové a každý, kto dlho sníval o tom, že si vytvorí samostatný notebook na rýchle a štruktúrované spracovanie dát, si môže kód skopírovať a naformátovať pre seba, resp. stiahnite si hotový notebook z Github.

Dostali sme súbor údajov. Čo urobiť ďalej?

Takže štandard: musíme pochopiť, s čím máme do činenia, celkový obraz. Aby sme to dosiahli, používame pandy na jednoduché definovanie rôznych typov údajov.

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

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

Poznámkový blok - cheat na rýchle predbežné spracovanie údajov

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

Poznámkový blok - cheat na rýchle predbežné spracovanie údajov

Pozrime sa na hodnoty stĺpcov:

  1. Zodpovedá počet riadkov v každom stĺpci celkovému počtu riadkov?
  2. Aká je podstata údajov v každom stĺpci?
  3. Na ktorý stĺpec chceme zacieliť, aby sme preň mohli predpovedať?

Odpovede na tieto otázky vám umožnia analyzovať súbor údajov a približne nakresliť plán vašich ďalších akcií.

Pre hlbší pohľad na hodnoty v každom stĺpci môžeme použiť aj funkciu pandas description(). Nevýhodou tejto funkcie však je, že neposkytuje informácie o stĺpcoch s hodnotami reťazca. Budeme sa nimi zaoberať neskôr.

df.describe()

Poznámkový blok - cheat na rýchle predbežné spracovanie údajov

Magická vizualizácia

Pozrime sa na to, kde nemáme vôbec žiadne hodnoty:

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

Poznámkový blok - cheat na rýchle predbežné spracovanie údajov

Toto bol krátky pohľad zhora, teraz prejdeme k zaujímavejším veciam

Pokúsme sa nájsť a ak je to možné, odstrániť stĺpce, ktoré majú iba jednu hodnotu vo všetkých riadkoch (žiadnym spôsobom neovplyvnia výsledok):

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

Teraz chránime seba a úspech nášho projektu pred duplicitnými riadkami (riadky, ktoré obsahujú rovnaké informácie v rovnakom poradí ako jeden z existujúcich riadkov):

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

Súbor údajov rozdeľujeme na dva: jeden s kvalitatívnymi hodnotami a druhý s kvantitatívnymi hodnotami

Tu musíme urobiť malé objasnenie: ak riadky s chýbajúcimi údajmi v kvalitatívnych a kvantitatívnych údajoch navzájom veľmi nekorelujú, potom sa budeme musieť rozhodnúť, čo obetujeme – všetky riadky s chýbajúcimi údajmi, iba časť z nich, alebo určité stĺpce. Ak sú čiary korelované, potom máme plné právo rozdeliť súbor údajov na dva. V opačnom prípade sa budete musieť najskôr vysporiadať s riadkami, ktoré nekorelujú chýbajúce údaje kvalitatívne a kvantitatívne, a až potom rozdeliť súbor údajov na dva.

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

Robíme to preto, aby sme si uľahčili spracovanie týchto dvoch rôznych typov údajov – neskôr pochopíme, o koľko nám to uľahčuje život.

Pracujeme s kvantitatívnymi údajmi

Prvá vec, ktorú by sme mali urobiť, je určiť, či sa v kvantitatívnych údajoch nachádzajú „špionážne stĺpce“. Tieto stĺpce tak nazývame, pretože sa prezentujú ako kvantitatívne údaje, ale pôsobia ako kvalitatívne údaje.

Ako ich môžeme identifikovať? Samozrejme, všetko závisí od povahy údajov, ktoré analyzujete, ale vo všeobecnosti môžu tieto stĺpce obsahovať málo jedinečných údajov (v oblasti 3 až 10 jedinečných hodnôt).

print(df_numerical.nunique())

Keď sme identifikovali špionážne stĺpce, presunieme ich z kvantitatívnych údajov na kvalitatívne údaje:

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čne sme úplne oddelili kvantitatívne dáta od kvalitatívnych a teraz s nimi môžeme správne pracovať. Prvá vec je pochopiť, kde máme prázdne hodnoty (NaN av niektorých prípadoch 0 budú akceptované ako prázdne hodnoty).

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

V tomto bode je dôležité pochopiť, v ktorých stĺpcoch môžu nuly označovať chýbajúce hodnoty: je to spôsobené tým, ako boli údaje zhromaždené? Alebo to môže súvisieť s hodnotami údajov? Na tieto otázky treba odpovedať od prípadu k prípadu.

Ak sa teda stále rozhodneme, že nám môžu chýbať údaje tam, kde sú nuly, mali by sme nuly nahradiť NaN, aby sme si uľahčili prácu s týmito stratenými údajmi neskôr:

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

Teraz sa pozrime, kde nám chýbajú údaje:

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

Poznámkový blok - cheat na rýchle predbežné spracovanie údajov

Tu by tie hodnoty v stĺpcoch, ktoré chýbajú, mali byť označené žltou farbou. A teraz začína zábava – ako s týmito hodnotami naložiť? Mám odstrániť riadky s týmito hodnotami alebo stĺpcami? Alebo vyplniť tieto prázdne hodnoty nejakými inými?

Tu je približný diagram, ktorý vám môže pomôcť rozhodnúť sa, čo možno v zásade urobiť s prázdnymi hodnotami:

Poznámkový blok - cheat na rýchle predbežné spracovanie údajov

0. Odstráňte nepotrebné stĺpce

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

1. Je počet prázdnych hodnôt v tomto stĺpci väčší ako 50 %?

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

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

2. Vymažte riadky s prázdnymi hodnotami

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

3.1. Vloženie náhodnej hodnoty

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

3.2. Vloženie konštantnej 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. Zadajte priemernú alebo najčastejšiu 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čítanú iným modelom

Niekedy je možné hodnoty vypočítať pomocou regresných modelov pomocou modelov z knižnice sklearn alebo iných podobných knižníc. Náš tím bude v blízkej budúcnosti venovať samostatný článok o tom, ako sa to dá urobiť.

Takže nateraz bude rozprávanie o kvantitatívnych údajoch prerušené, pretože existuje mnoho ďalších nuancií o tom, ako lepšie pripraviť a predspracovať údaje pre rôzne úlohy, a základné veci pre kvantitatívne údaje boli v tomto článku zohľadnené a teraz je čas vrátiť sa ku kvalitatívnym údajom.ktoré sme od kvantitatívnych oddelili o niekoľko krokov späť. Tento zápisník môžete ľubovoľne meniť, prispôsobovať ho rôznym úlohám, takže predspracovanie údajov pôjde veľmi rýchlo!

Kvalitatívne údaje

V zásade sa pre kvalitatívne údaje používa metóda One-hot-encoding, aby sa naformátovali z reťazca (alebo objektu) na číslo. Predtým, ako prejdeme k tomuto bodu, použijeme vyššie uvedený diagram a kód na riešenie prázdnych hodnôt.

df_categorical.nunique()

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

Poznámkový blok - cheat na rýchle predbežné spracovanie údajov

0. Odstráňte nepotrebné stĺpce

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

1. Je počet prázdnych hodnôt v tomto stĺpci väčší ako 50 %?

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

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

2. Vymažte riadky s prázdnymi hodnotami

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

3.1. Vloženie náhodnej hodnoty

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

3.2. Vloženie konštantnej 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 sme konečne získali kontrolu nad nulami v kvalitatívnych údajoch. Teraz je čas vykonať jednorazové kódovanie hodnôt, ktoré sú vo vašej databáze. Táto metóda sa veľmi často používa na zabezpečenie toho, aby sa váš algoritmus mohol učiť z vysokokvalitných údajov.

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 sme konečne dokončili spracovanie oddelených kvalitatívnych a kvantitatívnych údajov – je čas ich spätne spojiť

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

Po spojení dátových množín do jednej môžeme konečne použiť transformáciu dát pomocou MinMaxScaler z knižnice sklearn. Vďaka tomu budú naše hodnoty medzi 0 a 1, čo pomôže pri trénovaní modelu v budúcnosti.

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

Tieto dáta sú teraz pripravené na čokoľvek – neurónové siete, štandardné ML algoritmy atď.!

V tomto článku sme nebrali do úvahy prácu s údajmi z časových radov, keďže pri takýchto údajoch by ste mali použiť mierne odlišné techniky spracovania v závislosti od vašej úlohy. Tejto téme bude náš tím v budúcnosti venovať samostatný článok a dúfame, že dokáže priniesť niečo zaujímavé, nové a užitočné do vášho života, ako je tento.

Zdroj: hab.com

Pridať komentár