Notesblok-snydeark til hurtig dataforbehandling

Ofte har folk, der går ind inden for datavidenskab, mindre end realistiske forventninger til, hvad der venter dem. Mange mennesker tror, ​​at nu vil de skrive seje neurale netværk, skabe en stemmeassistent fra Iron Man eller slå alle på de finansielle markeder.
Men arbejde data Videnskabsmand er datadrevet, og et af de vigtigste og mest tidskrævende aspekter er at behandle dataene, før de føres ind i et neuralt netværk eller analysere dem på en bestemt måde.

I denne artikel vil vores team beskrive, hvordan du kan behandle data hurtigt og nemt med trin-for-trin instruktioner og kode. Vi forsøgte at gøre koden ret fleksibel og kunne bruges til forskellige datasæt.

Mange fagfolk finder måske ikke noget ekstraordinært i denne artikel, men begyndere vil kunne lære noget nyt, og enhver, der længe har drømt om at lave en separat notesbog til hurtig og struktureret databehandling, kan kopiere koden og formatere den til sig selv, eller download den færdige notesbog fra Github.

Vi modtog datasættet. Hvad skal man så gøre?

Så standarden: vi skal forstå, hvad vi har med at gøre, det overordnede billede. For at gøre dette bruger vi pandaer til blot at definere forskellige datatyper.

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

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

Notesblok-snydeark til hurtig dataforbehandling

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

Notesblok-snydeark til hurtig dataforbehandling

Lad os se på kolonneværdierne:

  1. Svarer antallet af linjer i hver kolonne til det samlede antal linjer?
  2. Hvad er essensen af ​​dataene i hver kolonne?
  3. Hvilken kolonne vil vi målrette mod for at lave forudsigelser for den?

Svarene på disse spørgsmål giver dig mulighed for at analysere datasættet og groft tegne en plan for dine næste handlinger.

For et dybere kig på værdierne i hver kolonne kan vi også bruge pandas describe()-funktionen. Ulempen ved denne funktion er dog, at den ikke giver information om kolonner med strengværdier. Vi tager os af dem senere.

df.describe()

Notesblok-snydeark til hurtig dataforbehandling

Magisk visualisering

Lad os se på, hvor vi slet ingen værdier har:

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

Notesblok-snydeark til hurtig dataforbehandling

Dette var et kort kig fra oven, nu vil vi gå videre til mere interessante ting

Lad os prøve at finde og, hvis det er muligt, fjerne kolonner, der kun har én værdi i alle rækker (de vil ikke påvirke resultatet på nogen måde):

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

Nu beskytter vi os selv og vores projekts succes mod duplikerede linjer (linjer, der indeholder de samme oplysninger i samme rækkefølge som en af ​​de eksisterende linjer):

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

Vi deler datasættet op i to: det ene med kvalitative værdier og det andet med kvantitative

Her skal vi lave en lille præcisering: Hvis linjerne med manglende data i kvalitative og kvantitative data ikke er særlig korrelerede med hinanden, så bliver vi nødt til at beslutte, hvad vi ofrer - alle linjerne med manglende data, kun en del af dem, eller visse kolonner. Hvis linjerne er korrelerede, så har vi ret til at dele datasættet i to. Ellers skal du først forholde dig til de linjer, der ikke korrelerer de manglende data i kvalitativ og kvantitativ, og først derefter opdele datasættet i to.

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

Det gør vi for at gøre det nemmere for os at behandle disse to forskellige typer data – senere vil vi forstå, hvor meget lettere dette gør vores liv.

Vi arbejder med kvantitative data

Den første ting, vi skal gøre, er at afgøre, om der er "spionkolonner" i de kvantitative data. Vi kalder disse kolonner det, fordi de præsenterer sig selv som kvantitative data, men fungerer som kvalitative data.

Hvordan definerer vi dem? Det afhænger selvfølgelig af arten af ​​de data, du analyserer, men generelt kan sådanne kolonner have få unikke data (i området 3-10 unikke værdier).

print(df_numerical.nunique())

Når vi har identificeret spionkolonnerne, flytter vi dem fra kvantitative data til kvalitative data:

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

Endelig har vi helt adskilt kvantitative data fra kvalitative data, og nu kan vi arbejde ordentligt med det. Den første ting er at forstå, hvor vi har tomme værdier (NaN, og i nogle tilfælde vil 0 blive accepteret som tomme værdier).

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

På dette tidspunkt er det vigtigt at forstå, i hvilke kolonner nuller kan indikere manglende værdier: skyldes det, hvordan dataene blev indsamlet? Eller kan det være relateret til dataværdierne? Disse spørgsmål skal besvares fra sag til sag.

Så hvis vi stadig beslutter, at vi muligvis mangler data, hvor der er nuller, bør vi erstatte nullerne med NaN for at gøre det lettere at arbejde med disse tabte data senere:

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

Lad os nu se, hvor vi mangler data:

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

Notesblok-snydeark til hurtig dataforbehandling

Her skal de værdier inde i kolonnerne, der mangler, markeres med gult. Og nu begynder det sjove - hvordan skal man håndtere disse værdier? Skal jeg slette rækker med disse værdier eller kolonner? Eller udfyld disse tomme værdier med nogle andre?

Her er et omtrentligt diagram, der kan hjælpe dig med at beslutte, hvad der i princippet kan gøres med tomme værdier:

Notesblok-snydeark til hurtig dataforbehandling

0. Fjern unødvendige kolonner

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

1. Er antallet af tomme værdier i denne kolonne større end 50%?

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

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

2. Slet linjer med tomme værdier

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

3.1. Indsættelse af en tilfældig værdi

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

3.2. Indsættelse af en konstant værdi

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. Indsæt den gennemsnitlige eller hyppigste værdi

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. Indsæt værdien beregnet af en anden model

Nogle gange kan værdier beregnes ved hjælp af regressionsmodeller ved hjælp af modeller fra sklearn-biblioteket eller andre lignende biblioteker. Vores team vil afsætte en separat artikel om, hvordan dette kan gøres i den nærmeste fremtid.

Så foreløbig vil fortællingen om kvantitative data blive afbrudt, fordi der er mange andre nuancer om, hvordan man bedre kan gøre dataforberedelse og forbehandling til forskellige opgaver, og de grundlæggende ting for kvantitative data er taget i betragtning i denne artikel, og nu er det tid til at vende tilbage til kvalitative data, som vi adskilte flere trin tilbage fra de kvantitative. Du kan ændre denne notesbog, som du vil, tilpasse den til forskellige opgaver, så dataforbehandlingen går meget hurtigt!

Kvalitative data

Grundlæggende, for kvalitative data, bruges One-hot-encoding-metoden for at formatere dem fra en streng (eller objekt) til et tal. Før vi går videre til dette punkt, lad os bruge diagrammet og koden ovenfor til at håndtere tomme værdier.

df_categorical.nunique()

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

Notesblok-snydeark til hurtig dataforbehandling

0. Fjern unødvendige kolonner

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

1. Er antallet af tomme værdier i denne kolonne større end 50%?

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

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

2. Slet linjer med tomme værdier

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

3.1. Indsættelse af en tilfældig værdi

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

3.2. Indsættelse af en konstant værdi

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)

Så vi har endelig fået styr på nuller i kvalitative data. Nu er det tid til at udføre one-hot-encoding på de værdier, der er i din database. Denne metode bruges meget ofte til at sikre, at din algoritme kan lære af data af høj kvalitet.

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

Så vi er endelig færdige med at behandle separate kvalitative og kvantitative data - tid til at kombinere dem tilbage

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

Efter at vi har kombineret datasættene til ét, kan vi endelig bruge datatransformation ved hjælp af MinMaxScaler fra sklearn-biblioteket. Dette vil gøre vores værdier mellem 0 og 1, hvilket vil hjælpe, når du træner modellen i fremtiden.

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

Disse data er nu klar til alt - neurale netværk, standard ML-algoritmer osv.!

I denne artikel har vi ikke taget højde for at arbejde med tidsseriedata, da du til sådanne data skal bruge lidt forskellige behandlingsteknikker afhængigt af din opgave. I fremtiden vil vores team afsætte en separat artikel til dette emne, og vi håber, at det vil være i stand til at bringe noget interessant, nyt og nyttigt ind i dit liv, ligesom denne.

Kilde: www.habr.com

Tilføj en kommentar