Деректерді жылдам өңдеуге арналған блокнот - алдау парағы

Көбінесе деректер ғылымы саласына кіретін адамдар оларды не күтіп тұрғаны туралы шынайы үміттерден азырақ болады. Көптеген адамдар қазір керемет нейрондық желілерді жазады, 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-кодтау әдісі қолданылады. Осы нүктеге көшпес бұрын, бос мәндермен жұмыс істеу үшін жоғарыдағы диаграмма мен кодты қолданайық.

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)

Деректер жиынын біріктіргеннен кейін біз sklearn кітапханасынан MinMaxScaler көмегімен деректерді түрлендіруді пайдалана аламыз. Бұл біздің мәндерімізді 0 мен 1 арасында жасайды, бұл болашақта модельді үйретуге көмектеседі.

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

Бұл деректер енді кез келген нәрсеге дайын - нейрондық желілер, стандартты ML алгоритмдері және т.б.!

Бұл мақалада біз уақыттық қатар деректерімен жұмыс істеуді ескермедік, өйткені мұндай деректер үшін тапсырмаңызға байланысты сәл басқа өңдеу әдістерін пайдалану керек. Болашақта біздің команда осы тақырыпқа жеке мақала арнайды және ол сіздің өміріңізге дәл осы сияқты қызықты, жаңа және пайдалы нәрсені енгізе алады деп үміттенеміз.

Ақпарат көзі: www.habr.com

пікір қалдыру