ورقة الغش في الكمبيوتر المحمول للمعالجة المسبقة للبيانات بسرعة

في كثير من الأحيان ، ليس لدى الأشخاص الذين يدخلون مجال علوم البيانات فكرة واقعية تمامًا عما ينتظرهم. يعتقد الكثير من الناس أنهم الآن سيكتبون شبكات عصبية رائعة ، أو ينشئون مساعدًا صوتيًا من 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. ما العمود الذي نريد استهدافه لعمل تنبؤات له؟

ستسمح لك الإجابات على هذه الأسئلة بتحليل مجموعة البيانات ورسم خطة تقريبًا للخطوات التالية.

أيضًا ، لإلقاء نظرة أعمق على القيم الموجودة في كل عمود ، يمكننا استخدام وظيفة وصف الباندا (). صحيح أن عيب هذه الوظيفة هو أنها لا توفر معلومات حول الأعمدة ذات قيم السلسلة. سنتعامل معهم لاحقًا.

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 القياسية وما إلى ذلك!

في هذه المقالة ، لم نأخذ في الاعتبار العمل مع البيانات المتعلقة بالسلاسل الزمنية ، حيث يجب أن تستخدم في مثل هذه البيانات تقنيات معالجة مختلفة قليلاً ، اعتمادًا على مهمتك. في المستقبل ، سيخصص فريقنا مقالًا منفصلاً لهذا الموضوع ، ونأمل أن يتمكن من تقديم شيء مثير للاهتمام وجديد ومفيد في حياتك ، مثل هذا الموضوع.

المصدر: www.habr.com

إضافة تعليق