Random Forest و AdaBoost | Extra-Trees و Feature Importance

جنگل تصادفی، Extra-Trees، اهمیت ویژگی‌ها و AdaBoost

توسط admin | گروه هوش مصنوعی | 1405/06/01

نظرات 0

جنگل تصادفی، Extra-Trees، اهمیت ویژگی‌ها و AdaBoost

عنوان اصلی
Random Patches and Random Subspaces; Random Forests; Extra-Trees; Feature Importance; Boosting; AdaBoost; Gradient Boosting
عنوان ترجمه‌شده
جنگل تصادفی، Extra-Trees، اهمیت ویژگی‌ها و AdaBoost
اثر
Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow - ویرایش سوم
نویسنده
Aurelien Geron
سمت/سابقهٔ نویسنده
مشاور یادگیری ماشین؛ مدیر پیشین تیم طبقه‌بندی ویدئوی YouTube
زبان اصلی
انگلیسی
صفحات منبع
45-52 از PDF فعلی؛ صفحات چاپی کتاب 219-226
وضعیت حقوق
حق‌نشر اثر اصلی متعلق به صاحب اثر است؛ کاربر حق ترجمه و استفاده/بازنشر را برای این پردازش تأیید کرده است.
تاریخ ترجمه
1405/06/01 / 2026-08-23
اعتبار ترجمه
ترجمه با کمک هوش مصنوعی

ادامهٔ ارزیابی OOB

بر اساس ارزیابی Out-of-Bag در بخش قبل، انتظار می‌رفت BaggingClassifier روی مجموعهٔ آزمون حدود ۸۹٫۶٪ دقت داشته باشد. با ارزیابی واقعی روی آزمون نتیجه چنین است:

>>> from sklearn.metrics import accuracy_score
>>> y_pred = bag_clf.predict(X_test)
>>> accuracy_score(y_test, y_pred)
0.92

دقت واقعی ۹۲٪ است؛ بنابراین ارزیابی OOB در این مثال کمی بدبینانه بوده و بیش از دو درصد کمتر از نتیجهٔ آزمون را برآورد کرده است.

تابع تصمیم OOB برای هر نمونهٔ آموزشی در oob_decision_function_ نیز موجود است. چون Estimator پایه متد predict_proba() دارد، این ویژگی احتمال کلاس‌ها را برای هر نمونه برمی‌گرداند. برای سه نمونهٔ نخست:

>>> bag_clf.oob_decision_function_[:3]
array([[0.32352941, 0.67647059],
       [0.3375    , 0.6625    ],
       [1.        , 0.        ]])

برای نمونهٔ اول، ارزیابی OOB احتمال کلاس مثبت را حدود ۶۷٫۶٪ و کلاس منفی را ۳۲٫۴٪ برآورد کرده است.

Random Patches و Random Subspaces

BaggingClassifier علاوه بر نمونه‌گیری از سطرهای آموزشی، می‌تواند از ویژگی‌ها نیز نمونه‌گیری کند. این کار با دو فراپارامتر max_features و bootstrap_features کنترل می‌شود؛ عملکرد آن‌ها مشابه max_samples و bootstrap است، با این تفاوت که به‌جای نمونه‌های آموزشی، ویژگی‌ها را انتخاب می‌کنند. بنابراین هر پیش‌بینی‌کننده می‌تواند فقط روی زیرمجموعه‌ای تصادفی از ویژگی‌های ورودی آموزش ببیند.

این تکنیک برای ورودی‌های پُربعد مانند تصویر بسیار مفید است، چون می‌تواند آموزش را به‌طور محسوسی سریع‌تر کند. نمونه‌گیری هم‌زمان از نمونه‌های آموزشی و ویژگی‌ها Random Patches نام دارد. اگر تمام نمونه‌ها حفظ شوند ــ با bootstrap=False و max_samples=1.0 ــ ولی فقط ویژگی‌ها نمونه‌گیری شوند، روش Random Subspaces نام دارد.

نمونه‌گیری ویژگی‌ها تنوع پیش‌بینی‌کننده‌ها را بیشتر می‌کند: Bias اندکی بالا می‌رود اما Variance کاهش می‌یابد.

جنگل‌های تصادفی

جنگل تصادفی مجموعه‌ای از درخت‌های تصمیم است که معمولاً با Bagging ــ و گاهی Pasting ــ آموزش داده می‌شوند و اغلب max_samples برابر اندازهٔ کل مجموعهٔ آموزشی است. به‌جای ساخت دستی BaggingClassifier با DecisionTreeClassifier، می‌توان از RandomForestClassifier استفاده کرد که هم ساده‌تر است و هم برای درخت تصمیم بهینه شده است. برای رگرسیون نیز RandomForestRegressor وجود دارد.

کد زیر جنگلی شامل ۵۰۰ درخت می‌سازد که هرکدام حداکثر ۱۶ برگ دارند و از همهٔ هسته‌های CPU استفاده می‌کند:

from sklearn.ensemble import RandomForestClassifier

rnd_clf = RandomForestClassifier(
    n_estimators=500,
    max_leaf_nodes=16,
    n_jobs=-1,
    random_state=42
)
rnd_clf.fit(X_train, y_train)
y_pred_rf = rnd_clf.predict(X_test)

به‌جز چند استثنا، RandomForestClassifier هم فراپارامترهای DecisionTreeClassifier را برای کنترل رشد درخت‌ها دارد و هم بسیاری از فراپارامترهای BaggingClassifier را برای کنترل خود Ensemble.

جنگل تصادفی هنگام رشد درخت‌ها تصادفی‌بودن بیشتری وارد می‌کند: به‌جای جست‌وجوی بهترین ویژگی در میان همهٔ ویژگی‌ها برای هر تقسیم، بهترین ویژگی را فقط از میان یک زیرمجموعهٔ تصادفی از ویژگی‌ها پیدا می‌کند. این کار تنوع درخت‌ها را افزایش می‌دهد؛ معمولاً Bias کمی بیشتر و Variance کمتر می‌شود و نتیجهٔ کلی مدل بهبود می‌یابد.

نمونهٔ زیر تقریباً معادل جنگل تصادفی قبل است:

bag_clf = BaggingClassifier(
    DecisionTreeClassifier(
        max_features="sqrt",
        max_leaf_nodes=16
    ),
    n_estimators=500,
    n_jobs=-1,
    random_state=42
)

Extra-Trees

در جنگل تصادفی، برای هر گره فقط زیرمجموعه‌ای تصادفی از ویژگی‌ها بررسی می‌شود، اما هنوز بهترین آستانهٔ تقسیم برای آن ویژگی‌ها جست‌وجو می‌شود. می‌توان تصادفی‌بودن را یک گام بیشتر کرد و آستانه‌ها را نیز به‌صورت تصادفی انتخاب کرد؛ برای این کار در DecisionTreeClassifier می‌توان splitter="random" را به کار برد.

جنگلی از این درخت‌های بسیار تصادفی Extremely Randomized Trees یا به اختصار Extra-Trees نام دارد. این روش نیز در برابر کاهش Variance، مقدار بیشتری Bias می‌پذیرد. همچنین آموزش Extra-Trees معمولاً بسیار سریع‌تر از Random Forest است، چون جست‌وجوی بهترین آستانه برای هر ویژگی از پرهزینه‌ترین بخش‌های رشد درخت است.

در Scikit-Learn کلاس‌های ExtraTreesClassifier و ExtraTreesRegressor وجود دارند. رابط آن‌ها تقریباً همان رابط Random Forest است، با این تفاوت که bootstrap به‌طور پیش‌فرض False است.

از قبل نمی‌توان با اطمینان گفت Random Forest بهتر است یا Extra-Trees. راه عملی این است که هر دو را امتحان کنید و با Cross-Validation مقایسه کنید.

اهمیت ویژگی‌ها

یکی از مزیت‌های مهم جنگل تصادفی امکان اندازه‌گیری سادهٔ اهمیت نسبی ویژگی‌ها است. Scikit-Learn اهمیت یک ویژگی را بر اساس میزان کاهش ناخالصی در گره‌هایی که از آن ویژگی استفاده کرده‌اند محاسبه می‌کند و سپس این کاهش را در همهٔ درخت‌های جنگل میانگین می‌گیرد. این میانگین وزن‌دار است و وزن هر گره با تعداد نمونه‌های آموزشی مرتبط با آن تعیین می‌شود.

پس از آموزش، Scikit-Learn این امتیازها را به‌صورت خودکار محاسبه و نرمال می‌کند تا مجموع اهمیت همهٔ ویژگی‌ها برابر ۱ شود. نتیجه در feature_importances_ قرار می‌گیرد. مثال زیر روی Iris نشان می‌دهد طول و عرض گلبرگ به‌ترتیب حدود ۴۴٪ و ۴۲٪ اهمیت دارند، در حالی که طول و عرض کاسبرگ فقط حدود ۱۱٪ و ۲٪ اهمیت دارند:

>>> from sklearn.datasets import load_iris
>>> iris = load_iris(as_frame=True)
>>> rnd_clf = RandomForestClassifier(n_estimators=500, random_state=42)
>>> rnd_clf.fit(iris.data, iris.target)
>>> for score, name in zip(
...     rnd_clf.feature_importances_, iris.data.columns):
...     print(round(score, 2), name)
...
0.11 sepal length (cm)
0.02 sepal width (cm)
0.44 petal length (cm)
0.42 petal width (cm)

اگر جنگل تصادفی روی MNIST آموزش داده شود و اهمیت هر پیکسل روی تصویر نمایش داده شود، نتیجهٔ شکل ۷-۶ به دست می‌آید. نواحی‌ای که در شکل رقم نقش بیشتری دارند اهمیت بیشتری پیدا می‌کنند.

اهمیت پیکسل‌های MNIST از دید Random Forest
شکل 7-6. اهمیت پیکسل‌های MNIST از دید Random Forest

بنابراین Random Forest ابزار مناسبی برای درک سریع ویژگی‌های مؤثر و همچنین انتخاب ویژگی است.

Boosting

Boosting به خانواده‌ای از روش‌های Ensemble گفته می‌شود که چند یادگیرندهٔ ضعیف را به یک یادگیرندهٔ قوی تبدیل می‌کنند. ایدهٔ کلی بیشتر روش‌های Boosting این است که مدل‌ها به‌صورت ترتیبی آموزش داده شوند و هر مدل تلاش کند خطاهای مدل قبلی را اصلاح کند. از معروف‌ترین روش‌ها AdaBoost و Gradient Boosting هستند.

AdaBoost

در AdaBoost هر پیش‌بینی‌کنندهٔ جدید توجه بیشتری به نمونه‌هایی می‌کند که مدل قبلی روی آن‌ها خطا داشته یا کم‌برازش بوده است. در نتیجه با ادامهٔ فرایند، مدل‌های جدید بیشتر روی نمونه‌های دشوار تمرکز می‌کنند.

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

آموزش ترتیبی AdaBoost با به‌روزرسانی وزن نمونه‌ها
شکل 7-7. آموزش ترتیبی AdaBoost با به‌روزرسانی وزن نمونه‌ها

شکل ۷-۸ مرز تصمیم پنج پیش‌بینی‌کنندهٔ متوالی را روی دادهٔ moons نشان می‌دهد. در این نمایش از SVMهای RBF بسیار منظم‌شده فقط برای توضیح ایده استفاده شده است. مدل اول چند نمونه را اشتباه می‌کند و وزن آن نمونه‌ها بیشتر می‌شود؛ مدل دوم بنابراین روی آن موارد تمرکز بیشتری دارد. در نمودار سمت راست نرخ یادگیری نصف شده و وزن خطاها در هر مرحله با شدت کمتری افزایش می‌یابد.

مرزهای تصمیم مدل‌های متوالی AdaBoost
شکل 7-8. مرزهای تصمیم مدل‌های متوالی AdaBoost

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

محدودیت مهم AdaBoost آن است که آموزش مدل‌ها قابل موازی‌سازی نیست؛ هر پیش‌بینی‌کننده فقط پس از آموزش و ارزیابی مدل قبلی ساخته می‌شود. از این رو مقیاس‌پذیری آن از Bagging و Pasting کمتر است.

جزئیات الگوریتم AdaBoost

در ابتدا وزن هر نمونه w⁽ⁱ⁾ برابر 1/m قرار می‌گیرد. نخستین پیش‌بینی‌کننده آموزش می‌بیند و نرخ خطای وزن‌دار آن محاسبه می‌شود:

معادلهٔ ۷-۱ ــ نرخ خطای وزن‌دار پیش‌بینی‌کنندهٔ j

rⱼ = Σi: ŷⱼ⁽ⁱ⁾ ≠ y⁽ⁱ⁾ w⁽ⁱ⁾

سپس وزن خود پیش‌بینی‌کننده با فراپارامتر نرخ یادگیری η محاسبه می‌شود:

معادلهٔ ۷-۲ ــ وزن پیش‌بینی‌کننده

αⱼ = η log((1 − rⱼ) / rⱼ)

هرچه مدل دقیق‌تر باشد، وزن αⱼ بیشتر است. اگر عملکرد آن تقریباً تصادفی باشد وزن به صفر نزدیک می‌شود و اگر اغلب اشتباه کند، وزن می‌تواند منفی شود.

سپس وزن نمونه‌ها به‌روزرسانی می‌شود؛ نمونه‌هایی که مدل اشتباه طبقه‌بندی کرده است وزن بیشتری می‌گیرند:

معادلهٔ ۷-۳ ــ قاعدهٔ به‌روزرسانی وزن

w⁽ⁱ⁾ ← w⁽ⁱ⁾ اگر ŷⱼ⁽ⁱ⁾ = y⁽ⁱ⁾
w⁽ⁱ⁾ ← w⁽ⁱ⁾ exp(αⱼ) اگر ŷⱼ⁽ⁱ⁾ ≠ y⁽ⁱ⁾

پس از آن همهٔ وزن‌ها با تقسیم بر مجموع وزن‌ها نرمال می‌شوند. مدل بعدی با وزن‌های جدید آموزش می‌بیند و فرایند تا رسیدن به تعداد موردنظر پیش‌بینی‌کننده‌ها یا پیدا شدن یک مدل کامل ادامه پیدا می‌کند.

برای پیش‌بینی، خروجی همهٔ مدل‌ها با وزن αⱼ جمع می‌شود و کلاسی که بیشترین رأی وزن‌دار را بگیرد انتخاب می‌شود:

معادلهٔ ۷-۴ ــ پیش‌بینی AdaBoost

ŷ(x) = argmaxk Σj: ŷⱼ(x)=k αⱼ

Scikit-Learn از نسخهٔ چندکلاسه‌ای با نام SAMME استفاده می‌کند که مخفف Stagewise Additive Modeling using a Multiclass Exponential loss است. در مسئلهٔ دودویی، SAMME با AdaBoost معادل است. اگر مدل‌های پایه احتمال کلاس‌ها را برآورد کنند، نسخهٔ SAMME.R می‌تواند از احتمال‌ها به‌جای خود کلاس‌های پیش‌بینی‌شده استفاده کند و معمولاً بهتر عمل می‌کند.

کد زیر AdaBoost با ۳۰ Decision Stump می‌سازد. Decision Stump درختی با max_depth=1 است، یعنی فقط یک گرهٔ تصمیم و دو برگ دارد و Estimator پایهٔ رایج AdaBoost است:

from sklearn.ensemble import AdaBoostClassifier

ada_clf = AdaBoostClassifier(
    DecisionTreeClassifier(max_depth=1),
    n_estimators=30,
    learning_rate=0.5,
    random_state=42
)
ada_clf.fit(X_train, y_train)
اگر AdaBoost روی مجموعهٔ آموزشی بیش‌برازش دارد، می‌توان تعداد Estimatorها را کاهش داد یا مدل پایه را قوی‌تر منظم‌سازی کرد.

آغاز Gradient Boosting

Gradient Boosting نیز مانند AdaBoost مدل‌ها را به‌صورت ترتیبی به Ensemble اضافه می‌کند و هر مدل در پی اصلاح مدل قبلی است. تفاوت این است که به‌جای تغییر وزن نمونه‌ها، مدل جدید روی خطاهای باقیمانده یا Residualهای مدل قبلی برازش می‌شود.

در یک مثال رگرسیون با درخت‌های تصمیم ــ که Gradient Tree Boosting یا GBRT نامیده می‌شود ــ ابتدا داده‌ای درجهٔ دوم و دارای نویز می‌سازیم و نخستین درخت را آموزش می‌دهیم:

import numpy as np
from sklearn.tree import DecisionTreeRegressor

np.random.seed(42)
X = np.random.rand(100, 1) - 0.5
y = 3 * X[:, 0] ** 2 + 0.05 * np.random.randn(100)

tree_reg1 = DecisionTreeRegressor(max_depth=2, random_state=42)
tree_reg1.fit(X, y)

در بخش بعد، درخت‌های بعدی روی Residualهای همین مدل آموزش داده می‌شوند.

پاورقی‌ها و منابع این بخش

  1. Random Patches در پژوهش Gilles Louppe و Pierre Geurts و Random Subspaces در پژوهش Tin Kam Ho معرفی شده‌اند.
  2. منبع اولیهٔ Random Decision Forests مقالهٔ Tin Kam Ho است.
  3. BaggingClassifier همچنان زمانی مفید است که بخواهید Ensembleای از مدلی غیر از درخت تصمیم بسازید.
  4. Extra-Trees در مقالهٔ Extremely Randomized Trees اثر Pierre Geurts و همکاران معرفی شده است.
  5. منبع AdaBoost مقالهٔ Yoav Freund و Robert Schapire با عنوان A Decision-Theoretic Generalization of On-Line Learning and an Application to Boosting است.
  6. در شکل‌های توضیحی از SVM به‌عنوان مدل پایهٔ AdaBoost فقط برای نمایش استفاده شده است؛ SVM در عمل معمولاً مدل پایهٔ مناسبی برای AdaBoost نیست، چون کند و در این ترکیب ناپایدار است.
  7. الگوریتم اصلی AdaBoost فراپارامتر Learning Rate نداشت.
  8. برای نسخهٔ چندکلاسهٔ AdaBoost، منبع به مقالهٔ Multi-Class AdaBoost اثر Ji Zhu و همکاران اشاره می‌کند.
  9. Gradient Boosting ابتدا در مقالهٔ Leo Breiman در ۱۹۹۷ مطرح و سپس در مقالهٔ Jerome H. Friedman با عنوان Greedy Function Approximation: A Gradient Boosting Machine توسعه داده شد.

امتیاز کاربران به این مقاله

☆☆☆☆☆

0 نفر امتیاز داده اند. میانگین: 0.0 از 5

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

0 / 500

اطلاعات تماس

  • آدرس:اصفهان-خیابان ام کلثوم غربی - بعد خیابان تخم چی - بیست متر بعد از پیتزا ننه شب - کوچه تعمیر گاه سمار زغالی - پلاک 354 - درب مشکی - طبقه هفتم
  • آدرس ایمیل:najafzade@gmail.com
  • وب سایت:http://www.a00b.com/
  • تلفن ثابت:(+98)9131253620
  • تلفن همراه:09131253620