← chapter

Gradient boosting

Guess the mean. Fit a tree to what's left over. Add a shrunken slice. Repeat.

AdaBoost's idea generalized: fit the gradient of the loss. For squared error, the gradient is just the residual.

Forest vs. boosting

The data

A 1-D curve, y = sin(x) + 0.25x + noise, 120 points. A sum of shallow trees is a staircase — watch it build toward the curve.

The math

Additive model, built one tree at a time:

FM(x)=F0+νm=1Mhm(x)F_M(x) = F_0 + \nu \sum_{m=1}^{M} h_m(x)

Squared-error loss, and its negative gradient at the current prediction:

L(y,F)=12(yF)2L(y, F) = \tfrac{1}{2}\,(y - F)^2 ri=L(yi,F)FF=Fm1(xi)=yiFm1(xi)r_i = -\left.\frac{\partial L(y_i, F)}{\partial F}\right|_{F = F_{m-1}(x_i)} = y_i - F_{m-1}(x_i)

The negative gradient is the residual. Fit a tree to it, take a shrunken step:

Fm(x)=Fm1(x)+νhm(x)F_m(x) = F_{m-1}(x) + \nu\, h_m(x)

Watch it build

One boosting round per frame, learning rate 0.1. Top: F(x) creeping toward the curve. Bottom: the residuals collapsing. Train MSE 1.007 → 0.069 over 50 rounds.

The learning rate is the knob

Test MSE vs. trees on real data, three learning rates. Small rate: lower floor, more trees, forgiving. Big rate: fast then overfits off a cliff.

Scratch vs. library

100 trees, lr 0.1, depth 3 on diabetes. Scratch R² 0.3766, sklearn R² 0.3916 — neck and neck. A single depth-3 tree scores 0.2564; boosting a hundred of them buys the climb to 0.38.

Takeaways