Meysam.A
Meysam.A
خواندن ۲ دقیقه·۳ سال پیش

اعتبارسنجی متقابل تو در تو (Nested Cross Validation) در Scikit-learn

آموزش مدل برای پیدا کردن پارامترای مناسب، و همچنین ارزیابی مدل روی یه دیتای یکسان، یه اشتباهه که میتونه منجر به overfitting بشه. و رویه درستش اینه که وقتی داریم عملکرد چندین مدل رو مقایسه میکنیم، دیتایی که برای hyperparameter tuning استفاده شده رو برای تست کردن مدل‌ها استفاده نکنیم.


تو این مطلب درمورد cross validation یه توضیحاتی داده شد. و گفتیم که برای ارزیابی عملکرد مدل و همچنین انتخاب بهترین ترکیب پارامترای مدلمون حین train روی دیتاست، از cross validation استفاده میکنیم.

اگه وقتی داریم مدل رو بر اساس یه سری از hyperparameterها tune میکنیم،بخوایم همزمان مدلمون رو ارزیابی(evaluate) کنیم، باید Nested Cross Validation انجام بدیم. در حالت عادی وقتی اینکارو نکنیم، و بیایم از همون دیتایی که برای انتخاب بهترین hyperparameterها استفاده کردیم، برای test کردن مدلمون استفاده کنیم، چون مدلمون در حین tuning ، داده‌ها رو تجربه کرده، test-score واقعی رو نشون نمیده(بهتر از چیزی که در واقع هست نشون میده) و اصطلاحا رو داده‌هامون overfit میشه، و اینو حتما باید وقتی عملکرد چندین مدل رو مقایسه میکنیم بهش توجه کنیم.

وقتی که Nested CV انجام میدیم، از یه inner-cv برای انتخاب بهترین پارامترا، و از یه outer-cv برای تست کردن مدلمون استفاده میکنیم. بعنوان مثال همچین اتفاقی میوفته (درصدها هم فرضی هستن):

اول دیتامون رو(در هر split از outer-cv) به دو قسمت 70-30 درصدی تقسیم میکنیم،بخش 30 درصدی(test set) رو برای تست نهایی(روی مدلی که tune شده) کنار میذاریم، و بعد خوده اون 70 درصد رو میاریم به دو قسمت 80-20 تقسیم میکنیم. بعد میایم hyperparameterهای مدل رو (در هر split از Inner-Cv) روی این 80 درصد train میکنیم(train set) و روی بخش 20 درصدی (validation set) ، test میکنیم تا بهترین پارامترا رو با توجه به عملکردشون انتخاب کنیم. بعد که مدلمون با بهترین پارامترا رو انتخاب کردیم، میایم این مدل رو روی اون 30 درصدی که اول کار کنار گذاشته بودیم test میکنیم، و اینبار عملکرد واقعی‌تر و منطقی‌تری رو از مدلمون انتظار داریم.

البته که میتونیم خودمون این روال رو بدون استفاده از Nested CV پیاده کنیم و دیتای تستمون رو جُدا از دیتایی که برای انتخاب پارامترا استفاده کردیم درنظر بگیریم. اما هدف ازین مطلب صرفا آشنایی با Nested CV هست.

تو قطعه کد زیر، داخل حلقه for دوتا splitter ساده KFold تعریف کردیم(با توجه به اینکه میدونیم داده‌هامون ارتباط گروهی و ... ندارن) و هر بار یه random state جدید در نظر میگیریم و بهترین score مربوط به GridSearch، و میانگین score مربوط به nested cros_val_score رو تو دوتا آرایه جُدا ذخیره می‌کنیم. و نهایتا خارج حلقه، اعداد این دو آرایه رو رسم کردیم:

میبینیم که اکثر مواقع وقتی با test-set ای که در outer_cv کنار گذاشته شده، مدل رو ارزیابی میکنیم، accuracy پایین تری داریم و این نتیجه منطقی تره.

ازین لینک میتونین به کدها دسترسی داشته باشین. موفق باشید ?

منبع

cross validation
every day is a chance to learn more
شاید از این پست‌ها خوشتان بیاید