رگرسیون با درخت تصمیم
درختهای تصمیم علاوه بر طبقهبندی میتوانند مسائل رگرسیون را نیز حل کنند. در مثال زیر با کلاس DecisionTreeRegressor یک درخت رگرسیون با max_depth=2 روی مجموعهدادهای درجهٔ دوم و دارای نویز آموزش داده میشود:
import numpy as np
from sklearn.tree import DecisionTreeRegressor
np.random.seed(42)
X_quad = np.random.rand(200, 1) - 0.5 # a single random input feature
y_quad = X_quad ** 2 + 0.025 * np.random.randn(200, 1)
tree_reg = DecisionTreeRegressor(max_depth=2, random_state=42)
tree_reg.fit(X_quad, y_quad)
درخت حاصل در شکل ۶-۴ نمایش داده شده است.
شکل 6-4. درخت تصمیم برای رگرسیون
ساختار این درخت بسیار شبیه درخت طبقهبندی پیشین است، اما بهجای پیشبینی یک کلاس، در هر برگ یک مقدار عددی پیشبینی میشود. برای نمونه فرض کنید ورودی جدید x₁ = 0.2 باشد. گرهٔ ریشه بررسی میکند آیا x₁ ≤ 0.197 است یا نه. چون پاسخ منفی است به فرزند راست میرویم. گرهٔ بعد میپرسد آیا x₁ ≤ 0.772 است؛ پاسخ مثبت است و مسیر به برگ چپ میرسد. این برگ مقدار 0.111 را پیشبینی میکند.
مقدار ۰٫۱۱۱ میانگین مقدار هدف ۱۱۰ نمونهٔ آموزشی مرتبط با همین برگ است. میانگین خطای مربعی روی این ۱۱۰ نمونه برابر حدود ۰٫۰۱۵ است.
پیشبینی همین مدل در سمت چپ شکل ۶-۵ دیده میشود. اگر max_depth=3 باشد، پیشبینیهای سمت راست به دست میآیند. مقدار پیشبینیشدهٔ هر ناحیه همیشه میانگین مقدار هدف نمونههای آموزشی همان ناحیه است. الگوریتم تقسیمها را طوری انتخاب میکند که نمونههای هر ناحیه تا حد امکان به مقدار پیشبینیشده نزدیک باشند.
شکل 6-5. پیشبینی دو مدل رگرسیون درخت تصمیم
تابع هزینهٔ CART برای رگرسیون
الگوریتم CART مانند حالت طبقهبندی کار میکند، اما بهجای کمینهکردن ناخالصی، تقسیمهایی را انتخاب میکند که خطای میانگین مربعات یا MSE را کمینه کنند:
معادلهٔ ۶-۴ ــ تابع هزینهٔ CART برای رگرسیون
J(k,tₖ) = (mleft/m) MSEleft + (mright/m) MSEright
MSEnode = Σi∈node(ŷnode − y⁽ⁱ⁾)² / mnode
ŷnode = Σi∈node y⁽ⁱ⁾ / mnode
در رگرسیون نیز درخت تصمیم مستعد بیشبرازش است. اگر از فراپارامترهای پیشفرض و بدون محدودیت استفاده شود، مدل سمت چپ شکل ۶-۶ بهشدت دادهٔ آموزشی را دنبال میکند. فقط با قرار دادن min_samples_leaf=10 مدل بسیار معقولتر سمت راست ایجاد میشود.
شکل 6-6. رگرسیون درخت بدون منظمسازی و منظمشده
حساسیت به جهت محورهای داده
درختهای تصمیم مزایای زیادی دارند: فهم و تفسیر آنها نسبتاً ساده است، استفاده از آنها آسان است، برای مسائل مختلف کاربرد دارند و قدرت زیادی دارند. با این حال، محدودیتهایی نیز دارند. یکی از مهمترین محدودیتها علاقهٔ طبیعی آنها به مرزهای تصمیم عمود بر محورهای ویژگی است؛ بنابراین به جهت قرارگیری داده حساساند.
شکل ۶-۷ یک مجموعهدادهٔ ساده و خطی جداییپذیر را نشان میدهد. در سمت چپ درخت بهراحتی داده را تقسیم میکند. اگر همان داده ۴۵ درجه چرخانده شود، مرز تصمیم سمت راست بدون نیاز واقعی پیچیده میشود. هر دو درخت دادهٔ آموزشی را کاملاً برازش کردهاند، اما احتمال تعمیم ضعیف مدل سمت راست بیشتر است.
شکل 6-7. حساسیت درخت تصمیم به چرخش مجموعهٔ آموزشی
یک راه محدودکردن این مشکل، ابتدا مقیاسبندی داده و سپس اعمال تبدیل PCA است. PCA در فصل ۸ با جزئیات بررسی میشود؛ در اینجا کافی است بدانیم که این تبدیل داده را به شکلی میچرخاند که همبستگی میان ویژگیها را کاهش دهد و در بسیاری از موارد ــ نه همیشه ــ ساخت تقسیمهای مناسب را برای درخت سادهتر کند.
Pipeline زیر داده را مقیاسبندی و با PCA میچرخاند، سپس یک DecisionTreeClassifier آموزش میدهد:
from sklearn.decomposition import PCA
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
pca_pipeline = make_pipeline(StandardScaler(), PCA())
X_iris_rotated = pca_pipeline.fit_transform(X_iris)
tree_clf_pca = DecisionTreeClassifier(max_depth=2, random_state=42)
tree_clf_pca.fit(X_iris_rotated, y_iris)
شکل ۶-۸ مرز تصمیم این درخت را نشان میدهد. پس از چرخش، مدل میتواند فقط با یک ویژگی جدید z₁ که ترکیبی خطی از طول و عرض گلبرگ اصلی است، داده را نسبتاً خوب تفکیک کند.
شکل 6-8. مرزهای تصمیم درخت روی دادهٔ Iris مقیاسبندی و چرخاندهشده با PCA
واریانس بالای درختهای تصمیم
بهطور کلی مشکل اصلی درخت تصمیم واریانس نسبتاً زیاد آن است. تغییر کوچک در فراپارامترها یا حتی تغییر اندک در داده میتواند درخت کاملاً متفاوتی بسازد. الگوریتم آموزشی Scikit-Learn نیز بخشی تصادفی دارد و مجموعهٔ ویژگیهای مورد ارزیابی در هر گره را بهصورت تصادفی انتخاب میکند؛ بنابراین حتی آموزش دوبارهٔ همان درخت روی همان داده میتواند مدل متفاوتی تولید کند، مگر آنکه random_state مشخص شده باشد.
شکل ۶-۹ نمونهای از آموزش دوبارهٔ همان مدل را نشان میدهد که ساختاری بسیار متفاوت با شکل ۶-۲ دارد.
شکل 6-9. آموزش دوباره همان مدل ممکن است درخت متفاوتی بسازد
خوشبختانه میتوان با میانگینگیری یا تجمیع پیشبینیهای تعداد زیادی درخت، واریانس را بهشدت کاهش داد. مجموعهای از درختها با این ایده جنگل تصادفی نامیده میشود و در فصل بعد بررسی خواهد شد.
تمرینهای فصل ۶
- عمق تقریبی یک درخت تصمیم بدون محدودیت که روی مجموعهای با یک میلیون نمونه آموزش داده شده است چقدر خواهد بود؟
- آیا ناخالصی Gini یک گره معمولاً از والد آن کمتر است یا بیشتر؟ آیا این رابطه همیشه برقرار است یا فقط در حالت معمول؟
- اگر درخت تصمیم روی دادهٔ آموزشی بیشبرازش دارد، آیا کاهش
max_depth اقدام مناسبی است؟
- اگر درخت تصمیم کمبرازش دارد، آیا مقیاسبندی ویژگیهای ورودی راهحل مناسبی است؟
- اگر آموزش یک درخت روی یک میلیون نمونه یک ساعت طول بکشد، با توجه به پیچیدگی CART، آموزش روی ده میلیون نمونه تقریباً چقدر طول خواهد کشید؟
- اگر آموزش روی مجموعهای مشخص یک ساعت طول بکشد، دو برابر شدن تعداد ویژگیها زمان را تقریباً چگونه تغییر میدهد؟
- برای مجموعهٔ
moons یک درخت تصمیم را آموزش و تنظیم کنید:
- با
make_moons(n_samples=10000, noise=0.4) داده بسازید.
- با
train_test_split() آن را به آموزش و آزمون تقسیم کنید.
- با
GridSearchCV و Cross-Validation فراپارامترهای مناسب DecisionTreeClassifier را پیدا کنید؛ مقادیر مختلف max_leaf_nodes را آزمایش کنید.
- مدل را با بهترین فراپارامترها روی کل مجموعهٔ آموزشی آموزش دهید و دقت آزمون را اندازه بگیرید؛ نتیجه باید حدود ۸۵ تا ۸۷ درصد باشد.
- یک «جنگل» بسازید:
- با ادامهٔ تمرین قبل، هزار زیرمجموعهٔ تصادفی از دادهٔ آموزشی بسازید که هر کدام ۱۰۰ نمونه دارند؛ میتوانید از
ShuffleSplit استفاده کنید.
- روی هر زیرمجموعه یک درخت با بهترین فراپارامترهای تمرین قبل آموزش دهید و هر هزار درخت را روی آزمون ارزیابی کنید. چون هر درخت دادهٔ کمتری دیده است، دقت هرکدام احتمالاً حدود ۸۰٪ و کمتر از درخت اصلی خواهد بود.
- برای هر نمونهٔ آزمون، پیشبینی هر هزار درخت را بگیرید و پرتکرارترین کلاس را نگه دارید؛ برای این کار میتوان از
scipy.stats.mode() استفاده کرد. این همان رأی اکثریت است.
- پیشبینی تجمیعی را ارزیابی کنید. دقت باید حدود ۰٫۵ تا ۱٫۵ درصد از درخت اولیه بهتر شود. با این کار عملاً یک طبقهبند جنگل تصادفی ساختهاید.
راهحل تمرینهای فصل در Notebook تکمیلی کتاب ارائه شده است.