Random Forest یا جنگل تصادفی، خروجی چند درخت را ترکیب میکند. در ساخت رایج آن، هر درخت نمونهای بازنمونهگیریشده از داده میبیند و در هر تقسیم، زیرمجموعهای از ویژگیها بررسی میشود. هدف این تنوع آن است که همه درختها دقیقاً همان خطا را تکرار نکنند؛ زیادکردن تعداد درخت بهتنهایی شاهد کیفیت بهتر نیست.
تفاوت با یک درخت تصمیم
راهنمای درخت تصمیم و Gini خود انتخاب یک شاخه را حساب میکند. اینجا همان مفهوم را در سه درخت تکتقسیمی کنار هم میگذاریم. کد یک جنگل کوچک آموزشی با محدودیت عمق یک است؛ جای پیادهسازی کامل کتابخانه یا تنظیم مدل برای داده واقعی نیست.
شش ردیف با دو ویژگی داریم: (۰،۰)، (۱،۱)، (۲،۰)، (۳،۱)، (۴،۰) و (۵،۱). برچسبها بهترتیب ۰،۰،۱،۱،۱،۰ هستند. شناسه ردیفها از صفر تا پنج است. نمونههای انتخابشده برای سه درخت را در کد ثابت کردهایم تا محاسبه دقیقاً تکرار شود؛ این فهرستها، خروجی تصادفی یک اجرای پنهان نیستند.
Bootstrap یعنی انتخاب با جایگذاری
درخت اول ردیفهای ۰،۰،۱،۳،۴،۵ را میبیند. ردیف صفر دو بار آمده و ردیف دو اصلاً در این نمونه نیست. همین معنی انتخاب با جایگذاری است؛ شش انتخاب لزوماً شش ردیف یکتا نمیسازد. هر درخت در این تمرین فقط یکی از دو ویژگی را برای همان تکتقسیم بررسی میکند.
| درخت | ویژگی مجاز؛ شماره از صفر | آستانه آموختهشده | احتمال کلاس۱ برای ورودی (۲٫۵،۰) |
|---|---|---|---|
| 1 | 0 | 2 | ۲÷۳ |
| 2 | 1 | ۰٫۵ | 1 |
| 3 | 0 | ۱٫۵ | ۳÷۴ |
هر احتمال از سهم برچسب ۱ در برگ همان نمونه درخت به دست میآید. میانگین سه مقدار برابر (۲÷۳+۱+۳÷۴)÷۳=۲۹÷۳۶، حدود ۰٫۸۰۵۵۵۶ است. در این مثال، میانگین احتمال را ترکیب میکنیم؛ رأی اکثریتِ برچسبهای سخت، قرارداد دیگری است. این عدد، دقت ۸۰ درصدی مدل نیست.
کد ساخت و ترکیب سه درخت
from collections import Counter
X = [(0,0), (1,1), (2,0), (3,1), (4,0), (5,1)]
y = [0,0,1,1,1,0]
# Fixed recorded bootstrap draws and feature choices for this teaching example.
specs = [([0,0,1,3,4,5],0), ([1,2,2,3,4,5],1), ([0,1,2,3,3,5],0)]
def gini(a):
return 1-sum((c/len(a))**2 for c in Counter(a).values())
def fit_stump(indices, feature):
values = sorted({X[i][feature] for i in indices})
options=[]
for a,b in zip(values,values[1:]):
t=(a+b)/2
left=[y[i] for i in indices if X[i][feature] <= t]
right=[y[i] for i in indices if X[i][feature] > t]
score=(len(left)*gini(left)+len(right)*gini(right))/len(indices)
options.append((score,t,sum(left)/len(left),sum(right)/len(right)))
_,threshold,pl,pr=min(options)
return feature,threshold,pl,pr
query=(2.5,0)
forest=[fit_stump(indices,j) for indices,j in specs]
probs=[pl if query[j] <= t else pr for j,t,pl,pr in forest]
mean=sum(probs)/len(probs)
print('stumps',forest)
print('tree p(class1)',probs,'mean',mean)
print('out-of-bag indices', [sorted(set(range(len(y)))-set(idx)) for idx,_ in specs])
assert abs(mean-29/36) < 1e-12
assert len(set(specs[0][0])) < len(specs[0][0])آستانهها با کمینهکردن Gini وزنی روی نمونه هر درخت پیدا میشوند. در صورت تساوی، ترتیب tuple گزینهها انتخاب را مشخص میکند. کد فقط برای داده ثابت این تمرین است؛ سیاست برگ خالی، داده گمشده، وزن نمونه یا ورودی عمومی ندارد.
داده بیرون نمونه هر درخت چه میگوید؟
برای هر درخت میتوان ردیفهایی را که در bootstrap آن نیامدهاند مشخص کرد؛ اینها نسبت به همان درخت بیرون نمونهاند، نه مجموعه آزمون مستقل نهایی کل پروژه. کد فقط شناسه آنها را چاپ میکند و امتیاز ارزیابی Out-of-bag گزارش نمیدهد. استفاده از همه درختها روی همان داده آموزش را با آزمون تازه اشتباه نگیرید.
برای تمرین، فقط فهرست bootstrap درخت اول را تغییر دهید و ببینید برگها و احتمالش چطور جابهجا میشوند. سپس مقایسه را با داده ارزیابی مستقل طراحی کنید؛ تعمیم و بیشبرازش همچنان موضوع اصلی سنجش کیفیت است.
نام الگوریتم جای شاهد را نمیگیرد
اگر پیشنهادی برای دستهبندی درخواستها دریافت میکنید، تعریف برچسب، سناریوی خطا و روش آزمون را بخواهید. برای مسئله پاسخگویی مشتری، نمونههای مجاز را در مسیر راهکارهای اپرا مطرح کنید؛ این جنگل کوچک، فناوری داخلی یا نتیجه محصول اپرا را توصیف نمیکند.
فایل تمرین و منابع
دریافت کد کامل این تمرین؛ این فایل فقط از کتابخانه استاندارد پایتون استفاده میکند. ورودیهای آن ساختگی و برای بازتولید محاسبهاند؛ اجرای آموزشی آن نتیجه یک محصول یا مشتری را نشان نمیدهد.
تاریخ بررسی منابع: ۳ نوامبر ۲۰۲۶. منابع، مرجع روشاند؛ دادهها، اعداد و کد مثال برای همین راهنما طراحی شدهاند.