فاز 2 · درس 10

مصالحه‌ی بایاس و واریانس در یادگیری ماشین

نوع
مفهومی
زمان
حدود 75 دقیقه
زبان‌ها
Python
پیش‌نیاز
یادگیری ماشین چیست؟ مفاهیم پایه، انواع و پیاده‌سازی از صفر، رگرسیون خطی از صفر تا پیاده‌سازی با scikit-learn، رگرسیون لجستیک و دسته‌بندی از صفر، درخت تصمیم و جنگل تصادفی: پیاده‌سازی از صفر و تئوری ریاضی، ماشین‌های بردار پشتیبان (SVM)؛ از فرمول‌بندی ریاضی تا پیاده‌سازی، الگوریتم K-نزدیک‌ترین همسایه (KNN) و معیارهای فاصله، یادگیری نظارت‌نشده و الگوریتم‌های خوشه‌بندی، مهندسی و انتخاب ویژگی در یادگیری ماشین، ارزیابی مدل در یادگیری ماشین: از صفر تا پیاده‌سازی و تحلیل
یک ترازوی چوبی قدیمی با دو کفه نامتعادل در کنار نمودارهای قوسی شفاف روی میز آزمایشگاهی
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفاهیم پایه
  4. بایاس: خطای سیستماتیک
  5. واریانس: حساسیت به داده‌های آموزش
  6. تجزیه‌ی خطای پیش‌بینی
  7. پیچیدگی مدل در برابر خطا
  8. منظم‌سازی ابزاری برای مهار بایاس-واریانس
  9. فرود دوگانه: دیدگاه مدرن
  10. عیب‌یابی مدل
  11. راهبردهای کاربردی
  12. روش‌های تجمیعی و کاهش واریانس
  13. منحنی‌های یادگیری
  14. روش تولید منحنی‌های یادگیری
  15. پیاده‌سازی گام‌به‌گام
  16. گام 1: تولید داده‌های مصنوعی از روی تابعی مشخص
  17. گام 2: بازنمونه‌گیری بوت‌استرپ و برازش چندجمله‌ای
  18. گام 3: محاسبه‌ی بایاس به توان دو و تجزیه‌ی واریانس
  19. گام 4: منحنی‌های یادگیری
  20. گام 5: جاروب منظم‌سازی
  21. استفاده از ابزارها
  22. منحنی اعتبارسنجی: جاروب پیچیدگی مدل
  23. منحنی یادگیری: جاروب اندازه‌ی مجموعه‌ی آموزش
  24. اعتبارسنجی متقاطع با جاروب منظم‌سازی
  25. جمع‌بندی: فرایند کامل عیب‌یابی
  26. خروجی نهایی
  27. تمرین‌ها
  28. اصطلاحات کلیدی
  29. برای مطالعه‌ی بیشتر

یکی از رایج‌ترین چالش‌ها پس از آموزش یک مدل یادگیری ماشین، مواجهه با خطای پیش‌بینی روی داده‌های جدید است. در چنین وضعیتی، تشخیص اینکه آیا باید مدل را پیچیده‌تر کرد، داده‌های بیشتری جمع‌آوری نمود یا از تکنیک‌های منظم‌سازی بهره برد، تفاوت میان یک آزمون‌وخطای فرساینده و یک مهندسی دقیق را رقم می‌زند.

مفهوم مصالحه‌ی بایاس و واریانس (Bias-Variance Tradeoff) چارچوب ریاضی و عملی دقیقی فراهم می‌کند تا ریشه‌ی خطاهای سیستماتیک (کم‌برازش) و حساسیت مفرط به نویز (بیش‌برازش) را شناسایی کنید. تسلط بر این توازن به شما کمک می‌کند تا رفتار مدل را در مواجهه با ابعاد داده تحلیل کرده و بهترین تصمیم را برای بهینه‌سازی آن بگیرید.

علاوه بر دیدگاه‌های کلاسیک، این درس به پدیده‌ی مدرن «فرود دوگانه» (Double Descent) نیز می‌پردازد تا علت عملکرد مطلوب شبکه‌های عصبی عمیق با تعداد پارامترهای بسیار بالا را درک کنید و بدون نیاز به حدس‌زدن، خطاهای مدل را گام‌به‌گام عیب‌یابی نمایید.

خطای هر مدل از یکی از سه منبع زیر سرچشمه می‌گیرد: بایاس (bias)، واریانس (variance) یا نویز (noise). شما فقط می‌توانید دو تای اول را کنترل کنید.

اهداف یادگیری

  • استخراج فرمول تجزیه‌ی خطای پیش‌بینی مورد انتظار به بایاس و واریانس و توضیح نقش نویز تقلیل‌ناپذیر
  • تشخیص ابتلای مدل به بایاس بالا یا واریانس بالا بر اساس الگوهای خطای آموزش و آزمون
  • توضیح شیوه‌ی تبادل بایاس با واریانس در تکنیک‌های منظم‌سازی (regularization) نظیر L1، L2، دراپ‌اوت (dropout) و توقف زودهنگام (early stopping)
  • پیاده‌سازی آزمایش‌هایی برای نمایش بصری مصالحه‌ی بایاس-واریانس در مدل‌هایی با پیچیدگی فزاینده

صورت مسئله

مدلی را آموزش داده‌اید و روی داده‌های آزمون خطایی دارد. منشأ این خطا کجاست؟

اگر مدل بیش از حد ساده باشد (مثل رگرسیون خطی روی داده‌هایی با الگوی منحنی)، همواره الگوی واقعی را از دست می‌دهد؛ به این خطا «بایاس» می‌گویند. اگر مدل بیش از حد پیچیده باشد (مثل چندجمله‌ای درجه‌ی 20 روی 15 نقطه‌ی داده)، داده‌های آموزشی را بی‌نقص برازش می‌کند، اما روی داده‌های جدید پیش‌بینی‌هایی به‌شدت متغیر و پرت تحویل می‌دهد؛ به این پدیده «واریانس» می‌گویند.

در یک ظرفیت مشخص از مدل، نمی‌توانید هر دو را هم‌زمان به حداقل برسانید. بایاس را کم کنید، واریانس بالا می‌رود؛ واریانس را پایین بیاورید، بایاس اوج می‌گیرد. درک این توازن و مصالحه (tradeoff)، مهم‌ترین مهارت تشخیصی در یادگیری ماشین (machine learning) است. این مهارت به شما می‌گوید که مدل را پیچیده‌تر کنید یا ساده‌تر، سراغ داده‌های بیشتر بروید یا ویژگی‌های بهتری بسازید، و منظم‌سازی را قوی‌تر کنید یا ضعیف‌تر.

مفاهیم پایه

بایاس: خطای سیستماتیک

بایاس نشان می‌دهد که میانگین پیش‌بینی‌های مدل چقدر از مقدار واقعی فاصله دارد. فرض کنید مدلی یکسان را روی چندین مجموعه‌ی آموزشیِ متفاوت اما برگرفته از یک توزیع آموزش دهیم و از خروجی‌های آن میانگین بگیریم؛ شکاف میان این میانگین و واقعیت، همان بایاس است.

بایاس بالا یعنی مدل ساختار صلب و خشکی دارد و نمی‌تواند الگوی واقعی را ثبت کند. برازش یک خط صاف روی یک سهمی، صرف‌نظر از حجم داده‌ها، هیچ‌گاه به انحنای تابع نمی‌رسد. این وضعیت را کم‌برازش (underfitting) می‌نامیم.

High bias (underfitting):
  Model always predicts roughly the same wrong thing.
  Training error: HIGH
  Test error: HIGH
  Gap between them: SMALL

واریانس: حساسیت به داده‌های آموزش

واریانس نشان می‌دهد که با آموزش مدل روی زیرمجموعه‌های متفاوتی از داده‌ها، پیش‌بینی‌ها چقدر دچار نوسان می‌شوند. اگر تغییراتی کوچک در مجموعه‌ی آموزشی باعث دگرگونی شدیدی در خروجی مدل شود، واریانس بالاست.

واریانس بالا یعنی مدل به جای درک سیگنال اصلی، روی نویز داده‌های آموزشی فیت شده است. یک چندجمله‌ای درجه‌ی 20 از تک‌تک نقاط آموزشی عبور می‌کند، اما میان این نقاط نوسانات بسیار شدیدی دارد. این وضعیت بیش‌برازش (overfitting) نام دارد.

High variance (overfitting):
  Model fits training data perfectly but fails on new data.
  Training error: LOW
  Test error: HIGH
  Gap between them: LARGE

تجزیه‌ی خطای پیش‌بینی

به ازای هر نقطه‌ی xx، خطای پیش‌بینی مورد انتظار تحت تابع زیان (loss) مربعی، دقیقاً به این صورت تجزیه می‌شود:

Expected Error=Bias2+Variance+Irreducible Noisewhere:Bias2=(E[f^(x)]−f(x))2Variance=E[(f^(x)−E[f^(x)])2]Noise=E[(y−f(x))2](σ2)\begin{aligned} & \text{Expected Error} = \text{Bias}^2 + \text{Variance} + \text{Irreducible Noise} \\[6pt] & \text{where:} \\ & \quad \text{Bias}^2 = (\mathbb{E}[\hat{f}(x)] - f(x))^2 \\ & \quad \text{Variance} = \mathbb{E}[(\hat{f}(x) - \mathbb{E}[\hat{f}(x)])^2] \\ & \quad \text{Noise} = \mathbb{E}[(y - f(x))^2] \quad (\sigma^2) \end{aligned}
  • عبارت f(x)f(x) نمایانگر تابع واقعی است
  • عبارت f^(x)\hat{f}(x) پیش‌بینی مدل شماست
  • عبارت E[…]\mathbb{E}[\ldots] امید ریاضی روی مجموعه‌های آموزشی متفاوت است
  • عبارت yy برچسب مشاهده‌شده است (تابع واقعی به‌علاوه‌ی نویز)

جمله‌ی نویز، تقلیل‌ناپذیر است؛ هیچ مدلی نمی‌تواند روی داده‌های دارای نویز، عملکردی بهتر از σ2\sigma^2 داشته باشد. مأموریت اصلی شما ایجاد تعادل میان bias2\text{bias}^2 و واریانس است.

پیچیدگی مدل در برابر خطا

افزایش پیچیدگیافزایش پیچیدگیمدل سادهنقطه بهینهمدل پیچیده

منحنی کلاسیک U-شکل:

پیچیدگی بایاس واریانس خطای کل
بیش از حد کم بالا کم بالا (کم‌برازش)
متناسب معتدل معتدل کمترین مقدار
بیش از حد زیاد کم بالا بالا (بیش‌برازش)

منظم‌سازی ابزاری برای مهار بایاس-واریانس

منظم‌سازی عمداً بایاس را بالا می‌برد تا از شدت واریانس بکاهد. این روش مدل را مقید می‌کند تا دنبال نویزها نرود.

  • منظم‌سازی L2 (Ridge): همه‌ی وزن‌ها را به سمت صفر فشرده می‌کند. کل ویژگی‌ها را نگه می‌دارد، اما اثرگذاری آن‌ها را کاهش می‌دهد.
  • منظم‌سازی L1 (Lasso): مقدار برخی وزن‌ها را دقیقاً به صفر می‌رساند و گزینش ویژگی (feature selection) انجام می‌دهد.
  • دراپ‌اوت (Dropout): در طول آموزش، نورون‌ها را به‌صورت تصادفی غیرفعال می‌کند تا شبکه مجبور به یادگیری بازنمایی‌های تکراری و افزونه (redundant) شود.
  • توقف زودهنگام (Early stopping): فرایند آموزش را پیش از برازشِ کامل مدل روی داده‌های آموزشی متوقف می‌کند.

شدت منظم‌سازی (لاندا، نرخ دراپ‌اوت، تعداد دورهای آموزش یا همان epochها) مستقیماً تعیین می‌کند که در کجای منحنی بایاس-واریانس قرار بگیرید. منظم‌سازی بیشتر یعنی بایاس بالاتر و واریانس کمتر.

فرود دوگانه: دیدگاه مدرن

دیدگاه کلاسیک می‌گوید: پس از نقطه‌ی بهینه، افزایش پیچیدگی همواره به ضرر مدل است. با این حال، پژوهش‌های سال 2019 به بعد پدیده‌ای غافلگیرکننده را نشان دادند: اگر ظرفیت مدل را بسیار فراتر از «آستانه‌ی درون‌یابی» (نقطه‌ای که مدل پارامترهای کافی برای برازش کاملِ داده‌های آموزشی پیدا می‌کند) افزایش دهید، خطای آزمون می‌تواند دوباره کاهش یابد.

ناحیه بیش‌برازش / کم‌برازشنقطه بهینه کلاسیکآستانه درون‌یابینزول دوگانه - کاهش مجدد خطا

پدیده‌ی «فرود دوگانه» (double descent) توضیح می‌دهد که چرا شبکه‌های عصبی (neural networks) به‌شدت بیش‌پارامتر (مدل‌هایی با تعداد پارامترهایی بسیار بیشتر از نمونه‌های آموزشی) همچنان تعمیم‌پذیری خوبی دارند. مصالحه‌ی کلاسیک بایاس-واریانس نادرست نیست، اما برای رژیم مدرن یادگیری ماشین ناقص است.

نکات کلیدی درباره‌ی فرود دوگانه:

  • در مدل‌های خطی، درخت‌های تصمیم و شبکه‌های عصبی رخ می‌دهد
  • افزایش داده در ناحیه‌ی درون‌یابی می‌تواند عملاً به مدل آسیب بزند (فرود دوگانه‌ی وابسته به نمونه)
  • افزایش دورهای آموزش نیز می‌تواند همین پدیده را ایجاد کند (فرود دوگانه‌ی وابسته به اپوک)
  • منظم‌سازی قله‌ی خطا را هموارتر می‌کند، اما آن را کاملاً از بین نمی‌برد

چرا این پدیده رخ می‌دهد؟ در آستانه‌ی درون‌یابی، مدل دقیقاً همان‌قدری ظرفیت دارد که همه‌ی نقاط آموزشی را برازش کند. در نتیجه ناچار به اتخاذ یک راهکار بسیار صلب و خاص می‌شود که باید از همه‌ی نقاط رد شود؛ از این رو اختلالات کوچک در داده‌ها باعث تغییرات بزرگی در برازش مدل می‌شوند و واریانس به اوج خود می‌رسد. اما فراتر از این آستانه، مدل راه‌حل‌های پرشماری برای برازش کامل داده‌ها در اختیار دارد. الگوریتم یادگیری (مثل گرادیان کاهشی به همراه منظم‌سازی ضمنی) ترجیح می‌دهد ساده‌ترین آن‌ها را برگزیند. همین گرایشِ ضمنی به راهکارهای ساده‌تر، دلیل تعمیم‌پذیری مدل‌های بیش‌پارامتر است.

رژیم مدل نسبت پارامترها به نمونه‌ها رفتار مدل
کم‌پارامتر (Underparameterized) p≪np \ll n مصالحه‌ی کلاسیک حاکم است
آستانه‌ی درون‌یابی p∼np \sim n واریانس به اوج می‌رسد، خطای آزمون جهش می‌کند
بیش‌پارامتر (Overparameterized) p≫np \gg n منظم‌سازی ضمنی فعال شده و خطای آزمون افت می‌کند

توصیه‌ای کاربردی: اگر از شبکه‌های عصبی یا گروه‌های بزرگی از درخت‌های تصمیم استفاده می‌کنید، روی آستانه‌ی درون‌یابی متوقف نشوید. یا خیلی پایین‌تر از آن بمانید (با منظم‌سازی صریح) یا خیلی فراتر از آن بروید. بدترین موقعیت، ایستادن دقیقاً روی آستانه است.

عیب‌یابی مدل

بلهخیربلهخیرمقایسه خطای آموزش در برابر آزمونشکاف زیاد است؟واریانس بالا - بیش‌برازشهر دو خطا بالا هستند؟بایاس بالا - کم‌برازشبرازش مناسبداده بیشتر / منظم‌سازی / مدل ساده‌ترویژگی‌های بیشتر / مدل پیچیده‌تر /منظم‌سازی کمتراستقرار
نشانه تشخیص راهکار
خطای بالای آموزش، خطای بالای آزمون بایاس افزایش ویژگی‌ها، مدل پیچیده‌تر، کاهش منظم‌سازی
خطای پایین آموزش، خطای بالای آزمون واریانس جمع‌آوری داده‌ی بیشتر، منظم‌سازی، مدل ساده‌تر، دراپ‌اوت
خطای پایین آموزش، خطای پایین آزمون برازش مناسب آماده‌ی استقرار (Ship it)
خطای آموزش رو به کاهش، خطای آزمون رو به افزایش در حال ورود به بیش‌برازش توقف زودهنگام

راهبردهای کاربردی

وقتی مشکل از بایاس است:

  • ویژگی‌های چندجمله‌ای یا تعاملی (interaction) اضافه کنید
  • سراغ مدلی با انعطاف بیشتر بروید (مجموعه درخت‌ها به جای مدل‌های خطی)
  • شدت منظم‌سازی را کاهش دهید
  • بیشتر آموزش دهید (اگر مدل هنوز همگرا نشده است)

وقتی مشکل از واریانس است:

  • داده‌های آموزشی بیشتری جمع کنید
  • از تکنیک بگینگ (جنگل‌های تصادفی) کمک بگیرید
  • منظم‌سازی را بیشتر کنید (افزایش لاندا، افزایش دراپ‌اوت)
  • دست به گزینش ویژگی بزنید (حذف ویژگی‌های نویزی)
  • از اعتبارسنجی متقاطع (cross-validation) برای تشخیص زودهنگام استفاده کنید

روش‌های تجمیعی و کاهش واریانس

روش‌های تجمیعی (ensemble methods) کاربردی‌ترین ابزار برای مهار واریانس هستند.

روش بگینگ (Bagging یا Bootstrap Aggregating) چند مدل مختلف را روی نمونه‌های بازنمونه‌گیری‌شده (bootstrap) از داده‌های آموزشی آموزش می‌دهد و سپس از پیش‌بینی‌های آن‌ها میانگین می‌گیرد. هر مدل به تنهایی واریانس بالایی دارد، اما میانگین خروجی آن‌ها واریانس بسیار کمتری دارد. جنگل‌های تصادفی (Random forests) حاصل اجرای همین روش روی درخت‌های تصمیم هستند.

دلیل ریاضی این موضوع: اگر از NN پیش‌بینی مستقل که هر کدام واریانسی برابر با σ2\sigma^2 دارند میانگین بگیرید، واریانس میانگین برابر با σ2/N\sigma^2 / N خواهد بود. البته چون این مدل‌ها همگی داده‌های مشابهی را می‌بینند، کاملاً مستقل نیستند و میزان کاهش واریانس کمتر از 1/N1/N است، اما در هر حال این کاهش چشمگیر است.

روش بوستینگ (Boosting) با ساخت ترتیبیِ مدل‌ها به دنبال کاهش بایاس است؛ به طوری که هر مدل جدید روی خطاهای مدل‌های قبلی تمرکز می‌کند. گرادیان بوستینگ (gradient boosting) و AdaBoost نمونه‌های اصلی این روش هستند. بوستینگ در صورت اضافه شدن بیش از حد مدل‌ها می‌تواند به بیش‌برازش کشیده شود؛ بنابراین به توقف زودهنگام یا منظم‌سازی نیاز دارید.

روش اثر اصلی تغییر بایاس تغییر واریانس
بگینگ کاهش واریانس بدون تغییر کاهش می‌یابد
بوستینگ کاهش بایاس کاهش می‌یابد ممکن است افزایش یابد
استکینگ (Stacking) کاهش هر دو وابسته به مدل تجمیع‌کننده (meta-learner) وابسته به مدل‌های پایه
دراپ‌اوت بگینگ ضمنی افزایش جزئی کاهش می‌یابد

یک قاعده‌ی تجربی: اگر مدل پایه‌ی شما واریانس بالایی دارد (مثل درخت‌های عمیق یا چندجمله‌ای‌های درجه‌بالا)، بگینگ را به کار بگیرید. اگر مدل پایه گرفتار بایاس بالاست (مثل درخت‌های بسیار کم‌عمق یا مدل‌های خطی ساده)، سراغ بوستینگ بروید.

منحنی‌های یادگیری

منحنی‌های یادگیری، خطای آموزش و اعتبارسنجی را بر حسب اندازه‌ی مجموعه‌ی داده‌های آموزشی ترسیم می‌کنند. این نمودارها کاربردی‌ترین ابزار تشخیصی شما هستند. برخلاف مقایسه‌ی ساده‌ی خطای آموزش و آزمون، منحنی‌های یادگیری روند تغییرات مدل را نشان می‌دهند و مشخص می‌کنند که آیا گردآوری داده‌ی بیشتر کمکی خواهد کرد یا نه.

منحنی یادگیری برازش مناسبمنحنی یادگیری واریانس بالامنحنی یادگیری بایاس بالاN کوچک: هر دو خطا بالاN بزرگ: همگرایی هر دو به خطای بالاN کوچک: آموزش پایین، آزمون بالا (شکافبزرگ)N بزرگ: کاهش کند شکافN کوچک: کمی شکافN بزرگ: همگرایی هر دو به خطای پایین

شیوه‌ی خواندن نمودارها:

سناریو خطای آموزش خطای اعتبارسنجی فاصله (شکاف) مفهوم اقدام لازم
بایاس بالا بالا بالا کم مدل توانایی یادگیری الگو را ندارد افزودن ویژگی، مدل پیچیده‌تر، منظم‌سازی کمتر
واریانس بالا کم بالا زیاد مدل داده‌های آموزش را حفظ کرده است داده‌ی بیشتر، منظم‌سازی، مدل ساده‌تر
برازش مناسب متوسط متوسط کم مدل به‌خوبی تعمیم یافته است آماده‌ی استقرار (Ship it)
واریانس بالا (رو به بهبود) کم رو به کاهش با افزایش داده رو به کاهش چالش واریانس که داده می‌تواند حلش کند گردآوری داده‌های بیشتر
بایاس بالا (افقی‌شده) بالا بالا و ثابت کم و ثابت داده‌های بیشتر کمکی نخواهند کرد اصلاح معماری مدل

نکته‌ی کلیدی: اگر هر دو منحنی به حالت افقی (plateau) رسیده‌اند و فاصله‌شان کم اما هر دو خطا بالا هستند، داده‌ی بیشتر هیچ فایده‌ای ندارد؛ شما به مدل بهتری نیاز دارید. اگر فاصله‌ی دو نمودار زیاد است و با افزودن نمونه‌ها مرتباً کمتر می‌شود، داده‌های بیشتر به کار خواهند آمد.

روش تولید منحنی‌های یادگیری

برای ساخت این نمودارها دو رویکرد وجود دارد:

رویکرد 1: تغییر اندازه‌ی مجموعه‌ی آموزش با مدل ثابت. مدل و هایپرپارامترها را ثابت نگه دارید. آن را روی زیرمجموعه‌هایی با اندازه‌ی فزاینده از داده‌ها آموزش دهید. خطای آموزش و اعتبارسنجی را در هر اندازه بسنجید. این همان منحنی یادگیری استاندارد است.

رویکرد 2: تغییر پیچیدگی مدل با داده‌های ثابت. داده‌ها را ثابت نگه دارید. یکی از پارامترهای پیچیدگی (درجه‌ی چندجمله‌ای، عمق درخت، تعداد لایه‌ها) را جاروب (sweep) کنید. در هر سطح از پیچیدگی، خطای آموزش و اعتبارسنجی را اندازه بگیرید. به این نمودار «منحنی اعتبارسنجی» می‌گویند که مصالحه‌ی بایاس-واریانس را مستقیماً نشان می‌دهد.

این دو رویکرد مکمل یکدیگرند. اولی می‌گوید که آیا داده‌ی بیشتر کارساز است یا خیر؛ دومی مشخص می‌کند که آیا تعویض مدل فایده‌ای دارد یا نه. پیش از تصمیم‌گیری درباره‌ی گام بعدی، هر دو آزمایش را اجرا کنید.

شکاف زیاد، اعتبارسنجیهمچنان نزولیشکاف کم، هر دو بالاشکاف زیاد، اعتبارسنجی ثابتعملکرد ضعیف مدلرسم منحنی یادگیریشکاف بین آموزش و اعتبارسنجی؟داده بیشتر کمک خواهد کردداده بیشتر کمکی نخواهد کردمنظم‌سازی یا ساده‌سازیرسم منحنی اعتبارسنجیآزمودن مدل پیچیده‌تر
سوگیری – واریانسپیچیدگی را بکشید
BIAS – VARIANCEGrey is training error, blue is test error. Simple models miss the signal (high bias); complex models fit the noise (high variance). Test error is their sum, lowest where the two pressures balance.
خاکستری خطای آموزش است و آبی خطای آزمون. مدل‌های ساده سیگنال اصلی را از دست می‌دهند (سوگیری بالا)؛ مدل‌های پیچیده نویز را برازش می‌کنند (واریانس بالا). خطای آزمون حاصل مجموع این دو است و در نقطه‌ای که این دو اثر به تعادل می‌رسند، کمترین مقدار را دارد.

پیاده‌سازی گام‌به‌گام

کد موجود در فایل code/bias_variance.py آزمایش کامل تجزیه‌ی بایاس-واریانس را اجرا می‌کند. در ادامه مراحل این کار را قدم‌به‌قدم می‌بینید.

گام 1: تولید داده‌های مصنوعی از روی تابعی مشخص

ما از تابع f(x) = sin(1.5x) + 0.5x همراه با نویز گاوسی استفاده می‌کنیم. شناختن تابع واقعی به ما اجازه می‌دهد مقادیر دقیق بایاس و واریانس را به دست آوریم.

def true_function(x):
    return np.sin(1.5 * x) + 0.5 * x

def generate_data(n_samples=30, noise_std=0.5, x_range=(-3, 3), seed=None):
    rng = np.random.RandomState(seed)
    x = rng.uniform(x_range[0], x_range[1], n_samples)
    y = true_function(x) + rng.normal(0, noise_std, n_samples)
    return x, y

گام 2: بازنمونه‌گیری بوت‌استرپ و برازش چندجمله‌ای

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

def fit_polynomial(x_train, y_train, degree, lam=0.0):
    X = np.column_stack([x_train ** d for d in range(degree + 1)])
    if lam > 0:
        penalty = lam * np.eye(X.shape[1])
        penalty[0, 0] = 0
        w = np.linalg.solve(X.T @ X + penalty, X.T @ y_train)
    else:
        w = np.linalg.lstsq(X, y_train, rcond=None)[0]
    return w

ما برازش را روی 200 نمونه‌ی مختلف بوت‌استرپ انجام می‌دهیم. هر نمونه‌ی بوت‌استرپ از همان توزیع زیربنایی استخراج شده اما شامل نقاط متفاوتی است.

گام 3: محاسبه‌ی بایاس به توان دو و تجزیه‌ی واریانس

با داشتن 200 دسته پیش‌بینی در هر نقطه‌ی آزمون، می‌توانیم تجزیه‌ی خطا را مستقیماً بر مبنای تعریف اصلی آن حساب کنیم:

mean_pred = predictions.mean(axis=0)
bias_sq = np.mean((mean_pred - y_true) ** 2)
variance = np.mean(predictions.var(axis=0))
total_error = np.mean(np.mean((predictions - y_true) ** 2, axis=1))
  • متغیر mean_pred همان E[f^(x)]\mathbb{E}[\hat{f}(x)] است که از روی نمونه‌های بوت‌استرپ تخمین زده شده است
  • متغیر bias_sq مجذور فاصله‌ی میان میانگین پیش‌بینی‌ها و مقادیر واقعی است
  • متغیر variance میانگین پراکندگی پیش‌بینی‌ها در طول نمونه‌های بوت‌استرپ را نشان می‌دهد
  • متغیر total_error باید تقریباً برابر با مجموع bias2+variance+noise\text{bias}^2 + \text{variance} + \text{noise} باشد

گام 4: منحنی‌های یادگیری

منحنی‌های یادگیری، اندازه‌ی مجموعه‌ی آموزش را تغییر می‌دهند در حالی که پیچیدگی مدل را ثابت نگه می‌دارند. این نمودارها نشان می‌دهند که آیا مدل شما با کمبود داده مواجه است یا با کمبود ظرفیت.

def demo_learning_curves():
    sizes = [10, 15, 20, 30, 50, 75, 100, 150, 200, 300]
    degree = 5

    for n in sizes:
        train_errors = []
        test_errors = []
        for seed in range(50):
            x_train, y_train = generate_data(n_samples=n, seed=seed * 100)
            w = fit_polynomial(x_train, y_train, degree)
            train_pred = predict_polynomial(x_train, w)
            train_mse = np.mean((train_pred - y_train) ** 2)
            test_pred = predict_polynomial(x_test, w)
            test_mse = np.mean((test_pred - y_test) ** 2)
            train_errors.append(train_mse)
            test_errors.append(test_mse)
        # میانگین‌گیری روی اجراها، نقطه منحنی یادگیری را می‌دهد

در مدلی با واریانس بالا (چندجمله‌ای درجه‌ی 5 با داده‌های کم)، این رفتار را می‌بینید:

  • خطای آموزش ابتدا پایین است و با افزایش حجم داده‌ها—چون حفظ کردنشان سخت‌تر می‌شود—بالا می‌رود
  • خطای آزمون ابتدا بالاست و با دریافت سیگنال بیشتر توسط مدل کاهش می‌یابد
  • فاصله‌ی دو نمودار با افزایش حجم داده‌ها کمتر می‌شود

در مدلی با بایاس بالا (چندجمله‌ای درجه‌ی 1)، هر دو خطا خیلی زود به یک مقدار بالای یکسان همگرا می‌شوند و داده‌های بیشتر هم هیچ کمکی نمی‌کنند.

گام 5: جاروب منظم‌سازی

این کد تابعی به نام demo_regularization_sweep() دارد که یک چندجمله‌ای درجه‌بالا (درجه‌ی 15) را ثابت نگه می‌دارد و قدرت منظم‌سازی Ridge را از 0.001 تا 100 جاروب می‌کند. این تابع مصالحه‌ی بایاس-واریانس را از زاویه‌ی دیگری نشان می‌دهد: به جای تغییر پیچیدگی مدل، شدت محدودیت را تغییر می‌دهیم.

def demo_regularization_sweep():
    alphas = [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 5.0, 10.0, 50.0, 100.0]
    for alpha in alphas:
        results = bias_variance_decomposition([15], lam=alpha)
        r = results[15]
        print(f"alpha={alpha:.3f}  bias={r['bias_sq']:.4f}  var={r['variance']:.4f}")

در مقادیر پایین آلفا، چندجمله‌ای درجه‌ی 15 تقریباً بدون محدودیت عمل می‌کند؛ در نتیجه واریانس غلبه دارد، چون مدل در هر نمونه‌ی بوت‌استرپ دنبال نویزها می‌رود. در مقادیر بالای آلفا، جریمه چنان سنگین است که مدل عملاً به تابعی نزدیک به ثابت تبدیل می‌شود و بایاس بالا دست بالا را می‌گیرد. آلفای بهینه جایی میان این دو حد افراطی قرار دارد.

این همان منحنی U-شکل حاصل از تغییر درجه‌ی چندجمله‌ای است، با این تفاوت که اینجا به جای متغیری گسسته، با یک پیچ تنظیم پیوسته کنترل می‌شود. در عمل، منظم‌سازی روش ترجیحی برای مهار این توازن است؛ چرا که بدون دستکاری مجموعه‌ی ویژگی‌ها، کنترلی دقیق و ریزدانه برایتان فراهم می‌کند.

استفاده از ابزارها

کتابخانه‌ی sklearn توابع learning_curve و validation_curve را ارائه می‌دهد تا بتوانید بدون نوشتن دستیِ حلقه‌های بوت‌استرپ، این ارزیابی‌ها را خودکار کنید.

منحنی اعتبارسنجی: جاروب پیچیدگی مدل

from sklearn.model_selection import validation_curve
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import Ridge

degrees = list(range(1, 16))
train_scores_all = []
val_scores_all = []

for d in degrees:
    pipe = make_pipeline(PolynomialFeatures(d), Ridge(alpha=0.01))
    train_scores, val_scores = validation_curve(
        pipe, X, y, param_name="polynomialfeatures__degree",
        param_range=[d], cv=5, scoring="neg_mean_squared_error"
    )
    train_scores_all.append(-train_scores.mean())
    val_scores_all.append(-val_scores.mean())

این نمودار مستقیماً منحنی مصالحه‌ی بایاس-واریانس را به شما می‌دهد. در جاهایی که امتیاز اعتبارسنجی در مقایسه با امتیاز آموزش بدترین وضعیت را دارد، واریانس غالب است؛ هر جا هر دو ضعیف باشند، بایاس دست بالا را دارد.

منحنی یادگیری: جاروب اندازه‌ی مجموعه‌ی آموزش

from sklearn.model_selection import learning_curve

pipe = make_pipeline(PolynomialFeatures(5), Ridge(alpha=0.01))
train_sizes, train_scores, val_scores = learning_curve(
    pipe, X, y, train_sizes=np.linspace(0.1, 1.0, 10),
    cv=5, scoring="neg_mean_squared_error"
)
train_mse = -train_scores.mean(axis=1)
val_mse = -val_scores.mean(axis=1)

نمودار train_mse و val_mse را در برابر train_sizes رسم کنید. شکل نهایی خطوط همه‌چیز را درباره‌ی مدلتان روشن می‌کند.

اعتبارسنجی متقاطع با جاروب منظم‌سازی

from sklearn.model_selection import cross_val_score

alphas = [0.001, 0.01, 0.1, 1.0, 10.0, 100.0]
for alpha in alphas:
    pipe = make_pipeline(PolynomialFeatures(10), Ridge(alpha=alpha))
    scores = cross_val_score(pipe, X, y, cv=5, scoring="neg_mean_squared_error")
    print(f"alpha={alpha:>7.3f}  MSE={-scores.mean():.4f} +/- {scores.std():.4f}")

این کد ضریب منظم‌سازی را برای یک مدل با پیچیدگی ثابت جاروب می‌کند. در اینجا نیز همان مصالحه‌ی بایاس-واریانس را خواهید دید: آلفای کم یعنی واریانس بالا، و آلفای زیاد یعنی بایاس بالا.

جمع‌بندی: فرایند کامل عیب‌یابی

در پروژه‌های واقعی، این مراحل عیب‌یابی را به ترتیب اجرا کنید:

  1. مدل را آموزش دهید. خطای آموزش و آزمون را به دست آورید.
  2. اگر هر دو بالا بودند: مشکل بایاس دارید. مستقیم به گام 4 بروید.
  3. اگر خطای آموزش پایین و خطای آزمون بالا بود: با مشکل واریانس روبه‌رو هستید. منحنی یادگیری رسم کنید تا ببینید آیا داده‌ی بیشتر کمکی می‌کند یا خیر. اگر کمکی نکرد، مدل را منظم‌سازی کنید.
  4. با جاروب کردن پارامتر اصلیِ پیچیدگی مدلتان، یک منحنی اعتبارسنجی رسم کرده و نقطه‌ی بهینه را پیدا کنید.
  5. در نقطه‌ی بهینه، یک منحنی یادگیری تولید کنید. اگر فاصله همچنان زیاد بود، به داده‌ی بیشتر یا منظم‌سازی قوی‌تر نیاز دارید.
  6. مدل‌های Ridge یا Lasso را با مقادیر مختلف آلفا با استفاده از cross_val_score امتحان کنید و آلفایی را که کمترین خطای اعتبارسنجی متقاطع را دارد برگزینید.

اجرای این مراحل برای اغلب مجموعه‌داده‌های جدولی بین 10 تا 15 دقیقه زمان پردازشی می‌برد و ساعت‌ها حدس‌وگمان بیهوده را از بین می‌برد.

خروجی نهایی

این درس سند زیر را تولید می‌کند: outputs/prompt-model-diagnostics.md

تمرین‌ها

  1. آزمایش تجزیه‌ی خطا را با noise_std=0 (بدون نویز) اجرا کنید. خطای تقلیل‌ناپذیر چه تغییری می‌کند؟ آیا نقطه‌ی بهینه‌ی پیچیدگی مدل تغییر خواهد کرد؟

  2. اندازه‌ی مجموعه‌ی آموزش را از 30 به 300 افزایش دهید. این کار چه اثری روی مؤلفه‌ی واریانس می‌گذارد؟ آیا درجه‌ی بهینه‌ی چندجمله‌ای جابه‌جا می‌شود؟

  3. منظم‌سازی L2 (رگرسیون Ridge) را به این آزمایش اضافه کنید. برای یک چندجمله‌ای درجه‌بالای ثابت (درجه‌ی 15)، لاندا را از 0 تا 100 جاروب کنید. نمودار bias2\text{bias}^2 و واریانس را بر حسب مقادیر لاندا رسم کنید.

  4. تابع واقعی داده‌ها را از چندجمله‌ای به sin(x) تغییر دهید. تجزیه‌ی بایاس-واریانس چطور دستخوش تغییر می‌شود؟ آیا هنوز هم یک درجه‌ی چندجمله‌ای بهینه‌ی مشخص وجود دارد؟

  5. یک پیاده‌سازی ساده برای بگینگ بنویسید: 10 مدل را روی نمونه‌های بوت‌استرپ آموزش دهید و از پیش‌بینی‌های آن‌ها میانگین بگیرید. نشان دهید که چطور این روش بدون افزایش چشمگیر در بایاس، واریانس را کاهش می‌دهد.

اصطلاحات کلیدی

اصطلاح اصطلاح رایج معنای دقیق علمی
بایاس (Bias) «مدل زیادی ساده است» خطای سیستماتیک ناشی از فرضیات نادرست؛ فاصله‌ی بین میانگین پیش‌بینی‌های مدل و واقعیت.
واریانس (Variance) «مدل اورفیت شده» خطا ناشی از حساسیت به داده‌های آموزش؛ شدت تغییرات پیش‌بینی‌ها روی مجموعه‌های آموزشی گوناگون.
خطای تقلیل‌ناپذیر (Irreducible error) «نویز توی داده‌هاست» خطا ناشی از تصادفی بودن ذاتی فرایند تولید داده که هیچ مدلی نمی‌تواند آن را از بین ببرد.
کم‌برازش (Underfitting) «مدل یاد نگرفته» داشتن بایاس بالا؛ ناتوانی مدل در یادگیری الگوهای واقعی، حتی روی داده‌های آموزش.
بیش‌برازش (Overfitting) «داده‌ها را حفظ کرده» داشتن واریانس بالا؛ برازش روی نویزهای داده‌های آموزش که تعمیم پیدا نمی‌کند.
منظم‌سازی (Regularization) «ایجاد محدودیت برای مدل» اضافه کردن جریمه برای کاهش پیچیدگی مدل و کاهش واریانس در ازای افزایش بایاس.
فرود دوگانه (Double descent) «پارامتر بیشتر می‌تواند کمک کند» کاهش دوباره‌ی خطای آزمون زمانی که ظرفیت مدل بسیار فراتر از آستانه‌ی درون‌یابی می‌رود.
پیچیدگی مدل (Model complexity) «مدل چقدر منعطف است» ظرفیت مدل در برازش الگوهای دلخواه که توسط معماری، ویژگی‌ها یا منظم‌سازی کنترل می‌شود.

برای مطالعه‌ی بیشتر

سؤالات متداول

چگونه بفهمیم مدل دچار بایاس بالا شده یا واریانس بالا؟

اگر خطای آموزش و خطای آزمون هر دو بالا باشند، مدل گرفتار بایاس بالا (کم‌برازش) است. اما اگر خطای آموزش پایین و خطای آزمون بالا باشد، مدل دچار واریانس بالا (بیش‌برازش) شده است.

آیا جمع‌آوری داده‌ی بیشتر همیشه واریانس و بایاس را برطرف می‌کند؟

افزایش داده به کاهش واریانس کمک می‌کند؛ اما اگر مدل دچار بایاس بالا باشد و منحنی‌های آموزش و اعتبارسنجی روی خطایی بالا افقی شده باشند، داده‌ی بیشتر کمکی نمی‌کند و باید معماری یا ویژگی‌های مدل را بهبود داد.

پدیده‌ی فرود دوگانه (Double Descent) چیست؟

فرود دوگانه نشان می‌دهد که با افزایش پیچیدگی مدل فراتر از آستانه‌ی درون‌یابی (جایی که پارامترها بسیار بیشتر از داده‌ها هستند)، بر خلاف دیدگاه کلاسیک، خطای آزمون دوباره به دلیل منظم‌سازی ضمنی کاهش می‌یابد.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.