XGBoost for Return Direction: Class Imbalance and Decision Thresholds
Кийинки сааттын кирешеси +0,5%дан ашарын алдын ала айтуу үчүн классификаторду үйрөтүңүз жана сиз тең салмактуу бинардык маселени кура элексиз. Тынч крипто режимдеринде тилкелердин 70--80% босогодон төмөн түшөт, ошондуктан модель эч качан бир позитивди алдын ала айтуу менен 75% тактыкка ээ болот. Бул жерде тактык пайдасыз. Демейки 0,5 чечим чеги да ошондой, аны эч ким атайылап тандап алган эмес - бул маани predict() колдонууга учурайт.
Үч стандарттуу жооп бар: жоготууну scale_pos_weight менен кайра салмактоо, жоготууну фокустук жоготууга алмаштыруу же жоготууну өзгөртпөй, чечим босогосун кийин жылдыруу. Адатта булар бири-бирин алмаштыра алат деп көрсөтүлөт. Чынында андай эмес. Алар тактык менен кайра табуунун ар башка тең салмактарын жана, андан да маанилүүсү, чыгымдан кийинки ар башка PnL берет, анткени соода кайра табууга караганда тактыкка көбүрөөк маани берет: өткөрүп жиберилген соода эч нерсе талап кылбайт, ал эми начар соода спред менен комиссияга чыгым болот.
Бул макала үчөөнү тең бир сааттык BTC жана ETH маалыматтарынын бирдей тазаланган бүктөмдөрүндө өлчөйт, андан кийин андан кийинки эки нерсени камтыйт: эмне үчүн min_child_weight бул саптардын санына караганда Гессиан босогосу (ошондуктан жоготууну кайра өлчөгөндө "туура" маани өзгөрөт) жана XGBoost, LightGBM жана CatBoost иш жүзүндө айырмаланат.
| Ыкма | Тактык | Кайра табуу | Соодалар | Чыгымдан кийинки PnL | Дефляцияланган Sharpe |
|---|---|---|---|---|---|
| Базалык (оңдоо жок, thr=0,5) | — | — | — | — | — |
scale_pos_weight = n_neg/n_pos |
— | — | — | — | — |
| Фокалдык жоготуу (γ=2, α=0,25) | — | — | — | — | — |
| Босогону оптималдаштыруу (минималдуу тактык 0,55) | — | — | — | — | — |
Бардык саптарда бүктөмдөр, белгилер жана чыгым модели бирдей. Sharpe текшерилген конфигурациялардын саны эске алынып дефляцияланат, ал эми чыгымдар тайгалануу жана чыгым моделдерине ылайык эсептелет.
Кайтарым багытындагы класстар дисбалансын оңдоо

1-ыкма: scale_pos_weight менен кайра салмактоо
Эң жөнөкөй ыкма — scale_pos_weight = n_negative / n_positive коюу:
n_pos = y_train.sum()
n_neg = len(y_train) - n_pos
scale_pos_weight = n_neg / n_pos # e.g., 3.0 if 75% negative
model = xgb.XGBClassifier(
scale_pos_weight=scale_pos_weight,
...
)
Бул оң класстагы үлгүлөрдүн градиентин масштабдайт да, модель үчүн оң мисалды туура эмес классификациялоо терс мисалды туура эмес классификациялоого караганда эсе кымбат болот.
Көзгө дароо урунбаган терс таасири да бар: Hessian'дар да кайра салмактанат. min_child_weight жалбырактагы Hessian суммасынын босогосу болгондуктан (төмөндө караңыз), жоготууну кайра салмактоо дарактын канчалык агрессивдүү бөлүнөрүн үнсүз өзгөртөт. scale_pos_weight=1 менен жөндөлгөн min_child_weight scale_pos_weight=3 болгондо ошол эле маанини билдирбейт. Экөөнү өз-өзүнчө эмес, бирге кайра жөндөө керек.
Экинчи терс таасири — чыгарылган ыктымалдыктар калибрленбейт. predict_proba чыныгы ыктымалдыкка монотондуу байланышта болгон, бирок ага тең эмес маанилерди кайтарат; демек, ошол сандарга негизделген кийинки позиция өлчөмү бурмаланат.
2-ыкма: Фокалдык жоготуу
Фокустук жоготуу класска карабастан жеңил мисалдардын салмагын азайтып, окутууну оор жана туура эмес классификацияланган мисалдарга бурат. Бул кайтарымды болжолдоого ылайыктуу ыкмадай көрүнөт: +0,5% менен +0,4% тилкенин айырмасы негизинен ызы-чуу. Бирок "так эмес учурларга көңүл буруу" менен "үйрөнүүгө болбой турган учурларга көңүл буруу" бир эле көрсөтмө болуп калат; энбелгилер ызы-чуу болгондо бул үйрөнүүдөн көрө өлчөөгө айланат.
мында — чыныгы класс үчүн болжолдонгон ыктымалдык, класстардын салмагын теңдейт, ал эми (адатта 1--3) жеңил мисалдардын салмагын канчалык азайтууну башкарат.
def focal_loss_objective(y_true, y_pred, gamma=2.0, alpha=0.25):
"""
Custom focal loss for XGBoost. Returns gradient and hessian.
"""
p = 1.0 / (1.0 + np.exp(-y_pred)) # sigmoid
g1 = alpha * y_true * (1 - p)**gamma * (gamma * p * np.log(p + 1e-9) + p - 1)
g2 = (1 - alpha) * (1 - y_true) * p**gamma * (
-gamma * (1 - p) * np.log(1 - p + 1e-9) - p
)
grad = -(g1 + g2)
hess = np.maximum(grad * (1 - grad), 1e-6)
return grad, hess
model = xgb.XGBClassifier(objective=focal_loss_objective, ...)
Ыңгайлаштырылган максаттарда жалбырактын салмагын эсептеген формула иштеши үчүн градиент жана оң Hessian керек. Фокустук жоготуунун так экинчи туундусу бардык жерде оң боло бербейт, ошондуктан ишке ашыруулар суррогатка кайрылат. Бирок масштабдоо суррогаттык кадамдын өлчөмүн өзгөртөт, ал эми Hessian суммасы аркылуу min_child_weight параметринин маанисин да өзгөртөт. Муну бир гана салыштыруу таблицасы эмес, иш жүзүндөгү чыгымдар менен текшерүү керек.
3-ыкма: Босогону оптималдаштыруу
Жоготууларды жалгыз калтырыңыз, калибрленген моделди үйрөтүңүз жана валидация топтомундагы чечим босогосун жылдырыңыз:
from sklearn.metrics import precision_recall_curve
def optimize_threshold(y_true, y_proba, min_precision=0.55):
"""
Find the threshold maximizing F1 subject to a minimum precision.
"""
precisions, recalls, thresholds = precision_recall_curve(y_true, y_proba)
f1_scores = 2 * (precisions * recalls) / (precisions + recalls + 1e-9)
valid = precisions[:-1] >= min_precision
if not valid.any():
return 0.5 # fallback
best_idx = np.argmax(f1_scores[:-1] * valid)
return thresholds[best_idx]
Тактыктын минималдуу деңгээли соода үчүн маанилүү. F1ди гана максималдаштыруу кайра табууга карай тактыкты курмандыкка чалат; PnL жагынан бул ар бири спред төлөгөн ашыкча соодалардын көбөйүшүн билдирет. Тактыкты чектеп, анын шартында кайра табууну максималдаштыруу "азыраак соода кыл, бирок соода кылганда туура бол" деген стратегияга туура келет.
Эки эреже бул чынчылдыкты сактайт: машыгуу терезесинен кийин хронологиялык түрдө турган валидация маалыматтарынын босогосун тууралаңыз жана аны ар бир бүктөмгө кайра орнотуңуз. Бүткүл үлгү боюнча бир жолу тандалган босого алдын ала көз салуу таксономиясында каталогдо көрсөтүлгөн түрдөгү алдыга карай агып кетүү болуп саналат. Ар бир бүктөмдү кайра орнотуу акысыз диагностиканы да берет — эгер оптималдуу босого бүктөлмөлөр аркылуу өтүп кетсе, калибрлөө туруксуз жана босого ызы-чуу болуп саналат.
Эмне үчүн min_child_weight саптардын саны эмес, Hessian суммасы

Градиенттик күчөтүү кошумча ансамбль түзөт. -кадамда ал XGBoost экинчи тартиптеги Тейлор кеңейтүүсү менен жакындаткан регуляризацияланган максатты минималдаштырган дарагын кошот:
мында , , ошондой эле
мында — жалбырактардын саны, — жалбырактын салмагы, — ар бир жалбырак үчүн айып, ал эми — L2 мүчөсү. Оптималдуу жалбырак салмагы болот.
Hessian суммасы бөлүү эрежесинин бөлгүчүндө турат. Ошондуктан min_child_weight жалбырактагы саптардын санын эмес, ушул сумманы чектейт. Логистикалык жоготууда ; ал болгондо эң чоң болуп, болжолдор ишенимдүү болгон сайын нөлгө жакындайт. Демек, ишенимдүү классификацияланган тилкелерге толгон жалбырактын Hessian суммасы кичине болуп, ал кыркылат, ал эми бир нече чындап күмөндүү тилкени камтыган жалбырак сакталып калышы мүмкүн.
Ызы-чуулуу каржы энбелгилери үчүн бул сиз каалаган жүрүм-турум жана ал практикалык кесепеттерди түшүндүрөт:
min_child_weightбир нече белгисиз байкоого таянган жалбырактарды кырка алат — дал ошол байкоолор ызы-чуу болушу мүмкүн. Булmin_child_samplesсыяктуу саптарды саноого караганда курчураак курал.- Жоготуунун масштабын өзгөрткөн нерсе Hessian'дардын масштабын да өзгөртөт.
scale_pos_weight, ыңгайлаштырылган максаттар жана үлгү салмактары терилген сан өзгөрбөсө да,min_child_weightпараметринин натыйжалуу маанисин өзгөртөт. - Кирешелер жана болжолдор курчуп, ишеним көбөйгөн сайын Hessian'дар глобалдык деңгээлде кичирейет. Ошондуктан туруктуу
min_child_weightкийинки раунддарда дарактарды дагы агрессивдүү бөлөт. Бул жашыруун күйдүрүү эффекти: көбүрөөк дарак жана төмөнүрөөк окуу ылдамдыгы азыраак, чоңураак кадамдардан башкача жүрөт.
LightGBM'деги min_child_samples саптардын санын чектейт, демек аттары окшош болгону менен бул чындап башка параметр. Анын Hessian боюнча аналогу — min_sum_hessian_in_leaf. Эки китепкананын конфигурациясын аттарын гана дал келтирип көчүрүү моделди байкабай өзгөртүүнүн кеңири таралган жолу.
XGBoost жана LightGBM жана CatBoost: Инженердик айырмачылыктар

Үчөө тең градиенттик күчөтүлгөн чечим дарактарын ишке ашырат. Айырмачылык дарактардын кандай курулушунда; ал окутуу убактысында жана үлгүдөн тышкаркы баалоодо көрүнөт.
XGBoost даракты деңгээл боюнча (кеңдик боюнча биринчи) өстүрөт: берилген тереңдиктеги бардык жалбырактар кийинки деңгээлге өтмөйүнчө бөлүнөт. Натыйжада дарактар тең салмактуу болуп, max_depth татаалдыкты жана жөндөөнү алдын ала башкарууга мүмкүндүк берет. Бирок ал азыраак жоготууну бере турган жалбырактарды да бөлүүгө жумуш коротот.
LightGBM жалбырак боюнча өсөт: кайсы жалбырак жайгашканына карабай, жоготууну эң көп азайткан жалбыракты бөлөт. Азыраак бөлүнүү менен эле ошол эле окутуу жоготуусуна жетет, бирок дарактар терең жана тең салмаксыз болуп калат. Ошондуктан негизги башкаруу баскычы max_depth эмес, num_leaves болот. Ылдамдыкты дагы эки ыкма жогорулатат:
- GOSS (градиентке негизделген бир тараптуу үлгү алуу) чоң градиенттүү бардык инстанцияларды сактап, кичине градиенттүүлөрдү кокусунан тандап алат; аман калгандардын салмагын көбөйтүү градиенттин баасын калыс сактайт. Финансылык маалыматта чоң градиенттүү инстанциялар модель азыр ката кетирип жаткан тилкелер, башкача айтканда энбелги ызы-чуусу жашаган жер болушу мүмкүн. Ошондуктан GOSS тандап алууну ызы-чуу эң күчтүү аймакка топтойт. Аны жөнөкөй субүлгү алуу менен салыштырып текшерүү керек.
- EFB (Exclusive Feature Bundling) бири-бирине эксклюзивдүү сейрек белгилерди бир кеңдикке бириктирет. Бул one-hot коддоодо натыйжалуу, бирок тыгыз үзгүлтүксүз белгилерде дээрлик пайдасыз — мындай матрицалардын көпчүлүгү ушундай.
CatBoost симметриялуу (oblivious) дарактарды өстүрөт: берилген тереңдиктеги ар бир түйүн бирдей бөлүү шартын колдонот. Бул күчтүү регуляризатор жана тыянак чыгарууну тездетет — дарак индекстик издөөгө айланат — бирок ар бир дарактын экспрессивдүүлүгүн чектейт. Анын эки айырмалоочу механизми бар:
- Иреттелген күчөтүү. Кадимки күчөтүү ошол эле үлгүдө окутулган модель менен калдыктарды эсептеп, калдыкты бир жактуу кылат — бул "болжолдоо жылышы". CatBoost ар бир үлгүнүн калдыгын кокус аралаштырууда өзүнөн мурун турган үлгүлөр менен гана окутулган модель аркылуу баалайт. Бул түзүлүш убакыт сериялары үчүн табигый ылайыктуу жана маалымат аз болгондо өзгөчө маанилүү.
- Категориялык коддоо үчүн иреттелген максат статистикасы максат статистикасын мурунку үлгүлөрдөн гана эсептейт. Ошентип, жөнөкөй орточо коддоодогу максат агып кетүүсүнөн сактайт. Биржа, актив деңгээли же режим энбелгилери белгилердин арасында болсо, CatBoost колдонууга ушул негиздүү себеп болот.
| Касиет | XGBoost | LightGBM | CatBoost |
|---|---|---|---|
| Дарактын өсүшү | Деңгээл боюнча | Жалбырак боюнча | Симметриялык (oblivious) |
| Татаалдуулук баскычы | max_depth |
num_leaves |
depth |
| Жалбырак өлчөмүндөгү коргоочу | min_child_weight (Гессиан) |
min_child_samples (саптар) |
min_data_in_leaf (саптар) |
| Категориялык белгилер | Кол менен коддоо | Негизги колдоо | Камтылган, иреттелген TS |
| Регуляризация | L1/L2 + gamma | L1/L2 + жалбырак саны | L2 + кокустук күчөтүү |
| Ыңгайлаштырылган жоготуу | Ийкемдүү | Ийкемдүү | Бир аз чектелген |
| Окутуу убактысы, ушул маалымат топтому | — | — | |
| Ошол эле бүктөмдөрдөгү OOS logloss | — | — |
Алгачкы саптар — китепканалардын туруктуу өзгөчөлүктөрү. Акыркы эки сап "кайсынысын колдонушум керек?" деген суроого жооп берет жана алар сиздин маалыматтарыңыздан өлчөнүшү керек. Жакшы жөндөлгөн ишке ашыруулардын айырмасы адатта маалымат топтомунун түзүлүшү аныктай тургандай кичине болот.
Китепкананы алмаштыруу көбүнчө аттарды гана өзгөртүү эмес. Төмөндө бир эле машыгуу функциясы параметрлердин айырмасын көрсөтөт:
import xgboost as xgb
def train_xgb_model(X_train, y_train, X_val, y_val, class_weight_ratio=1.0):
"""Train XGBoost classifier for return direction prediction."""
model = xgb.XGBClassifier(
n_estimators=2000,
max_depth=5,
learning_rate=0.01,
subsample=0.7,
colsample_bytree=0.7,
min_child_weight=10, # Hessian sum, not row count
gamma=1.0,
reg_alpha=0.1,
reg_lambda=1.0,
scale_pos_weight=class_weight_ratio,
objective='binary:logistic',
eval_metric='logloss',
tree_method='hist',
random_state=42,
early_stopping_rounds=50,
)
model.fit(X_train, y_train, eval_set=[(X_val, y_val)], verbose=False)
return model
| Концепция | XGBoost | LightGBM | CatBoost |
|---|---|---|---|
| Дарак саны | n_estimators |
n_estimators |
iterations |
| L2 пенальти | reg_lambda |
reg_lambda |
l2_leaf_reg |
| Мамычаларды тандоо | colsample_bytree |
colsample_bytree |
rsm |
| Класстык дисбаланс | scale_pos_weight |
scale_pos_weight |
auto_class_weights='Balanced' |
| Эрте токтотуу | early_stopping_rounds |
lgb.early_stopping() кайра чалуу |
early_stopping_rounds |
Альфанын өчүшүн аныктоочу бүктөмдөрдөгү SHAP мааниси

Блогдо градиенттик күчөтүү моделиндеги SHAP, TreeExplainer, жыйынтык графиктер жана аларды окуу жолу баяндалган. Бул жерде SHAP'ты убакыт боюнча колдонуу каралат: ар бир walk-forward бүктөмү үчүн бир түшүндүргүч түзүлүп, ар бир белгинин орточо абсолюттук атрибуциясы убакыт өтүшү менен көзөмөлдөнөт.
def shap_over_time(models, test_sets, feature_names) -> pd.DataFrame:
"""
Track SHAP-based feature importance across walk-forward folds.
Rows are folds, columns are features.
"""
importance_over_time = []
for fold_idx, (model, X_test) in enumerate(zip(models, test_sets)):
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_test)
mean_abs_shap = np.abs(shap_values).mean(axis=0)
importance_over_time.append(
pd.Series(mean_abs_shap, index=feature_names, name=fold_idx)
)
return pd.DataFrame(importance_over_time)
Чыгуу бүктөлгөн × өзгөчөлүк матрицасы жана анда үч айырмаланган форма бар:
- Бир калыпта төмөндөө — белгинин артыкчылыгы өчүп жатат. Белгини алып салууга же рынок түзүмүндө эмне өзгөргөнүн иликтөөгө талапкер.
- Жогорку дисперсия, тенденция жок — модель айрым режимдерде жабышып калган ызы-чуу белги. Бул параметрлер үчүн плато талдоосу берген сандык көрсөткүчтөрдү белгилерге колдонууга окшош.
- Режим алмашкандагы секирик — маанилүүлүк белгилүү бир бүктөмдө төмөндөп, кайра калыбына келбейт. Көп учурда мунун себеби альфа өчүшү эмес, биржа, листинг же комиссия түзүмүндөгү окуя болот.
Мындагы тузак — моделдин жалпы ишеним деңгээли өзгөргөндө бүктөмдөрдөгү орточо абсолюттук SHAP маанилерин түз салыштыруу мүмкүн эмес. Бардык жерде 0,5ке жакын болжол чыгарган модель бир убакта бардык белгилер үчүн кичине атрибуция берет. Салыштыруудан мурун ар бир бүктөмдүн маанилүүлүктөрүн суммасы 1 болчудай нормалдаштырыңыз; ошондо ишенимдин жылышын эмес, салыштырмалуу маанилүүлүктүн өзгөрүшүн окуйсуз.
Эмне үчүн дарактар? Кыскача

Grinsztajn, Oyallon жана Varoquaux (NeurIPS 2022) дарак ансамблдерин 45 таблицалык маалымат топтомунда терең үйрөнүү менен салыштырып, дарактарга артыкчылык берген үч түзүмдүк касиетти бөлүп көрсөтүшкөн. Үчөө тең каржылык маалыматка мүнөздүү:
- Түз эмес максат функциялары. Кирешелер жылмакай эмес: үзүлүүлөр, режим алмашуулар жана босого эффекттери бар. Окко параллелдүү бөлүнүүлөр аларды жылмакай бетке жакындатпастан кармайт.
- Маалымат бербеген белгилер. Альфа конвейери жүздөгөн талапкерди жаратат, алардын көбү ызы-чуу. Дарактар ар бир бөлүнүүдө тандоо жасайт, ал эми нейрон тармактары бардык киргизүүлөргө кубаттуулугун жайып, ызы-чууга да параметр коротот.
- Айлантууга инвариант эместик. Көлөмдү өзгөрмөлүүлүккө алмаштырууга болбойт. Нейрон тармактары демейкиде айлантууга инвариант болуп, белгилердин сызыктуу айкалыштарын баштапкы белгилерге тең көрөт — айырмалуу семантикалык мааниси бар белгилер үчүн бул туура эмес.
Бул тандоонун практикалык жагы — маалымат көлөмү, кечигүү, белгилерди түзүүгө кеткен эмгек, чечмеленүү жана режимге ыңгайлашуу — боюнча блогдо машина үйрөнүү менен спредди моделдөөгө арналган толук чечим таблицасы бар.
Белгилерди түзүү

import pandas as pd
import numpy as np
def build_features(df: pd.DataFrame) -> pd.DataFrame:
"""
Build trading features from OHLCV data.
Expects columns: open, high, low, close, volume, timestamp
"""
feat = pd.DataFrame(index=df.index)
feat['return_1'] = df['close'].pct_change(1)
feat['return_5'] = df['close'].pct_change(5)
feat['return_15'] = df['close'].pct_change(15)
feat['return_60'] = df['close'].pct_change(60)
log_ret = np.log(df['close'] / df['close'].shift(1))
feat['volatility_20'] = log_ret.rolling(20).std()
feat['volatility_60'] = log_ret.rolling(60).std()
feat['vol_ratio'] = feat['volatility_20'] / feat['volatility_60']
feat['parkinson_vol'] = np.sqrt(
(1 / (4 * np.log(2)))
* (np.log(df['high'] / df['low']) ** 2).rolling(20).mean()
)
feat['volume_sma_ratio'] = df['volume'] / df['volume'].rolling(20).mean()
feat['volume_std_20'] = df['volume'].rolling(20).std()
feat['obv'] = (np.sign(df['close'].diff()) * df['volume']).cumsum()
feat['obv_slope'] = feat['obv'].diff(5) / feat['obv'].shift(5)
feat['high_low_range'] = (df['high'] - df['low']) / df['close']
feat['close_position'] = (df['close'] - df['low']) / (df['high'] - df['low'])
feat['gap'] = df['open'] / df['close'].shift(1) - 1
delta = df['close'].diff()
gain = delta.clip(lower=0).rolling(14).mean()
loss = (-delta.clip(upper=0)).rolling(14).mean()
feat['rsi_14'] = 100 - 100 / (1 + gain / loss)
ema_12 = df['close'].ewm(span=12).mean()
ema_26 = df['close'].ewm(span=26).mean()
feat['macd'] = (ema_12 - ema_26) / df['close']
feat['macd_signal'] = feat['macd'].ewm(span=9).mean()
feat['macd_hist'] = feat['macd'] - feat['macd_signal']
for window in [10, 20, 50]:
sma = df['close'].rolling(window).mean()
feat[f'distance_sma_{window}'] = (df['close'] - sma) / sma
std = df['close'].rolling(window).std()
feat[f'bb_position_{window}'] = (df['close'] - sma) / (2 * std)
return feat
Жогорудагы ар бир белги түзүлүшү боюнча себептүү: жылдыруу жана кеңейтүү операциялары гана колдонулат, бүт үлгү боюнча статистика жок. Бул атайын жасалган, анткени бүт серия боюнча z-стандартташтыруу мындай конвейердеги эң кеңири тараган агып кетүү; анын билдирилген Sharpe'ге таасири алдыга көз салуу жаңылыштыгынын таксономиясында өлчөнөт.
Финансылык маалыматтагы XGBoost үчүн гиперпараметр диапазондору

Максат — үлгүнүн ичиндеги максималдуу көрсөткүч эмес, үлгүдөн тышкаркы максималдуу туруктуулук. Алгач регуляризация, андан кийин татаалдык:
| Параметр | Типтүү диапазон | Максаты |
|---|---|---|
max_depth |
3--7 | Өз ара аракеттенүүнүн тартибин чектейт. Терең дарактар жогорку тартиптеги өз ара аракеттенүүнү моделдейт, бирок тез ашыкча туураланат. 4. |
min_child_weight |
5--100 | Жалбырактагы минималдуу Hessian суммасы. scale_pos_weight же максат өзгөрсө, кайра жөндөңүз. |
learning_rate |
0,005--0,05 | Кыскартуу. Төмөн маанилер көбүрөөк даракты талап кылат, бирок жалпылоо жакшырат. |
subsample |
0,5--0,8 | Ар бир дарак үчүн саптарды үлгүлөө. Кокустандык кошуп, ашыкча тууралоону азайтат. |
colsample_bytree |
0,5--0,8 | Ар бир дарак үчүн мамычаларды үлгүлөө. Өз ара байланышкан белгилер көп болгондо пайдалуу. |
gamma |
0,5--5,0 | Бөлүнүү үчүн талап кылынган минималдуу жоготууну азайтуу. Кыркуу босогосу катары иштейт. |
reg_alpha (L1) |
0,01--1,0 | Жалбырак салмактарына L1 айыбы. Сейректикке түртөт. |
reg_lambda (L2) |
0,1--10,0 | Жалбырак салмактарына L2 айыбы. Чоң жалбырак маанилеринин алдын алат. |
Издөө процедурасынын өзү — TPE, изилдөө бюджети жана эмне үчүн Байес издөөсү координаттык түшүүнү жеңери — тууралуу Optuna жана координаттык түшүү материалын караңыз. Кайсы тест упайын колдонбоңуз, кийин Sharpe'ти дефляциялашыңыз керек.
Бул макала атайылап эмнени кийинки материалдарга калтырат

Градиенттик күчөтүү моделинин айланасында өлчөөлөрү бар төмөнкү курулуштар кийинки материалдарда каралат:
- Валидация бөлүнүштөрү. Алга жылма оптималдаштыруу анкердик жана жылма терезелерди, ошондой эле начарлоо ылдамдыгын талдайт;
purged_walk_forwardмашина үйрөнүү менен спредди моделдөөдө чыныгы тазалоо/эмбарго ажырымы бар бөлгүчтү берет. Тазалоосуз ишке киргизбеңиз — бири-бирине кабатталган алдыга терезе максаттары бүктөм чек аралары аркылуу агып кетет. - Ашыкча тууралоону көзөмөлдөө. Окутуу/сыноо ажырымы жана бүктөмдөр боюнча белгилердин туруктуулугу плато талдоосунда жана бэктестке ашыкча тууралануу ыктымалдыгында каралат.
- PnLге которулган болжолдор. Жалпак bps чыгымы бар векторлоштурулган
signal * shifted-returnбэктести бир нече ийгиликтүү соодадан Sharpe түзүп коюшу мүмкүн — максат функциясынын дизайнынан жана активдүү убакыттагы PnL метрикасынан караңыз. Издөөдөн кийинки каалаган Sharpe'ти дефляцияланган Sharpe менен оңдоңуз; чынчыл терс натыйжа туруктуу артыкчылык жок болгондо эмнеге окшош экенин көрсөтөт. - Транзакция чыгымдары. Тайгалануу чыгымдарынын моделдери жана мейкер-тейкер комиссиялары. 53% тактыктагы багыт модели сиз тандаган чыгым моделинен көз каранды.
Бул жерде дагы үч тузак натыйжа катары эмес, гипотеза катары гана айтылды: тизмедеги активдер менен гана окутуунун туруктуулугу; бета-калдык кирешелер жакшыраак болушу мүмкүн болгон чийки кайтарым максаттарынын стационарсыздыгы; жана кайра окутуу мезгили, мында SHAP бүктөмдөрү боюнча диагностика табигый дрейфтин мониторун берет.
Жыйынтык

Кайтарым багытын классификациялоо — эч ким атайын тандабаган чечим босогосу бар тең салмаксыз маселе; үч стандарттуу оңдоо бири-бирин алмаштыра албайт. scale_pos_weight жөнөкөй, бирок ыктымалдыктарды калибрлебейт жана min_child_weight параметрин үнсүз өзгөртөт. Фокустук жоготуу Hessian'ды талап кылат, ал эми көпчүлүк ишке ашырууларда ал болжолдуу. Босогону оптималдаштыруу моделди өзгөртпөй, соодага тиешелүү чектөөнү — тактыкты — керектүү жерге коёт; бирок босого окутуудан кийинки маалыматта ар бир бүктөм үчүн кайра тандалганда гана ишенимдүү болот.
Кайсы ыкма утары — маалыматтарыңызга, босогоңузга жана чыгым моделиңизге байланышкан эмпирикалык суроо. Жогорудагы таблица бир маалымат топтомунун жообу гана; аны өз маалыматыңызда иштетүү болжоп отуруп жөндөөгө кеткен убакыттан арзаныраак.
Кошумча окуу:
- Grinsztajn жана башкалар, "Эмне үчүн дарак моделдери кадимки таблицалык маалыматта терең үйрөнүүдөн дагы деле ашат?" (NeurIPS 2022)
- Wang жана башкалар, "Imbalance-XGBoost: салмакталган жана фокустук жоготууларды бинардык энбелги дисбалансына колдонуу"
- Chen жана Guestrin, "XGBoost: Масштабдалуучу дарак күчөтүү системасы" (KDD 2016)
- Ke жана башкалар, "LightGBM: жогорку натыйжалуу градиенттик күчөтүлгөн чечим дарагы" (NeurIPS 2017)
- Prokhorenkova жана башкалар, "CatBoost: категориялык белгилер менен калыс күчөтүү" (NeurIPS 2018)
- XGBoost документтери: параметрлерди жөндөө боюнча эскертүүлөр
Authors
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.