Gradient Boosting مدل را مرحلهبهمرحله میسازد: یک پیشبینی پایه داریم و مدل تازه اصلاحی به خروجی قبلی اضافه میکند. برای زیان مربعی، میتوان این اصلاح را با برازش روی باقیماندهها دید. این تعریف به معنی گرفتن میانگین چند مدل مستقل نیست؛ هر مرحله به خروجی مرحلههای قبل وابسته است.
چهار هدف و یک پیشبینی آغازین
داده آموزشی ما xهای ۱،۲،۳،۴ و yهای ۱،۲،۶،۷ است. پیشبینی ثابت آغازین را میانگین y یعنی ۴ میگذاریم. باقیماندهها، y منهای پیشبینی، برابر منفی ۳، منفی ۲، ۲ و ۳ هستند. SSE اولیه ۲۶ میشود. عددها ساختگیاند و واحد یا نتیجه کسبوکار به آنها نسبت داده نشده است.
درخت اول کدام خطا را دنبال میکند؟
یک درخت تکتقسیمی روی باقیماندهها برازش میدهیم. در هر طرف آستانه، مقدار برگ میانگین باقیماندههای همان طرف است. بین آستانههای ۱٫۵،۲٫۵ و۳٫۵، مقدار ۲٫۵ کمترین مربع خطای برازش باقیمانده را دارد. میانگین چپ منفی ۲٫۵ و راست مثبت ۲٫۵ است.
نرخ افزودن اصلاح را ۰٫۵ انتخاب میکنیم: پیشبینی تازه برابر پیشبینی قبلی بهعلاوه نصف خروجی درخت است. پس چهار پیشبینی ۲٫۷۵،۲٫۷۵،۵٫۲۵،۵٫۲۵ میشوند. SSE روی همین داده به ۷٫۲۵ میرسد.
باقیمانده مرحله دوم را دوباره بسازیم
| مرحله | باقیمانده پیش از ساخت درخت | خروجی برگ چپ و راست | SSE پس از اصلاح |
|---|---|---|---|
| 1 | −۳، −۲، ۲، ۳ | −۲٫۵ و ۲٫۵ | ۷٫۲۵ |
| 2 | −۱٫۷۵، −۰٫۷۵، ۰٫۷۵، ۱٫۷۵ | −۱٫۲۵ و ۱٫۲۵ | ۲٫۵۶۲۵ |
درخت دوم روی باقیماندههای تازه آموزش میبیند، نه دوباره روی همان هدف اولیه. با همان نرخ، خروجی نهایی ۲٫۱۲۵،۲٫۱۲۵،۵٫۸۷۵،۵٫۸۷۵ است. فاصله این اعداد تا هدفها هنوز صفر نیست. افت SSE مربوط به همین چهار ردیف آموزش است و کیفیت داده تازه را نشان نمیدهد.
کد دو مرحله با درخت تکتقسیمی
x=[1.0,2.0,3.0,4.0]
y=[1.0,2.0,6.0,7.0]
rate=0.5
pred=[sum(y)/len(y)]*len(y)
def sse(values):
return sum((a-b)**2 for a,b in zip(y,values))
print('initial',pred,sse(pred))
models=[]
for stage in range(2):
residual=[a-b for a,b in zip(y,pred)]
options=[]
for a,b in zip(x,x[1:]):
t=(a+b)/2
left=[r for u,r in zip(x,residual) if u<=t]
right=[r for u,r in zip(x,residual) if u>t]
lv,rv=sum(left)/len(left),sum(right)/len(right)
fit=[lv if u<=t else rv for u in x]
error=sum((r-f)**2 for r,f in zip(residual,fit))
options.append((error,t,lv,rv,fit))
_,t,lv,rv,fit=min(options)
pred=[p+rate*f for p,f in zip(pred,fit)]
models.append((t,lv,rv))
print('stage',stage+1,'stump',(t,lv,rv),'prediction',pred,'SSE',sse(pred))
assert pred == [2.125,2.125,5.875,5.875]
assert sse(pred) == 2.5625 and models[0] == (2.5,-2.5,2.5)کد همه آستانههای میان چهار x متمایز را بررسی میکند و فقط دو مرحله دارد. این یک نمونه محدود برای زیان مربعی است. در سایر زیانها، عبارت «همیشه باقیمانده ساده را برازش بده» درست نیست؛ جهت اصلاح به گرادیان زیان و روش تنظیم برگها وابسته میشود. نباید این فایل را پیادهسازی عمومی همه نسخههای Gradient Boosting معرفی کرد.
با گرادیان نزولی و Random Forest چه نسبتی دارد؟
در گرادیان نزولی عددی خود یک پارامتر تغییر میکند. اینجا در هر مرحله تابعی کوچک به پیشبینی اضافه کردهایم. در Random Forest، درختها با نمونهگیری و ویژگیهای متفاوت ساخته و خروجیشان ترکیب میشود؛ ترتیب آنها همان نقش اصلاح باقیمانده مرحله قبل را ندارد. برای اصل انتخاب یک آستانه هم ساخت تقسیم درخت را ببینید؛ معیار آن مقاله برای طبقهبندی بود و اینجا مربع خطای عددی داریم.
چه چیزی را در آزمون نگه داریم؟
تعداد مرحله، عمق درخت، نرخ اصلاح و داده اعتبارسنجی را پیش از نتیجه نهایی مشخص کنید. برای تمرین نرخ را ۱ بگذارید و خروجی دو مرحله را بررسی کنید؛ نتیجه این چهار ردیف، دلیل انتخاب همان نرخ برای پروژه دیگر نیست. برای نیاز پاسخگویی مشتری، خروجی مطلوب و نمونه خطا را در مسیر خدمات اپرا مطرح کنید؛ این متن استفاده از این الگوریتم یا بهبود قطعی محصول را اعلام نمیکند.
فایل تمرین و منابع
دریافت کد کامل این تمرین؛ این فایل فقط از کتابخانه استاندارد پایتون استفاده میکند. ورودیهای آن ساختگی و برای بازتولید محاسبهاند؛ اجرای آموزشی آن نتیجه یک محصول یا مشتری را نشان نمیدهد.
تاریخ بررسی منابع: ۳ نوامبر ۲۰۲۶. منابع، مرجع روشاند؛ دادهها، اعداد و کد مثال برای همین راهنما طراحی شدهاند.