Notepad-svindlblað fyrir hraðvirka gagnaforvinnslu

Oft hefur fólk sem kemur inn á sviði gagnafræði síður en raunhæfar væntingar um hvað bíður þeirra. Margir halda að nú muni þeir skrifa flott tauganet, búa til raddaðstoðarmann frá Iron Man eða sigra alla á fjármálamörkuðum.
En vinna Gögn Vísindamaður er gagnadrifinn og einn mikilvægasti og tímafrekasti þátturinn er að vinna úr gögnunum áður en þau eru færð inn í taugakerfi eða greina þau á ákveðinn hátt.

Í þessari grein mun teymið okkar lýsa því hvernig þú getur unnið úr gögnum fljótt og auðveldlega með skref-fyrir-skref leiðbeiningum og kóða. Við reyndum að gera kóðann nokkuð sveigjanlegan og gæti verið notaður fyrir mismunandi gagnasöfn.

Mörgum fagfólki finnst kannski ekkert óvenjulegt í þessari grein, en byrjendur munu geta lært eitthvað nýtt og allir sem hafa lengi dreymt um að búa til sérstaka minnisbók fyrir hraðvirka og skipulagða gagnavinnslu geta afritað kóðann og forsniðið hann sjálfur, eða hlaða niður fullbúnu minnisbókinni frá Github.

Við fengum gagnasafnið. Hvað á að gera næst?

Svo, staðallinn: við þurfum að skilja hvað við erum að fást við, heildarmyndina. Til að gera þetta notum við pöndur til að skilgreina einfaldlega mismunandi gagnategundir.

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

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

Notepad-svindlblað fyrir hraðvirka gagnaforvinnslu

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

Notepad-svindlblað fyrir hraðvirka gagnaforvinnslu

Við skulum skoða dálkgildin:

  1. Samsvarar fjöldi lína í hverjum dálki heildarfjölda lína?
  2. Hver er kjarninn í gögnunum í hverjum dálki?
  3. Hvaða dálk viljum við miða á til að spá fyrir um hann?

Svörin við þessum spurningum gera þér kleift að greina gagnasafnið og gera gróflega áætlun fyrir næstu aðgerðir þínar.

Einnig, til að skoða gildin í hverjum dálki dýpri, getum við notað Pandas describe() aðgerðina. Hins vegar er ókosturinn við þessa aðgerð að hún veitir ekki upplýsingar um dálka með strengjagildum. Við munum takast á við þá síðar.

df.describe()

Notepad-svindlblað fyrir hraðvirka gagnaforvinnslu

Töfrasýn

Við skulum skoða hvar við höfum engin gildi:

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

Notepad-svindlblað fyrir hraðvirka gagnaforvinnslu

Þetta var stutt yfirlit að ofan, nú verður farið að áhugaverðari hlutum

Við skulum reyna að finna og, ef mögulegt er, fjarlægja dálka sem hafa aðeins eitt gildi í öllum línum (þeir munu ekki hafa áhrif á niðurstöðuna á nokkurn hátt):

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

Nú verndum við okkur sjálf og árangur verkefnisins okkar gegn tvíteknum línum (línur sem innihalda sömu upplýsingar í sömu röð og ein af núverandi línum):

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

Við skiptum gagnasafninu í tvennt: annað með eigindlegum gildum og hitt með megindlegum

Hér þurfum við að gera smá skýringu: ef línurnar með gögnum sem vantar í eigindlegum og megindlegum gögnum eru ekki mjög tengdar innbyrðis, þá þurfum við að ákveða hverju við fórnum - allar línur sem vantar gögn, aðeins hluti þeirra, eða ákveðnum dálkum. Ef línurnar eru tengdar, þá höfum við fullan rétt á að skipta gagnasafninu í tvennt. Annars þarftu fyrst að takast á við línurnar sem tengja ekki gögnin sem vantar í eigindlegu og megindlegu, og aðeins þá skipta gagnasafninu í tvennt.

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

Við gerum þetta til að auðvelda okkur að vinna úr þessum tveimur mismunandi tegundum gagna - seinna munum við skilja hversu miklu auðveldara þetta gerir líf okkar.

Unnið er með megindleg gögn

Það fyrsta sem við ættum að gera er að ákvarða hvort það séu „njósnadálkar“ í megindlegu gögnunum. Við köllum þessa dálka það vegna þess að þeir sýna sig sem megindleg gögn, en virka sem eigindleg gögn.

Hvernig getum við borið kennsl á þá? Auðvitað fer þetta allt eftir eðli gagna sem þú ert að greina, en almennt geta slíkir dálkar haft lítil einstök gögn (á bilinu 3-10 einstök gildi).

print(df_numerical.nunique())

Þegar við höfum borið kennsl á njósnadálkana munum við færa þá úr megindlegum gögnum yfir í eigindleg gögn:

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

Að lokum höfum við algjörlega aðskilið megindleg gögn frá eigindlegum gögnum og nú getum við unnið með þau almennilega. Í fyrsta lagi þurfum við að skilja hvar við höfum tóm gildi (NaN og í sumum tilfellum 0 verða samþykkt sem tóm gildi).

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

Á þessum tímapunkti er mikilvægt að skilja í hvaða dálkum núll geta gefið til kynna að gildi vantar: er þetta vegna þess hvernig gögnunum var safnað? Eða gæti það tengst gagnagildunum? Þessum spurningum verður að svara í hverju tilviki fyrir sig.

Þannig að ef við ákveðum enn að okkur vanti gögn þar sem núll eru, ættum við að skipta núllunum út fyrir NaN til að gera það auðveldara að vinna með þessi týndu gögn síðar:

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

Nú skulum við sjá hvar okkur vantar gögn:

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

Notepad-svindlblað fyrir hraðvirka gagnaforvinnslu

Hér ættu þau gildi inni í dálkunum sem vantar að vera merkt með gulu. Og nú byrjar fjörið - hvernig á að takast á við þessi gildi? Ætti ég að eyða línum með þessum gildum eða dálkum? Eða fylltu þessi tómu gildi með einhverjum öðrum?

Hér er áætluð skýringarmynd sem getur hjálpað þér að ákveða hvað er í grundvallaratriðum hægt að gera með tómum gildum:

Notepad-svindlblað fyrir hraðvirka gagnaforvinnslu

0. Fjarlægðu óþarfa dálka

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

1. Er fjöldi tómra gilda í þessum dálki meiri en 50%?

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

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

2. Eyða línum með tómum gildum

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

3.1. Að setja inn slembigildi

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

3.2. Að setja inn fast gildi

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. Settu inn meðaltal eða algengasta gildi

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. Settu inn gildið sem er reiknað með öðru líkani

Stundum er hægt að reikna gildi með aðhvarfslíkönum með líkönum frá sklearn bókasafninu eða öðrum svipuðum söfnum. Teymið okkar mun verja sérstakri grein um hvernig þetta er hægt að gera á næstunni.

Svo, í bili, verður frásögninni um megindleg gögn rofin, vegna þess að það eru mörg önnur blæbrigði um hvernig á að gera betur gagnaundirbúning og forvinnslu fyrir mismunandi verkefni, og grundvallaratriðin fyrir megindleg gögn hafa verið tekin með í reikninginn í þessari grein, og Nú er kominn tími til að fara aftur í eigindleg gögn sem við skildum nokkur skref aftur á bak frá þeim megindlegu. Þú getur breytt þessari minnisbók eins og þú vilt, aðlaga hana að mismunandi verkefnum, þannig að forvinnsla gagna gengur mjög hratt!

Eigindleg gögn

Í grundvallaratriðum, fyrir eigindleg gögn, er One-hot-encoding aðferðin notuð til að forsníða þau úr streng (eða hlut) í tölu. Áður en haldið er áfram að þessum tímapunkti skulum við nota skýringarmyndina og kóðann hér að ofan til að takast á við tóm gildi.

df_categorical.nunique()

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

Notepad-svindlblað fyrir hraðvirka gagnaforvinnslu

0. Fjarlægðu óþarfa dálka

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

1. Er fjöldi tómra gilda í þessum dálki meiri en 50%?

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

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

2. Eyða línum með tómum gildum

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

3.1. Að setja inn slembigildi

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

3.2. Að setja inn fast gildi

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)

Svo höfum við loksins náð tökum á núllum í eigindlegum gögnum. Nú er kominn tími til að framkvæma eina heita kóðun á gildunum sem eru í gagnagrunninum þínum. Þessi aðferð er mjög oft notuð til að tryggja að reikniritið þitt geti lært af hágæða gögnum.

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

Þannig að við höfum loksins lokið við að vinna aðskilin eigindleg og megindleg gögn - kominn tími til að sameina þau aftur

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

Eftir að við höfum sameinað gagnasöfnin saman í eitt, getum við loksins notað gagnaumbreytingu með MinMaxScaler úr sklearn bókasafninu. Þetta mun gera gildi okkar á milli 0 og 1, sem mun hjálpa til við að þjálfa líkanið í framtíðinni.

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

Þessi gögn eru nú tilbúin fyrir hvað sem er - taugakerfi, staðlað ML reiknirit osfrv.!

Í þessari grein tókum við ekki tillit til þess að vinna með tímaraðargögn, þar sem fyrir slík gögn ættir þú að nota aðeins mismunandi vinnsluaðferðir, allt eftir verkefni þínu. Í framtíðinni mun teymið okkar helga þessu efni sérstaka grein og við vonum að það geti komið með eitthvað áhugavert, nýtt og gagnlegt inn í líf þitt, alveg eins og þetta.

Heimild: www.habr.com

Bæta við athugasemd