Kaggle و پروژهای یکپارچه برای رقابتهای آن: پیشبینی قیمت املاک با استفاده از یادگیری ماشین
در این نوشتار، پروژه یکپارچهای که در رقابتهای Kaggle با موضوع تکنیکهای پیشرفتهی رگرسیون انجام دادم را، به صورت گام به گام، برای مخاطبان توضیح خواهم داد. قرار است مخاطبان بتوانند از این مقاله به عنوان یک دوره آموزشی مختصر در مورد یادگیری ماشین استفاده کنند.
هدف و دادهها
دلیل این رقابتها پیشبینی قیمت خانه در شهر ایمز ایالت آیوا بود. در ابتدا یک دیتاست آموزشی و آزمایشی به فرمت csv و همچنین یک دیکشنری داده در اختیار شرکتکنندگان قرار گرفت.
آموزش: دادههای آموزشی شامل 1460 نمونه خانه هستند که توسط 79 ویژگی به صورت جامع توصیف میشوند. هر کدام از این خانهها قیمت (برچسب) دارند. از دادههای آموزشی برای آموزش مدلها استفاده میکنیم.
آزمایش: دادههای آزمایشی شامل 1459 نمونه (خانه) هستند که همان تعداد ویژگی (79 عدد) برای توصیفشان به کار میرود. در مجموعه آزمایشی قیمت خانهها مشخص نیست، چون ما باید آن را پیشبینی کنیم. بهترین مدلهای ساخته شده، روی دادههای آزمایشی اجرا میشوند و نتیجه روی صفحهی اعلان نتایج Kaggle ثبت میگردد.
در این لینک میتوانید اطلاعات بیشتری در مورد دادهها به دست آورید.
مسئله: مسائل یادگیری ماشین عموماً در سه گروه دستهبندی میشوند: نظارتشده، غیرنظارتشده و تقویتی. مسئلهی ما در این رقابتها از نوع یادگیری نظارتشده است.
در یادگیری نظارتشده از نمونهها و برچسبها برای پیدا کردن الگو در دادهها استفاده میشود.
با توجه به دادهها و هدف راحتتر میتوانید نوع مسئلهی یادگیری ماشینی که در دست دارید را تشخیص دهید. اینجا دادهها مربوط به املاک (شامل ویژگیها و برچسبها) هستند و مسئلهای که باید حل کنیم پیشبینی برچسب (قیمت) برای خانههایی است که در دیتاست آموزشی نبودهاند.
ابزار
من برای این رقابت از پایتون و ژوپیتر نوتبوک استفاده کردم. ژوپیتر نوتبوک محبوبیت بالایی بین متخصصان علوم داده دارند، زیرا یادگیری آنها آسان است و گامهای در حال اجرا را نشان میدهند.
توجه داشته باشید که این کد در تولید کاربردی ندارد و از نظر مهندسی نرمافزار هم بهترین عملکرد را از خود نشان نمیدهد. دلیل انتخاب من به خاصیت توضیحپذیری این کد برمیگردد.
کتابخانهها: پایتون برای مدیریت مسائل متداول، چارچوبهایی دارد. به افراد تازهوارد در علوم داده پیشنهاد میکنم با این کتابخانههای آشنا شوند:
Pandas: برای مدیریت دادههای ساختاریافته
Scikit Learn: برای یادگیری ماشینی
NumPy: برای ریاضیات و جبر خطی
Seaborn: برای مصورسازی دادهها
روال پردازشی پروژه
میتوان گفت همهی پروژههای یادگیری ماشین از فرآیندی مشابه پیروی میکنند. ورود دادهها Data ingestion، پاکسازی دادهها Data cleaning، تجزیه و تحلیل اکتشافی دادهها Explanatory data analysis، مهندسی ویژگیها Feature engineering و در نهایت یادگیری ماشین.
روال پردازشی معمولاً خطی نیست و لازم است که از گامی به گام دیگر (عقب یا جلو) حرکت کنید. این نکتهی مهم اغلب نادیده گرفته میشود و مطالب آموزشی این فرآیند را خیلی آسانتر از آنچه هست نشان میدهند.
قبل از شروع: یادگیری ماشین یک فرآیند تکراری و دورهای است، نه سرراست و ساده. پس اگر در پروژهای کنترل اوضاع از دستتان خارج شد، نگران نباشید. باید به مطالعه، آزمایش و طرح سؤال ادامه دهید تا بالاخره به جواب خود برسید.
در ادامهی این نوشتار مراحل روال پردازشی پروژه را با هم بررسی میکنیم. در مواردی که میتواند مفید باشد نمونههایی از کد پایتون را ذکر میکنیم.
Kaggle و پاکسازی دادهها
Kaggle همه تلاش خود را میکند تا دادههایی پاکسازیشده در اختیار کاربران قرار دهد. با این حال نباید از موارد استثنائی احتمالی غافل شویم.
به هیچ وجه از مرحلهی پاکسازی داده غافل نشوید. با اینکه خستهکننده به نظر میرسد، میتواند از مشکلات جدیتر در آینده جلوگیری کند.
نمونههای کپی و NaNs: من کار را با حذف نمونههای کپی موجود در دادهها شروع کردم. سپس به دنبال مقادیر NaN (غیرعددی) گشتم. بررسی دادهها به منظور یافتن مقادیر NaN از نظر اخلاق اجتماعی و به دلیل مشکلزا شدن در مدلهای یادگیری ماشین گام مهمی است.
ویژگیهای ردهای: متغیرهای ردهای زیادی هستند که وقتی یکی از ویژگیهای خانهها وجود نداشته باشد (برای مثال، زمانی که هیچ خیابانی مشخص نشده است)، به صورت N/A مشخص میشوند. من همهی این موارد در دادههای آموزشی و آزمایشی تشخیص دادم و N/A را با برچسب دیگری جایگزین کردم که اطلاعات بیشتری در اختیار قرار میدهد. برچسبهای N/A میتوانند مشکلزا باشند، به همین دلیل باید آنها را حذف کنید.
ویژگیهای Date: در این پروژه بهتر است date را به صورت متغیر ردهای (و نه عدد صحیح) در نظر بگیریم. زیرا اینجا بزرگی date اهمیتی ندارد، بلکه مهم این است که dateها سالهای متفاوتی را نشان میدهند. حل این مسئله آسان است، تنها کافیست Date را به string تبدیل کنید.
متغیرهای رمزگشاییشده: برخی از متغیرهای ردهای به صورت عددی رمزگذاری شدهاند. به مثال پایین توجه کنید:
مشکل اینجاست که الگوریتم یادگیری ماشینی میتواند بزرگی عدد را به معنای اهمیت آن در نظر بگیرد (نه نشاندهندهی گروههای مختلف یک ویژگی). برای حل این مشکل گروهها را تحت مهندسی معکوس قرار دادم و مجدداً رمزگذاری کردم.
تجزیه و تحلیل اکتشافی دادهها (EDA)
مصورسازی دادهها از این گام شروع میشود. هدف از EDA در یادگیری ماشین، بررسی کیفیت دادههاست. اینجا مشخص میشود آیا الگوی عجیبی در دادهها وجود دارد که بعدها مشکلزا شود؟
برچسبها: من قیمتها را روی یک نمودار هیستوگرام قرار دادم. توزیع قیمتها به سمت راست کجی دارد (همانطور که میرفت). برای مثال، احتمالاً در همسایگی محل زندگیتان خانههایی را میبینید که به طور غیرمعمولی گرانتر هستند.
این مرحله مربوط به اولین گام مهندسی ویژگی است. از تبدیلات لگاریتمی روی قیمتها استفاده میکنم تا دادههای پرت را فشردهسازی کرده و شکل توزیع را به صورت نرمال درآورم.
دادههای پرت میتوانند تأثیراتی بسیار مخرب بر مدلهایی داشته باشند که از توابع زیان برای به حداقل رساندن خطای مجذورات Squared error استفاده میکنند. به جای حذف دادههای پرت میتوانید از تبدیلات استفاده کنید.
هیستوگرام را در پایتون رسم کنید.
همبستگی: رسم ماتریس همبستگی Correlation matrix به درک بهتر روابط بین دادهها کمک میکند. علاوه بر این میتواند ساختار مدل را نیز هدایت کند. برای مثال اگر ببینید تعداد زیادی از ویژگیها با یکدیگر همبستگی دارند، دقت میکنید تا رگرسیون خطی انجام ندهید.
نمودار همبستگی پیرسون را در پایتون رسم کنید.
اینجا از ضریب همبستگی پیرسون استفاده شده است. در نمودار بالا، هرچه رنگ مربع روشنتر باشد، همبستگی بین دو متغیر قویتر است.
ویژگیهای مرتبط با فضای خانه (همچون ورودی، قسمت پارکینگ و زمینهای اطراف منطقهی زندگی) با قیمت خانه همبستگی مثبت داشتند (بدیهی است هرچه ملک بزرگتر باشد، قیمتش هم باید بیشتر باشد). مقادیر همبستگی تا اینجا مورد عجیبی نداشتند.
روابط ردهای: به نظر میرسید قیمت خانهها در همهی ردهها توزیعی تقریباً نرمال دارند. هیچ موردی غیرعادی به نظر نرسید. در برخی از ردهها دادههای کمی وجود دارد یا اصلاً دادهای وجود ندارد. برخی دیگر توانایی کمی در تمیز بین کلاسهای قیمت دارند یا اصلاً قادر به این کار نیستند. پروژهی مصورسازی دادهها را در این لینک به صورت کامل در GitHub مشاهده کنید.
مهندسی ویژگی
مدلهای یادگیری ماشین دادههای ردهای را درک نمیکنند. به همین دلیل باید با استفاده از تبدیلات این ردهها را به اعداد تغییر دهیم. بهترین روش انجام این کار، روش one hot است.
حتماً از الگوریتم OneHotEncoder کتابخانه SciKitLearn استفاده کنید و تابع get_dummies ابزار Panda را به کار نبرید. در غیر این صورت، اگر تعداد ردههای دیتاست آموزشی و آزمایشی با هم تفاوت داشته باشند، با مشکل روبرو میشوید.
OneHotEncoder با مدیریت موارد نامعلوم و تنظیم گزینههایی برای ردهها، این مشکل را حل میکند. استفاده از این الگوریتم کمی سختتر است، اما برای یادگیری ماشین ضروری است.
در این لینک میتوانید مقالهای را مشاهده کنید که نمونههایی از OneHotEncoder در پایتون را در بردارد.
یادگیری ماشین
من از یک چرخهی استاندارد برای ساخت یادگیری ماشینی پیروی کردم. فارغ از اینکه تازهکار هستید یا حرفهای، احتمالاً مجبور خواهید شد چندین بار این چرخه را تکرار کنید تا به مدلی با استانداردهای موردانتظار دست یابید. هرچه تجربهی بیشتری کسب کنید، تعداد تکرارهای لازم کمتر میشود.
انتخاب مدل
همانطور که در ابتدای مقاله مطرح کردیم، مسئلهای که در دست داریم یادگیری ماشینی نظارتشده است و از آنجایی که باید یک خروجی عددی (قیمت خانه) را پیشبینی کنیم، مسئله از نوع رگرسیون است.
به همین دلیل من با سه مدل یادگیری ماشینی به این مسئله نگاه کردم: درخت تصمیم، جنگل تصادفی و ماشینهای تقویت گرادیان. من از درخت تصمیم به عنوان مدل پایه استفاده کردم، سپس براساس این تجربه مدلهای داوطلب را تنظیم کردم. این رویکرد باعث صرفهجویی در زمان میشود، زیرا سرعت آموزش را افزایش میدهد و در مورد چگونگی تنظیم هایپرپارامترهای مدلهای داوطلب نیز مفید است.
مکانیک مدل: در این نوشتار وارد جزئیات نحوهی کارکرد مدل نخواهیم شد. اما توضیح مختصری از انواع مدلها ارائه خواهیم داد و لینک مقالات مربوطه را در دسترس مخاطبان قرار میدهیم.
درخت تصمیم: الگوریتم درخت در یادگیری ماشین به منظور پیدا کردن الگو در دادهها از قوانین تصمیم استفاده میکند.
جنگل تصادفی: این رویکرد یکی از روشهای بستهای است که بر اساس اثر هوش جمعی عمل میکند. در این روش برای یادگیری از دادهها از چندین درخت تصمیم مستقل به صورت موازی استفاده میشود و پیشبینیهای آنها برای رسیدن به یک خروجی کلی جمع میشود.
ماشینهای تقویت گرادیان: نوعی روش تقویتی است که از چندین درخت تصمیم به صورت متوالی استفاده میکند. درختها به صورت تراکمی، خروجی درختهای قبلی را پیشبینی و تصحیح میکنند.
جنگلهای تصادفی و تقویت گرادیان میتوانند درختهای تصمیمی که به تنهایی عملکرد ضعیفی دارند را به صورت مدلهای پیشبین قوی درآورند. اگر دیتاستهای آموزشی کوچکی دارید (مثل پروژهی حاضر) میتوانید از این الگوریتمها استفاده کنید.
آموزش
منظور از آموزش در یادگیری ماشین فرآیندی است که طی آن با استفاده از نمونههایی از دیتاست آموزشی مدل خود را آموزش میدهید. در مرحلهی آموزش، باید هایپرپارامترهای مدل خود را تنظیم کنید.
قبل از اینکه وارد جزئیات بیشتر شویم، در مورد رابطهی تبادلی بایاس-واریانس توضیح مختصری خواهیم داد.
بایاس مدل: مدلهایی که مشکل کمبرازش دارند، قابلیت پایینی برای پیشبینی دادههای جدید دارند. در کل، هرچه مدل سادهتر باشد، بایاس بیشتر خواهد بود.
واریانس مدل: مدلهایی که دادههای آموزشی را بیشبرازش میکنند قابلیت پایینی در پیشبینی دادههای جدید دارند. در کل، هرچه مدل پیچیدهتر باشد، واریانس بالاتر خواهد بود.
پیچیدگی مدل را میتوان تعداد ویژگیهای مدل در نظر گرفت. واریانس و بایاس مدل رابطهای معکوس با یکدیگر دارند و این امر منجر به یک رابطهی تبادلی میشود. در میزان پیچیدگی مدل یک نقطهی بهینه وجود دارد که خطا در آنجا به حداقل میرسد. هدف ما این است که با تنظیم هایپرپارامترها به این نقطه برسیم.
این مقاله مبحث مذکور را با جزئیات بیشتر توضیح میدهد.
هایپرپارامترها: هایپرپارامترها به ما کمک میکنند پیچیدگی مدل را کنترل کنیم. از موارد عملی زیادی که در این باره وجود دارند، میتوان در مورد تنظیم هایپرپارامترهای هر نوع مدلی راهنمایی کسب کرد. در این قسمت ابتدا انواع هایپرپارامترها را معرفی میکنم و سپس خواهم گفت که برای هر مدل از کدام هایپرپارامترها استفاده کردهام.
max_depth: حداکثر تعداد گرههای یک درخت تصمیم.
max_features: اندازهی زیرمجوعهی ویژگیهایی که برای تقسیم (شاخه شاخه کردن) یک گره استفاده میشود.
n_estimators: تعداد درختهایی که برای تقویت یا ارتقاء به کار میروند. این هایپرپارمتر تنها روی جنگل تصادفی و ماشینهای تقویت گرادیان اجرا میشود.
learning_rate: نرخ یادگیری برای کاهش سهم هر درخت به کار میرود. این هایپرپارامتر تنها در ماشینهای تقویت گرادیان اجرا میشود.
درخت تصمیم: هایپرپارامترهایی که در این الگوریتم قابل تنظیم هستند max_depth و max_features میباشند.
جنگل تصادفی: مهمترین هایپرپارامترهایی که در این الگوریتم قابلیت تنظیم دارند n_estimators و max_features هستند.
ماشینهای تقویت گرادیان: مهمترین هایپرپارامترهایی که در این الگوریتم قابلیت تنظیم دارند n_estimator، max_depth و learning_rate هستند.
جستجوی شبکهای: انتخاب دامنهی هایپرپارامترها فرآیندی دورهای است. اما هرچه تجربهی بیشتری داشته باشید، میتوانید این دامنهها را بیشتر به صورت شهودی مشخص کنید. خوشبختانه بعد از اینکه دامنهی هایپرپارامترهای لازم را انتخاب کردید، جستجوی شبکهای شما را قادر خواهد ساخت مدل را در هر ترکیبی از این دامنهها آزمایش کنید. در بخش بعد در این مورد بیشتر صحبت خواهیم کرد.
اعتبارسنجی متقاطع: مدلها با اعتبارسنجی متقاطع 5 بخشی آموزش میبینند. تکنیکی که کل دیتاست آموزشی شما را گرفته و طی 5 بار تکرار آن را به دیتاستهای آموزشی و آزمایشی تقسیم میکند.
در نتیجه، 5 دیتاست آموزشی و آزمایشی متفاوت خواهید داشت که میتوانید برای ساخت و آزمایش مدل خود از آنها استفاده کنید. این روش برای مقابله با بیشبرازش راه خوبی است.
اعتبارسنجی متقاطعی که بدین شکل باشد را به عنوان اعتبارسنجی متقاطع 5 بخشی میشناسند. برای کسب اطلاعات بیشتر در مورد این تکنیک به این لینک مراجعه کنید.
پیادهسازی: کتابخانهی ScikitLearn با قابلیت GridSearchCv ما را قادر میسازد تنظیم هایپرپارامترها و اعتبارسنجی متقاطع را با هم ترکیب کنیم. در این صورت برای نمایش نتایج هر بار آموزشی که انجام میدهید چندین گزینه خواهید داشت.
اینجا میتوانید اجرای کد برای ساخت مدل در جنگل تصادفی را مشاهده کنید.
ارزیابی
این آخرین گام فرآیند است و میتواند تعیینکنندهی موفقیت یا شکست کل فرآیند باشد. برای مشاهدهی نتایج هرکدام از مدلهای داوطلب از مصورسازی دادهها استفاده میکنیم. اگر نتایج رضایتبخش نباشند، میتوانیم فرآیند را (در هرکدام از مراحل قبلی که لازم است) مورد بازبینی قرار دهیم.
معیار ارزیابی عملکرد منفی مجذور میانگین مربعات خطا (NRMSE) خواهد بود. من به این دلیل از این معیار استفاده کردم که بیشترین شباهت را به معیار نمرهدهی در رقابت Kaggle دارد.
درخت تصمیم
این روش بدترین عملکرد را از نظر قدرت پیشبینی داشت. نمرهای که بهترین مدل درخت تصمیم به دست آورد 205/0- NRMSE بود. تنظیم هایپرپارامترها نیز تغییر چندانی در این نتیجه ایجاد نکرد؛ البته سرعت آموزش را به زیر 2 ثانیه رساند. قطعاً مقیاسی وجود دارد که بتوان دامنهی گستردهتری از هایپرپارامترها را در آن مورد سنجش قرار داد.
جنگل تصادفی
مدل جنگل تصادفی نسبت به درخت تصمیم عملکرد بسیار خوبی داشت و به NRMSE 144/0- دست یافت. آموزش این مدل حدود 75 ثانیه طول کشید.
ماشین تقویت گرادیان
در بین مدلهای ما، بهترین عملکرد متعلق به ماشین تقویت گرادیان بود (NRMSE= -0/126). هایپرپارامترهای این مدل به طرز چشمگیری روی نتایج تأثیرگذار بودند؛ در نتیجه در مدلهای پیچیدهتر باید تنظیم آنها را با دقت بالایی انجام داد. مدت زمان آموزش این مدل حدود 196 ثانیه بود.
نتایج رقابت
من مدلی که بهترین عملکرد را داشت وارد رقابت Kaggle کرده و روی دیتاست آزمایشی آن اجرا کردم. مدل من در میان 39% اول قرار گرفت که دستاورد بدی نیست اما قطعاً جای پیشرفت دارد. برای بهبود نتایج میتوان از این روشها استفاده کرد:
متغیرهای ردهای: تعداد برخی از ویژگیهای ردهای زیاد است. به همین دلیل ممکن است درختهای تصمیم دچار بایاس شوند. شاید با دستهبندی مجدد این ویژگیهای پیشرفته به ویژگیهایی با ابعاد پایینتر بتوان عملکرد مدل را بهبود بخشید.
تنظیم هایپرپارامترها: میتوانیم فضای راهکارها Solutions space را برای هایپرپارامترها گسترش دهیم تا به موقعیتی بهینه برسیم. اما این کار نیازمند قدرت محاسباتی بالاست.