Random Forest و XGBoost
مدلهای ensemble برای پیشبینی.
Random Forest و XGBoost: مدلهای Ensemble برای پیشبینی بازارهای مالی
هدف یادگیری
پس از مطالعه این درس، قادر خواهید بود:
- معماری ریاضی Random Forest و XGBoost را درک کرده و تفاوتهای بنیادین آنها را توضیح دهید.
- توابع loss و مکانیزم gradient boosting را برای دادههای سری زمانی مالی فرموله کنید.
- هایپرپارامترهای کلیدی هر دو مدل را برای دادههای OHLCV بهینهسازی کنید.
- Feature importance را تفسیر کرده و از آن برای ساخت سیگنال تریدینگ استفاده کنید.
---
۱. پایههای Ensemble Learning: چرا یک مدل کافی نیست؟
در بازارهای مالی، هیچ مدل تکی نمیتواند تمام الگوهای پنهان در داده را کشف کند. این مشکل را با مفهوم bias-variance tradeoff میشناسیم:
$$\text{MSE}(\hat{f}) = \text{Bias}^2(\hat{f}) + \text{Var}(\hat{f}) + \sigma^2_\epsilon$$
یک مدل ساده (مثل درخت تصمیم کمعمق) بایاس بالا دارد و الگوهای پیچیده بازار را از دست میدهد. یک مدل عمیق واریانس بالا دارد و به نوید دادههای آموزشی overfit میشود.
روشهای Ensemble این معضل را با ترکیب چندین مدل ضعیف حل میکنند. دو رویکرد اصلی وجود دارد:
- Bagging (Bootstrap Aggregating): مدلها موازی آموزش میبینند و نتایجشان میانگینگیری میشود → Random Forest
- Boosting: مدلها سری آموزش میبینند و هر مدل اشتباهات مدل قبلی را اصلاح میکند → XGBoost
در بازار کریپتو که نوسان ذاتی و رژیمهای مختلف (trending, ranging, volatile) وجود دارد، این تمایز اهمیت بسیار زیادی پیدا میکند.
---
۲. Random Forest: ریاضیات Bagging و Decorrelation
ساختار معماری
Random Forest مجموعهای از $B$ درخت تصمیم است که هر کدام روی یک bootstrap sample آموزش دیدهاند. پیشبینی نهایی برای رگرسیون:
$$\hat{f}_{RF}(x) = \frac{1}{B} \sum_{b=1}^{B} T_b(x)$$
واریانس این estimator:
$$\text{Var}\left(\frac{1}{B}\sum_{b=1}^{B} T_b\right) = \frac{\rho \sigma^2 (B-1) + \sigma^2}{B} = \sigma^2\left(\rho + \frac{1-\rho}{B}\right)$$
که $\rho$ همبستگی بین درختان و $\sigma^2$ واریانس هر درخت است. با $B \to \infty$، واریانس به $\rho\sigma^2$ میل میکند. بنابراین کاهش همبستگی بین درختان (decorrelation) کلید اصلی موفقیت است.
Random Forest این کار را با random feature selection انجام میدهد: در هر split، فقط $m = \sqrt{p}$ ویژگی از $p$ ویژگی کل بررسی میشود.
Out-of-Bag Error و اهمیت آن در مالی
هر درخت روی ~63% دادهها (bootstrap) آموزش میبیند. دادههای باقیمانده (OOB) یک ارزیابی unbiased بدون نیاز به validation set جداگانه میدهند:
$$\text{OOB Error} = \frac{1}{N}\sum_{i=1}^{N}\left(y_i - \hat{f}^{(-i)}(x_i)\right)^2$$
در دادههای سری زمانی مالی، این ویژگی مهم است چون نمیتوان به سادگی داده را به train/test تقسیم کرد بدون اینکه temporal leakage ایجاد شود.
Feature Importance در Random Forest
دو روش اصلی وجود دارد:
۱. MDI (Mean Decrease in Impurity):
$$\text{Imp}(X_j) = \frac{1}{B}\sum_{b=1}^{B}\sum_{t \in T_b : v(t)=j} p(t) \cdot \Delta I(t)$$
که $p(t)$ نسبت نمونههای رسیده به گره $t$ و $\Delta I(t)$ کاهش ناخالصی است.
۲. MDA (Mean Decrease in Accuracy / Permutation Importance): ویژگی $j$ را permute کرده و کاهش دقت را اندازه میگیریم. این روش bias کمتری دارد و برای ویژگیهای با cardinality بالا (مثل volume در کریپتو) قابل اعتمادتر است.
---
۳. XGBoost: Gradient Boosting با بهینهسازی دقیق
فرمولبندی کلی Boosting
در Gradient Boosting، مدل به صورت additive ساخته میشود:
$$\hat{y}_i^{(t)} = \hat{y}_i^{(t-1)} + \eta \cdot h_t(x_i)$$
که $h_t$ درخت جدید و $\eta$ learning rate است. هر درخت جدید برای minimize کردن loss روی residuals آموزش میبیند:
$$L^{(t)} = \sum_{i=1}^{N} l\left(y_i, \hat{y}_i^{(t-1)} + h_t(x_i)\right) + \Omega(h_t)$$
بسط Taylor و نوآوری XGBoost
XGBoost با بسط Taylor مرتبه دوم، تابع هدف را تقریب میزند:
$$L^{(t)} \approx \sum_{i=1}^{N}\left[l(y_i, \hat{y}^{(t-1)}) + g_i h_t(x_i) + \frac{1}{2}h_i h_t^2(x_i)\right] + \Omega(h_t)$$
که:
- $g_i = \partial_{\hat{y}^{(t-1)}} l(y_i, \hat{y}^{(t-1)})$ — gradient (شبیه residual اما کلیتر)
- $h_i = \partial^2_{\hat{y}^{(t-1)}} l(y_i, \hat{y}^{(t-1)})$ — hessian (اطلاعات curvature)
ترم regularization:
$$\Omega(h) = \gamma T + \frac{1}{2}\lambda\sum_{j=1}^{T}w_j^2$$
که $T$ تعداد برگها و $w_j$ وزن هر برگ است.
مقدار بهینه برگها
پس از سادهسازی، وزن بهینه برگ $j$:
$$w_j^* = -\frac{G_j}{H_j + \lambda}$$
و gain بهینه برای هر split:
$$\text{Gain} = \frac{1}{2}\left[\frac{G_L^2}{H_L+\lambda} + \frac{G_R^2}{H_R+\lambda} - \frac{(G_L+G_R)^2}{H_L+H_R+\lambda}\right] - \gamma$$
این معادله دقیقاً میگوید XGBoost چه زمانی یک split انجام میدهد: وقتی gain بزرگتر از $\gamma$ باشد. این پارامتر $\gamma$ مستقیماً عمق درخت و پیچیدگی مدل را کنترل میکند.
---
۴. کاربرد در بازار کریپتو: Feature Engineering و Target Definition
تعریف Target متناسب با بازار
انتخاب target در مالی از ساختار مدل مهمتر است. چند رویکرد:
بازده لگاریتمی:
$$r_t = \ln\left(\frac{P_{t+h}}{P_t}\right)$$
Triple-Barrier Method (پیشنهاد لوپز د پرادو):
به جای پیشبینی بازده خام، label به سه دسته تقسیم میشود:
- +1: قیمت به take-profit برسد قبل از stop-loss
- -1: قیمت به stop-loss برسد قبل از take-profit
- 0: در بازه زمانی مشخص هیچکدام لمس نشود
این روش برای کریپتو که نوسان شدید دارد بسیار مناسبتر از regression خام است.
Feature Engineering برای OHLCV
ویژگیهای استاندارد برای مدلهای ensemble:
python
Technical Features
features = [
'rsi_14', 'rsi_7',
'macd_signal', 'macd_hist',
'bb_width', # Bollinger Band width
'atr_14', # Average True Range
'volume_ratio', # volume / rolling_mean(volume, 20)
'obv_slope', # On-Balance Volume slope
# Microstructure
'spread_pct', # (high - low) / close
'close_location', # (close - low) / (high - low)
# Regime Features
'realized_vol_20',
'vol_of_vol', # std(realized_vol)
'trend_strength', # ADX
]
نکته مهم برای سری زمانی: همه features باید از lag استفاده کنند تا از look-ahead bias جلوگیری شود:
python
df['rsi_14'] = df['rsi_14'].shift(1) # از کندل قبل استفاده کن
---
۵. پیادهسازی و بهینهسازی هایپرپارامترها
Purged Cross-Validation برای دادههای مالی
استفاده از k-fold standard در سری زمانی منجر به information leakage میشود. باید از Purged Walk-Forward CV استفاده کرد:
python
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(
n_splits=5,
gap=24 # 24 ساعت فاصله بین train و test
)
هایپرپارامترهای کلیدی Random Forest
| پارامتر | محدوده توصیهشده | تأثیر |
|---------|-----------------|-------|
| n_estimators | 200–1000 | واریانس را کاهش میدهد |
| max_features | sqrt(p) تا log2(p) | decorrelation درختان |
| max_depth | 5–15 | overfitting |
| min_samples_leaf | 5–50 | regularization |
هایپرپارامترهای کلیدی XGBoost
| پارامتر | محدوده توصیهشده | تأثیر |
|---------|-----------------|-------|
| learning_rate | 0.01–0.1 | speed vs. quality |
| n_estimators | 500–2000 | با early stopping |
| max_depth | 3–7 | complexity |
| subsample | 0.6–0.9 | مانع overfitting |
| colsample_bytree | 0.5–0.8 | feature randomization |
| gamma | 0–5 | minimum split gain |
| lambda | 1–10 | L2 regularization |
python
xgb_params = {
'objective': 'binary:logistic', # برای classification
'eval_metric': 'logloss',
'learning_rate': 0.05,
'n_estimators': 1000,
'max_depth': 5,
'subsample': 0.8,
'colsample_bytree': 0.7,
'gamma': 1.0,
'lambda': 2.0,
'early_stopping_rounds': 50
}
SHAP Values برای تفسیر مدل
برای درک اینکه چرا مدل یک پیشبینی خاص داده، از SHAP (SHapley Additive exPlanations) استفاده میکنیم:
$$\phi_i(f) = \sum_{S\subseteq F\setminus\{i\}} \frac{|S|!(|F|-|S|-1)!}{|F|!}\left[f(S\cup\{i\}) - f(S)\right]$$
SHAP مقدار کمک واقعی هر feature به پیشبینی را محاسبه میکند. برای تریدینگ این به معنی فهمیدن است که آیا RSI، volume، یا volatility در یک لحظه خاص بیشترین تأثیر را داشتهاند.
---
۶. مقایسه عملی و انتخاب مدل مناسب
Random Forest بهتر است وقتی:
- دادههای کم داریم (overfitting کمتر) - سرعت inference مهم است (parallelizable) - features دارای nonlinear interactions هستند - رژیمهای بازار ناپایدار و شدید هستند (robustness)XGBoost بهتر است وقتی:
- دادههای زیاد با noise کم داریم - دقت بالا اولویت است - میخواهیم روابط ضعیفتر بین features کشف شوند - custom loss function داریم (مثل Sharpe-based loss)Custom Loss برای مالی
یکی از مزایای XGBoost امکان تعریف custom objective است. برای maximize کردن Sharpe ratio به جای minimize کردن MSE:
python
def sharpe_objective(y_pred, dtrain):
y_true = dtrain.get_label()
returns = y_true * np.sign(y_pred)
sharpe = returns.mean() / (returns.std() + 1e-8)
# Gradient
grad = -y_true / (returns.std() + 1e-8)
# Hessian (تقریب)
hess = np.ones_like(grad) * 0.01
return grad, hess
این رویکرد مدل را مستقیماً برای هدف مالی (نه statistical accuracy) بهینه میکند.
---
نتیجهگیری
Random Forest و XGBoost دو ابزار قدرتمند ensemble هستند که هر کدام معماری متفاوتی برای مقابله با bias-variance tradeoff دارند. Random Forest با parallelism و robustness، و XGBoost با دقت بالا و انعطاف در تعریف objective، هر دو در arsenal یک quant trader جایگاه دارند.
تفاوت اصلی در تولید پولساز نهایی نیست — بلکه در feature engineering و target definition است. مدلهای ensemble نیرومند هستند اما بدون triple-barrier labeling، purged cross-validation، و SHAP analysis، به سادگی overfit میشوند و در live trading عملکرد ضعیف دارند.
---
خلاصه نقطهای
- Bagging (RF) vs. Boosting (XGBoost): موازی با decorrelation در برابر سری با error correction
- فرمول کلیدی RF: واریانس نهایی به $\rho\sigma^2$ میل میکند — کاهش $\rho$ با random feature selection
- فرمول کلیدی XGBoost: وزن بهینه برگ $w^* = -G_j/(H_j+\lambda)$ و gain هر split با hessian تنظیم میشود
- Target: Triple-barrier method برای کریپتو بهتر از regression خام است
- Validation: Purged Walk-Forward CV اجباری است — k-fold standard منجر به data leakage میشود
- Interpretability: SHAP values سهم واقعی هر feature را با مبنای تئوری بازی محاسبه میکند
- Custom Loss: XGBoost اجازه میدهد مستقیماً برای Sharpe یا سایر متریکهای مالی بهینهسازی کنیم
- انتخاب مدل: RF برای robustness و کمداده، XGBoost برای دقت و دادههای فراوان