तेज़ डेटा प्रीप्रोसेसिंग के लिए नोटपैड-चीट शीट

अक्सर डेटा साइंस के क्षेत्र में प्रवेश करने वाले लोगों को जो कुछ मिलने वाला है उसकी वास्तविक अपेक्षाएं कम होती हैं। बहुत से लोग सोचते हैं कि अब वे शानदार न्यूरल नेटवर्क लिखेंगे, आयरन मैन से एक वॉयस असिस्टेंट बनाएंगे, या वित्तीय बाजारों में सभी को हरा देंगे।
लेकिन काम करो जानकारी वैज्ञानिक डेटा-चालित है, और सबसे महत्वपूर्ण और समय लेने वाला पहलू डेटा को तंत्रिका नेटवर्क में फीड करने या एक निश्चित तरीके से विश्लेषण करने से पहले संसाधित करना है।

इस लेख में, हमारी टीम बताएगी कि आप चरण-दर-चरण निर्देशों और कोड के साथ डेटा को कैसे जल्दी और आसानी से संसाधित कर सकते हैं। हमने कोड को काफी लचीला बनाने की कोशिश की और इसे विभिन्न डेटासेट के लिए इस्तेमाल किया जा सके।

कई पेशेवरों को इस आलेख में कुछ भी असाधारण नहीं मिल सकता है, लेकिन शुरुआती लोग कुछ नया सीखने में सक्षम होंगे, और जिसने भी लंबे समय से तेज़ और संरचित डेटा प्रोसेसिंग के लिए एक अलग नोटबुक बनाने का सपना देखा है, वह कोड की प्रतिलिपि बना सकता है और इसे अपने लिए प्रारूपित कर सकता है, या जीथब से तैयार नोटबुक डाउनलोड करें।

हमें डेटासेट प्राप्त हुआ। आगे क्या करना है?

तो, मानक: हमें यह समझने की ज़रूरत है कि हम किसके साथ काम कर रहे हैं, समग्र तस्वीर। ऐसा करने के लिए, हम विभिन्न डेटा प्रकारों को परिभाषित करने के लिए पांडा का उपयोग करते हैं।

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. इसके लिए पूर्वानुमान लगाने के लिए हम किस कॉलम को लक्षित करना चाहते हैं?

इन सवालों के जवाब आपको डेटासेट का विश्लेषण करने और मोटे तौर पर अपने अगले कार्यों के लिए एक योजना बनाने की अनुमति देंगे।

साथ ही, प्रत्येक कॉलम में मूल्यों को गहराई से देखने के लिए, हम पांडा वर्णन() फ़ंक्शन का उपयोग कर सकते हैं। हालाँकि, इस फ़ंक्शन का नुकसान यह है कि यह स्ट्रिंग मान वाले कॉलम के बारे में जानकारी प्रदान नहीं करता है। हम उनसे बाद में निपटेंगे.

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. किसी अन्य मॉडल द्वारा परिकलित मान डालें

कभी-कभी स्केलेर लाइब्रेरी या अन्य समान लाइब्रेरी से मॉडल का उपयोग करके प्रतिगमन मॉडल का उपयोग करके मूल्यों की गणना की जा सकती है। निकट भविष्य में यह कैसे किया जा सकता है, इस पर हमारी टीम एक अलग लेख समर्पित करेगी।

तो, अभी के लिए, मात्रात्मक डेटा के बारे में कथा बाधित हो जाएगी, क्योंकि विभिन्न कार्यों के लिए डेटा तैयारी और प्रीप्रोसेसिंग को बेहतर तरीके से करने के बारे में कई अन्य बारीकियां हैं, और इस आलेख में मात्रात्मक डेटा के लिए बुनियादी चीजों को ध्यान में रखा गया है, और अब गुणात्मक डेटा पर लौटने का समय है। जिसे हमने मात्रात्मक डेटा से कई कदम पीछे अलग किया है। आप इस नोटबुक को अपनी इच्छानुसार बदल सकते हैं, इसे विभिन्न कार्यों के लिए अनुकूलित कर सकते हैं, ताकि डेटा प्रीप्रोसेसिंग बहुत तेज़ी से हो सके!

गुणात्मक तथ्य

मूल रूप से, गुणात्मक डेटा के लिए, इसे एक स्ट्रिंग (या ऑब्जेक्ट) से एक संख्या में प्रारूपित करने के लिए वन-हॉट-एन्कोडिंग विधि का उपयोग किया जाता है। इस बिंदु पर आगे बढ़ने से पहले, आइए खाली मानों से निपटने के लिए उपरोक्त आरेख और कोड का उपयोग करें।

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 का उपयोग करके डेटा परिवर्तन का उपयोग कर सकते हैं। इससे हमारा मान 0 और 1 के बीच हो जाएगा, जो भविष्य में मॉडल को प्रशिक्षित करते समय मदद करेगा।

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

यह डेटा अब किसी भी चीज़ के लिए तैयार है - तंत्रिका नेटवर्क, मानक एमएल एल्गोरिदम, आदि!

इस लेख में, हमने समय श्रृंखला डेटा के साथ काम करने पर ध्यान नहीं दिया, क्योंकि ऐसे डेटा के लिए आपको अपने कार्य के आधार पर थोड़ी अलग प्रसंस्करण तकनीकों का उपयोग करना चाहिए। भविष्य में, हमारी टीम इस विषय पर एक अलग लेख समर्पित करेगी, और हमें उम्मीद है कि यह इस लेख की तरह ही आपके जीवन में कुछ दिलचस्प, नया और उपयोगी लाने में सक्षम होगा।

स्रोत: www.habr.com

एक टिप्पणी जोड़ें