2.3.9 · D3Tree-Based & Instance Methods

Worked examples — Out-of-bag error estimation

2,578 words12 min readBack to topic

A drill-book for Out-of-bag error estimation. We march through every case the OOB idea can throw at you: normal forests, tiny forests, degenerate points that are OOB for nobody, ties, regression vs classification, the large- limit, and a real-world twist. Guess before you read the steps.

Before anything, one plain-word refresher so no symbol arrives unearned:


The scenario matrix

Every OOB question is really one of these cells. The examples below are tagged with the cell they hit.

Cell Case class What makes it tricky Example
A Identify OOB set from one bootstrap Repeats hide unique picks Ex 1
B Classification vote, clear majority which trees count Ex 2
C Classification vote, tie even , no majority Ex 3
D Regression average different aggregation rule Ex 4
E Full OOB error over all points mixing per-point Ex 5
F Degenerate: point OOB for zero trees prediction undefined Ex 6
G Limiting: vs small the number Ex 7
H Real-world word problem translate story → OOB Ex 8
I Exam twist: OOB vs train error gap why they differ Ex 9

The blueprint below is the whole world our examples live in: rows are points, columns are trees, a cell is dark (in-bag) or amber (OOB). Everything else is bookkeeping on this grid.

Figure — Out-of-bag error estimation

Example 1 — Read the OOB set off a bootstrap (Cell A)

Forecast: guess how many of the 6 points ended up OOB before reading on.

  1. List the distinct indices that appear. They are . Why this step? A point is in-bag if it appears at least once; repeats ( thrice, twice) don't add new points, so we collapse to the unique set.
  2. OOB = everything not in that set: . Why this step? By definition OOB means "never drawn". Points are absent, so the tree never saw them.
  3. Fraction OOB: . Why this step? Just count OOB over .

Verify: in-bag OOB , and they're disjoint — every point is classified exactly once. ✓ Fraction here; for tiny the OOB fraction is noisy and only settles onto its long-run value for large — we derive that long-run value () carefully in Example 7, so don't worry where it comes from yet.


Example 2 — Classification, clear majority (Cell B)

Forecast: which label wins, and does it match ?

  1. Count votes only inside . Zeros: → three. Ones: → two. Why this step? Only trees that never trained on may vote — that keeps the estimate honest (no bagging label leakage).
  2. Majority vote: . Why this step? Classification aggregation is the plurality of the sub-ensemble .
  3. Loss: (recall is if the inside is true, else ; here is false). Why this step? 0/1 loss is when prediction matches truth.

Verify: — all OOB votes accounted for. Prediction equals , so this point adds nothing to the error. ✓


Example 3 — Classification with a TIE (Cell C)

Forecast: two ones, two zeros — what does a forest actually do?

  1. Count: ones , zeros . A genuine tie. Why this step? An even can split evenly — the case the naive "majority" rule doesn't cover.
  2. Turn the 0/1 votes into a class-1 probability. Each tree votes a hard or ; the ensemble's estimated probability of class 1 is simply the fraction of trees voting 1 among : . Why this step? "Probability of class 1" is not mystical here — it is just how many of the qualifying trees said 1, divided by how many voted. Averaging the votes gives that fraction directly.
  3. Apply the deterministic tie rule. The default rule predicts the class with the largest ; at an exact tie it returns the lower class index, so . Why this step? We must state a reproducible rule; scikit-learn's default is "argmax of averaged probabilities", and on an exact it returns the first class (index ).
  4. Loss: . Why this step? 0/1 loss penalizes the mismatch fully.

Verify: exactly ( of votes are ), confirming a true tie; the deterministic rule gives a reproducible answer instead of a coin flip. ✓ (If your library breaks ties toward class 1, and loss — always know your library's rule.)


Example 4 — Regression average (Cell D)

Forecast: guess the averaged prediction to the nearest integer.

  1. Average the OOB predictions. . Why this step? Regression aggregation is the mean over , not a vote — trees output numbers, so we average.
  2. Squared error: . Why this step? Squared-error loss is the standard regression loss .

Verify: , and . The scatter around () cancels, giving a perfect hit — a nice reminder that averaging reduces variance (Bias-Variance Tradeoff). ✓


Example 5 — Full OOB error with per-point sub-ensembles (Cell E)

Forecast: how many of the 4 points get misclassified?

  1. Point 1: ones vs zeros → loss . Why this step? Point 1 is judged only by its own (3 trees); majority is , matching .
  2. Point 2: zeros vs ones → loss . Why this step? has 4 trees, a different set from ; the majority matches .
  3. Point 3: tie → lower-index rule → → loss . Why this step? has only 2 trees and splits evenly, so we fall back to the Example-3 tie rule (predict class ), which misses the truth.
  4. Point 4: ones vs zeros → loss . Why this step? (3 trees) votes majority , but the truth is — an honest mistake this sub-ensemble makes.
  5. Average: Why divide by ? We average the per-point losses over all training points, each scored by its own — no shared hold-out.

Verify: two of four points wrong → . ✓ Note each point used a different number of votes () — legitimate and typical.


Example 6 — Degenerate: a point OOB for NOBODY (Cell F)

Forecast: can we even predict this point with OOB rules?

  1. Look at . It is empty: no tree qualifies to vote. Why this step? OOB prediction is defined only over . With there is nothing to average or vote.
  2. The prediction is undefined. Implementations either skip from the OOB error or emit a warning. Why this step? You cannot leak a label into the estimate, so you must exclude the point — it contributes terms to both numerator and denominator of the average.
  3. Estimate how likely this is. The chance one tree leaves out is the exact finite- miss-probability (derived in Example 7). So the chance it is in-bag for one tree is , and for all trees at once: For a large dataset the inner term approaches its limit , giving . For (and large ): — a whopping 25% chance! For : — vanishing. Why this step? We separate the exact finite- formula from its large- shortcut , so you know the is an approximation valid when is big.

Verify: ✓ This is exactly the "OOB needs many trees" mistake from the parent: small leaves points undefined and estimates high-variance.


Example 7 — The limiting number, small vs large (Cell G)

Forecast: is the fraction increasing or decreasing toward ?

  1. : . Why this step? Direct plug-in of the exact miss-probability formula from the parent.
  2. : . Why this step? Larger pushes toward the limit; still slightly above it.
  3. : Why this step? This is the definition at — the exponential is the tool that answers "what does repeated tiny multiplication converge to?"
Figure — Out-of-bag error estimation

How to read this figure: the horizontal axis is the dataset size ; the vertical axis is the OOB fraction . The cyan curve plots that fraction as grows — it climbs steadily. The dashed amber line is the limit . The two white dots mark our computed values at () and (). Read off the key message: the curve rises from below and flattens onto the amber line, so real datasets always have a little more than OOB when is small, converging down onto as grows.

Verify: the sequence climbs monotonically toward from below. ✓ So every real dataset has slightly more than 37% OOB for small , converging down onto as grows.


Example 8 — Real-world word problem (Cell H)

Forecast: guess how many of the 500 trees vote per customer.

  1. OOB fraction per tree . Why this step? is huge, so we use the limiting value.
  2. Expected trees with the customer OOB: trees. Why this step? Each tree independently leaves the customer out with probability ; expected count .
  3. Trust argument: those trees never saw that customer, so their averaged vote is an honest test prediction. Doing this for all customers yields a test-error estimate for free during training — no extra model fits, unlike -fold CV which refits times. Why this step? This is the core value proposition of OOB from the parent note.

Verify: . ✓ And , so no undefined predictions — large cures Cell F.


Example 9 — Exam twist: OOB vs training error (Cell I)

Forecast: which number is closer to real-world performance?

  1. Training error uses ALL trees, including those that memorized each point. So a point is scored partly by trees that trained on it → optimistic → artificially low (). Why this step? Decision trees can perfectly fit their bootstrap sample, so in-bag scoring leaks labels.
  2. OOB error uses only (unseen trees). No leakage → honest → higher and realistic (). Why this step? This is exactly why we restrict to .
  3. Conclusion: the model did not get worse; is the trustworthy test-error estimate. The gap is the optimism of training error. Why this step? OOB CV true test error; training error is a lower bound you should never quote.

Verify: gap (OOB train for a well-fit forest). ✓ Reporting would over-promise; report .


Recall One-line summary of the matrix

Guess the cell first ::: Identify OOB set (A) → aggregate by vote or mean over only (B/C/D) → average per-point losses (E) → watch empty (F) and the limit (G) → translate stories (H) and never confuse OOB with train error (I).


Connections

  • Bootstrap Sampling — creates the in-bag/OOB split every example reads off.
  • Bootstrap Aggregating (Bagging) — the sub-ensemble is honest bagging on unseen data.
  • Random Forests — the real consumer of OOB error (Ex 8).
  • Cross-Validation — the paid alternative OOB replaces for free.
  • Bias-Variance Tradeoff — averaging (Ex 4) cancels variance.
  • Decision Trees — memorizing base learners cause the Ex 9 gap.