Decision trees · Gradient boosting

Gradient Boosting: A Quick Deep Dive

Build gradient boosting from residual corrections, then connect the same additive procedure to classification and optimization in function space.

Introduction

Machine learning is often introduced through neural networks, but tabular data has followed a somewhat different path.

When the inputs are columns such as age, income, account balance, product category, or transaction count, tree-based models remain remarkably competitive. Trees are naturally suited to this kind of data because a useful pattern can often be expressed through questions such as whether a feature is above a threshold, whether another falls inside a range, or whether two conditions occur together.

Gradient Boosted Decision Trees, or GBDTs, combine this strength of decision trees with an idea that feels much closer to classical numerical optimization.

Instead of training one large tree to solve the entire problem, we build a model sequentially. We begin with a crude prediction, inspect how that prediction should change to reduce the loss, train a small model to generalize those corrections across the input space, and then add that model to what we already have.

The result is an additive model:

FM(x)=F0(x)+ηh1(x)+ηh2(x)++ηhM(x)F_M(x) = F_0(x) + \eta h_1(x) + \eta h_2(x) +\cdots+ \eta h_M(x)

where F0F_0 is the initial prediction, each hmh_m is a new learner, and η\eta controls how much each learner is allowed to modify the current model.

This creates an interesting bridge between decision trees and gradient descent. In a neural network, we normally define a parameterized function f(x;θ)f(x;\theta) and repeatedly modify its parameters θ\theta to reduce a loss. In gradient boosting, the current predictor itself is gradually modified by adding new functions to it.

Another way to think about this is that we stop asking a single model to learn the complete mapping from XX to yy at once. Instead, at every iteration, we study the pattern of corrections that the current model still needs. A weak learner generalizes that correction, we add it to the model, and then we inspect what remains.

With enough iterations, surprisingly complex functions can emerge from many individually simple trees.

Each new tree fits what the current model still misses, creating the next model.

Intuition

Starting Simple

Complex algorithms are often much easier to understand when we first strip away everything that is not essential. So let us begin with an intentionally simple regression problem.

Suppose our dataset contains only one input feature xx. The target follows a small synthetic signal with a gradual drift, a wave, two level changes, and some random noise:

yf(x)+ϵy \approx f(x) + \epsilon

This is still small enough that both the data and the model’s predictions can be visualized directly in two dimensions. The extra changes give different parts of the input space genuinely different errors for the trees to discover.

If we trained a regression tree on this dataset, its prediction would be piecewise constant. Different intervals of the xx-axis would fall into different leaves, and every point inside a leaf would receive the same prediction.

One regression tree makes a step-shaped predictionThirty-six observations follow a one-dimensional signal. A depth-two regression tree predicts one constant value in each learned interval.-101-303input xtarget yone tree
A regression tree divides the input axis into intervals and gives every point in one interval the same prediction.

Now we are going to change how we think about the problem.

Rather than asking how to build one regression tree that predicts yy, suppose we decide in advance that we are going to train several models sequentially. Each new model will focus only on correcting what the previous model has not captured yet.

Before training any tree, we need some initial prediction.

For squared-error regression, a natural starting point is the mean target value:

F0(x)=yˉF_0(x)=\bar y

Every input therefore receives exactly the same prediction at the beginning. Graphically, the model is simply a horizontal line.

For each observation, we can now measure how far the true target is from this baseline:

ri=yiF0(xi)r_i = y_i - F_0(x_i)
The mean baseline leaves a different error in each regionEvery observation starts with the same prediction, zero point one three. Amber vertical segments show the signed distance from that baseline to each target.-101-303input xtarget yF₀ = mean = 0.13
The constant baseline is too high in some regions and too low in others. Each vertical segment is one residual.

The vertical segments represent exactly these differences. If a point lies above the baseline, its residual is positive; if it lies below it, its residual is negative.

At this point, those residuals become the new prediction problem.

Instead of keeping the original yy values as our target, we temporarily replace them with the amount by which the current model needs to move at every training observation.

Because this toy problem has only one feature, we can visualize those residuals as another dataset.

The baseline residuals still have a pattern across the input axisThe horizontal coordinate stays fixed while each target moves to its residual value. Negative residuals gather on the left and positive residuals gather through the central rise.-101-303input xresidualzero residual
Once the baseline is subtracted, the errors are still arranged by x rather than scattered randomly around zero.

This residual plot should look almost identical to the original target plot. Subtracting the same constant, yˉ\bar y, shifts every point vertically without changing its input coordinate or the shape of the dataset. The shifted values now have mean zero, but their pattern across xx remains.

The important observation is that the residuals are not necessarily random.

If the baseline systematically underestimates one region of the curve and overestimates another, the residuals themselves contain structure. A decision tree can learn some of that structure.

So we train a regression tree h1(x)h_1(x), but its target is now the residual:

h1(x)yF0(x)h_1(x) \approx y-F_0(x)
A shallow tree learns a regional approximation to the residualsA depth-two tree fits four constant levels to the residual pattern. Its step line is negative on the left, strongly positive in the central rise, and mildly positive on the right.-101-303input xresidualh₁(x)
The tree cannot reproduce every residual. It turns their shared regional pattern into a correction function.

The resemblance to the first tree we drew is also expected. Subtracting one constant from every target does not change which split boundaries reduce squared error most. With the same tree settings, a tree trained on yyˉy-\bar y therefore learns the same regions as a tree trained directly on yy; only its leaf values are shifted. This special equivalence belongs to the first round. Once F1(x)F_1(x) varies across the input space, the next residuals are no longer a constant shift of the original targets.

Once this tree has learned a useful approximation of the correction, we add it to the baseline:

F1(x)=F0(x)+h1(x)F_1(x)=F_0(x)+h_1(x)

A prediction is therefore no longer coming from one tree. It is the sum of an initial value and a learned correction.

Adding the first correction changes one constant into a regional modelThe dashed horizontal baseline remains visible behind the updated step-shaped model F one. The observed targets stay fixed.-101-303input xtarget yF₀F₁
The targets do not move. The model moves from the dashed baseline to the solid updated prediction F₁ = F₀ + h₁.

Even this one step already contains most of the intuition behind boosting. The first model does not need to solve the entire problem. It only gives us somewhere to start. The next model studies what is still wrong and learns a function that moves the predictions in a better direction.

Nothing Is That Simple

There is one problem with applying the full correction immediately.

A regression tree is itself an approximation. It does not know the true correction function; it only estimates it from a finite training set. If we completely trust every tree and add its predictions at full magnitude, the ensemble can react too aggressively to patterns that happen to exist only in the training data.

Consider points from a test set that were never used to train the tree. The tree may estimate the corrections well in some regions while producing unnecessarily large corrections in others.

A simple way to make the process more conservative is to shrink every correction before adding it.

Instead of

F1(x)=F0(x)+h1(x),F_1(x)=F_0(x)+h_1(x),

we use

F1(x)=F0(x)+ηh1(x),F_1(x)=F_0(x)+\eta h_1(x),

where η\eta is the learning rate, usually chosen somewhere between 0 and 1.

If η=0.1\eta=0.1, for example, a tree that proposes a correction of +4+4 only moves the current prediction by +0.4+0.4.

This means each individual tree has less influence, but it also means that later trees will have an opportunity to keep correcting the remaining error.

Even before we add more trees, the learning rate determines how much of this first correction reaches the model. A large value moves the four regional predictions farther from the baseline. A small value preserves the same regions but keeps every step closer to F0F_0.

The interaction below keeps both F0F_0 and the already fitted tree h1h_1 fixed. It changes only the multiplier in F1(x)=F0+ηh1(x)F_1(x)=F_0+\eta h_1(x). Before moving the slider, predict which part of the step line can change: its split locations, its heights, or both.

Scale the first correctionF₁(x) = F₀ + ηh₁(x) · η 1.00
Baseline plus one treeRMSE 0.247
The first correction at the selected learning rateOpen circles are held-out targets. The dashed horizontal line is the fixed baseline. The solid four-level step line is that baseline plus the fixed first residual tree scaled by the learning rate. Thin amber segments are the resulting held-out residuals.-101-303input xF₀F₁(x)
Held-out errors
Distribution of held-out residualsThe fixed horizontal scale runs from minus zero point nine to plus zero point nine. Residuals closer to zero form bars near the center line.−0.900.9held-out residual

The baseline and tree stay fixed. η changes only the height of the tree's four regional corrections.

Learning rate 1.00. Held-out root mean squared error 0.247.

On this particular held-out sample, a value just below 11 performs slightly better than taking the complete first correction. That is enough to show that shrinking a learned correction can help, but it does not make that value universally optimal. In full ensembles, values around 0.10.1 are common starting points because later trees keep working on what remains. The appropriate learning rate depends on the dataset, tree complexity, number of boosting iterations, regularization, and validation behavior.

More Trees

After training the first tree, we have a better model:

F1(x)=F0(x)+ηh1(x)F_1(x)=F_0(x)+\eta h_1(x)

but usually not a perfect one.

So we repeat the same procedure.

We calculate a new residual for every training observation:

ri(2)=yiF1(xi)r_i^{(2)} = y_i-F_1(x_i)

These residuals describe what the ensemble still needs to correct after the first tree has already contributed.

The first tree leaves a new residual target for the second treeThe current model F one and its remaining vertical errors appear on the left. The same signed errors appear around zero on the right, still arranged by input x.Current model F₁-101-303input xWhat F₁ still misses-101-303input xF₁(x)zero
After F₁ has changed by region, the remaining errors form a genuinely new target for tree two.

We can now train another tree,

h2(x)r(2),h_2(x)\approx r^{(2)},

and update the model again:

F2(x)=F1(x)+ηh2(x)=F0(x)+ηh1(x)+ηh2(x)F_2(x) = F_1(x)+\eta h_2(x) = F_0(x)+\eta h_1(x)+\eta h_2(x)

To make this update concrete, the next figure isolates three observations from the same training set. It does not show the whole fitted curve. Each example begins at the shared baseline F0F_0, follows the first tree’s amber correction to F1F_1, and then follows the second tree’s green correction to F2F_2. The black circle is the observed target, which never moves.

Tree two responds to the errors that tree one leaves behindThree observations from the training data are shown. Each observed target stays fixed. An amber arrow moves the baseline prediction F zero to F one, and a green arrow moves F one to F two. The second tree continues downward for the left observation, reverses part of an overshoot for the middle observation, and continues upward for the right observation.-101-303input xtarget ykeeps moving downturns backkeeps moving upF₀first correctionsecond correctionobserved targetη 0.75
Three observations from the same training set. Tree two keeps moving toward the target where error remains and turns back where tree one overshot.

In the left and right examples, error remains in the same direction after the first update, so the second tree keeps moving the prediction toward the target. In the middle example, the first tree has overshot, so the second correction points back. Here the second steps are smaller because they are fitted to what remains after tree one, not because the second tree is inherently weaker.

These are three local snapshots of one fitted model, not three separate models. The ensemble is not building a fixed decomposition of the target; every new learner responds to the predictions produced by all previous learners.

That is why the sequence matters.

Tree h2h_2 is solving a different problem from h1h_1, because h1h_1 has already changed the predictions. Tree h3h_3 will solve another problem again.

After MM iterations:

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

The following animation expands this iterative process into its three recurring actions. The axes and observations stay fixed. Only the current residual target, the tree fitted to it, and the accumulated model change. Use the numbered rounds to inspect any state directly, or play the complete sequence.

One boosting round changes the next problemη 0.60 · four depth-two trees

Start from one constant prediction.

Current prediction0 trees
Current ensemble predictionObserved targets remain fixed while the piecewise constant ensemble changes as trees are added.-101-303input xF(x)
Next targetresidual
Remaining residualsEach point keeps its input coordinate and moves to the signed difference between its target and current prediction.-101-303input xzero
baseline0.13
current round

Start from one constant prediction.

There is another useful way to observe the same process.

Instead of focusing on the trees themselves, we can monitor the distribution of the remaining errors. Early in training, the residuals may be widely dispersed. As useful corrections are added, we expect that distribution to become more concentrated around zero, at least on data where the model is genuinely improving.

The residual histogram and error trace below use exactly those same four updates. Watch the distribution narrow around zero while the root mean squared error falls. This is evidence for this training run, not a guarantee that validation error must decrease forever.

Useful corrections pull the remaining errors toward zero0 trees · training RMSE 0.719
Current prediction
Current ensemble predictionObserved targets remain fixed while the piecewise constant ensemble changes as trees are added.-101-303input xF(x)
Remaining errors
Remaining residual distribution−1.401.4
Error by trees
Error across boosting rounds0.20.40.601234
completed trees

After 0 trees, training root mean squared error is 0.719.

The interaction between learning rate and number of trees becomes particularly important here.

With a very small learning rate and only a few trees, the ensemble may barely move away from its baseline. With a large learning rate, the first trees may overshoot substantially, forcing later trees to learn corrections in the opposite direction. Somewhere between these extremes is a regime in which each tree contributes enough to be useful without dominating the entire ensemble.

Now vary both quantities. Keep the number of trees small enough that every contribution remains inspectable. A very small learning rate should leave visible structure in the residuals after four rounds. An aggressive rate may make a later tree point in the opposite direction. Hover over the prediction plot, or focus it and use the arrow keys, to decompose one prediction into its baseline and tree contributions.

Balance step size and number of trees2 trees · η 0.60 · RMSE 0.220
Composed predictionhover or focus to inspect x
Current ensemble predictionObserved targets remain fixed while the piecewise constant ensemble changes as trees are added.-101-303input xF(x)
What remainsafter F2
Remaining residualsEach point keeps its input coordinate and moves to the signed difference between its target and current prediction.-101-303input xzero
baseline0.13
h1η × tree 1
h2η × tree 2
=predictionF2

Predict first: with only a few trees, will a small η stop short, or will a large η force later trees to correct back?

Number of trees

2 trees at learning rate 0.60. Training root mean squared error 0.220.

The learning rate does two jobs across several rounds. It scales each contribution directly, and by changing the current prediction it also changes the residual target used to fit every later tree. That is why the trees themselves can change when you move this slider; unlike the earlier one-tree playground, this is no longer one fixed tree viewed at different scales.

Getting More Complex

Our first one-dimensional signal was intentionally sparse. Four shallow trees were enough to make every contribution inspectable, but not enough to show what a large additive model can construct.

For the next experiment, we will preserve the one-dimensional view while making the target substantially richer. The new signal combines a global drift, broad waves, a fine ripple, two localized features, two level changes, and random noise. One small tree cannot express all of those scales at once.

Before touching the controls, predict what a limited ensemble will learn first. Will it spend its earliest trees on the broad shape, or on the narrow rise and dip?

Build detail from many shallow trees50 trees · η 0.10 · train 0.108 · held-out 0.152
Layered signaldrift · broad waves · fine ripple · local rise and dip · level changes
Composed predictiontraining points
Many shallow trees approximate the layered signalSeventy-two training observations contain broad curves, a fine ripple, two localized features, two level changes, and noise. The dashed line is an earlier ensemble and the green line is the selected tree budget.-101-303input xF50(x)
What remainsheld-out points
Held-out residuals at the selected tree budgetOne hundred and twenty held-out observations keep their input coordinate and move to their remaining signed error. Open amber circles distinguish them from the training points.-101-303input xzero
baseline0.10
+h1
+h2
+h3
h50
=ensembleF50

50 depth-two corrections

Predict before moving the budget: which structure appears first—the broad shape or the narrow local details?

50 trees at learning rate 0.10. Training root mean squared error 0.108. Held-out root mean squared error 0.152.

The broad structure appears with relatively few trees because it accounts for large, repeated errors. Smaller local details need a larger budget: they become worthwhile only after the ensemble has removed enough of the dominant pattern.

The held-out error also gives us a boundary on the intuition that more trees are always better. Training error keeps falling as the ensemble gains capacity. Held-out error can flatten or eventually rise because later trees are increasingly able to model peculiarities of the training observations. Tree count is therefore a regularization choice, not merely a request for more accuracy.

Real gradient boosting models may contain hundreds or thousands of learners. Every new learner observes the correction required by the model at its current stage and tries to generalize that correction.

With many input features, the tree decides which features are useful through its splits. One branch might partition the data according to age, another according to account balance, and another according to the interaction between several previous decisions. We do not need to manually specify which feature should be responsible for each correction.

This is one reason trees are particularly attractive as base learners for tabular data. They naturally represent thresholds, nonlinearities, and feature interactions without requiring every relationship to be expressed as a smooth transformation in a continuous representation space.

The individual trees used in boosting are usually kept relatively small.

If each learner were an extremely deep tree capable of almost perfectly fitting the current residuals, then each boosting step could memorize a large portion of the training set. Shallow trees instead provide a restricted function class: every update can capture only part of the remaining structure.

This creates an important interaction between tree complexity, learning rate, and the number of boosting rounds. Hundreds of trees with a sufficiently small learning rate may gradually construct a useful function, while hundreds of highly expressive trees combined with aggressive updates can eventually overfit.

There is also nothing in the mathematical definition of gradient boosting that says the learners must be trees.

We could, in principle, use linear models, splines, small neural networks, or other function classes. Decision trees became the dominant choice because they combine useful approximation capacity with an inductive bias that works extremely well for many structured datasets.

What Do We Do When We Want to Classify?

So far, our example has had an especially convenient property: the prediction can be any real number.

If the target is continuous, there is no problem with predicting

4.2,0.7,38.1-4.2,\quad 0.7,\quad 38.1

or any other value in

(,).(-\infty,\infty).

With squared error, we can also compute a particularly intuitive correction:

yy^y-\hat y

and add a model that predicts it.

Binary classification is different.

Now the final quantity we want is a probability:

p(y=1x)[0,1].p(y=1\mid x)\in[0,1].

Adding arbitrary corrections directly to probabilities would be awkward. A probability of 0.90.9, for example, cannot simply receive a correction of +0.4+0.4, because 1.31.3 is not a valid probability.

A convenient solution is to perform boosting in a different numerical space.

Instead of constructing the additive model directly in probability space, we transform probabilities from (0,1)(0,1) into values that can range from -\infty to ++\infty. The trees operate in that unconstrained space, and when we need an actual probability, we transform the model’s output back into (0,1)(0,1).

Regression predicts directly, while classification boosts through logit spaceRegression adds two tree corrections directly on a real-valued prediction number line. Binary classification starts in probability space, where targets are zero or one and predictions lie between them. Logit maps the prediction to an unconstrained number line, two tree corrections are added there, and sigmoid maps the result back to a probability.Regressionadd directly in prediction spacereal-valued prediction−∞+∞F₀+ ηh₁+ ηh₂F₂Binary classificationleave probability space only while fitting correctionsprobability space01p₀ 0.40logitlogit space−∞+∞F₀+ ηh₁+ ηh₂F₂sigmoidprobability space01p₂ 0.53targets stay at 0 or 1 · predictions return between themRegression predicts directly, while classification boosts through logit spaceRegression adds two tree corrections directly on a real-valued prediction number line. Binary classification starts in probability space, uses logit to enter an unconstrained number line, adds two tree corrections, and uses sigmoid to return to probability space where targets are zero or one.Regressionadd directly in prediction space−∞+∞F₀+ ηh₁+ ηh₂F₂Binary classificationmove spaces only while fitting correctionsprobability space01p₀ 0.40logitlogit space−∞+∞F₀+ ηh₁+ ηh₂F₂sigmoidprobability space01p₂ 0.53targets stay at 0 or 1 · predictions return between them
Regression adds on the prediction line. Classification uses logit space for the additions, then sigmoid returns the score to a probability.

Sigmoid and Logits

The two functions that connect these spaces are the sigmoid and the logit.

The sigmoid takes any real number zz and maps it to a value between zero and one:

σ(z)=11+ez.\sigma(z) = \frac{1}{1+e^{-z}}.

As zz\rightarrow-\infty, the sigmoid approaches zero. As z+z\rightarrow+\infty, it approaches one.

Its inverse is the logit:

logit(p)=log(p1p).\operatorname{logit}(p) = \log\left(\frac{p}{1-p}\right).

The logit takes a probability p(0,1)p\in(0,1) and maps it onto the entire real line.

Sigmoid: logit → probability

00.51-404z = −0.405 → p = 0.40logit zprobability p

Logit: probability → logit

-8-4048-1012p = 0.40 → z = −0.405probability plogit z−∞ as p → 0+∞ as p → 1
The functions undo each other: swapping the horizontal and vertical coordinates turns one graph into the other. The shared baseline appears in both views: probability 0.40 is logit −0.405.

These functions therefore provide a two-way bridge:

plogitzsigmoidp.p \overset{\text{logit}}{\longrightarrow} z \overset{\text{sigmoid}}{\longrightarrow} p.

A probability of 0.50.5 corresponds to a logit of 00. Probabilities above 0.50.5 have positive logits, while probabilities below 0.50.5 have negative logits.

Gradient boosting can construct an additive model in this logit space:

FM(x)=F0(x)+ηh1(x)++ηhM(x),F_M(x) = F_0(x) + \eta h_1(x) +\cdots+ \eta h_M(x),

and the final probability is

p(x)=σ(FM(x)).p(x)=\sigma(F_M(x)).

Putting the Pieces Together

Consider a one-dimensional classification dataset with forty observations. It keeps the same input range as the regression problem, but every target is now either class 00 or class 11. Sixteen observations belong to class 11 and twenty-four belong to class 00.

The tables below highlight five observations from this dataset. We will keep the complete forty-row problem fixed for every table, curve, tree, and animation in this section.

Before training the first tree, we again need a baseline.

The empirical probability of class 11 is

p0=1640=0.4.p_0=\frac{16}{40}=0.4.

Because our additive model operates in logit space, the initial model value is

F0=logit(0.4)=log(0.40.6)0.405.F_0 = \operatorname{logit}(0.4) = \log\left(\frac{0.4}{0.6}\right) \approx -0.405.

Every observation initially receives this same logit, which corresponds through the sigmoid to a probability of 0.40.4.

We now need to decide what the next tree should learn.

With binary cross-entropy, the relevant quantity turns out to be

ri=yipi.r_i=y_i-p_i.

If yi=1y_i=1 while the current model predicts pi=0.4p_i=0.4, then

ri=10.4=0.6.r_i=1-0.4=0.6.

The model needs to move in a direction that raises the logit and therefore raises the probability.

If yi=0y_i=0,

ri=00.4=0.4,r_i=0-0.4=-0.4,

so the correction points in the opposite direction.

These values are usually called pseudo-residuals because they play the same role that ordinary residuals played in squared-error regression, even though they arise from the gradient of a different loss.

We will derive this formally later. For now, the important idea is that the loss gives us a correction signal for every training observation.

The loss gives each observation a signed correction signalregional-classes-v1 · highlighted rows
The loss gives each observation a signed correction signal
rowinput xclass ybaseline p₀baseline F₀signal y − p₀
C07−1.9700.40−0.405−0.40
C16−0.6510.40−0.4050.60
C19−0.2200.40−0.405−0.40
C260.8010.40−0.4050.60
C352.1200.40−0.405−0.40
At the baseline, class-1 rows ask for +0.60 and class-0 rows ask for −0.40 in the first-order gradient direction.

In the first-order construction used by this article’s playgrounds, a new tree models this correction signal across the feature space. Some production implementations then refine the leaf values using the curvature of the loss. That changes the size of an update, not the correction loop itself.

For observation C16, the first fitted tree and a learning rate of 0.80.8 contribute approximately +0.292+0.292 in logit space. Starting from

F0=0.405,F_0=-0.405,

the updated score becomes

F10.405+0.2920.114.F_1\approx-0.405+0.292\approx-0.114.

To convert this back into a probability:

p1=σ(0.114)=11+e0.1140.472.p_1 = \sigma(-0.114) = \frac{1}{1+e^{0.114}} \approx 0.472.

The probability therefore moves from 0.40.4 to about 0.4720.472.

If this observation belongs to class 11, that is a useful correction. For observations belonging to class 00, useful updates should generally move their logits downward and consequently decrease their probabilities.

One tree moves different input regions in different directionsregional-classes-v1 · highlighted rows
One tree moves different input regions in different directions
rowinput xclass ybaseline p₀baseline F₀signal y − p₀ηh₁(x)new F₁new p₁
C07−1.9700.40−0.405−0.40−0.32−0.7250.33
C16−0.6510.40−0.4050.600.29−0.1140.47
C19−0.2200.40−0.405−0.400.29−0.1140.47
C260.8010.40−0.4050.600.29−0.1140.47
C352.1200.40−0.405−0.40−0.02−0.4250.40
The tree predicts the pseudo-residual pattern by region. Its scaled output is added to the logit, then sigmoid converts the result back to probability.

Notice that the tree does not correct each observation independently. It learns one regional pattern. A noisy class-00 observation can therefore move upward with nearby class-11 observations even while the total cross-entropy falls. Boosting improves the shared model, not necessarily every row on every round.

After the update, the model should assign lower probabilities to at least some class-00 examples and higher probabilities to at least some class-11 examples. We can then calculate a new probability for every observation, obtain a new set of pseudo-residuals, train another tree, and repeat the process.

The overall architecture is therefore almost unchanged from regression.

What changes is the loss, and because the loss changes, so does the correction signal produced at every iteration.

A More Concrete Example

The five highlighted rows expose the arithmetic, but the complete dataset makes the regional decision pattern visible.

The same forty observations now appear on two class rails. Rather than learning a continuous regression target, the model must learn how the probability of class 11 changes across the input space.

Before pressing play, predict what will remain unchanged from regression and what must change. Then follow the class labels, the ypy-p correction signal, and the additive logit contributions through four shallow trees.

The correction loop survives a new loss0 trees · η 0.80 · log loss 0.673

Start from the class-one rate: p₀ = 0.40 and F₀ = −0.405.

Probability of class 1labels stay fixed
Current probability of class oneBinary observations remain fixed at zero and one. A green piecewise curve shows the probability obtained by applying sigmoid to the accumulated logit model.00.51-303input xp0(x)class 1class 0
Correction signal y − pnext tree h1
Current pseudo-residual correction signalEach observation keeps its input coordinate and moves to y minus the current class-one probability. The amber step line is the next shallow tree fitted to this signal.-101-303input xzeroh1(x)
baseline logit−0.405
=logit F0score
sigmoidp0

hover or focus a point

completed trees

After 0 trees, training log loss is 0.673. The probability curve is the sigmoid of the additive logit model.

The important difference is what the curve represents.

In regression, the ensemble directly approximated the numerical target. In binary classification, the additive ensemble builds a score in logit space, while the sigmoid transforms that score into the probability curve we actually interpret.

A tree that makes a positive correction in some interval is increasing the log-odds of class 11 there. A negative correction decreases them. Repeating these local adjustments can eventually form a highly nonlinear classification boundary even though every individual tree remains small.

Before adding more notation, compress the entire journey into one loop. The current model makes predictions. The chosen loss turns those predictions into a correction signal. A small tree learns the part of that signal that can be explained from the inputs. We shrink and add the tree, obtain a new model, and ask the loss again.

Regression and classification differ in the prediction space and the correction signal, but not in this sequence.

Mathematics

Regression

The residual-based explanation above is exact for one particularly important case: squared-error regression.

Suppose our training set is

{(xi,yi)}i=1n,\{(x_i,y_i)\}_{i=1}^{n},

and our current model is F(x)F(x).

We want to minimize an empirical loss

L(F)=i=1nL(yi,F(xi)).\mathcal{L}(F) = \sum_{i=1}^{n} L(y_i,F(x_i)).

For squared error, we can write

L(yi,F(xi))=12(yiF(xi))2.L(y_i,F(x_i)) = \frac{1}{2} \left(y_i-F(x_i)\right)^2.

The derivative with respect to the prediction F(xi)F(x_i) is

LF(xi)=F(xi)yi.\frac{\partial L}{\partial F(x_i)} = F(x_i)-y_i.

The negative derivative is therefore

LF(xi)=yiF(xi),-\frac{\partial L}{\partial F(x_i)} = y_i-F(x_i),

which is exactly the residual.

This gives us a more general interpretation of what we were doing earlier.

At boosting iteration mm, we calculate

rim=[L(yi,F(xi))F(xi)]F=Fm1.r_{im} = - \left[ \frac{\partial L(y_i,F(x_i))} {\partial F(x_i)} \right]_{F=F_{m-1}}.

These are the negative gradients of the loss with respect to the current predictions.

We then fit a learner hm(x)h_m(x) so that

hm(xi)rim.h_m(x_i)\approx r_{im}.

Finally, we update the predictive function:

Fm(x)=Fm1(x)+ηhm(x).F_m(x) = F_{m-1}(x) + \eta h_m(x).

For squared error this reduces to the intuitive residual procedure we have already seen, because the negative gradient happens to be yy^y-\hat y.

For another differentiable loss, the negative gradient will generally be something else.

This is the point at which the word gradient in gradient boosting becomes precise.

The gradient is not being taken with respect to the split thresholds of a decision tree, nor are we differentiating through the tree. Instead, at every training observation, we ask how the loss would change if the current prediction moved slightly.

If the model currently produces the vector

F=[F(x1)F(x2)F(xn)],\mathbf F = \begin{bmatrix} F(x_1)\\ F(x_2)\\ \vdots\\ F(x_n) \end{bmatrix},

then the loss defines a gradient vector

FL=[LF(x1)LF(x2)LF(xn)].\nabla_{\mathbf F}\mathcal L = \begin{bmatrix} \frac{\partial \mathcal L}{\partial F(x_1)}\\ \frac{\partial \mathcal L}{\partial F(x_2)}\\ \vdots\\ \frac{\partial \mathcal L}{\partial F(x_n)} \end{bmatrix}.

Ordinary gradient descent would like to move the predictions in the direction

FL.-\nabla_{\mathbf F}\mathcal L.

But simply storing one independent correction for every training point would not give us a model that can make predictions for unseen inputs.

Gradient boosting therefore introduces a crucial approximation: it trains a learner hm(x)h_m(x) to generalize the desired gradient direction as a function of the features.

This is the central bridge between optimization and supervised learning.

The gradient tells us how the predictions should change on the training set. The weak learner searches for structure in those changes and turns them into a function that can also be evaluated at new xx.

This perspective is often described as optimization in function space.

In ordinary gradient descent, we might have

f(x;θ)f(x;\theta)

and update a finite-dimensional parameter vector:

θm=θm1ηθL.\theta_m = \theta_{m-1} - \eta\nabla_\theta\mathcal L.

In gradient boosting, we instead build the predictive function additively:

Fm=Fm1+ηhm.F_m = F_{m-1} + \eta h_m.

The search direction is therefore represented by a new function rather than by a direct perturbation of an existing parameter vector.

A more complete version of the update can also include a step size γm\gamma_m:

Fm(x)=Fm1(x)+ηγmhm(x),F_m(x) = F_{m-1}(x) + \eta\gamma_m h_m(x),

where

γm=argminγi=1nL(yi,Fm1(xi)+γhm(xi)).\gamma_m = \arg\min_\gamma \sum_{i=1}^{n} L\left( y_i, F_{m-1}(x_i)+\gamma h_m(x_i) \right).

Different implementations approximate or optimize these updates in different ways, but the underlying structure remains the same: obtain a direction from the loss, approximate that direction with a learner, and add the learner to the current function.

Change the loss and the correction target changes. The fit-and-add engine stays the same.

Once we formulate boosting this way, squared-error regression stops being a special algorithm and becomes one instance of a general framework.

Change the loss and the gradient changes with it. The same additive procedure can therefore be adapted to absolute-error-like objectives, Poisson regression, binary classification, multiclass classification, and many other tasks.

Classification

Let us now formalize the binary classification procedure.

For a binary target

yi{0,1},y_i\in\{0,1\},

we let the ensemble produce a raw score

F(xi)R.F(x_i)\in\mathbb R.

This score represents a logit. The corresponding probability is

pi=σ(F(xi))=11+eF(xi).p_i = \sigma(F(x_i)) = \frac{1}{1+e^{-F(x_i)}}.

We can optimize binary cross-entropy:

L(yi,F(xi))=[yilogpi+(1yi)log(1pi)].L(y_i,F(x_i)) = - \left[ y_i\log p_i + (1-y_i)\log(1-p_i) \right].

Although the loss is written in terms of pip_i, that probability depends on the raw model score through

pi=σ(F(xi)).p_i=\sigma(F(x_i)).

Taking the derivative with respect to the raw score gives

LF(xi)=piyi.\frac{\partial L}{\partial F(x_i)} = p_i-y_i.

Therefore the negative gradient is

LF(xi)=yipi.-\frac{\partial L}{\partial F(x_i)} = y_i-p_i.

This is precisely the pseudo-residual introduced earlier.

At iteration mm,

pim=σ(Fm1(xi)),p_{im} = \sigma(F_{m-1}(x_i)),

and we calculate

rim=yipim.r_{im} = y_i-p_{im}.

A tree is then fitted using these gradient signals as targets.

Conceptually:

hm(xi)yipim.h_m(x_i)\approx y_i-p_{im}.

The ensemble is subsequently updated in raw-score space,

Fm(x)=Fm1(x)+ηcorrectionm(x),F_m(x) = F_{m-1}(x) + \eta\,\text{correction}_m(x),

and the new probability is

pm(x)=σ(Fm(x)).p_m(x) = \sigma(F_m(x)).

This makes the similarity with regression much clearer.

For squared-error regression:

ri=yiF(xi).r_i=y_i-F(x_i).

For logistic classification:

ri=yiσ(F(xi)).r_i=y_i-\sigma(F(x_i)).

In both cases, these quantities are negative gradients of the chosen loss with respect to the current prediction representation.

Optional implementation note: using curvature to choose leaf values

Saying that a classification tree predicts ypy-p is the first-order description used by the playgrounds in this article. Many practical gradient boosting algorithms do not simply average those pseudo-residuals inside a leaf and add that value directly. Once a tree has defined its regions, the value assigned to each leaf can be chosen to minimize the loss. This can use curvature information from the second derivative.

For logistic loss, let

gi=LF(xi)=piyi,g_i = \frac{\partial L}{\partial F(x_i)} = p_i-y_i,

while

Hi=2LF(xi)2=pi(1pi).H_i = \frac{\partial^2L}{\partial F(x_i)^2} = p_i(1-p_i).

A second-order approximation to the loss around the current prediction has the form

L(F+Δ)L(F)+gΔ+12HΔ2.L(F+\Delta) \approx L(F) + g\Delta + \frac{1}{2}H\Delta^2.

Minimizing this local quadratic approximation gives a Newton-like correction

ΔgH.\Delta \approx -\frac{g}{H}.

When several observations fall into one tree leaf RjR_j, a corresponding aggregate Newton step has the general form

wjiRjgiiRjHi,w_j \approx - \frac{\sum_{i\in R_j}g_i} {\sum_{i\in R_j}H_i},

before considering additional regularization terms that a particular implementation may introduce.

Because

igi=i(yipi),-\sum_i g_i = \sum_i(y_i-p_i),

the first-order and second-order stories are not competing explanations. The pseudo-residual gives the direction in which the loss wants each prediction to move. Curvature can help choose the size of the update. This is the idea behind second-order boosting methods such as XGBoost, although individual implementations add their own regularization, split criteria, and computational machinery.

The initial classification prediction also follows directly from the loss.

If the training set contains a fraction

yˉ=1ni=1nyi\bar y = \frac{1}{n}\sum_{i=1}^{n}y_i

of positive examples, then the constant probability that minimizes binary cross-entropy is

p0=yˉ.p_0=\bar y.

Since the ensemble operates in logit space, the corresponding initial raw score is

F0=log(yˉ1yˉ).F_0 = \log\left( \frac{\bar y}{1-\bar y} \right).

From there, boosting repeatedly computes probabilities, derives gradients from the loss, fits trees to useful correction patterns, and updates the additive score.

The same general principle extends beyond binary classification. Multiclass problems require multiple class scores and a softmax transformation, while other statistical objectives produce their own gradients and Hessians. The mechanics become more elaborate, but the central procedure remains unchanged.

Conclusion and Caveats

Gradient boosting becomes considerably easier to reason about once we stop thinking of it as a mysterious sequence of trees.

The ensemble starts with a simple function:

F0(x).F_0(x).

The loss tells us how the current predictions should change. A weak learner observes those desired corrections across the training set and tries to generalize them from the input features. We shrink its contribution, add it to the current model, calculate what is still wrong, and repeat.

For squared-error regression, those corrections are the familiar residuals

yy^.y-\hat y.

More generally, they are negative gradients

LF(x).-\frac{\partial L}{\partial F(x)}.

This is what allows the same framework to move from regression to classification and many other objectives simply by changing the loss.

Decision trees are especially effective as the learners inside this process because they can capture thresholds, interactions, and nonlinear structure that frequently appear in tabular data. At the same time, keeping individual trees weak forces the ensemble to construct the final function gradually rather than allowing one learner to dominate the fit.

That gradual construction introduces several tradeoffs. The learning rate controls the magnitude of each update. Tree depth controls the complexity available in one update. The number of boosting rounds controls how many opportunities the ensemble receives to correct itself. Increasing any of them indiscriminately can eventually make the model fit training-specific structure rather than generalizable patterns, which is why validation performance and early stopping are important in practice.

The optimization interpretation also has an important limitation. A tree does not reproduce the exact negative-gradient vector independently for every observation. It approximates that vector using a restricted function class. Points assigned to the same leaf share a correction, and the quality of every boosting step therefore depends on whether the tree can find meaningful structure in the gradients.

That restriction is also part of what makes the method useful. Instead of memorizing an arbitrary update for every training observation, gradient boosting repeatedly searches for corrections that can be expressed as reusable rules over the feature space.

After enough iterations, the final model may contain hundreds of trees, yet each one solves a relatively modest problem:

Given what the ensemble predicts now, what systematic correction should come next?\text{Given what the ensemble predicts now, what systematic correction should come next?}

Gradient Boosted Decision Trees turn that sequence of small questions into a powerful predictive function.