Four points with y = [10, 20, 30, 40] and a learning rate of 0.5. Start at the mean:
F₀ = 25 for all four
round 1: residuals y − F₀ = [−15, −5, 5, 15]
best two-leaf tree splits between x₂ and x₃:
left leaf = mean(−15, −5) = −10
right leaf = mean( 5, 15) = +10
update 0.5 × [−10, −10, +10, +10] = [−5, −5, +5, +5]
F₁ = [20, 20, 30, 30] MSE 125 → 50
round 2: residuals y − F₁ = [−10, 0, 0, 10]
best split is now between x₁ and x₂:
left = −10, right = mean(0, 0, 10) = +3.333
update 0.5 × [−10, +3.333, +3.333, +3.333]
F₂ = [15, 21.667, 31.667, 31.667] MSE → 25 exactly
round 3: residuals [−5, −1.667, −1.667, 8.333]
best split between x₃ and x₄: left = −2.778, right = +8.333
F₃ = [13.611, 20.278, 30.278, 35.833] MSE → 7.64
125 → 50 → 25 → 7.64: each tree halves or better the remaining
error, and no tree ever saw a raw label — only leftovers.
The same mechanism explains the learning-rate trade-off in the lab. After one tree the toy dataset’s MSE is 2.483 at lr = 0.1 and 1.201 at lr = 0.5; after ten trees it is 0.847 versus 0.208. The small rate lags early, but with enough trees it can catch up while making gentler corrections that usually generalize better. Typical production values run 0.01–0.3.