Նոթատետր-խաբե թերթ՝ տվյալների արագ նախնական մշակման համար

Հաճախ Տվյալների գիտության ոլորտ մուտք գործող մարդիկ ունեն ավելի քիչ, քան իրատեսական ակնկալիքներ, թե ինչ է իրենց սպասվում: Շատերը կարծում են, որ հիմա նրանք կգրեն զովացուցիչ նեյրոնային ցանցեր, կստեղծեն ձայնային օգնական Iron Man-ից կամ կհաղթեն բոլորին ֆինանսական շուկաներում։
Բայց աշխատիր Ամսաթիվ Գիտնականը հիմնված է տվյալների վրա, և ամենակարևոր և ժամանակատար ասպեկտներից մեկը տվյալների մշակումն է նախքան դրանք նեյրոնային ցանց մտցնելը կամ որոշակի ձևով վերլուծելը:

Այս հոդվածում մեր թիմը նկարագրելու է, թե ինչպես կարող եք արագ և հեշտությամբ մշակել տվյալները՝ քայլ առ քայլ հրահանգներով և կոդով: Մենք փորձեցինք կոդը դարձնել բավականին ճկուն և կարող էր օգտագործվել տարբեր տվյալների հավաքածուների համար:

Շատ մասնագետներ կարող են որևէ արտառոց բան չգտնել այս հոդվածում, բայց սկսնակները կկարողանան ինչ-որ նոր բան սովորել, և յուրաքանչյուրը, ով վաղուց երազում էր առանձին նոթատետր պատրաստել արագ և կառուցվածքային տվյալների մշակման համար, կարող է պատճենել կոդը և ձևաչափել այն իրենց համար, կամ ներբեռնեք պատրաստի նոթատետրը Github-ից:

Մենք ստացանք տվյալների բազան: Ի՞նչ անել հետո:

Այսպիսով, չափանիշը. մենք պետք է հասկանանք, թե ինչի հետ գործ ունենք, ընդհանուր պատկերը։ Դա անելու համար մենք օգտագործում ենք պանդաներ՝ պարզապես տվյալների տարբեր տեսակներ սահմանելու համար:

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

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

Նոթատետր-խաբե թերթ՝ տվյալների արագ նախնական մշակման համար

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

Նոթատետր-խաբե թերթ՝ տվյալների արագ նախնական մշակման համար

Դիտարկենք սյունակների արժեքները.

  1. Արդյո՞ք յուրաքանչյուր սյունակի տողերի թիվը համապատասխանում է տողերի ընդհանուր թվին:
  2. Ո՞րն է յուրաքանչյուր սյունակի տվյալների էությունը:
  3. Ո՞ր սյունակն ենք ուզում թիրախավորել դրա համար կանխատեսումներ անելու համար:

Այս հարցերի պատասխանները թույլ կտան ձեզ վերլուծել տվյալների հավաքածուն և մոտավորապես գծել ձեր հաջորդ գործողությունների պլանը:

Բացի այդ, յուրաքանչյուր սյունակի արժեքներին ավելի խորը դիտելու համար մենք կարող ենք օգտագործել pandas describe() ֆունկցիան: Այնուամենայնիվ, այս ֆունկցիայի թերությունն այն է, որ այն տեղեկատվություն չի տրամադրում լարային արժեքներով սյունակների մասին։ Մենք նրանց հետ կզբաղվենք ավելի ուշ:

df.describe()

Նոթատետր-խաբե թերթ՝ տվյալների արագ նախնական մշակման համար

Կախարդական պատկերացում

Եկեք նայենք, թե որտեղ մենք ընդհանրապես արժեքներ չունենք.

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

Նոթատետր-խաբե թերթ՝ տվյալների արագ նախնական մշակման համար

Սա կարճ հայացք էր վերեւից, հիմա կանցնենք ավելի հետաքրքիր բաների

Փորձենք գտնել և, հնարավորության դեպքում, հեռացնել սյունակները, որոնք ունեն միայն մեկ արժեք բոլոր տողերում (դրանք որևէ կերպ չեն ազդի արդյունքի վրա).

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

Այժմ մենք պաշտպանում ենք մեզ և մեր նախագծի հաջողությունը կրկնօրինակ տողերից (տողեր, որոնք պարունակում են նույն տեղեկատվությունը նույն հաջորդականությամբ, ինչ գոյություն ունեցող տողերից մեկը).

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

Տվյալների հավաքածուն բաժանում ենք երկուսի՝ մեկը որակական արժեքներով, իսկ մյուսը՝ քանակական

Այստեղ մենք պետք է մի փոքր պարզաբանում անենք. եթե որակական և քանակական տվյալների բացակայող տողերը միմյանց հետ այնքան էլ փոխկապակցված չեն, ապա պետք է որոշենք, թե ինչ ենք զոհաբերում. բացակայող բոլոր տողերը, միայն դրանց մի մասը, կամ որոշակի սյունակներ: Եթե ​​տողերը փոխկապակցված են, ապա մենք լրիվ իրավունք ունենք տվյալների բազան երկուսի բաժանելու: Հակառակ դեպքում, դուք նախ պետք է գործ ունենաք այն տողերի հետ, որոնք չեն փոխկապակցում բաց թողնված տվյալները որակական և քանակական առումով, և միայն այնուհետև բաժանեք տվյալների բազան երկուսի:

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

Մենք դա անում ենք, որպեսզի մեզ համար հեշտացնենք այս երկու տարբեր տեսակի տվյալների մշակումը. ավելի ուշ մենք կհասկանանք, թե որքանով է դա հեշտացնում մեր կյանքը:

Մենք աշխատում ենք քանակական տվյալներով

Առաջին բանը, որ մենք պետք է անենք, պարզելն է, թե արդյոք քանակական տվյալների մեջ կան «լրտեսական սյունակներ»: Այս սյունակները մենք անվանում ենք այդպես, քանի որ նրանք իրենց ներկայացնում են որպես քանակական տվյալներ, բայց գործում են որպես որակական տվյալներ։

Ինչպե՞ս կարող ենք բացահայտել դրանք: Իհարկե, ամեն ինչ կախված է ձեր վերլուծած տվյալների բնույթից, բայց ընդհանուր առմամբ նման սյունակները կարող են ունենալ քիչ եզակի տվյալներ (3-10 եզակի արժեքների շրջանում):

print(df_numerical.nunique())

Երբ մենք նույնականացնենք լրտեսական սյունակները, մենք դրանք քանակական տվյալներից կտեղափոխենք որակական տվյալների՝

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

Ի վերջո, մենք ամբողջությամբ տարանջատել ենք քանակական տվյալները որակական տվյալներից և այժմ կարող ենք ճիշտ աշխատել դրանց հետ։ Առաջին բանը հասկանալն է, թե որտեղ ունենք դատարկ արժեքներ (NaN, իսկ որոշ դեպքերում 0-ը կընդունվի որպես դատարկ արժեքներ):

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

Այս պահին կարևոր է հասկանալ, թե որ սյունակներում զրոները կարող են ցույց տալ բացակայող արժեքները. արդյոք դա պայմանավորված է նրանով, թե ինչպես են հավաքվել տվյալները: Կամ կարող է դա կապված լինել տվյալների արժեքների հետ: Այս հարցերին պետք է պատասխանել յուրաքանչյուր դեպքի համար:

Այսպիսով, եթե մենք դեռ որոշենք, որ մենք կարող ենք բացակայել տվյալներ, որտեղ կան զրոներ, մենք պետք է փոխարինենք զրոները NaN-ով, որպեսզի ավելի ուշ հեշտացնենք աշխատել այս կորցրած տվյալների հետ.

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

Հիմա եկեք տեսնենք, թե որտեղ են մեզ բացակայում տվյալները.

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

Նոթատետր-խաբե թերթ՝ տվյալների արագ նախնական մշակման համար

Այստեղ այն արժեքները, որոնք բացակայում են սյունակների ներսում, պետք է նշվեն դեղինով: Եվ հիմա սկսվում է զվարճանքը. ինչպե՞ս վարվել այս արժեքների հետ: Պե՞տք է ջնջեմ այս արժեքներով կամ սյունակներով տողերը: Կամ այս դատարկ արժեքները լրացրե՞լ որոշ այլ արժեքներով:

Ահա մոտավոր դիագրամ, որը կարող է օգնել ձեզ որոշել, թե սկզբունքորեն ինչ կարելի է անել դատարկ արժեքներով.

Նոթատետր-խաբե թերթ՝ տվյալների արագ նախնական մշակման համար

0. Հեռացրեք ավելորդ սյունակները

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

1. Արդյո՞ք այս սյունակում դատարկ արժեքների թիվը 50%-ից մեծ է:

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

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

2. Ջնջել դատարկ արժեքներով տողերը

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

3.1. Պատահական արժեքի տեղադրում

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

3.2. Մշտական ​​արժեքի տեղադրում

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. Տեղադրեք միջին կամ առավել հաճախակի արժեքը

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. Տեղադրեք մեկ այլ մոդելի կողմից հաշվարկված արժեքը

Երբեմն արժեքները կարող են հաշվարկվել ռեգրեսիայի մոդելների միջոցով՝ օգտագործելով sklearn գրադարանի կամ այլ նմանատիպ գրադարանների մոդելները: Մեր թիմը կհատկացնի առանձին հոդված այն մասին, թե ինչպես կարելի է դա անել մոտ ապագայում:

Այսպիսով, առայժմ քանակական տվյալների մասին պատմությունը կդադարեցվի, քանի որ կան բազմաթիվ այլ նրբերանգներ այն մասին, թե ինչպես կարելի է ավելի լավ կատարել տվյալների պատրաստում և նախնական մշակում տարբեր խնդիրների համար, և քանակական տվյալների հիմնական բաները հաշվի են առնվել այս հոդվածում, և Հիմա ժամանակն է վերադառնալու որակական տվյալներին, որոնք մենք մի քանի քայլ հետ տարանք քանակականից։ Դուք կարող եք փոխել այս նոթատետրը, ինչպես ցանկանում եք՝ հարմարեցնելով այն տարբեր առաջադրանքներին, որպեսզի տվյալների նախնական մշակումն ընթանա շատ արագ:

Որակական տվյալներ

Հիմնականում որակական տվյալների համար օգտագործվում է One-hot-encoding մեթոդը՝ այն տողից (կամ օբյեկտից) թվի ձևաչափելու համար։ Նախքան այս կետին անցնելը, եկեք օգտագործենք վերը նշված դիագրամը և կոդը դատարկ արժեքների հետ գործ ունենալու համար:

df_categorical.nunique()

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

Նոթատետր-խաբե թերթ՝ տվյալների արագ նախնական մշակման համար

0. Հեռացրեք ավելորդ սյունակները

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

1. Արդյո՞ք այս սյունակում դատարկ արժեքների թիվը 50%-ից մեծ է:

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

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

2. Ջնջել դատարկ արժեքներով տողերը

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

3.1. Պատահական արժեքի տեղադրում

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

3.2. Մշտական ​​արժեքի տեղադրում

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)

Այսպիսով, մենք վերջապես ձեռք ենք բերել որակական տվյալների զրոյական արժեքներ: Այժմ ժամանակն է կատարել մեկ տաք կոդավորում այն ​​արժեքների վրա, որոնք գտնվում են ձեր տվյալների բազայում: Այս մեթոդը շատ հաճախ օգտագործվում է ապահովելու համար, որ ձեր ալգորիթմը կարող է սովորել բարձրորակ տվյալներից:

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

Այսպիսով, մենք վերջապես ավարտեցինք առանձին որակական և քանակական տվյալների մշակումը. ժամանակն է դրանք հետ համատեղելու

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

Այն բանից հետո, երբ մենք միավորեցինք տվյալների հավաքածուները մեկում, մենք վերջապես կարող ենք օգտագործել տվյալների փոխակերպումը, օգտագործելով MinMaxScaler-ը sklearn գրադարանից: Սա մեր արժեքները կդարձնի 0-ի և 1-ի միջև, ինչը կօգնի ապագայում մոդելը վարժեցնելիս:

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

Այս տվյալներն այժմ պատրաստ են ամեն ինչի համար՝ նեյրոնային ցանցեր, ստանդարտ ML ալգորիթմներ և այլն:

Այս հոդվածում մենք հաշվի չենք առել աշխատել ժամանակային շարքերի տվյալների հետ, քանի որ նման տվյալների համար դուք պետք է օգտագործեք մի փոքր այլ մշակման տեխնիկա՝ կախված ձեր առաջադրանքից: Հետագայում մեր թիմը առանձին հոդված կնվիրի այս թեմային, և հուսով ենք, որ այն կկարողանա հետաքրքիր, նոր և օգտակար բան բերել ձեր կյանք, ինչպես այս մեկը:

Source: www.habr.com

Добавить комментарий