NjerĂ«zit qĂ« hyjnĂ« nĂ« fushĂ«n e Data Science shpesh kanĂ« ŰȘŰ”Ù۱ime jo shumĂ« realiste pĂ«r atĂ« qĂ« i pret. ShumĂ« mendojnĂ« se tani do tĂ« fillojnĂ« tĂ« krijojnĂ« rrjete nervore tĂ« shkĂ«lqyera, tĂ« krijojnĂ« njĂ« ndihmĂ«s zĂ«ri si Iron Man, ose tĂ« fitojnĂ« mbi tĂ« gjithĂ« nĂ« tregjet financiare.
Por puna Data e Scientist është e lidhur ngushtë me të dhënat, dhe një nga momentet më të rëndësishme dhe më të shumëfishta është përpunimi i të dhënave para se ato të kalojnë në rrjetin nervor ose të analizohet në një mënyrë të caktuar.
Në këtë artikull, ekipi ynë do të përshkruajë si mund të përpunoni lehtësisht dhe shpejt të dhënat me udhëzime hap pas hapi dhe kod. Ne u munduam ta bëjmë kodin mjaft fleksibël dhe ta përdorim për grupe të ndryshme të dhënash.
Shumë profesionistë ndoshta nuk do të gjejnë asgjë jashtëzakonisht interesante në këtë artikull, por fillestarët mund të nxjerrin diçka të re, si dhe çdo person që ka dëshiruara një notebook të veçantë për përpunimin e shpejtë dhe të strukturuar të të dhënave mund të kopjojë kodin dhe ta formatojë për nevojat e tij, ose
Kemi marrĂ« dataset. ĂfarĂ« tĂ« bĂ«jmĂ« mĂ« tej?
Pra, standardi: duhet të kuptojmë me çfarë kemi të bëjmë, pamjen e përgjithshme. Për këtë do të përdorim pandas, që thjesht të përcaktojmë llojet e ndryshme të të dhënave.
import pandas as pd #importojmë pandas
import numpy as np #importojmë numpy
df = pd.read_csv("AB_NYC_2019.csv") #lemë datasetin dhe e ruajmë në variablën df
df.head(3) #shohim tre rreshtat e parë për të kuptuar se si duken vlerat 
df.info() #Tregojmë informacionin mbi kolonat 
Shohim vlerat e kolonave:
- A përputhet numri i rreshtave në secilën kolone me numrin e përgjithshëm të rreshtave?
- Cili është thelbi i të dhënave në secilën kolone?
- Cilën kolone duam ta bëjmë target, për të bërë parashikime për të?
Përgjigjet në këto pyetje do të lejojnë të analizojmë datasetin dhe të vizatojmë një plan për veprimet e afërta.
Gjithashtu, për një vështrim më të thellë në vlerat në secilën kolone, mund të përdorim funksionin pandas describe(). Sidoqoftë, mangësia e këtij funksioni është se ai nuk jep informacion për kolonat me vlera string. Ne do të merremi me to më vonë.
df.describe() 
Vizualizimi magjik
Të shohim për ku na mungojnë vlerat krejtësisht:
import seaborn as sns
sns.heatmap(df.isnull(),yticklabels=False,cbar=False,cmap='viridis') 
Ky ishte një vështrim i vogël nga lart, tani do të vazhdojmë me gjëra më interesante.
Do të përpiqemi të gjejmë dhe, nëse është e mundur, të heqim kolonat që kanë vetëm një vlerë në të gjitha rreshtat (ato nuk do të ndikojnë në rezultat):
df = df[[c for c
in list(df)
if len(df[c].unique()) > 1]] #Rikthejmë datasetin, duke lënë vetëm ato kolona që kanë më shumë se një vlerë unikeTani e ruajmë veten dhe suksesin e projektit tonë nga rreshtat e dyfishtë (rreshtat që kanë të njëjtin informacion në të njëjtin rend si një nga rreshtat ekzistues):
df.drop_duplicates(inplace=True) #E bëjmë këtë, nëse e konsiderojmë të nevojshme.
#NĂ« disa projekte, heqja e tĂ« dhĂ«nave tĂ« tilla nĂ« fillim nuk Ă«shtĂ« e nevojshme.NdajmĂ« datasetin nĂ« dy: njĂ« me vlera cilĂ«sore dhe tjetrin â me vlera sasiore.
KĂ«tu duhet tĂ« bĂ«jmĂ« njĂ« sqarim tĂ« vogĂ«l: nĂ«se rreshtat me tĂ« dhĂ«na tĂ« munguar nĂ« tĂ« dhĂ«nat cilĂ«sore dhe sasiore nuk korrespondojnĂ« shumĂ« me njĂ«ri-tjetrin, atĂ«herĂ« do tĂ« duhet tĂ« marrim njĂ« vendim pĂ«r atĂ« se çfarĂ« do tĂ« sakrifikojmĂ« â tĂ« gjitha rreshtat me tĂ« dhĂ«na tĂ« munguar, vetĂ«m njĂ« pjesĂ« tĂ« tyre ose disa kolona tĂ« caktuara. NĂ«se rreshtat korrespondojnĂ«, atĂ«herĂ« kemi tĂ« drejtĂ« tĂ« ndajmĂ« datasetin nĂ« dy. NĂ« tĂ« kundĂ«rt, duhet tĂ« merremi fillimisht me rreshtat qĂ« nuk korrespondojnĂ« me tĂ« dhĂ«na tĂ« munguar nĂ« cilĂ«sore dhe sasiore, dhe pastaj tĂ« ndajmĂ« datasetin nĂ« dy.
df_numerical = df.select_dtypes(include = [np.number])
df_categorical = df.select_dtypes(exclude = [np.number])Ne e bĂ«jmĂ« kĂ«tĂ« pĂ«r ta bĂ«rĂ« mĂ« tĂ« lehtĂ« pĂ«rpunimin e kĂ«tyre dy llojeve tĂ« ndryshme tĂ« tĂ« dhĂ«nave â mĂ« vonĂ« do tĂ« kuptojmĂ« se sa e thjeshton kjo jetĂ«n tonĂ«.
Puna me të dhënat sasiore
E para qĂ« duhet tĂ« bĂ«jmĂ« â tĂ« pĂ«rcaktojmĂ« nĂ«se ka "kolona-spiun" nĂ« tĂ« dhĂ«nat sasiore. Ne i quajmĂ« kĂ«shtu kĂ«to kolona sepse ato duken si tĂ« dhĂ«na sasiore, por nĂ« fakt operojnĂ« si tĂ« dhĂ«na cilĂ«sore.
Si tâi pĂ«rcaktojmĂ« ato? Sigurisht, gjithçka varet nga natyra e tĂ« dhĂ«nave qĂ« po analizoni, por zakonisht kĂ«to kolona mund tĂ« kenĂ« pak vlera unike (rreth 3-10 vlera unike).
print(df_numerical.nunique())Pasi tĂ« kemi pĂ«rcaktuar kolonat-spiun, do tâi zhvendosim ato nga tĂ« dhĂ«nat sasiore nĂ« ato cilĂ«sore:
spy_columns = df_numerical[['kolonka1', 'koloka2', 'kolonka3']]#ndajmë kolonat-spiun dhe i regjistrojmë në një dataframe të veçantë
df_numerical.drop(labels=['kolonka1', 'kolonka2', 'kolonka3'], axis=1, inplace = True)#heqim këto kolona nga të dhënat numerikë
df_categorical.insert(1, 'kolonka1', spy_columns['kolonka1']) #shtojmë kolonën e parë-spiun në të dhënat kategorike
df_categorical.insert(1, 'kolonka2', spy_columns['kolonka2']) #shtojmë kolonën e dytë-spiun në të dhënat kategorike
df_categorical.insert(1, 'kolonka3', spy_columns['kolonka3']) #shtojmĂ« kolonĂ«n e tretĂ«-spiun nĂ« tĂ« dhĂ«nat kategorikeMĂ« nĂ« fund, ne i ndamĂ« plotĂ«sisht tĂ« dhĂ«nat numerike nga ato kategorike dhe tani mund tĂ« punojmĂ« me to. E para â duhet tĂ« kuptojmĂ« se ku kemi vlera tĂ« zbrazĂ«ta (NaN, dhe nĂ« disa raste 0 do tĂ« pranohen si vlera tĂ« zbrazĂ«ta).
for i in df_numerical.columns:
print(i, df[i][df[i]==0].count())Në këtë hap është e rëndësishme të kuptojmë se në cilat kolona 0-të mund të nënkuptojnë mungesë vlerash: a është kjo e lidhur me mënyrën se si u mblodhën të dhënat? Apo mund të jetë e lidhur me vlerat e të dhënave? Duhet të përgjigjemi në këto pyetje për çdo rast të veçantë.
Pra, nëse e kemi vendosur se të dhënat tona mund të mungojnë atje ku ka 0, duhet të zëvendësojmë 0-të me NaN, në mënyrë që të jetë më e lehtë të punojmë më vonë me këto të dhëna të humbura:
df_numerical[["kolonka 1", "kolonka 2"]] = df_numerical[["kolonka 1", "kolonka 2"]].replace(0, nan)Tani le të shikojmë se ku kemi të dhëna të humbura:
sns.heatmap(df_numerical.isnull(),yticklabels=False,cbar=False,cmap='viridis') # Mund të përdorim gjithashtu df_numerical.info() 
KĂ«tu duhet tĂ« jenĂ« tĂ« theksuara me ngjyrĂ« tĂ« verdhĂ« ato vlera brenda kolonave qĂ« mungojnĂ«. Dhe tani fillon e gjitha interesante â si tĂ« sillet me kĂ«to vlera? TĂ« heqim rreshtat me kĂ«to vlera apo kolonat? Ose tĂ« mbushim kĂ«to vlera tĂ« zbrazĂ«ta me disa tĂ« tjera?
Ja një skemë e përafërt, që mund t'ju ndihmojë të vendosni se çfarë mund të bëni në parim me vlerat e zbrazëta:

0. Heqim kolonat e panevojshme
df_numerical.drop(labels=["kolonka1","kolonka2"], axis=1, inplace=True)1. A është numri i vlerave të zbrazëta në këtë kolonë më shumë se 50%?
print(df_numerical.isnull().sum() / df_numerical.shape[0] * 100)df_numerical.drop(labels=["kolonka1","kolonka2"], axis=1, inplace=True)#Heqim, nëse ndonjë kolonë ka më shumë se 50 vlera të zbrazëta2. Të heqim rreshtat me vlera të zbrazëta
df_numerical.dropna(inplace=True)#Heqim rreshtat me vlera të zbrazëta, nëse pastaj do të mbetet mjaft të dhëna për trajnimin3.1. Shtojmë një vlerë të rastësishme
import random #importojmë random
df_numerical["kolonka"].fillna(lambda x: random.choice(df[df[column] != np.nan]["kolonka"]), inplace=True) #shtojmë vlera të rastësishme në qelizat e zbrazëta të tabelës3.2. Shtojmë një vlerë konstante
from sklearn.impute import SimpleImputer #importojmë SimpleImputer, që do ndihmojë në vendosjen e vlerave
imputer = SimpleImputer(strategy='constant', fill_value="") #vendosim një vlerë të caktuar me SimpleImputer
df_numerical[["nova_kolonka1",'nova_kolonka2','nova_kolonka3']] = imputer.fit_transform(df_numerical[['kolonka1', 'kolonka2', 'kolonka3']]) #E aplikojmë këtë për tabelën tonë
df_numerical.drop(labels = ["kolonka1","kolonka2","kolonka3"], axis = 1, inplace = True) #Heqim kolonat me vlerat e vjetra3.3. Shtojmë mesataren ose vlerën më të shpeshtë
from sklearn.impute import SimpleImputer #importojmë SimpleImputer, që do ndihmojë në vendosjen e vlerave
imputer = SimpleImputer(strategy='mean', missing_values = np.nan) #mund të përdorim gjithashtu most_frequent në vend të mesatares
df_numerical[["nova_kolonka1",'nova_kolonka2','nova_kolonka3']] = imputer.fit_transform(df_numerical[['kolonka1', 'kolonka2', 'kolonka3']]) #E aplikojmë këtë për tabelën tonë
df_numerical.drop(labels = ["kolonka1","kolonka2","kolonka3"], axis = 1, inplace = True) #Heqim kolonat me vlerat e vjetra3.4. Shtojmë një vlerë të llogaritur nga një model tjetër
Ndonjëherë, vlerat mund të llogariten duke përdorur modele regresive, duke përdorur modele nga biblioteka sklearn ose biblioteka të ngjashme. Ekipa jonë do t'i kushtojë një artikull të veçantë se si mund ta bëni këtë në të ardhmen e afërt.
Pra, për tani narrativa për të dhënat numerike do të ndërpritet, sepse ka shumë nuanca të tjera rreth mënyrës më të mirë për të bërë përgatitjen dhe përpunimin e të dhënave për detyra të ndryshme, dhe gjërat themelore për të dhënat numerike janë marrë në këtë artikull, dhe tani është koha të kthehemi te të dhënat kategorike, që i ndamë disa hapa më parë nga ato numerike. Ju mund të modifikoni këtë notebook ashtu siç ju pëlqen, duke e përshtatur atë për detyra të ndryshme, në mënyrë që përgatitja e të dhënave të kalojë shumë shpejt!
Të dhënat kategorike
Kryesisht, për të dhënat kategorike përdoret metoda One-hot-encoding, për të i formatuar ato nga string (ose object) në numër. Para se të kalojmë në këtë pikë, le të përdorim skemën dhe kodin më lart, për të u marrë me vlerat e zbrazëta.
df_categorical.nunique()sns.heatmap(df_categorical.isnull(),yticklabels=False,cbar=False,cmap='viridis') 
0. Heqim kolonat e panevojshme
df_categorical.drop(labels=["kolona1","kolona2"], axis=1, inplace=True)1. A është numri i vlerave të zbrazëta në këtë kolonë më shumë se 50%?
print(df_categorical.isnull().sum() / df_numerical.shape[0] * 100)df_categorical.drop(labels=["kolona1","kolona2"], axis=1, inplace=True) #Heqim, nese ndonjë kolona
#ka më shumë se 50% vlera bosh2. Të heqim rreshtat me vlera të zbrazëta
df_categorical.dropna(inplace=True) #Heqim rreshtat me vlera bosh,
#nëse pastaj do të mbesin të dhëna të mjaftueshme për trajnim3.1. Shtojmë një vlerë të rastësishme
import random
df_categorical["kolona"].fillna(lambda x: random.choice(df[df[column] != np.nan]["kolona"]), inplace=True)3.2. Shtojmë një vlerë konstante
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='constant', fill_value="")
df_categorical[["kolona_e_re1",'kolona_e_re2','kolona_e_re3']] = imputer.fit_transform(df_categorical[['kolona1', 'kolona2', 'kolona3']])
df_categorical.drop(labels = ["kolona1","kolona2","kolona3"], axis = 1, inplace = True)Tani, pĂ«rfundimisht kemi trajtuar vlerat bosh nĂ« tĂ« dhĂ«na cilĂ«sore. ĂshtĂ« koha tĂ« kryejmĂ« one-hot-encoding pĂ«r vlerat qĂ« gjenden nĂ« bazĂ«n tuaj tĂ« tĂ« dhĂ«nave. Ky metod Ă«shtĂ« jashtĂ«zakonisht i pĂ«rdorur pĂ«r qĂ« algoritmi juaj tĂ« mund tĂ« trajnohet duke marrĂ« parasysh tĂ« dhĂ«nat cilĂ«sore.
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 = ["kolona1","kolona2","kolona3"]
for feature in features_to_encode:
df_categorical = encode_and_bind(df_categorical, feature)KĂ«shtu, pĂ«rfundimisht kemi pĂ«rfunduar pĂ«rpunimin e veçantĂ« tĂ« tĂ« dhĂ«nave cilĂ«sore dhe sasiore â tani Ă«shtĂ« koha t'i bashkojmĂ« ato pĂ«rsĂ«ri
new_df = pd.concat([df_numerical,df_categorical], axis=1)Pasi që kemi bashkuar dataset të dhënat në një, në fund mund të përdorim transformimin e të dhënave me MinMaxScaler nga biblioteka sklearn. Kjo do t'i vendosë vlerat tona midis 0 dhe 1, që do të ndihmojë në trajnim të modelit në të ardhmen.
from sklearn.preprocessing import MinMaxScaler
min_max_scaler = MinMaxScaler()
new_df = min_max_scaler.fit_transform(new_df)KĂ«to tĂ« dhĂ«na tani janĂ« gati pĂ«r gjithçka â pĂ«r rrjetet neuronale, algoritmet standarde tĂ« ML etj!
NĂ« kĂ«tĂ« artikull nuk kemi marrĂ« parasysh punĂ«n me tĂ« dhĂ«nat qĂ« i pĂ«rkasin serive temporale, pasi pĂ«r kĂ«to tĂ« dhĂ«na duhet tĂ« pĂ«rdoren pak teknika tĂ« ndryshme tĂ« pĂ«rpunimit, nĂ« varĂ«si tĂ« detyrĂ«s suaj. NĂ« tĂ« ardhmen, ekipi ynĂ« do tâi dedikojĂ« kĂ«tij temĂ« njĂ« artikull tĂ« veçantĂ«, dhe shpresojmĂ« se do t'ju sjellĂ« diçka interesante, tĂ« re dhe tĂ« dobishme, ashtu si dhe ky.
Burimi: habr.com
