Cheat sheet pentru notebook pentru preprocesare rapidă a datelor

Adesea, oamenii care intră în domeniul științei datelor au așteptări mai puțin realiste cu privire la ceea ce îi așteaptă. Mulți oameni cred că acum vor scrie rețele neuronale grozave, vor crea un asistent vocal de la Iron Man sau vor învinge pe toată lumea de pe piețele financiare.
Dar munca Date Omul de știință este bazat pe date, iar unul dintre cele mai importante și consumatoare de timp este procesarea datelor înainte de a le introduce într-o rețea neuronală sau de a le analiza într-un anumit mod.

În acest articol, echipa noastră va descrie modul în care puteți procesa datele rapid și ușor, cu instrucțiuni pas cu pas și cod. Am încercat să facem codul destul de flexibil și să poată fi folosit pentru diferite seturi de date.

Mulți profesioniști s-ar putea să nu găsească nimic extraordinar în acest articol, dar începătorii vor putea învăța ceva nou, iar oricine a visat de mult să facă un notebook separat pentru procesarea rapidă și structurată a datelor poate copia codul și îl poate forma singur, sau descărcați caietul terminat de pe Github.

Am primit setul de date. Ce e de facut in continuare?

Deci, standardul: trebuie să înțelegem cu ce avem de-a face, imaginea de ansamblu. Pentru a face acest lucru, folosim panda pentru a defini pur și simplu diferite tipuri de date.

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 pentru notebook pentru preprocesare rapidă a datelor

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

Cheat sheet pentru notebook pentru preprocesare rapidă a datelor

Să ne uităm la valorile coloanei:

  1. Numărul de linii din fiecare coloană corespunde cu numărul total de linii?
  2. Care este esența datelor din fiecare coloană?
  3. Ce coloană dorim să vizam pentru a face predicții pentru ea?

Răspunsurile la aceste întrebări vă vor permite să analizați setul de date și să desenați aproximativ un plan pentru următoarele acțiuni.

De asemenea, pentru o privire mai profundă asupra valorilor din fiecare coloană, putem folosi funcția panda describe(). Cu toate acestea, dezavantajul acestei funcții este că nu oferă informații despre coloanele cu valori de șir. Ne vom ocupa de ei mai târziu.

df.describe()

Cheat sheet pentru notebook pentru preprocesare rapidă a datelor

Vizualizare magică

Să ne uităm unde nu avem deloc valori:

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

Cheat sheet pentru notebook pentru preprocesare rapidă a datelor

Aceasta a fost o scurtă privire de sus, acum vom trece la lucruri mai interesante

Să încercăm să găsim și, dacă este posibil, să eliminăm coloanele care au o singură valoare în toate rândurile (acestea nu vor afecta în niciun fel rezultatul):

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

Acum ne protejăm pe noi înșine și succesul proiectului nostru de liniile duplicat (linii care conțin aceleași informații în aceeași ordine ca una dintre liniile existente):

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

Împărțim setul de date în două: unul cu valori calitative, iar celălalt cu valori cantitative

Aici trebuie să facem o mică precizare: dacă liniile cu date lipsă în datele calitative și cantitative nu sunt foarte corelate între ele, atunci va trebui să decidem ce sacrificăm - toate rândurile cu date lipsă, doar o parte dintre ele, sau anumite coloane. Dacă liniile sunt corelate, atunci avem tot dreptul să împărțim setul de date în două. În caz contrar, va trebui mai întâi să vă ocupați de liniile care nu corelează datele lipsă din punct de vedere calitativ și cantitativ și abia apoi să împărțiți setul de date în două.

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

Facem acest lucru pentru a ne ușura procesarea acestor două tipuri diferite de date - mai târziu vom înțelege cât de ușoară ne face viața.

Lucrăm cu date cantitative

Primul lucru pe care ar trebui să-l facem este să stabilim dacă există „coloane spion” în datele cantitative. Aceste coloane le numim așa pentru că se prezintă ca date cantitative, dar acționează ca date calitative.

Cum le putem identifica? Desigur, totul depinde de natura datelor pe care le analizați, dar, în general, astfel de coloane pot avea puține date unice (în regiunea de 3-10 valori unice).

print(df_numerical.nunique())

Odată ce am identificat coloanele spion, le vom muta de la date cantitative la date calitative:

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

În cele din urmă, am separat complet datele cantitative de datele calitative și acum putem lucra cu ele corect. Primul lucru este să înțelegem unde avem valori goale (NaN, iar în unele cazuri 0 va fi acceptat ca valori goale).

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

În acest moment, este important să înțelegem în ce coloane zerourile pot indica valori lipsă: se datorează modului în care au fost colectate datele? Sau ar putea fi legat de valorile datelor? La aceste întrebări trebuie să se răspundă de la caz la caz.

Deci, dacă totuși decidem că s-ar putea să ne lipsească date unde există zerouri, ar trebui să înlocuim zerourile cu NaN pentru a face mai ușor să lucrăm cu aceste date pierdute mai târziu:

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

Acum să vedem unde ne lipsesc datele:

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

Cheat sheet pentru notebook pentru preprocesare rapidă a datelor

Aici acele valori din interiorul coloanelor care lipsesc trebuie marcate cu galben. Și acum începe distracția - cum să faceți față acestor valori? Ar trebui să șterg rândurile cu aceste valori sau coloane? Sau umple aceste valori goale cu altele?

Iată o diagramă aproximativă care vă poate ajuta să decideți ce se poate face, în principiu, cu valori goale:

Cheat sheet pentru notebook pentru preprocesare rapidă a datelor

0. Eliminați coloanele inutile

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

1. Numărul de valori goale din această coloană este mai mare de 50%?

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

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

2. Ștergeți liniile cu valori goale

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

3.1. Inserarea unei valori aleatorii

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

3.2. Introducerea unei valori constante

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. Introduceți valoarea medie sau cea mai frecventă

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. Introduceți valoarea calculată de alt model

Uneori, valorile pot fi calculate folosind modele de regresie folosind modele din biblioteca sklearn sau din alte biblioteci similare. Echipa noastră va dedica un articol separat despre cum se poate face acest lucru în viitorul apropiat.

Deci, deocamdată, narațiunea despre datele cantitative va fi întreruptă, deoarece există multe alte nuanțe despre cum să faceți mai bine pregătirea și preprocesarea datelor pentru diferite sarcini, iar lucrurile de bază pentru datele cantitative au fost luate în considerare în acest articol și acum este momentul să revenim la datele calitative.pe care le-am separat cu câţiva paşi înapoi de cele cantitative. Puteți schimba acest notebook după bunul plac, adaptându-l la diferite sarcini, astfel încât preprocesarea datelor să meargă foarte repede!

Date calitative

Practic, pentru datele calitative, metoda One-hot-encoding este folosită pentru a le formata dintr-un șir (sau obiect) la un număr. Înainte de a trece la acest punct, să folosim diagrama și codul de mai sus pentru a trata valorile goale.

df_categorical.nunique()

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

Cheat sheet pentru notebook pentru preprocesare rapidă a datelor

0. Eliminați coloanele inutile

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

1. Numărul de valori goale din această coloană este mai mare de 50%?

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

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

2. Ștergeți liniile cu valori goale

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

3.1. Inserarea unei valori aleatorii

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

3.2. Introducerea unei valori constante

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)

Așadar, în sfârșit ne-am priceput la valorile nule din datele calitative. Acum este timpul să efectuați o codificare la cald pentru valorile care se află în baza dvs. de date. Această metodă este foarte des folosită pentru a vă asigura că algoritmul dumneavoastră poate învăța din date de înaltă calitate.

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

Deci, am terminat în sfârșit de procesarea datelor calitative și cantitative separate - este timpul să le combinăm înapoi

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

După ce am combinat seturile de date într-unul singur, putem folosi în sfârșit transformarea datelor folosind MinMaxScaler din biblioteca sklearn. Acest lucru va face ca valorile noastre să fie între 0 și 1, ceea ce va ajuta la antrenarea modelului în viitor.

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

Aceste date sunt acum gata pentru orice - rețele neuronale, algoritmi standard de ML etc.!

În acest articol, nu am luat în considerare lucrul cu datele serii cronologice, deoarece pentru astfel de date ar trebui să utilizați tehnici de procesare ușor diferite, în funcție de sarcina dvs. În viitor, echipa noastră va dedica un articol separat acestui subiect și sperăm că va putea aduce ceva interesant, nou și util în viața ta, la fel ca acesta.

Sursa: www.habr.com

Adauga un comentariu