XGBoost, Explained | Oh My Kode

XGBoost, Explained

10 Sep 2023

10 minutes read

If neural networks rule images, audio and text, there is another model that quietly wins almost everything else, the spreadsheets, the tables, the columns of numbers that run banks, hospitals and Kaggle leaderboards : XGBoost (Chen & Guestrin, 2016). Its idea is charmingly human. Instead of building one enormous, clever model, it assembles a team of very simple ones, where each new member studies the mistakes the team has made so far and does its best to correct them. Add enough of these humble correctors and the team becomes formidably accurate. This post explains that idea from scratch, keeps the mathematics that makes XGBoost special, and answers the practical questions : why is it so good, and when should you reach for it ?

1. Where XGBoost shines

Most real-world data is tabular : rows of examples, columns of mixed features (age, price, a category, a count). For this kind of data, a well-tuned XGBoost is very often the single best model you can train, beating deep networks while being faster and needing far less tuning. Its home turf is exactly where deep learning is weakest, and vice versa, a division of labour we will make precise at the end.

2. The big idea : boosting is teamwork by correction

Imagine guessing a house’s price. Your first guess is crude, say the average price, $300{,}000. Someone points at the leftover error (this house is bigger than average) and adds a correction : $+50{,}000. Someone else notices the corrected guess is still off (bad neighbourhood) and adds $-20{,}000. Each helper looks only at what the team got wrong so far and nudges the answer. That is boosting.

Boosting builds a strong predictor as a sum of many weak ones, added one at a time. Each new weak learner is trained to correct the residual errors left by the sum of all the previous ones.

The weak learners in XGBoost are shallow decision trees : little flowcharts that split the data on one feature at a time and output a number at each leaf. On their own they are mediocre. Summed by the hundreds, each fixing its predecessors’ mistakes, they become excellent. The animation shows the ensemble’s prediction (blue) sharpening towards the truth (grey) as trees are added.

grey = truth · purple = ensemble prediction as trees are added (1 → 2 → 4 → 8)
Figure 1 - Boosting in action. With one tree the prediction is a crude flat guess ; each added tree carves the input into finer regions to fix the remaining error, and the staircase closes in on the target function.

3. Gradient boosting, the maths

Let the model after $t$ rounds be a sum of trees $f_k$ :

\[\begin{equation} \hat{y}_i^{(t)} = \sum_{k=1}^{t} f_k(x_i) = \hat{y}_i^{(t-1)} + f_t(x_i). \label{eq:additive} \end{equation}\]

We want to choose the new tree $f_t$ to reduce the total loss $\sum_i l(y_i, \hat{y}_i)$. Friedman’s insight (Friedman, 2001) was that the best direction to move the predictions is the negative gradient of the loss, so each new tree should be fitted to point that way. In other words, boosting is gradient descent, but taking steps in the space of functions rather than the space of weights : each tree is one downhill step.

For the squared error $l = \tfrac12(y-\hat{y})^2$, the negative gradient is simply the residual $y_i - \hat{y}_i$. So "fit the next tree to the negative gradient" becomes the intuitive "fit the next tree to what is still left over", exactly the correction story from the house-price example.

4. What makes XGBoost special

Plain gradient boosting fits each tree to the residual. XGBoost (Chen & Guestrin, 2016) sharpens this in two ways that together explain its accuracy and speed.

A second-order step. Instead of using only the gradient $g_i = \partial_{\hat{y}} l$, XGBoost also uses the curvature $h_i = \partial^2_{\hat{y}} l$ (a Taylor expansion to second order). The objective for the new tree becomes

\[\begin{equation} \tilde{\mathcal{L}}^{(t)} = \sum_{i}\Big[ g_i\, f_t(x_i) + \tfrac{1}{2} h_i\, f_t(x_i)^2 \Big] + \Omega(f_t), \qquad \Omega(f) = \gamma T + \tfrac{1}{2}\lambda \sum_{j=1}^{T} w_j^2. \label{eq:obj} \end{equation}\]

Built-in regularisation. The penalty $\Omega$ charges $\gamma$ per leaf (discouraging big bushy trees, $T$ = number of leaves) and $\lambda$ for large leaf values $w_j$ (keeping corrections modest). This is what stops the ensemble from memorising the training data.

Because a tree just assigns every example to one leaf, $\eqref{eq:obj}$ can be solved in closed form. If $G_j = \sum_{i \in \text{leaf } j} g_i$ and $H_j = \sum_{i \in \text{leaf } j} h_i$, the optimal value to put in leaf $j$, and the resulting objective, are

\[\begin{equation} w_j^{\ast} = -\frac{G_j}{H_j + \lambda}, \qquad \tilde{\mathcal{L}}^{\ast} = -\frac{1}{2}\sum_{j=1}^{T}\frac{G_j^2}{H_j + \lambda} + \gamma T. \label{eq:leaf} \end{equation}\]

This last expression is a quality score for a tree’s shape. To decide whether to split a leaf into two, XGBoost simply checks whether the split improves that score, giving the famous gain formula :

\[\begin{equation} \text{Gain} = \frac{1}{2}\left[ \frac{G_L^2}{H_L+\lambda} + \frac{G_R^2}{H_R+\lambda} - \frac{(G_L+G_R)^2}{H_L+H_R+\lambda} \right] - \gamma. \label{eq:gain} \end{equation}\]

In plain words : $\eqref{eq:gain}$ measures how much cleaner the two children are than the parent, minus a fixed cost $\gamma$ for adding a leaf. If no split beats that cost, the branch stops growing, this is how XGBoost prunes itself.

yesno yesno age < 30 ? income < 40k ? leafw = +0.7 w = −0.4 w = +0.2 each leaf outputs a small correction wⱼ from eq. (3)
Figure 2 - One weak learner : a shallow tree. It routes an example through yes/no questions to a leaf, whose value $w_j$ (chosen by $\eqref{eq:leaf}$) is the correction this tree contributes. XGBoost adds hundreds of such trees, each scaled by a small learning rate $\eta$ (shrinkage) so no single tree dominates.

5. Why it works so well

Several ingredients combine to make XGBoost a default winner on tabular data.

  • It captures interactions automatically. A tree that splits on age and then on income has expressed “the effect of income depends on age” without you specifying it, structured data is full of such interactions.
  • Regularisation is built in. The $\gamma$ and $\lambda$ penalties $\eqref{eq:obj}$, plus shrinkage (scaling each tree by a learning rate $\eta$) and column/row subsampling, keep the ensemble from overfitting.
  • It is fast and scalable. XGBoost sorts features once, grows trees using the closed-form gain $\eqref{eq:gain}$, and parallelises split-finding across features with a cache-aware, out-of-core implementation, the engineering that gave it its name (eXtreme Gradient Boosting).
  • It handles messy reality. Missing values are routed to a learned default direction at each split (sparsity-aware), and the model yields interpretable feature-importance scores for free.

6. When to use it (and when not)

The honest guidance is a clean split by data type.

For tabular / structured data (finite columns of numbers and categories), reach for XGBoost first. For unstructured data, images, audio, raw text, where the meaning lives in spatial or sequential patterns, reach for a neural network.

Why the divide ? Trees split on individual features, so they excel when features are individually meaningful (income, age, blood pressure) but are poor at raw pixels, where meaning emerges from patterns across thousands of coordinates, exactly what convolutions and attention are built to capture. XGBoost is also a superb choice when you need results fast, with little tuning, on modest data, or when interpretability matters. Its limitations are the mirror image : it does not natively handle images or long text, and it does not learn transferable representations the way large pre-trained networks do.

7. Conclusion

XGBoost turns a very human strategy, let each helper fix what the group got wrong, into rigorous mathematics : an additive ensemble of shallow trees, each one a second-order gradient-descent step in function space, regularised so the team generalises rather than memorises, and engineered to run fast on real data. It will not caption your photos or write your emails, that is the neural network’s job, but when your problem lives in a table, a stack of humble, self-correcting trees remains remarkably hard to beat. 1

References

  1. Chen, T., & Guestrin, C. (2016). XGBoost: A Scalable Tree Boosting System. Proceedings of the 22nd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining, 785–794.
    @inproceedings{Chen2016,
      author = {Chen, Tianqi and Guestrin, Carlos},
      title = {XGBoost: A Scalable Tree Boosting System},
      booktitle = {Proceedings of the 22nd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining},
      pages = {785--794},
      year = {2016},
      publisher = {ACM}
    }
    
  2. Friedman, J. H. (2001). Greedy Function Approximation: A Gradient Boosting Machine. The Annals of Statistics, 29(5), 1189–1232.
    @article{Friedman2001,
      author = {Friedman, Jerome H.},
      title = {Greedy Function Approximation: A Gradient Boosting Machine},
      journal = {The Annals of Statistics},
      volume = {29},
      number = {5},
      pages = {1189--1232},
      year = {2001}
    }
    
  1. XGBoost belongs to the gradient boosting machine family introduced by Friedman (Friedman, 2001) ; its close cousins LightGBM and CatBoost share the same mathematics with different engineering trade-offs (histogram splits, ordered boosting). All remain the tools of choice for tabular prediction. ↩

who am i

Hi! I am a Data Scientist by profession, an Emacs devotee and an untalented bassist. I intend to use this space for writing about things that I think I have understood well in the hope that they may be helpful to others, including my future self.

what is this

OhMyKode is an opportunity to share knowledge about mathematics, computer science, machine learning and algorithmic beauty, which allows us to improve our skills and learn in depth. It is a sharing place to learn the how and the why.

© MMXVIII - MMXX by Maâmra Youcef - معامره يوسف
Content available under Creative Commons (BY-NC-SA) unless otherwise noted.
This site is hosted at Github Pages and powered by Jekyll & Papyrus.
“We can't skip Math forever !”