Train multiple XGBoost sub-models by segment, fuse them into a main model through OOF Stacking, and evaluate the ensemble gain.
Stage 1: Train segmented sub-models
Parameter description
Parameter spec:
_vendor/xgb_cli.pyindomain=deepmodel-sub. Complex nested JSON (segments / features_per_segment / pos_weight_per_segment)mustgo through--config。
| Parameter | Required | Default value | Description |
|---|---|---|---|
--data_path / -d |
✅ | - | Data file path |
--target / -t |
✅ | - | Target variable column name |
--segments |
✅* | - | Segmentation condition JSON (Recommended to pass through the --config of segments field) |
--segment_col |
✅* | - | Automatically segment by column unique values (choose either this or segments) |
--time_col |
busi_dt |
Time column name | |
--train_filter |
Automatic split | Global training set filter condition | |
--val_filter |
val_ratio split out |
Global validation set filter condition | |
--oot_filter |
Split out by time | OOT test set condition | |
--exclude_cols |
- | Excluded columns, comma-separated | |
--features |
Automatic filtering | Global feature list, comma-separated | |
--features_per_segment |
- | Segmented differentiated feature JSON (go through --config) |
|
--sample_weight_col |
- | Sample weight column name | |
--pos_weight_per_segment |
- | Positive sample weight JSON for each segment (go through --config) |
|
--auto |
false |
flag. Automatically tune parameters for segments with OOT Gap > 0.05 | |
--output_dir |
./outputs/<ts> |
Sub-model save directory | |
--config |
- | JSON configuration path |
Execution method
python scripts/sub_trainer.py \
--data_path ./data.parquet --target y_label \
--time_col busi_dt --exclude_cols "cust_code,busi_dt" \
--auto --output_dir ./outputs/deepmodel
With --config pass in structured JSON:
{
"segments": {"高风险": "risk_score > 500", "低风险": "risk_score <= 500"},
"pos_weight_per_segment": {"高风险": 2.0, "低风险": 1.0}
}
python scripts/sub_trainer.py \
--data_path ./data.parquet --target y_label \
--auto --config ./config.json --output_dir ./outputs/deepmodel
Output
- Model file for each segment:
{output_dir}/{segment_name}.json - Markdown report: comparison table of Train/Val/OOT AUC/KS/Gap for each segment, quality gate check results
Stage 2: Stacking fusion
Parameter description
Parameter spec:
domain=deepmodel-stack。submodel_paths/segmentsstructured JSON such as go through--config。
| Parameter | Required | Default value | Description |
|---|---|---|---|
--data_path / -d |
✅ | - | Data file path |
--target / -t |
✅ | - | Target variable column name |
--submodel_paths |
✅ | - | Sub-model path JSON list (go through --config) |
--segments |
✅* | - | Segmentation conditions consistent with sub_trainer |
--segment_col |
✅* | - | Segmentation column consistent with sub_trainer |
--time_col |
busi_dt |
Time column name | |
--train_filter |
Automatic split | Training set condition (consistent with sub_trainer) | |
--val_filter |
val_ratio split out |
Validation set condition | |
--oot_filter |
Split out by time | OOT condition | |
--cv_folds |
5 |
Number of OOF cross-validation folds | |
--output_dir |
./outputs/<ts> |
Meta-learner save directory | |
--config |
- | JSON configuration path |
Execution method
python scripts/stacker.py \
--data_path ./data.parquet --target y_label \
--cv_folds 5 --output_dir ./outputs/deepmodel
With --config:
{
"submodel_paths": ["./outputs/deepmodel/高风险.json", "./outputs/deepmodel/低风险.json"],
"segments": {"高风险": "risk_score > 500", "低风险": "risk_score <= 500"}
}
python scripts/stacker.py \
--data_path ./data.parquet --target y_label \
--config ./config.json --output_dir ./outputs/deepmodel
Output
- Meta-learner model file:
{output_dir}/stack_meta.json - OOF prediction score distribution plot (each sub-model OOF AUC vs Meta-learner)
Stage 3: Ensemble comparison report
Parameter description
Parameter spec:
domain=deepmodel-compare。
| Parameter | Required | Default value | Description |
|---|---|---|---|
--data_path / -d |
✅ | - | Data file path |
--target / -t |
✅ | - | Target variable column name |
--stack_model_path |
- | Stacking model path (optional) | |
--submodel_paths |
✅ | - | Sub-model path JSON list (via --config) |
--segments |
✅* | - | Segment condition |
--segment_col |
✅* | - | Segment column |
--time_col |
busi_dt |
Time column name | |
--train_filter |
Automatic split | Training set condition | |
--val_filter |
val_ratio split out |
Validation set condition | |
--oot_filter |
Split out by time | OOT condition | |
--baseline_model_path |
- | Single-model baseline path (if not provided, a full baseline will be trained automatically) | |
--extra_baseline_algos |
- | Additional single-model baseline algorithms, comma-separated (optional values:lr,dnn) |
|
--output_dir |
./outputs/<ts> |
Artifact save directory | |
--config |
- | JSON config path |
Execution mode
python scripts/comparator.py \
--data_path ./data.parquet --target y_label \
--stack_model_path ./outputs/deepmodel/stack_meta.json \
--output_dir ./outputs/deepmodel
With --config:
{
"submodel_paths": ["./outputs/deepmodel/高风险.json", "./outputs/deepmodel/低风险.json"],
"segments": {"高风险": "risk_score > 500", "低风险": "risk_score <= 500"}
}
python scripts/comparator.py \
--data_path ./data.parquet --target y_label \
--stack_model_path ./outputs/deepmodel/stack_meta.json \
--config ./config.json --output_dir ./outputs/deepmodel
Output
- Comparison table:Single-model XGB baseline / (optional LR baseline / DNN baseline) / best sub-model / Stacking ensemble(Train/Val/OOT AUC/KS/Gap)
- OOT KS comparison of each segment under each model
- Final recommendation: whether to use Stacking / best sub-model / baseline
Tip: if you needstrict fair comparison of multiple algorithms (including hyperparameter tuning), please switch back to Agent mode and call
xgb-tuning → lr-tuning → dnn-tuning → model-comparison --use_tuned. This skill's--extra_baseline_algosonly uses default hyperparameters, positioned as a "low-cost preliminary screening comparison".
Complete workflow example
# 阶段1:训练分群子模型
python scripts/sub_trainer.py \
--data_path ./data.parquet --target y_label \
--config ./config.json --auto --output_dir ./outputs/deepmodel
# 阶段2:Stacking 融合
python scripts/stacker.py \
--data_path ./data.parquet --target y_label \
--config ./config.json --output_dir ./outputs/deepmodel
# 阶段3:集成对比报告
python scripts/comparator.py \
--data_path ./data.parquet --target y_label \
--stack_model_path ./outputs/deepmodel/stack_meta.json \
--config ./config.json --output_dir ./outputs/deepmodel
Quality gating criteria
| Check item | Criteria | Handling when not meeting standards |
|---|---|---|
| Sample size of each segment | ≥ 500 | Recommend merging this segment |
| OOT Gap of each segment | < 0.05 | Enable --auto |
| Stacking OOT AUC | ≥ max(sub-model OOT AUC) - 0.01 | Indicates the ensemble has no significant gain |
| Ensemble vs baseline OOT AUC | Ensemble is higher | Recommend abandoning the ensemble and using the best sub-model or baseline |
Relationship with other skills
| Skill | Responsibility | Relationship |
|---|---|---|
xgb-modeling |
Single-model training | Reused to train sub-models and baselines |
segment-modeling |
Segment strategy exploration | Difference: segment-modeling explores the optimal segmentation, while this Skill performs Stacking according to the specified segmentation |
model-comparison |
Fair comparison of multiple algorithms | Follow-up: for strict comparison, use model-comparison (including hyperparameter tuning) |
Notes
- Segment mutual exclusivity: the conditions of each segment should be mutually exclusive (one sample belongs to only one segment), otherwise Stacking will have information leakage
- Sample size: the training samples of each segment should be ≥ 500; segments that are too small are recommended to be merged
- OOF generation: Stacking's OOF predictions perform k-fold independently within each segment to ensure no label leakage
- Meta-learner: conservatively fixed parameters are used (max_depth=2), with no hyperparameter search, to avoid overfitting
- Sub-model path passing: stacker and comparator support reading sub-model paths from
--configRead sub-model path - Three-stage sequence: must be sub_trainer → stacker → comparator in order; artifacts are passed between stages via the file system