Gradient Boosting — How XGBoost and LightGBM Work
Sequential weak learners, residuals, learning rate, and why gradient boosting wins almost every tabular ML competition — built from plain English first.
Random Forest trains 500 trees independently and averages them. Gradient Boosting trains 500 trees sequentially — each one fixing the mistakes of all the previous trees.
You trained a Random Forest on DoorDash delivery time data and got a mean absolute error of 4.2 minutes. Some orders are predicted well. Others are consistently wrong — long-distance orders during peak hours that the model always underestimates. The errors are not random noise. They have a pattern.
Random Forest ignores this. It trains every tree independently on a random sample of data. It has no mechanism to say "pay more attention to the orders we keep getting wrong."
Gradient Boosting does exactly this. After training the first tree, it looks at every prediction error. It trains the second tree specifically to predict those errors — not the original target, but the residuals (the mistakes). The third tree predicts the residuals of the first two combined. Each new tree corrects what all previous trees got wrong. After 500 trees, the accumulated corrections produce a model that consistently outperforms any single tree or Random Forest on almost every tabular dataset.
You are learning to throw darts. First throw: you miss the bullseye by 8cm to the right. A coach watches and says "next throw, aim 8cm to the left of wherever you aimed before." Second throw: miss by 3cm upward. Coach: "aim 3cm down from last time." Each throw corrects the accumulated error of all previous throws.
Gradient Boosting trains each new tree to hit where the previous ensemble missed. The final prediction is the sum of all trees — each one having corrected the previous collection's errors.
Residuals — what each tree actually learns to predict
A residual is simply the difference between the actual value and what the current ensemble predicts. If the true delivery time is 42 minutes and the current ensemble predicts 35 minutes, the residual is 42 − 35 = +7 minutes. The next tree tries to predict +7. After adding it, the ensemble now predicts 35 + 7 = 42. Exact.
Of course real data has noise — you cannot eliminate all error. The next tree predicts the residuals imperfectly. But each iteration reduces them further. After many iterations the residuals shrink to near-zero for most training points.
Learning rate and n_estimators — always tune them together
The learning rate controls how much each tree contributes to the final prediction. A small learning rate (0.01) means each tree makes tiny corrections — you need many more trees to converge, but the final model generalises better because it took small careful steps. A large learning rate (0.5) means each tree makes large corrections — you converge faster but risk overshooting and overfitting.
This creates an important relationship: lower learning rate requires more trees, but generally produces a better model. The two hyperparameters must be tuned together. Halving the learning rate and doubling n_estimators often improves performance.
Four ways to regularise gradient boosting
Gradient boosting can overfit severely if unconstrained. With 1000 deep trees, it will eventually memorise the training data. Four parameters control overfitting — each from a different angle. Understanding all four lets you tune systematically rather than randomly.
Maximum depth of each tree. Shallower trees = simpler weak learners = less overfitting. Gradient boosting works best with shallow trees (3–6) — unlike Random Forest which uses full-depth trees.
Fraction of training data used for each tree. Like Random Forest's bootstrap, but without replacement. Introduces randomness — each tree sees a different subset. Reduces variance and often improves generalisation.
Minimum samples required at a leaf. Forces the tree to only make splits that affect at least this many samples. Prevents the tree from fitting single-sample noise.
Number of features considered at each split. Like Random Forest's random feature selection. Introduces randomness and can improve generalisation, especially with many correlated features.
The gradient connection — residuals are negative gradients of MSE
The word "gradient" in gradient boosting is not just marketing. It connects directly to gradient descent from Module 07. When the loss function is mean squared error, the residuals y − ŷ are exactly the negative gradient of the loss with respect to the predictions. So fitting a tree on residuals is the same as taking a gradient descent step in the space of functions.
The power of the gradient framework is that it works for any differentiable loss function. For regression you use MSE residuals. For classification you use the gradient of the log-loss. For ranking problems you use custom ranking loss gradients. XGBoost extends this further by using both first and second derivatives (the Hessian) for more accurate tree fitting.
sklearn GB vs XGBoost vs LightGBM — what changed and why it matters
sklearn's GradientBoostingRegressor implements the original Friedman (2001) algorithm faithfully. XGBoost (2016) and LightGBM (2017) are engineering breakthroughs that made gradient boosting 10–100× faster while often improving accuracy. Understanding what they changed explains why they dominate every tabular ML benchmark today.
Day-one task — production delivery time predictor
Every common gradient boosting error — explained and fixed
Five things people get wrong about gradient boosting
It is not just branding — "gradient" refers to a specific, precise quantity: the negative gradient of the loss function with respect to the current prediction. For MSE loss this negative gradient happens to equal the plain residual (y − ŷ), which is why Section 2 could get away with saying "each tree predicts the residual." But swap in log-loss for classification, and the tree is fitting the gradient of log-loss (a probability residual, y − sigmoid(ŷ)) — not a literal label difference. The "residual" framing is a special case of the gradient framing that only looks identical because MSE's gradient is unusually simple.
Lower learning rate paired with more trees does generally improve test performance, but it is not a free lunch — it is a straight trade of training compute for a small accuracy gain, with diminishing returns. The learning-rate sweep earlier in this module needed 2,000 trees at lr=0.01 to match what 50 trees did at lr=0.3 — a 40× increase in training cost for a modest MAE improvement. Past some point, additional trees stop helping regardless of how small the learning rate is, which is exactly why you tune both together with cross-validation and let early stopping — not intuition — decide where to stop.
It is usually the opposite. Random Forest averages many independent trees trained on bootstrap samples — that averaging cancels out noise by construction, whether you regularise it or not. Gradient boosting has no such built-in safety net: each new tree is explicitly optimising away whatever error remains, including error that is just noise in the training labels. Left unconstrained, later trees will happily fit that noise. This is exactly why gradient boosting needs the four regularisation levers from Section 4 (shallow trees, subsampling, min_samples_leaf, feature sampling) tuned deliberately — Random Forest gets comparable protection almost for free from its bagging mechanism.
It wins on most tabular benchmarks, which is why it dominates competitions — but "most" is not "always." On small or noisy-labelled datasets, an untuned Random Forest is often more robust out of the box, because bagging's variance-cancelling averaging degrades gracefully with poor hyperparameters, whereas an untuned gradient boosting model (high learning rate, no regularisation) can overfit badly and underperform a default Random Forest. Gradient boosting earns its accuracy advantage only when you invest the tuning time — an untuned comparison is not a fair one.
Random Forest trees are trained completely independently, so building 500 of them across 500 cores is trivial. Gradient boosting cannot do this: tree i+1 needs the residuals produced by the ensemble through tree i, so trees must be built one after another — there is a hard sequential dependency between boosting rounds. What XGBoost and LightGBM actually parallelise is the work *inside* each tree — histogram construction and split-finding across features run on multiple threads — but the 500 rounds themselves still happen in sequence. This is why gradient boosting training time scales roughly linearly with n_estimators almost regardless of core count, unlike Random Forest which genuinely speeds up with more parallel hardware.
Gradient boosting — 5 questions interviewers actually ask
Start with a single constant prediction — the mean of the target for regression. Compute the residual for every training point: actual value minus the current ensemble's prediction. Fit a new, shallow tree whose target is that residual, not the original label. Scale that tree's output by the learning rate and add it to the running ensemble prediction. Repeat for n_estimators rounds — each new tree is trained specifically to correct whatever error is left after every previous tree. The final prediction is the initial constant plus the learning rate times the sum of every tree's output.
For MSE loss, the residual (y − ŷ) is exactly the negative gradient of the loss with respect to the current prediction, so fitting a tree on the residual is mathematically the same as taking one step of gradient descent — except the "step" is an entire decision tree function instead of a fixed numeric update. This generalises beyond MSE: for any differentiable loss (log-loss for classification, a custom ranking loss), you compute the negative gradient — the pseudo-residual — at every point and fit the next tree on that. XGBoost goes one step further and also uses the second derivative (the Hessian) for a more accurate Newton-style update.
Learning rate scales down each tree's contribution; a smaller value means gentler, more conservative corrections that require more trees to converge but generalise better because no single tree can dominate the ensemble. A reliable rule of thumb is that halving the learning rate while doubling n_estimators tends to improve test performance. In practice you rarely hand-tune n_estimators directly — set it very high (thousands) with a small learning rate (0.01–0.05), then use early stopping against a validation set so training automatically halts at the point where validation error stops improving, regardless of the learning rate chosen.
Random Forest trains trees independently on bootstrap samples and averages them — that is inherently robust, needs very little hyperparameter tuning to get a strong baseline, trains in parallel across cores, and tends to tolerate noisy labels better because errors get averaged away rather than explicitly chased. Gradient boosting, especially with a high learning rate or too many trees, can overfit noisy data because later trees are built specifically to reduce whatever training residual remains, noise included. I would reach for Random Forest when I need a fast, low-maintenance baseline or I'm working with a small/noisy dataset, and reach for gradient boosting when I have the time budget to tune it properly and want the best possible accuracy on structured tabular data.
First symptom: a large gap between training and validation/test error — near-perfect training score with much worse held-out score is the classic signature. Fix it using the four regularisation levers together, not just one: lower the learning rate and correspondingly raise n_estimators with early stopping enabled; keep max_depth shallow (3–5, since gradient boosting trees are meant to be weak learners, unlike Random Forest's often-unconstrained trees); add subsample below 1.0 so each tree only sees a random fraction of rows (stochastic gradient boosting); and raise min_samples_leaf so trees can't carve out single-sample leaves. Tune all of this with cross-validation, never by reading training score alone.
You understand gradient boosting. Now the production implementation.
Gradient boosting is the concept. XGBoost is the implementation that won every Kaggle competition from 2016–2019 and is still deployed at most fintech companies today. Module 30 covers XGBoost in practice — regularisation parameters, early stopping with a validation set, SHAP values for explaining individual predictions, and a complete end-to-end workflow.
Train, tune, and interpret XGBoost on a real dataset. Regularisation parameters, early stopping, SHAP values, and production deployment.
🎯 Key Takeaways
- ✓Gradient Boosting trains trees sequentially. Each new tree learns to predict the residuals — the errors — of all previous trees combined. Final prediction = initial mean + learning_rate × sum of all trees.
- ✓Residuals are the negative gradient of the MSE loss. This is why it is called gradient boosting — fitting trees on residuals is equivalent to gradient descent in function space. The framework generalises to any differentiable loss function.
- ✓Learning rate and n_estimators must be tuned together. Lower learning rate requires more trees but generally produces better generalisation. Halving the learning rate and doubling n_estimators is a reliable improvement strategy.
- ✓Four regularisation handles: max_depth (keep at 3–5), subsample (0.7–0.9 adds beneficial randomness), min_samples_leaf (prevents leaf overfitting), max_features (random feature selection). Use all four together for the most regularised model.
- ✓For datasets above 50,000 rows, use HistGradientBoostingRegressor (sklearn), XGBoost, or LightGBM instead of the original GradientBoostingRegressor. Histogram-based splitting gives 10–50× speedup with equal or better accuracy.
- ✓Enable early stopping for automatic n_estimators selection. It monitors a held-out validation set and stops training when performance stops improving — preventing overfitting and saving you from manually tuning n_estimators.
Discussion
0Have a better approach? Found something outdated? Share it — your knowledge helps everyone learning here.