مدیریت داده گمشده در داده کاوی با پایتون | راهنمای کاربردی

هنگام کار با یک مجموعه داده، ممکن است به مشاهداتی برخورد کنیم که یک یا چند متغیر یا ویژگی آن، مقدار نداشته باشند. این مشکل اغلب در صورتی اتفاق میافتد که در هنگام جمع اوری دادهها دقت کافی صورت نگرفته باشد. در چنین مواردی میگوییم که مشاهدات دارای «مقدار گمشده» (Missing Value) هستند یا مجموعه داده از مشکل داده گمشده رنج میبرد. راه کارهای مختلفی برای مجموعه داده با مقادیر گمشده وجود دارد که هر یک از آنها دارای معایب با مزایایی خاص خودش است. در این متن به مدیریت داده پرت در داده کاوی پرداخته و محاسبات و عملیات را به کمک زبان برنامهنویسی پایتون مورد تحلیل قرار میدهیم. خوشبختانه در پایتون کتابخانه متعددی برای بررسی و مدیریت داده گمشده در داده کاوی وجود دارد. در لابلای متن از الگوریتمها و کدهایی به زبان پایتون برای این امر استفاده خواهیم کرد.
به منظور آشنایی بیشتر با مفهوم «داده گمشده» یا «نامشخص» بهتر است، نوشتارهای دیگر مجله فرادرس در این رابطه را مطالعه کنید. به این ترتیب خواندن مطالب داده های گمشده در SPSS — راهنمای کاربردی و داده گمشده یا ناموجود (Missing Data) در R – روش های پاکسازی داده ها موثر هستند. از آنجایی که یکی از گامهای مهم در داده کاوی، بررسی دادههای پرت و پاکسازی دادهها است، خواندن مطالب ساخت تابع پایتون برای پاکسازی داده ها — راهنمای کاربردی و تبدیل و پاکسازی داده ها با کتابخانه dplyr و tidyr در R — راهنمای کاربردی نیز خالی از لطف نیست.
مدیریت داده گمشده در داده کاوی با پایتون
به روشهای مختلفی میتوان بر مشکل دادهها گمشده یا از دست داده رفته، غلبه پیدا کرد. به موضوعات زیر توجه کنید. هر یک از آنها لزوم توجه به دادههای گمشده را به نوعی بیان میکند.
- یک خانه 2 خوابه اطلاعاتی برای اندازه یا مساحت اتاق خواب سوم ارائه نمیکند.
- ممکن است شخصی که تحت نظرسنجی قرار گرفته است، درآمد خود را مشخص نکند.
کتابخانههای پایتون دادههای گمشده را به صورت عبارت nan نشان میدهند که مخفف "not a number" است. به کمک توابع مرتبط با این کتابخانهها میتوانید مشخص کنید که کدام سلولها مقادیر گمشده دارند و سپس با دستوراتی نظیر کد زیر تعداد هر ستون یا متغیرهای مجموعه داده را بشمارید:
missing_val_count_by_column = (data.isnull().sum()) print(missing_val_count_by_column[missing_val_count_by_column > 0
اگر میخواهید با استفاده از دادهها با «مقادیر گمشده» (Missing Data) یا از دست رفته، مدلی بسازید، بیشتر کتابخانهها (از جمله scikit-learn) و تابع مدلسازی پیغامی مبنی بر وجود خطا ظاهر میسازند. بنابراین شما باید برای غلبه بر این خطاها و مشخص کردن یا مدیریت مقدار گمشده در مجموعه داده، یکی از راهکارهای زیر را انتخاب کنید.
- حذف ستون یا متغیر با مقادیر گمشده
- جایگزینی دادههای گمشده با مقدار ثابت
- جایگزینی دادههای گمشده با چند نوع مقدار
البته مشخص است که هر کدام از آنها مزایا و معایب خاص خود را دارند. بنابراین در ادامه هر یک از راهکارهای ارائه شده را معرفی و مورد ارزیابی قرار میدهیم.
روش اول، گزینه ساده، حذف ستون با مقادیر گمشده
فرض کنید که دادههای شما در «چارچوب داده» (DataFrame) به نام original_data قرار گرفته است و میتوانید ستونهایی با مقادیر از دست رفته را حذف کنید. بنابراین از کد زیر برای انجام این کار کمک میگیریم.
data_without_missing_values = original_data.dropna(axis=1)
به این ترتیب یک مجموعه داده شسته رفته و بدون داده گمشده در چارچوب داده data_without_missing_value ساخته میشود. مشخص است که متد یا روش dropna روی مجموعه داده original_data عمل کرده و به ترتیب ستونی، متغیرهای دارای مقدار گمشده را حذف میکند.
در بسیاری از موارد، در عملیات داده کاوی و به منظور اندازهگیری خطا یا تنظیم یک پارامتر در مدل، شما یک «مجموعه داده آموزشی» (Training Dataset) و یک «مجموعه داده آزمون» (Testing Dataset) خواهید داشت. اگر میخواهید عمل مشابهی را در هر دو مجموعه به کار بگیرید، از کدی که در ادامه مشاهده میکنید، استفاده کرده و ستون یا متغیرهای دارای مقدار گمشده را حذف کنید.
cols_with_missing = [col for col in original_data.columns if original_data[col].isnull().any()] reduced_original_data = original_data.drop(cols_with_missing, axis=1) reduced_test_data = test_data.drop(cols_with_missing, axis=1)
این عمل هر چند ساده به نظر میرسد ولی با حذف متغیر یا متغیرها، اطلاعاتی که بعضی از مشاهدات در آن متغیر دارند را نادیده گرفته و مدل با کمبود اطلاعات مواجه میشود. از جهتی کاهش تعداد متغیرها در مدلهای آماری، باعث عدم عمومیت آنها خواهد شد و کارایی مدلها را کاهش خواهد داد. بنابراین، اگر تعداد متغیرها محدود و کم هستند شاید استفاده از این راهکار، بهترین راه حل نباشد.
به نظر میرسد که بهتر است از این روش برای حذف متغیرهایی که تعداد زیادی مقدار گمشده دارند استفاده کرد و اگر تعداد مقدارهای از دست رفته از یک مقدار آستانه (یا درصد) بیشتر بود، متغیر را حذف نمود. در غیر اینصورت روشهای دیگری که در ادامه به آنها اشاره خواهیم کرد، مفید و موثرتر عمل خواهند کرد.
روش دوم با عملکرد بهتر، تبدیل و مدیریت داده گمشده
در این روش با کمک محاسباتی، مشاهداتی با مقدار گمشده در یک متغیر با عددی دلخواه جایگزین میشود. البته بر سر اینکه چه مقداری جایگزین مقادیر گمشده شود، جای بحث دارد ولی اغلب مدل ساخته شده در این حالت، بهتر از مدلهایی است که متغیر با داد گمشده از آن حذف شده است.
در اکثر مواقع، از میانگین به عنوان مقدار جایگزین برای مشاهدات با مقدار گمشده استفاده میشود. البته در صورتی که داده پرت وجود نداشته یا فرض داشتن توزیع نرمال برای دادهها مورد تایید قرار گیرد، میانگین میتواند بهترین گزینه باشد.
در کدی که مشاهده میکنید، «میانگین» (Mean) جایگزین مقادیر گمشده برای یک متغیر شده است. مشخص است که تابع SimpleImputer از کتابخانه sklearn به کار رفته است.
from sklearn.impute import SimpleImputer my_imputer = SimpleImputer() data_with_imputed_values = my_imputer.fit_transform(original_data)
مقدار پیشفرض برای SimpleImputer، همان مقدار میانگین است. البته میتوان شاخصهای آماری دیگری نیز برای مقدار گمشده در نظر گرفت. «میانه» (Median) و «نما» (Mode) دیگر شاخصهای تمرکزی هستند که در این مواقع قابل استفاده هستند.
یکی از نکات مهم در زمان استفاده از SimpleImputer، این است که میتوان آن را به راحتی در یک مدل یادگیری ماشین به کار برد. به این ترتیب تعیین یک مقدار ثابت برای هر متغیر به عنوان جایگزین مشاهدات گمشده، ساخت مدل، اعتبارسنجی مدل و به کارگیری مدل را ساده میکند.
البته مشخص است که استفاده از یک مقدار ثابت برای همه مقادیر گمشده، ممکن است باعث اریبی (Bias) شده و مدل با خطای زیاد برای بعضی از مقادیر جدید همراه باشد. برای کسب اطلاعات بیشتر در این زمینه بهتر است نوشتار موازنه واریانس و بایاس | به زبان ساده را مطالعه کنید.
روش سوم، جایگزینی به نزدیکترین مقدار
جایگزین کردن مقدار گمشده یک روش استاندارد برای مدیریت دادههای از دسته رفته است که البته در اکثر مواقع نیز به خوبی عمل میکند. با این حال، ثبت مقادیر ثابت برای همه مشاهدات گمشده ممکن است به طور سیستماتیک برآوردی ایجاد کند که بزرگتر یا کوچکتر از مقدار واقعی برای مقادیر از دست رفته هستند.
انتخاب مشاهدات مشابه و استخراج مقدار گمشده از طریق متغیرهای آن، یک راه کار مناسب برای برخورد با دادههای از دست رفته محسوب میشود. به این ترتیب نزدیکترین شرایط برای مشاهدات مبنایی برای انتخاب مقدار گمشده برای یک متغیر محسوب میشود.
به کد زیر توجه کنید. پیشبینی و مدیریت مقدار گمشده برای یک متغیر متناسب با مشاهدات دیگر در این کد صورت گرفته است.
# make copy to avoid changing original data (when Imputing) new_data = original_data.copy() # make new columns indicating what will be imputed cols_with_missing = (col for col in new_data.columns if new_data[col].isnull().any()) for col in cols_with_missing: new_data[col + '_was_missing'] = new_data[col].isnull() # Imputation my_imputer = SimpleImputer() new_data = pd.DataFrame(my_imputer.fit_transform(new_data)) new_data.columns = original_data.columns
در برخی موارد این روش نتایج را به طور معنیداری بهبود میبخشد. البته در صورتی که مشاهدات با مقدار گمشده منحصر به فرد باشند، چنین کاری امکانپذیر نیست و بهتر است از روشهای خوشهبندی، مشاهدات را گروهبندی کرده و برای دادههایی با مقدار گمشده از میانگین هر خوشه به عنوان مقدار جایگزین استفاده کرد.
برای اطلاع از نحوه خوشهبندی و به کارگیری تکنیکهای متنوع آن نوشتار آشنایی با خوشهبندی (Clustering) و شیوههای مختلف آن را مطالعه کنید.
مثال و مقایسه رویکردهای مختلف مدیریت داده گمشده
نمونه پیش بینی قیمت مسکن را از داده های مسکن ملبورن در نظر بگیرید. برای تسلط بر کنترل مقدار از دست رفته، مراحل گفته شده در قسمتهای قبلی را اجرا کرده و نتایج را مرور خواهیم کرد.
تنظیم اصول مسئله
ابتدا مجموعه داده را خوانده و مسئله را به پیش میبریم. البته فرض بر این است که قبلا این مجموعه داده را در رایانه خود بارگذاری کردهاید. برای دریافت این اطلاعات در قالب یک فایل متنی (csv) اینجا کلیک کنید. پس از خارج کردن فایل فشرده، میتوانید آن را در اکسل یا برنامه پایتون فراخوانی کرده و سطرها و مشاهدات را نمایش دهید. به منظور مدیریت داده گمشده از قطعه کد زیر استفاده کردهایم.
# Load data melb_data = pd.read_csv('../input/melbourne-housing-snapshot/melb_data.csv') from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_absolute_error from sklearn.model_selection import train_test_split melb_target = melb_data.Price melb_predictors = melb_data.drop(['Price'], axis=1) # For the sake of keeping the example simple, we'll use only numeric predictors. melb_numeric_predictors = melb_predictors.select_dtypes(exclude=['object'])
اندازهگیری کیفیت هر یک از رویکردها
ابتدای امر، مجموعه داده مورد نظر را به دو بخش آموزشی و آزمایشی تقسیم میکنیم. به این ترتیب میتوانیم مقدار خطای حاصل از مدل را برای دادههای آزمایشی اندازهگیری کرده و نتایج را مقایسه کنیم. چنین کاری معمولا به «اعتبار سنجی متقابل» (Cross validation) معروف است.
ما یک تابع به شکل (score_dataset (X_train، X_test، y_train، y_test را بارگیری کردهایم تا کیفیت رویکردهای مختلف نسبت به مدیریت داده گمشده را مقایسه کنیم. این تابع نمره «میانگین قدر مطلق خطا» (MAE) یا Mean Absolute Error را برای یک نمونه آزمایشی از یک «جنگل تصادفی» (RandomForest) گزارش میکند.
در مرحله اول نمره مدل را که از حذف متغیر یا ستونها با مقدار گمشده، حاصل شده است، محاسبه میکنیم.
cols_with_missing = [col for col in X_train.columns if X_train[col].isnull().any()] reduced_X_train = X_train.drop(cols_with_missing, axis=1) reduced_X_test = X_test.drop(cols_with_missing, axis=1) print("Mean Absolute Error from dropping columns with Missing Values:") print(score_dataset(reduced_X_train, reduced_X_test, y_train, y_test))
نتیجه انجام این گونه محاسبات در این حالت به صورت زیر است. در انتها، میزان خطا را مشاهده میکنید.
Mean Absolute Error from dropping columns with Missing Values: /opt/conda/lib/python3.6/site-packages/sklearn/ensemble/forest.py:246: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22. "10 in version 0.20 to 100 in 0.22.", FutureWarning) 190206.25740935552
در قسمت بعدی با جایگزین کردن مقدار گمشده، مدل را برازش کرده و مقدار MAE را براساس مجموعه داده آزمایشی محاسبه میکنیم.
from sklearn.impute import SimpleImputer my_imputer = SimpleImputer() imputed_X_train = my_imputer.fit_transform(X_train) imputed_X_test = my_imputer.transform(X_test) print("Mean Absolute Error from Imputation:") print(score_dataset(imputed_X_train, imputed_X_test, y_train, y_test))
همانطور که میبینید، میزان خطا به میزان قابل توجهی، کاهش پیدا کرده است. این کاهش در اثر جایگزینی مقادیر گمشده با میانگین هر متغیر بدست آمده است.
Mean Absolute Error from Imputation: /opt/conda/lib/python3.6/site-packages/sklearn/ensemble/forest.py:246: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22. "10 in version 0.20 to 100 in 0.22.", FutureWarning) 183672.59241765435
با استفاده از ستون های اضافی آنچه را که از لحاظ امتیازات مجاز است، نمایش دادهایم. در گام بعدی با استفاده از روش مقدار دهی توسعه یافته و مشخص کردن مشاهدات مشابه و جایگزینی مقدار گمشده، مدلسازی صورت میگیرد. به این ترتیب مقدار پیشبینی شده و مقدار واقعی با هم مقایسه شده و خطای MAE بدست میآید.
imputed_X_train_plus = X_train.copy() imputed_X_test_plus = X_test.copy() cols_with_missing = (col for col in X_train.columns if X_train[col].isnull().any()) for col in cols_with_missing: imputed_X_train_plus[col + '_was_missing'] = imputed_X_train_plus[col].isnull() imputed_X_test_plus[col + '_was_missing'] = imputed_X_test_plus[col].isnull() # Imputation my_imputer = SimpleImputer() imputed_X_train_plus = my_imputer.fit_transform(imputed_X_train_plus) imputed_X_test_plus = my_imputer.transform(imputed_X_test_plus) print("Mean Absolute Error from Imputation while Track What Was Imputed:") print(score_dataset(imputed_X_train_plus, imputed_X_test_plus, y_train, y_test))
همانطور که در ادامه مشاهده میکنید، مقدار خطا افزایش داشته است و رویکرد مورد نظر در کم کردن خطا موثر نبوده است.
Mean Absolute Error from Imputation while Track What Was Imputed: /opt/conda/lib/python3.6/site-packages/sklearn/ensemble/forest.py:246: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22. "10 in version 0.20 to 100 in 0.22.", FutureWarning) 184784.40251186382
نتیجهگیری
همانطور که معمول است، محاسبه و جایگزینی مقادیر از دست رفته یا گمشده به ما این امکان را میدهد که مدل خود را در مقایسه با حذف ستونها یا متغیرهایی که مقدار گمشده دارند، بهبود بخشیم. به این ترتیب میتوان به یک مدل بهینه در این زمینه رسیده و مقدارهای مربوط به دادههای آزمایشی یا حتی خارج از آن را به صورت بهینه برآورد کرد.
هنگام اجرای تحلیل روی دادههای از دست رفته مراحل زیر را طی باید طی کنید تا بهترین نتیجه را در مدیریت داده گمشده در مدلهای آماری بدست آورید.
- ستون با مقادیر از دست رفته را در مجموعه داده خود پیدا کنید.
- از کلاس Imputer استفاده کنید تا بتوانید مقادیر جایگزین برای مشاهدات از دست رفته را محاسبه کنید.
- ستون یا متغیرهای با مقادیر از دست رفته یا گمشده پس از جایگزینی به پیش بینیهای خود اضافه کرده و مدل را بهبود بخشید.
اگر مقدار مناسب برای مقدارهای گمشده در یک یا چند متغیر را پیدا کنید، ممکن است بهبودی در نمرات مدل حاصل شود. همچنین این احتمال نیز وجود دارد که در مجموعه داده، مقادیر گمشده درصد کمی از مشاهدات را شامل شود که در این صورت جایگزینی دادههای از دست رفته اصلاح موثری در مدل ایجاد شده نخواهد داشت. بنابراین، تصمیم نسبت به این که آیا در این مرحله پیشرفتی در بهینه بودن مدل مشاهده میکنید یا خیر، به جزئیات دیگر دادهها و نوع مدل بستگی دارد.
خلاصه و جمعبندی
در این نوشتار به موضوع مدیریت داده گمشده در داده کاوی به زبان پایتون پرداختیم. از آنجایی که یکی از مراحل اصلی در داده کاوی، عمل پاکسازی دادهها است، بررسی داده گمشده بسیار مهم جلوه میکند. اگر مشاهدات با داده گمشده را از مدل آماری و تحلیل کنار بگذاریم، ممکن است تعداد نمونههای مورد استفاده کاهش یافته و مدل از عمومیت خارج شود. از طرفی اگر مقدار داده گمشده را با یک مقدار ثابت جایگزین کنیم، با مشکل اریبی برخورد خواهیم کرد. با این وجود الگوریتمهای متعددی در برای جایگزین و مدیریت داده گمشده وجود داشته که بخصوص در پایتون تحت کتابخانه sklearn مختلف، پیادهسازی شدهاند. در این متن به بررسی این الگوریتمها یا راه کارهای جایگزینی و مدیریت داده گمشده در مجموعه اطلاعات و مشاهدات آماری پرداختیم.