Trees & Ensembles
A Practical Guide to XGBoost Hyperparameter Tuning
Suresh Madhra·Jun 18, 2026·9 min read
Tune in order of impact, not alphabetically
XGBoost exposes dozens of parameters and most of them will not change your score. A repeatable workflow beats a giant random search: fix the ones that control the budget, tune the ones that control model capacity, then regularize.
The parameters that actually move the needle
- n_estimators + learning_rate — a joint budget. Halve the learning rate, roughly double the trees. Fix learning_rate at 0.05–0.1 and let early stopping pick n_estimators.
- max_depth — the single biggest capacity lever. 3–8 covers almost every tabular problem; deeper mostly buys overfitting.
- min_child_weight — the minimum summed instance weight in a leaf. Raise it to stop the model carving out tiny, noisy leaves.
- subsample and colsample_bytree — stochasticity, typically 0.6–1.0. Cheap variance reduction and a genuine speed-up.
- reg_lambda (L2) and reg_alpha (L1) — apply after depth is settled, when train and validation scores have diverged.
- gamma — minimum loss reduction to split. A blunt but effective brake on tree growth.
- scale_pos_weight — for imbalanced binary targets, roughly negatives / positives.
A workflow you can repeat
- 1. Build an honest validation scheme first — stratified k-fold, or a time-based split if the data has an ordering.
- 2. Fit a default model with early stopping. That is your baseline and your compute estimate.
- 3. Tune max_depth and min_child_weight together on a small grid.
- 4. Tune subsample and colsample_bytree.
- 5. Add regularization (lambda, alpha, gamma) if the train/validation gap is wide.
- 6. Drop the learning rate, raise the tree budget, and refit with early stopping for the final model.
The simulation below shows why step 3 comes before step 5 — it walks a small depth grid on a synthetic problem and prints the classic bias/variance signature you should learn to recognise.
depth_sweep.py
Reference configuration
xgb_reference.py
Mistakes that cost real points
- Tuning against the test set. Use a validation split for tuning and touch test once, at the end.
- Early stopping on the same fold you report. The stopping round is a fitted parameter; it leaks.
- Grid-searching learning_rate and n_estimators independently — they trade off directly.
- Ignoring categorical handling. One-hot on a high-cardinality column creates thousands of sparse splits; use target or ordinal encoding, or native categorical support.
- Chasing the fourth decimal place. Beyond a point, feature work beats parameter work every time.