Piezīmju grāmatiņa ātrai datu pirmapstrādei

Bieži vien cilvēkiem, kas ienāk datu zinātnes jomā, ir mazāk nekā reālistiskas cerības par to, kas viņus sagaida. Daudzi cilvēki domā, ka tagad viņi rakstīs foršus neironu tīklus, izveidos balss asistentu no Iron Man vai pārspēs visus finanšu tirgos.
Bet strādāt Datums Zinātnieks ir balstīts uz datiem, un viens no svarīgākajiem un laikietilpīgākajiem aspektiem ir datu apstrāde pirms ievadīšanas neironu tīklā vai noteikta veida analīze.

Šajā rakstā mūsu komanda aprakstīs, kā varat ātri un vienkārši apstrādāt datus, izmantojot detalizētus norādījumus un kodu. Mēs centāmies padarīt kodu diezgan elastīgu un to varētu izmantot dažādām datu kopām.

Iespējams, daudzi profesionāļi šajā rakstā neatradīs neko ārkārtēju, taču iesācēji varēs iemācīties ko jaunu, un ikviens, kurš jau sen ir sapņojis izveidot atsevišķu piezīmju grāmatiņu ātrai un strukturētai datu apstrādei, var nokopēt kodu un formatēt to sev, vai lejupielādējiet gatavo piezīmju grāmatiņu no Github.

Mēs saņēmām datu kopu. Ko darīt tālāk?

Tātad, standarts: mums ir jāsaprot, ar ko mums ir darīšana, kopējā aina. Lai to izdarītu, mēs izmantojam pandas, lai vienkārši definētu dažādus datu tipus.

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

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

Piezīmju grāmatiņa ātrai datu pirmapstrādei

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

Piezīmju grāmatiņa ātrai datu pirmapstrādei

Apskatīsim kolonnu vērtības:

  1. Vai rindu skaits katrā kolonnā atbilst kopējam rindu skaitam?
  2. Kāda ir katras kolonnas datu būtība?
  3. Kuru sleju mēs vēlamies atlasīt, lai veiktu tās prognozes?

Atbildes uz šiem jautājumiem ļaus jums analizēt datu kopu un aptuveni sastādīt plānu turpmākajām darbībām.

Turklāt, lai padziļināti apskatītu vērtības katrā kolonnā, mēs varam izmantot funkciju pandas description(). Tomēr šīs funkcijas trūkums ir tāds, ka tā nesniedz informāciju par kolonnām ar virknes vērtībām. Mēs ar tiem tiksim galā vēlāk.

df.describe()

Piezīmju grāmatiņa ātrai datu pirmapstrādei

Burvju vizualizācija

Apskatīsim, kur mums vispār nav vērtību:

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

Piezīmju grāmatiņa ātrai datu pirmapstrādei

Šis bija īss ieskats no augšas, tagad pāriesim pie interesantākām lietām

Mēģināsim atrast un, ja iespējams, noņemt kolonnas, kurām visās rindās ir tikai viena vērtība (tās nekādā veidā neietekmēs rezultātu):

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

Tagad mēs aizsargājam sevi un sava projekta panākumus no dublētām rindām (rindas, kurās ir tāda pati informācija tādā pašā secībā kā viena no esošajām rindām):

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

Mēs sadalām datu kopu divās daļās: viena ar kvalitatīvām vērtībām un otra ar kvantitatīvām vērtībām.

Šeit mums ir jāveic neliels precizējums: ja rindas ar trūkstošiem datiem kvalitatīvajos un kvantitatīvos datos nav ļoti savstarpēji saistītas, tad mums būs jāizlemj, ko mēs upurēsim - visas rindas ar trūkstošiem datiem, tikai daļa no tiem, vai noteiktas kolonnas. Ja līnijas ir korelētas, mums ir visas tiesības sadalīt datu kopu divās daļās. Pretējā gadījumā vispirms būs jārisina rindas, kas nekorelē trūkstošos datus kvalitatīvā un kvantitatīvā ziņā, un tikai pēc tam jāsadala datu kopa divās daļās.

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

Mēs to darām, lai mums būtu vieglāk apstrādāt šos divus dažādos datu veidus – vēlāk sapratīsim, cik tas atvieglo mūsu dzīvi.

Mēs strādājam ar kvantitatīviem datiem

Pirmā lieta, kas mums jādara, ir noteikt, vai kvantitatīvos datos ir “spiegu kolonnas”. Mēs tā saucam šīs kolonnas, jo tās uzrāda sevi kā kvantitatīvus datus, bet darbojas kā kvalitatīvi dati.

Kā mēs varam tos identificēt? Protams, tas viss ir atkarīgs no analizējamo datu veida, taču kopumā šādās kolonnās var būt maz unikālu datu (aptuveni 3–10 unikālo vērtību).

print(df_numerical.nunique())

Kad būsim identificējuši spiegu kolonnas, mēs tās pārvietosim no kvantitatīviem datiem uz kvalitatīviem datiem:

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

Visbeidzot, mēs esam pilnībā atdalījuši kvantitatīvos datus no kvalitatīvajiem datiem, un tagad mēs varam pareizi ar tiem strādāt. Pirmā lieta ir saprast, kur mums ir tukšas vērtības (NaN, un dažos gadījumos 0 tiks pieņemtas kā tukšas vērtības).

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

Šajā brīdī ir svarīgi saprast, kurās kolonnās nulles var norādīt uz trūkstošām vērtībām: vai tas ir saistīts ar to, kā dati tika vākti? Vai arī tas varētu būt saistīts ar datu vērtībām? Uz šiem jautājumiem ir jāatbild katrā gadījumā atsevišķi.

Tātad, ja mēs joprojām nolemjam, ka mums, iespējams, trūkst datu tur, kur ir nulles, nulles jāaizstāj ar NaN, lai vēlāk būtu vieglāk strādāt ar šiem zaudētajiem datiem:

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

Tagad apskatīsim, kur mums trūkst datu:

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

Piezīmju grāmatiņa ātrai datu pirmapstrādei

Šeit tās vērtības kolonnās, kuras trūkst, ir jāatzīmē dzeltenā krāsā. Un tagad sākas jautrība – kā tikt galā ar šīm vērtībām? Vai man vajadzētu dzēst rindas ar šīm vērtībām vai kolonnas? Vai arī aizpildīt šīs tukšās vērtības ar citām?

Šeit ir aptuvenā diagramma, kas var palīdzēt izlemt, ko principā var izdarīt ar tukšām vērtībām:

Piezīmju grāmatiņa ātrai datu pirmapstrādei

0. Noņemiet nevajadzīgās kolonnas

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

1. Vai tukšo vērtību skaits šajā kolonnā ir lielāks par 50%?

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

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

2. Dzēsiet rindas ar tukšām vērtībām

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

3.1. Nejaušas vērtības ievietošana

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

3.2. Konstantas vērtības ievietošana

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. Ievadiet vidējo vai biežāko vērtību

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. Ievietojiet vērtību, kas aprēķināta pēc cita modeļa

Dažreiz vērtības var aprēķināt, izmantojot regresijas modeļus, izmantojot modeļus no sklearn bibliotēkas vai citām līdzīgām bibliotēkām. Mūsu komanda tuvākajā laikā veltīs atsevišķu rakstu par to, kā to izdarīt.

Līdz ar to pagaidām stāstījums par kvantitatīviem datiem tiks pārtraukts, jo ir daudz citu nianšu, kā labāk veikt datu sagatavošanu un priekšapstrādi dažādiem uzdevumiem, un kvantitatīvo datu pamatlietas šajā rakstā ir ņemtas vērā, un tagad ir pienācis laiks atgriezties pie kvalitatīvajiem datiem.kurus mēs atdalījām vairākus soļus atpakaļ no kvantitatīviem. Jūs varat mainīt šo piezīmju grāmatiņu pēc saviem ieskatiem, pielāgojot to dažādiem uzdevumiem, lai datu priekšapstrāde noritētu ļoti ātri!

Kvalitatīvie dati

Būtībā kvalitatīviem datiem tiek izmantota One-hot-kodēšanas metode, lai formatētu to no virknes (vai objekta) uz skaitli. Pirms pāriet uz šo punktu, izmantosim iepriekš redzamo diagrammu un kodu, lai apstrādātu tukšās vērtības.

df_categorical.nunique()

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

Piezīmju grāmatiņa ātrai datu pirmapstrādei

0. Noņemiet nevajadzīgās kolonnas

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

1. Vai tukšo vērtību skaits šajā kolonnā ir lielāks par 50%?

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

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

2. Dzēsiet rindas ar tukšām vērtībām

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

3.1. Nejaušas vērtības ievietošana

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

3.2. Konstantas vērtības ievietošana

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)

Tātad, mēs beidzot esam ieguvuši rokturi ar nullēm kvalitatīvajos datos. Tagad ir pienācis laiks veikt vienreizēju kodējumu vērtībām, kas atrodas jūsu datubāzē. Šo metodi ļoti bieži izmanto, lai nodrošinātu, ka jūsu algoritms var mācīties no augstas kvalitātes datiem.

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

Tātad, mēs beidzot esam pabeiguši atsevišķu kvalitatīvo un kvantitatīvo datu apstrādi — laiks tos apvienot

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

Kad datu kopas esam apvienojuši vienā, mēs beidzot varam izmantot datu pārveidošanu, izmantojot sklearn bibliotēkas MinMaxScaler. Tas padarīs mūsu vērtības starp 0 un 1, kas noderēs, apmācot modeli nākotnē.

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

Šie dati tagad ir gatavi jebkam - neironu tīkliem, standarta ML algoritmiem utt.!

Šajā rakstā mēs neņēmām vērā darbu ar laikrindu datiem, jo ​​šādiem datiem atkarībā no uzdevuma ir jāizmanto nedaudz atšķirīgas apstrādes metodes. Nākotnē mūsu komanda šai tēmai veltīs atsevišķu rakstu, un mēs ceram, ka tas spēs jūsu dzīvē ienest ko interesantu, jaunu un noderīgu, tāpat kā šis.

Avots: www.habr.com

Pievieno komentāru