Bagging

ml basics

Bagging is covered in section 8.2 of An Introduction to Statistical Learning. The method comes from Leo Breiman’s 1996 paper “Bagging Predictors”. The name is short for bootstrap aggregating.

The bias and variance post ended with a problem: a deep tree has almost no bias but huge variance. Its answer depends heavily on which data it happened to see. Bagging fixes that by averaging many trees.

The idea: ask a committee

If you ask one settlements analyst how late a trade will settle, you get their answer, quirks and all. Ask twenty analysts who each learned from a slightly different set of past trades, and take the average: their individual quirks partly cancel out, and what’s left is closer to the real pattern.

Bagging does this with models:

  1. Make many bootstrap samples of the training data.
  2. Train one model (usually a deep decision tree) on each.
  3. Average their predictions. For classification, average their probabilities, or take a vote.

Step 1: the bootstrap sample

A bootstrap sample is drawn from the training data with replacement, and it has the same size as the original. Some rows get picked more than once, some not at all.

Eight trades, numbered 1 to 8, and three bootstrap samples of them:

SampleRows drawnLeft out
11, 3, 7, 7, 7, 7, 8, 82, 4, 5, 6
21, 1, 2, 5, 5, 7, 7, 83, 4, 6
32, 3, 4, 7, 7, 7, 8, 81, 5, 6

Each tree sees a different version of the history, so each tree comes out different.

How many rows does a bootstrap sample leave out? The chance that a given row is not picked in one draw is 1−1/n1 - 1/n. Over nn draws:

ρ, how alike the trees' errors arevariance

(1−1n)n  ⟶  1e≈0.368as n grows\left(1 - \frac{1}{n}\right)^n \;\longrightarrow\; \frac{1}{e} \approx 0.368 \quad \text{as } n \text{ grows}

So each tree never sees about 37% of the data. With 10,000 rows, I measured 36.7%. Those left-out rows are called out-of-bag rows, and they’re useful: each tree can be tested on the rows it never saw, which gives a free estimate of performance without a separate test set.

Step 3: why averaging reduces variance

An Introduction to Statistical Learning (section 8.2.1) starts from a simple fact: averaging nn independent numbers, each with variance σ2\risk{\sigma^2}, gives an average with variance σ2/n\risk{\sigma^2} / n. Bagged trees aren’t independent, though: they learn from overlapping data. If you average BB predictions that each have variance σ2\risk{\sigma^2}, and every pair has correlation ρ\key{\rho}, the average has variance (The Elements of Statistical Learning, equation 15.1):

Var(average)=ρ σ2+1−ρB σ2\risk{\text{Var}}(\text{average}) = \key{\rho}\,\risk{\sigma^2} + \frac{1 - \key{\rho}}{B}\,\risk{\sigma^2}
SymbolMeaning
BBnumber of models averaged
σ2\risk{\sigma^2}variance of one model’s prediction
ρ\key{\rho}correlation between two models’ predictions

Plain meaning: the second term shrinks as you add models. The first term doesn’t. If the models were completely independent (ρ=0\key{\rho} = 0), averaging 100 of them would cut variance 100-fold. But trees trained on overlapping data make similar mistakes (ρ>0\key{\rho} > 0), so variance falls towards a floor of ρ σ2\key{\rho}\,\risk{\sigma^2} and stops. (It’s the same maths as the diversification floor in a portfolio of correlated assets.)

Measuring it

Same made-up problem as the bias and variance post: predict how many days late a trade settles, from how many hours after the cut-off it was booked. Same method: 200 fresh training samples of 80 trades, measuring how much the predictions move between samples.

Trees averagedBias²VarianceExpected error on new trades
1 (one deep tree)0.00060.12110.2442
20.00050.09080.2138
50.00030.07140.1943
100.00050.06430.1872
250.00030.06060.1834
1000.00020.05720.1800

Left: one deep tree zig-zags through the 80 trades; the average of 100 trees is much smoother and closer to the true curve. Right: variance falls fast for the first 10 trees, then levels off; bias stays near zero.

  • Bias stays near zero. Averaging deep trees doesn’t make them too simple.
  • Variance halves, from 0.121 to 0.057, most of it by the first 10 trees.
  • Then it levels off. That’s the ρ σ2\key{\rho}\,\risk{\sigma^2} floor. From these numbers, the trees’ predictions are correlated at roughly ρ≈0.47\key{\rho} \approx 0.47 (my estimate: 0.057/0.1210.057 / 0.121, ignoring the small leftover term).

Honest note: on this small, simple problem, the best single tree from the bias and variance post (depth 2, error 0.154) still beats 100 bagged deep trees (0.180). Bagging removes variance. It doesn’t remove the need to choose a sensible model.

On the settlement-fail data

Now the classification problem from the decision trees post: will this OTC trade fail to settle? Scores are AUC on 5,000 test trades (0.5 is a coin flip, 1.0 is perfect):

Base treeOne treeBag of 200Change
Fully grown0.5840.743big gain
Depth 80.7970.811small gain
Depth 50.8100.810none

This table is the whole lesson of bagging:

  • It helps a lot when the base model is unstable (high variance), like a fully grown tree.
  • It helps little or not at all when the model is already stable. A depth-5 tree changes little between bootstrap samples, so there’s little noise to average away.

And the out-of-bag estimate: from the training data alone, without touching the test set, the bag of fully grown trees reported an AUC of 0.724, close to its real test score of 0.743.

The code

from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier

bag = BaggingClassifier(
    DecisionTreeClassifier(max_depth=8),   # the model to copy
    n_estimators=200,                       # how many copies
    oob_score=True,                         # test each tree on the rows it never saw
    random_state=0,
)
bag.fit(X_train, y_train)
bag.predict_proba(X_test)[:, 1]             # averaged probability of a fail
bag.oob_score_                              # out-of-bag accuracy estimate

Summary

IdeaFormula / ruleRemember it as
Bootstrapsample nn rows with replacementeach tree sees a different history
Left out(1−1/n)n→1/e≈37%(1 - 1/n)^n \to 1/e \approx 37\%free test data: out-of-bag
Aggregateaverage (regression), average or vote (classification)the committee answer
Variance of an averageρσ2+(1−ρ)σ2/B\key{\rho}\risk{\sigma^2} + (1-\key{\rho})\risk{\sigma^2}/Bmore models help, until correlation stops them
When it helpsunstable, high-variance modelsdeep trees: yes; shallow trees: barely

Next

Random forests: bagging, plus one extra trick that makes the trees less correlated, so the ρ σ2\key{\rho}\,\risk{\sigma^2} floor drops and averaging works even better.

References