quantlab.model.predefined.xgb.XGBoostRegressor#
- class quantlab.model.predefined.xgb.XGBoostRegressor(config)[source]#
Bases:
LibraryModelPredict future returns with an XGBoost Booster.
Training calls
xgb.trainon the rowsLibraryModelbuilds: one per cell with a valid training target, NaN features kept (xgboost treats them as missing; the default_transform_featureturns infinities into NaN). The label a tree fits is the training target, so overriding_transform_targettrains on a per-bar rank or z-score while the headline metrics still score the raw primary label, index 0. Each label is one output of a multi-output regression.The training objective is the pooled CCC loss
1 - ccc(seeccc_objective), applied to every label column on its own. Unlessbase_scoreis given, the Booster starts from the mean of the training target (written to the run summary asbase_score) instead of xgboost’s0.5, because the CCC gradient barely corrects a constant offset whilecccis near zero. Settingobjectivein the hyperparameters switches back to that built-in xgboost objective.Hyperparameters come from
config.hyperparameters, without the keysLibraryModelreads itself (LIBRARY_RESERVED_HYPERPARAMETERS).num_boost_round(default 1000) is taken out separately; every other key overrides the matching entry ofDEFAULT_PARAMS, andseeddefaults toconfig.random_seed. Unlessdeviceis given, training runs on"cuda"when the installed xgboost is a CUDA build and a CUDA device is visible, and on"cpu"otherwise, never on Apple MPS; the check does not import torch. scikit-learn style aliases such aslearning_rateorn_estimatorsare rewritten to the native names first; giving both an alias and its native name raisesValueError. The user’s dict is never modified, and the parameters actually used are recorded underresolved_hyperparametersin the trained unit’srun.jsonand in the run config.With
hyperparameters["early_stopping"]set and validation rows,xgb.callback.EarlyStoppingwatches the validationrmse;rmseis appended to a usereval_metricthat lacks it. Every other metric, and theccc_losscurve of the training objective, is logged only. Patience counts boosting rounds.save_best=Truemeans the returned Booster is already truncated tobest_iteration + 1trees, so the.joblibcheckpoint is the best model, andbest_iterationandbest_score(an RMSE) are written to the run summary. Without a usable validation segment a warning is logged and all rounds are trained.After training, per-factor importance (
weight,gainandtotal_gain) is written to the run summary asimportance_{type}/{factor}and logged as a sorted table plus a top-30 bar chart. This is best effort: a Booster that cannot report an importance type only logs a warning, and the checkpoint is never lost because of it.train_cv(rolling walk-forward cross-validation) is inherited. Each fold does its own native early stopping and writes its own.joblib. The folds train one after another.- Parameters:
- configModelConfig
Factors, labels, date ranges, early-stopping settings and hyperparameters. See
ModelConfig.
Examples
>>> config = ModelConfig( ... factors=[alpha], # factor objects ... labels=[fwd_return], # label objects ... model_save_dir="checkpoints", ... factor_data_strategy="read", ... label_data_strategy="read", ... train_start="2024-01-01", train_end="2024-02-09", ... test_start="2024-02-10", test_end="2024-02-29", ... hyperparameters={ ... "early_stopping": True, "early_stopping_patience": 5, ... "num_boost_round": 20, "max_depth": 3, ... }, ... ) >>> model = XGBoostRegressor(config) >>> checkpoint = model.collect().train() >>> checkpoint.name 'XGBoostRegressor_total.joblib' >>> model.predict(np.zeros((5, 2, 3), dtype="float32")).shape (5, 2, 1) >>> model.train_cv(train_periods=500)
- EARLY_STOPPING_METRIC = 'rmse'#
Metric watched by early stopping on the validation segment.