Classical machine learning
Gradient boosting
Boosting adds shallow trees one after another, each fitting the residual of the ensemble so far. Shrinkage and early stopping keep the sum from hugging noise.
Boosting builds trees sequentially. Each new tree fits the residuals (or gradients of the loss) of the ensemble so far. Predictions add up. That is the opposite of bagging, which trains trees independently and averages them.
Concept
Gradient boosting treats the loss L(y, F(x)) as a function of the prediction. The next tree regresses onto the negative gradient −∂L/∂F evaluated at the current F. For squared error that gradient is exactly the residual y − F. For log loss it is y − σ(F).
The big idea
F₀(x) = base score (e.g. mean of y)
F_m(x) = F_{m−1}(x) + η · h_m(x)h_m is a small tree. η is the learning rate (shrinkage).
Key knobs:
| Knob | Effect |
|---|---|
n_estimators | More trees → more capacity. Stop with early stopping |
learning_rate | Smaller η needs more trees, usually generalizes better |
max_depth / num_leaves | Tree size. Boosting wants shallow trees (depth 3–8) |
subsample / colsample | Row/column sampling — regularization |
min_child_weight / min_data_in_leaf | Prevent tiny leaves |
Why shallow trees? A depth-10 tree already models complex interactions alone. Boosting a forest of deep trees stacks capacity on capacity and overfits faster. A depth-4 tree is a weak learner — slightly better than the current residual guess — and the ensemble becomes strong by addition.
Early stopping watches a validation metric every few rounds and freezes the ensemble when improvement stalls. You set n_estimators deliberately too high and let stopping pick the effective size. Without it, people either underfit (too few trees) or overfit (train for thousands of rounds at high η).
Walking through three points
Targets y = [10, 20, 30], start F₀ = 20. Residuals [-10, 0, 10]. Tree 1 predicts roughly those residuals. With η = 0.5, F₁ ≈ [15, 20, 25]. New residuals [-5, 0, 5]. Tree 2 shrinks them again. After enough rounds F_M hugs y on train. Early stopping on validation prevents hugging noise.
Default gain / split-count importances are useful but biased toward high-cardinality features. SHAP (SHapley Additive exPlanations) attributes each prediction to features using game-theoretic shares — slower, much more trustworthy for stakeholder conversations. Use global SHAP to debug leakage (one feature dominates) and local SHAP to explain a single denied loan.
import numpy as np
y = np.array([10.0, 20.0, 30.0])
F = np.full(3, y.mean()) # 20, 20, 20
eta = 0.5
resid = y - F
h1 = resid.copy() # toy: tree predicts residuals exactly
F = F + eta * h1
print("F1", F, "resid", y - F)Output:
F1 [15. 20. 25.] resid [-5. 0. 5.]Common mistakes
- Boosting deep trees. Capacity stacks on capacity. Keep them shallow.
- Skipping early stopping. You either underfit or memorize.
- Trusting gain importance on a high-cardinality ID. Use SHAP.
Check yourself
- For squared error, what does the next tree fit? Answer: The residual
y − F. - Why is a smaller learning rate usually better? Answer: Each tree is a smaller correction, so you need more trees but you overfit less.
Key takeaways
- Gradient boosting adds shallow trees on loss gradients with shrinkage.
- Early-stop on validation. Set
n_estimatorshigh and let stopping pick the size. - Shallow trees are the point. Deep trees overfit faster here than in a forest.
- SHAP is the credible explanation. Gain importance is a rough hint.
Further learning
Next: XGBoost, LightGBM and CatBoost.
StatQuest’s gradient boost series is the clearest visual of residual fitting:
Related
Trees and gradient boosting
Decision trees, random forests and XGBoost/LightGBM: still the best default for tabular data.
Bagging and random forests
Bagging trains many trees on bootstrap samples and averages them. A random forest also tries a random subset of features at each split, which decorrelates the trees.
XGBoost, LightGBM and CatBoost
Three libraries implement gradient boosting with different engineering. LightGBM is a fast default, CatBoost handles categoricals well, and features still matter more than the logo.