Notepad-cheatblêd foar rappe gegevensfoarferwurking

Faak hawwe minsken dy't it fjild fan Data Science yngeane minder dan realistyske ferwachtings fan wat har te wachtsjen stiet. In protte minsken tinke dat se no koele neurale netwurken sille skriuwe, in stimassistent meitsje fan Iron Man, of elkenien op 'e finansjele merken ferslaan.
Mar wurk Data Wittenskipper is gegevens-oandreaune, en ien fan 'e wichtichste en tiidslinend aspekten is it ferwurkjen fan de gegevens foardat se it yn in neural netwurk fiede of it op in bepaalde manier analysearje.

Yn dit artikel sil ús team beskriuwe hoe't jo gegevens fluch en maklik kinne ferwurkje mei stap-foar-stap ynstruksjes en koade. Wy hawwe besocht de koade frij fleksibel te meitsjen en koe wurde brûkt foar ferskate datasets.

In protte professionals meie net fine neat bûtengewoane yn dit artikel, mar begjinners sille by steat wêze om te learen wat nijs, en elkenien dy't hat lang dreamde fan it meitsjen fan in apart notebook foar flugge en strukturearre gegevens ferwurking kin kopiearje de koade en opmaak foar harsels, of download it klear notebook fan Github.

Wy hawwe de dataset krigen. Wat te dwaan neist?

Dus, de standert: wy moatte begripe wêr't wy mei te krijen hawwe, it totale byld. Om dit te dwaan, brûke wy panda's om gewoan ferskate gegevenstypen te definiearjen.

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

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

Notepad-cheatblêd foar rappe gegevensfoarferwurking

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

Notepad-cheatblêd foar rappe gegevensfoarferwurking

Litte wy nei de kolomwearden sjen:

  1. Komt it oantal rigels yn elke kolom oerien mei it totale oantal rigels?
  2. Wat is de essinsje fan de gegevens yn elke kolom?
  3. Hokker kolom wolle wy rjochtsje om dêrfoar foarsizzingen te meitsjen?

Mei de antwurden op dizze fragen kinne jo de dataset analysearje en rûchwei in plan tekenje foar jo folgjende aksjes.

Ek, foar in djipper sjen nei de wearden yn elke kolom, kinne wy ​​​​de funksje pandas beskriuwe () brûke. It neidiel fan dizze funksje is lykwols dat it gjin ynformaasje jout oer kolommen mei tekenrige wearden. Wy sille letter mei har omgean.

df.describe()

Notepad-cheatblêd foar rappe gegevensfoarferwurking

Magic fisualisaasje

Litte wy sjen wêr't wy hielendal gjin wearden hawwe:

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

Notepad-cheatblêd foar rappe gegevensfoarferwurking

Dit wie in koarte blik fan boppen, no sille wy oergean nei mear nijsgjirrige dingen

Litte wy besykje kolommen te finen en, as it mooglik is, te ferwiderjen dy't mar ien wearde hawwe yn alle rigen (se sille it resultaat op gjin inkelde manier beynfloedzje):

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

No beskermje wy ússels en it sukses fan ús projekt tsjin dûbele rigels (rigels dy't deselde ynformaasje befetsje yn deselde folchoarder as ien fan 'e besteande rigels):

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

Wy diele de dataset yn twaen: ien mei kwalitative wearden, en de oare mei kwantitative

Hjir moatte wy in lytse ferdúdliking meitsje: as de rigels mei ûntbrekkende gegevens yn kwalitative en kwantitative gegevens net heul korrelearre binne mei elkoar, dan moatte wy beslute wat wy opofferje - alle rigels mei ûntbrekkende gegevens, mar in diel fan har, of bepaalde kolommen. As de rigels korrelearre binne, dan hawwe wy it rjocht om de dataset yn twa te dielen. Oars moatte jo earst omgean mei de rigels dy't de ûntbrekkende gegevens net yn kwalitative en kwantitative korrelearje, en pas dan de dataset yn twa dielen.

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

Wy dogge dit om it makliker foar ús te meitsjen om dizze twa ferskillende soarten gegevens te ferwurkjen - letter sille wy begripe hoefolle makliker dit ús libben makket.

Wy wurkje mei kwantitative gegevens

It earste ding dat wy moatte dwaan is om te bepalen oft d'r "spykolommen" binne yn 'e kwantitative gegevens. Wy neame dizze kolommen dat om't se harsels presintearje as kwantitative gegevens, mar fungearje as kwalitative gegevens.

Hoe kinne wy ​​se identifisearje? Fansels hinget it allegear ôf fan 'e aard fan' e gegevens dy't jo analysearje, mar yn 't algemien kinne sokke kolommen net folle unike gegevens hawwe (yn' e regio fan 3-10 unike wearden).

print(df_numerical.nunique())

Sadree't wy de spionkolommen hawwe identifisearre, sille wy se ferpleatse fan kwantitative gegevens nei kwalitative gegevens:

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

Uteinlik hawwe wy kwantitative gegevens folslein skieden fan kwalitative gegevens en no kinne wy ​​der goed mei wurkje. Earst moatte wy begripe wêr't wy lege wearden hawwe (NaN en yn guon gefallen 0 wurde akseptearre as lege wearden).

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

Op dit punt is it wichtich om te begripen yn hokker kolommen nullen kinne oanjaan op ûntbrekkende wearden: komt dit troch hoe't de gegevens waarden sammele? Of kin it relatearre wurde oan de gegevenswearden? Dizze fragen moatte wurde beantwurde op in saak-by-case basis.

Dus, as wy noch beslute dat wy gegevens misse kinne wêr't nullen binne, moatte wy de nullen ferfange troch NaN om it letter makliker te meitsjen mei dizze ferlerne gegevens:

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

Litte wy no sjen wêr't wy gegevens misse:

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

Notepad-cheatblêd foar rappe gegevensfoarferwurking

Hjir moatte dy wearden yn 'e kolommen dy't ûntbrekke yn giel markearre wurde. En no begjint de wille - hoe om te gean mei dizze wearden? Moat ik rigen mei dizze wearden as kolommen wiskje? Of folje dizze lege wearden mei guon oare?

Hjir is in ûngefear diagram dat jo kin helpe beslute wat yn prinsipe kin wurde dien mei lege wearden:

Notepad-cheatblêd foar rappe gegevensfoarferwurking

0. Fuortsmite ûnnedige kolommen

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

1. Is it oantal lege wearden yn dizze kolom grutter dan 50%?

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

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

2. Wiskje rigels mei lege wearden

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

3.1. It ynfoegjen fan in willekeurige wearde

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

3.2. It ynfoegjen fan in konstante wearde

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. Foegje de gemiddelde of meast foarkommende wearde yn

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. Foegje de wearde berekkene troch in oar model

Soms kinne wearden wurde berekkene mei regressionmodellen mei modellen út 'e sklearn-bibleteek as oare ferlykbere bibleteken. Us team sil in apart artikel wije oer hoe't dit yn 'e heine takomst kin wurde dien.

Dat, foar no, sil it ferhaal oer kwantitative gegevens ûnderbrutsen wurde, om't d'r in protte oare nuânses binne oer hoe't jo gegevenstarieding en foarferwurking better kinne dwaan foar ferskate taken, en de basis dingen foar kwantitative gegevens binne yn dit artikel rekken holden, en no is it tiid om werom te gean nei kwalitative gegevens dy't wy ferskate stappen werom skieden fan 'e kwantitative. Jo kinne dit notebook wizigje as jo wolle, it oanpasse oan ferskate taken, sadat de foarferwurking fan gegevens heul fluch giet!

Kwalitative gegevens

Yn prinsipe, foar kwalitative gegevens, wurdt de One-hot-kodearjen metoade brûkt om it op te meitsjen fan in tekenrige (as objekt) nei in nûmer. Foardat jo nei dit punt gean, litte wy it diagram en koade hjirboppe brûke om lege wearden te behanneljen.

df_categorical.nunique()

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

Notepad-cheatblêd foar rappe gegevensfoarferwurking

0. Fuortsmite ûnnedige kolommen

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

1. Is it oantal lege wearden yn dizze kolom grutter dan 50%?

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

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

2. Wiskje rigels mei lege wearden

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

3.1. It ynfoegjen fan in willekeurige wearde

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

3.2. It ynfoegjen fan in konstante wearde

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)

Dat, wy hawwe einlings in greep op nullen yn kwalitative gegevens. No is it tiid om ien-hot-kodearring út te fieren op 'e wearden dy't yn jo database binne. Dizze metoade wurdt heul faak brûkt om te soargjen dat jo algoritme kin leare fan gegevens fan hege kwaliteit.

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

Dat, wy binne einlings klear mei it ferwurkjen fan aparte kwalitative en kwantitative gegevens - tiid om se werom te kombinearjen

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

Neidat wy hawwe kombinearre de datasets tegearre yn ien, wy kinne úteinlik brûke gegevens transformaasje mei help fan MinMaxScaler út de sklearn bibleteek. Dit sil ús wearden tusken 0 en 1 meitsje, wat sil helpe by it trainen fan it model yn 'e takomst.

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

Dizze gegevens binne no klear foar alles - neurale netwurken, standert ML-algoritmen, ensfh.!

Yn dit artikel hawwe wy gjin rekken holden mei it wurkjen mei tiidsearjegegevens, om't jo foar sokke gegevens wat ferskillende ferwurkingstechniken moatte brûke, ôfhinklik fan jo taak. Yn 'e takomst sil ús team in apart artikel wije oan dit ûnderwerp, en wy hoopje dat it wat ynteressant, nij en nuttich yn jo libben kin bringe, krekt lykas dizze.

Boarne: www.habr.com

Add a comment