Bagging: many copies of a model, averaged

Machine Learning Series 1

On this page
  1. The idea: ask a committee
  2. Step 1: the bootstrap sample
  3. Step 3: why averaging reduces variance
  4. Measuring it
  5. On the stress-month data
  6. Three more experiments
  7. The code
  8. Summary
  9. References

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 risk analyst how volatile next month will be, you get their answer, quirks and all. Ask twenty analysts who each learned from a slightly different few years of history, 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 training rows, 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:

(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, and uses about two-thirds of it (ISLP section 8.2.1, Murphy section 18.3). 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:

ρ, how alike the trees' errors areσ², one tree's variance

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. ISLP (section 8.2.2) says the same in words: averaging highly correlated quantities does not reduce variance as much as averaging uncorrelated ones. (It’s the same maths as the diversification floor in a portfolio of correlated assets.)

Where the formula comes from

The variance of a sum is the sum of every variance plus every covariance between pairs. BB models each have variance σ2\risk{\sigma^2}, and each of the B(B−1)B(B - 1) ordered pairs has covariance ρ σ2\key{\rho}\,\risk{\sigma^2}. Dividing the sum by BB divides its variance by B2B^2:

Var(average)=1B2(B σ2+B(B−1) ρ σ2)=σ2B+B−1B ρ σ2=ρ σ2+1−ρB σ2\begin{aligned} \text{Var}(\text{average}) &= \frac{1}{B^2}\left(B\,\risk{\sigma^2} + B(B - 1)\,\key{\rho}\,\risk{\sigma^2}\right) \\[10pt] &= \frac{\risk{\sigma^2}}{B} + \frac{B - 1}{B}\,\key{\rho}\,\risk{\sigma^2} \\[10pt] &= \key{\rho}\,\risk{\sigma^2} + \frac{1 - \key{\rho}}{B}\,\risk{\sigma^2} \end{aligned}

Measuring it

Same made-up problem as the bias and variance post: predict next month’s volatility from this month’s, on a curve I invented so the truth is known. Same method: 200 fresh training samples of 80 made-up months, measuring how much the predictions move between samples.

Trees averagedBias²VarianceExpected error on new months
1 (one deep tree)0.048.8817.93
20.036.6915.72
50.025.2314.26
100.034.7113.74
250.034.4413.47
1000.024.2013.22

{"panels":[{"x0":43.64,"x1":565.2,"y0":29.16,"y1":223.28,"title":"1. Same 80 months: one deep tree against the average of 100","xlabel":"This month's volatility (% a year)","ylabel":"Next month's volatility (% a year)","xlog":false},{"x0":43.64,"x1":565.2,"y0":311.96,"y1":506.08,"title":"2. Variance falls with more trees, then levels off; bias stays flat","xlabel":"Number of trees averaged (log scale)","ylabel":"Squared error on new months (volatility points\u00b2)","xlog":true}],"series":[{"panel":0,"label":"one deep tree","color":"#e0676b","x":[5.0,5.20101,5.40201,5.60302,5.80402,6.00503,6.20603,6.40704,6.60804,6.80905,7.01005,7.21106,7.41206,7.61307,7.81407,8.01508,8.21608,8.41709,8.61809,8.8191,9.0201,9.22111,9.42211,9.62312,9.82412,10.0251,10.2261,10.4271,10.6281,10.8291,11.0302,11.2312,11.4322,11.6332,11.8342,12.0352,12.2362,12.4372,12.6382,12.8392,13.0402,13.2412,13.4422,13.6432,13.8442,14.0452,14.2462,14.4472,14.6482,14.8492,15.0503,15.2513,15.4523,15.6533,15.8543,16.0553,16.2563,16.4573,16.6583,16.8593,17.0603,17.2613,17.4623,17.6633,17.8643,18.0653,18.2663,18.4673,18.6683,18.8693,19.0704,19.2714,19.4724,19.6734,19.8744,20.0754,20.2764,20.4774,20.6784,20.8794,21.0804,21.2814,21.4824,21.6834,21.8844,22.0854,22.2864,22.4874,22.6884,22.8894,23.0905,23.2915,23.4925,23.6935,23.8945,24.0955,24.2965,24.4975,24.6985,24.8995,25.1005,25.3015,25.5025,25.7035,25.9045,26.1055,26.3065,26.5075,26.7085,26.9095,27.1106,27.3116,27.5126,27.7136,27.9146,28.1156,28.3166,28.5176,28.7186,28.9196,29.1206,29.3216,29.5226,29.7236,29.9246,30.1256,30.3266,30.5276,30.7286,30.9296,31.1307,31.3317,31.5327,31.7337,31.9347,32.1357,32.3367,32.5377,32.7387,32.9397,33.1407,33.3417,33.5427,33.7437,33.9447,34.1457,34.3467,34.5477,34.7487,34.9497,35.1508,35.3518,35.5528,35.7538,35.9548,36.1558,36.3568,36.5578,36.7588,36.9598,37.1608,37.3618,37.5628,37.7638,37.9648,38.1658,38.3668,38.5678,38.7688,38.9698,39.1709,39.3719,39.5729,39.7739,39.9749,40.1759,40.3769,40.5779,40.7789,40.9799,41.1809,41.3819,41.5829,41.7839,41.9849,42.1859,42.3869,42.5879,42.7889,42.9899,43.191,43.392,43.593,43.794,43.995,44.196,44.397,44.598,44.799,45.0],"y":[11.852,11.852,11.852,11.852,11.852,11.852,11.852,11.852,8.94497,8.94497,8.94497,6.06014,6.06014,6.06014,6.06014,8.74634,8.74634,2.5224,2.5224,2.5224,2.5224,7.82229,7.82229,7.82229,7.82229,7.82229,4.26322,4.26322,4.26322,13.8056,13.8056,13.8056,13.8056,13.8056,14.5951,14.5951,14.5951,14.5951,14.5951,14.5951,14.5951,15.3526,15.3526,15.3526,15.3526,15.3526,14.115,14.115,14.2192,14.2192,12.2153,13.4073,13.4073,16.9551,13.6607,8.54086,12.4078,13.9045,13.9045,11.7422,11.7422,13.7413,13.7413,13.7413,11.1421,11.1421,11.1421,11.1421,13.644,19.0833,19.0833,19.0833,19.0833,13.759,13.759,13.759,13.759,21.5125,17.1478,18.2522,15.3974,15.2432,14.1519,14.1519,14.1519,17.888,17.888,17.888,17.888,19.0902,19.0902,19.0902,23.4932,23.4932,23.4932,20.7252,20.7252,20.7252,20.7252,20.1777,20.1777,20.1777,21.5406,21.5406,21.5406,21.5406,20.5867,20.5867,20.5867,28.4094,19.9061,19.9061,21.7259,21.965,25.1717,25.1717,18.1023,18.1023,24.8201,20.3173,20.3173,30.29,26.4644,26.962,25.9214,27.5054,27.5054,27.5054,18.7234,18.7234,18.7234,28.1423,28.1423,28.4691,28.4691,27.6798,26.8892,26.8892,26.8892,29.0064,29.0064,32.832,26.8351,26.8351,26.8618,27.1187,27.1187,27.1187,27.0324,27.0324,27.0324,27.0324,31.9554,31.9554,30.2339,32.9215,35.3438,35.3438,35.3438,35.3438,35.3438,35.3438,31.3188,31.3188,31.3188,31.3188,31.3188,31.3188,31.3188,31.1643,31.1643,31.1643,31.1643,31.1643,36.3013,36.3013,36.3013,36.3013,32.4903,32.4903,30.7639,30.7639,30.7639,30.7639,29.6591,29.6591,34.7382,34.7382,34.7382,34.7382,29.2674,29.2674,29.2674,33.5172,33.5172,33.5172,34.6535,34.6535,34.6535,34.6535],"sx":[67.35,69.73,72.11,74.5,76.88,79.26,81.65,84.03,86.41,88.79,91.18,93.56,95.94,98.32,100.71,103.09,105.47,107.85,110.24,112.62,115.0,117.38,119.77,122.15,124.53,126.92,129.3,131.68,134.06,136.45,138.83,141.21,143.59,145.98,148.36,150.74,153.12,155.51,157.89,160.27,162.65,165.04,167.42,169.8,172.19,174.57,176.95,179.33,181.72,184.1,186.48,188.86,191.25,193.63,196.01,198.39,200.78,203.16,205.54,207.92,210.31,212.69,215.07,217.46,219.84,222.22,224.6,226.99,229.37,231.75,234.13,236.52,238.9,241.28,243.66,246.05,248.43,250.81,253.19,255.58,257.96,260.34,262.73,265.11,267.49,269.87,272.26,274.64,277.02,279.4,281.79,284.17,286.55,288.93,291.32,293.7,296.08,298.46,300.85,303.23,305.61,308.0,310.38,312.76,315.14,317.53,319.91,322.29,324.67,327.06,329.44,331.82,334.2,336.59,338.97,341.35,343.73,346.12,348.5,350.88,353.27,355.65,358.03,360.41,362.8,365.18,367.56,369.94,372.33,374.71,377.09,379.47,381.86,384.24,386.62,389.0,391.39,393.77,396.15,398.54,400.92,403.3,405.68,408.07,410.45,412.83,415.21,417.6,419.98,422.36,424.74,427.13,429.51,431.89,434.27,436.66,439.04,441.42,443.81,446.19,448.57,450.95,453.34,455.72,458.1,460.48,462.87,465.25,467.63,470.01,472.4,474.78,477.16,479.54,481.93,484.31,486.69,489.07,491.46,493.84,496.22,498.61,500.99,503.37,505.75,508.14,510.52,512.9,515.28,517.67,520.05,522.43,524.81,527.2,529.58,531.96,534.34,536.73,539.11,541.49],"sy":[165.71,165.71,165.71,165.71,165.71,165.71,165.71,165.71,180.9,180.9,180.9,195.97,195.97,195.97,195.97,181.94,181.94,214.45,214.45,214.45,214.45,186.77,186.77,186.77,186.77,186.77,205.36,205.36,205.36,155.51,155.51,155.51,155.51,155.51,151.38,151.38,151.38,151.38,151.38,151.38,151.38,147.42,147.42,147.42,147.42,147.42,153.89,153.89,153.35,153.35,163.81,157.59,157.59,139.05,156.26,183.01,162.81,154.99,154.99,166.29,166.29,155.84,155.84,155.84,169.42,169.42,169.42,169.42,156.35,127.93,127.93,127.93,127.93,155.75,155.75,155.75,155.75,115.24,138.05,132.28,147.19,148.0,153.7,153.7,153.7,134.18,134.18,134.18,134.18,127.9,127.9,127.9,104.9,104.9,104.9,119.36,119.36,119.36,119.36,122.22,122.22,122.22,115.1,115.1,115.1,115.1,120.08,120.08,120.08,79.21,123.64,123.64,114.13,112.88,96.13,96.13,133.06,133.06,97.96,121.49,121.49,69.39,89.37,86.77,92.21,83.93,83.93,83.93,129.81,129.81,129.81,80.61,80.61,78.9,78.9,83.02,87.15,87.15,87.15,76.09,76.09,56.11,87.44,87.44,87.3,85.95,85.95,85.95,86.41,86.41,86.41,86.41,60.69,60.69,69.68,55.64,42.98,42.98,42.98,42.98,42.98,42.98,64.01,64.01,64.01,64.01,64.01,64.01,64.01,64.82,64.82,64.82,64.82,64.82,37.98,37.98,37.98,37.98,57.89,57.89,66.91,66.91,66.91,66.91,72.68,72.68,46.15,46.15,46.15,46.15,74.73,74.73,74.73,52.53,52.53,52.53,46.59,46.59,46.59,46.59]},{"panel":0,"label":"average of 100 trees","color":"var(--chart-maroon, #b6262c)","x":[5.0,5.20101,5.40201,5.60302,5.80402,6.00503,6.20603,6.40704,6.60804,6.80905,7.01005,7.21106,7.41206,7.61307,7.81407,8.01508,8.21608,8.41709,8.61809,8.8191,9.0201,9.22111,9.42211,9.62312,9.82412,10.0251,10.2261,10.4271,10.6281,10.8291,11.0302,11.2312,11.4322,11.6332,11.8342,12.0352,12.2362,12.4372,12.6382,12.8392,13.0402,13.2412,13.4422,13.6432,13.8442,14.0452,14.2462,14.4472,14.6482,14.8492,15.0503,15.2513,15.4523,15.6533,15.8543,16.0553,16.2563,16.4573,16.6583,16.8593,17.0603,17.2613,17.4623,17.6633,17.8643,18.0653,18.2663,18.4673,18.6683,18.8693,19.0704,19.2714,19.4724,19.6734,19.8744,20.0754,20.2764,20.4774,20.6784,20.8794,21.0804,21.2814,21.4824,21.6834,21.8844,22.0854,22.2864,22.4874,22.6884,22.8894,23.0905,23.2915,23.4925,23.6935,23.8945,24.0955,24.2965,24.4975,24.6985,24.8995,25.1005,25.3015,25.5025,25.7035,25.9045,26.1055,26.3065,26.5075,26.7085,26.9095,27.1106,27.3116,27.5126,27.7136,27.9146,28.1156,28.3166,28.5176,28.7186,28.9196,29.1206,29.3216,29.5226,29.7236,29.9246,30.1256,30.3266,30.5276,30.7286,30.9296,31.1307,31.3317,31.5327,31.7337,31.9347,32.1357,32.3367,32.5377,32.7387,32.9397,33.1407,33.3417,33.5427,33.7437,33.9447,34.1457,34.3467,34.5477,34.7487,34.9497,35.1508,35.3518,35.5528,35.7538,35.9548,36.1558,36.3568,36.5578,36.7588,36.9598,37.1608,37.3618,37.5628,37.7638,37.9648,38.1658,38.3668,38.5678,38.7688,38.9698,39.1709,39.3719,39.5729,39.7739,39.9749,40.1759,40.3769,40.5779,40.7789,40.9799,41.1809,41.3819,41.5829,41.7839,41.9849,42.1859,42.3869,42.5879,42.7889,42.9899,43.191,43.392,43.593,43.794,43.995,44.196,44.397,44.598,44.799,45.0],"y":[10.1521,10.1521,10.1521,10.1521,10.1521,10.1521,10.1521,10.1521,9.07653,9.07653,9.07653,7.1985,7.09865,7.09865,6.39825,7.39214,7.38092,4.31547,4.31547,4.31783,4.31783,6.91296,6.97508,6.97508,7.47025,7.47025,6.85023,6.85023,6.85023,11.3604,11.3604,11.9023,12.0306,12.3318,13.7045,13.7045,14.1481,14.3492,14.4725,14.6881,14.6722,14.9525,14.9525,14.8661,14.8473,14.7997,14.2923,14.0508,14.0891,13.962,13.2866,14.0198,14.3009,15.5952,13.7931,10.4873,11.6971,13.145,13.0788,12.5401,12.5075,13.2478,13.1055,13.0403,12.1407,12.2719,12.6458,12.6444,14.6612,16.5659,16.6024,16.8118,17.0953,15.9678,16.3937,16.3771,16.3771,19.3907,18.2855,17.5058,15.7051,15.2412,14.7392,14.8242,15.0887,16.5524,17.6831,17.9815,18.5419,19.1219,19.926,19.926,21.8281,21.8281,22.1355,21.32,21.4293,20.7331,20.6415,20.4006,20.612,20.612,21.4979,21.4965,21.4965,21.5169,22.5596,22.4451,22.4531,25.8951,22.5753,22.6737,21.8892,22.3232,25.668,25.4048,20.6337,20.1165,23.671,21.9145,22.97,28.4817,27.5338,26.8239,26.3724,27.0685,26.9528,26.4989,21.3668,21.438,21.4556,26.0647,26.0647,27.8855,28.0553,27.8106,27.2898,27.3274,28.1952,29.8488,29.8455,31.301,28.4476,27.0878,27.1471,27.1976,27.0236,27.0763,27.04,27.713,28.1275,28.1275,31.3242,31.584,31.195,33.1395,34.2053,34.2053,34.2053,34.2053,34.2053,34.2312,32.4168,31.7047,31.7047,31.7047,32.061,32.0935,32.0935,32.041,32.0084,32.0084,32.0084,32.6385,34.385,34.5485,34.5285,34.5119,32.9193,32.9907,31.494,31.494,30.9579,31.1377,31.2698,31.1995,33.0514,32.9616,33.0442,32.9972,30.5065,30.5065,30.6546,32.3971,32.3971,33.4743,34.0084,34.0084,34.0084,34.0084],"sx":[67.35,69.73,72.11,74.5,76.88,79.26,81.65,84.03,86.41,88.79,91.18,93.56,95.94,98.32,100.71,103.09,105.47,107.85,110.24,112.62,115.0,117.38,119.77,122.15,124.53,126.92,129.3,131.68,134.06,136.45,138.83,141.21,143.59,145.98,148.36,150.74,153.12,155.51,157.89,160.27,162.65,165.04,167.42,169.8,172.19,174.57,176.95,179.33,181.72,184.1,186.48,188.86,191.25,193.63,196.01,198.39,200.78,203.16,205.54,207.92,210.31,212.69,215.07,217.46,219.84,222.22,224.6,226.99,229.37,231.75,234.13,236.52,238.9,241.28,243.66,246.05,248.43,250.81,253.19,255.58,257.96,260.34,262.73,265.11,267.49,269.87,272.26,274.64,277.02,279.4,281.79,284.17,286.55,288.93,291.32,293.7,296.08,298.46,300.85,303.23,305.61,308.0,310.38,312.76,315.14,317.53,319.91,322.29,324.67,327.06,329.44,331.82,334.2,336.59,338.97,341.35,343.73,346.12,348.5,350.88,353.27,355.65,358.03,360.41,362.8,365.18,367.56,369.94,372.33,374.71,377.09,379.47,381.86,384.24,386.62,389.0,391.39,393.77,396.15,398.54,400.92,403.3,405.68,408.07,410.45,412.83,415.21,417.6,419.98,422.36,424.74,427.13,429.51,431.89,434.27,436.66,439.04,441.42,443.81,446.19,448.57,450.95,453.34,455.72,458.1,460.48,462.87,465.25,467.63,470.01,472.4,474.78,477.16,479.54,481.93,484.31,486.69,489.07,491.46,493.84,496.22,498.61,500.99,503.37,505.75,508.14,510.52,512.9,515.28,517.67,520.05,522.43,524.81,527.2,529.58,531.96,534.34,536.73,539.11,541.49],"sy":[174.59,174.59,174.59,174.59,174.59,174.59,174.59,174.59,180.21,180.21,180.21,190.02,190.55,190.55,194.21,189.01,189.07,205.09,205.09,205.07,205.07,191.52,191.19,191.19,188.6,188.6,191.84,191.84,191.84,168.28,168.28,165.45,164.78,163.21,156.03,156.03,153.72,152.67,152.02,150.9,150.98,149.51,149.51,149.97,150.06,150.31,152.96,154.23,154.03,154.69,158.22,154.39,152.92,146.16,155.57,172.84,166.52,158.96,159.3,162.12,162.29,158.42,159.16,159.5,164.2,163.52,161.57,161.57,151.04,141.09,140.9,139.8,138.32,144.21,141.99,142.07,142.07,126.33,132.1,136.18,145.58,148.01,150.63,150.18,148.8,141.16,135.25,133.69,130.76,127.73,123.53,123.53,113.59,113.59,111.99,116.25,115.68,119.31,119.79,121.05,119.95,119.95,115.32,115.33,115.33,115.22,109.77,110.37,110.33,92.35,109.69,109.18,113.28,111.01,93.53,94.91,119.83,122.54,103.97,113.14,107.63,78.83,83.79,87.49,89.85,86.22,86.82,89.19,116.0,115.63,115.54,91.46,91.46,81.95,81.06,82.34,85.06,84.86,80.33,71.69,71.71,64.1,79.01,86.12,85.81,85.54,86.45,86.18,86.37,82.85,80.68,80.68,63.98,62.63,64.66,54.5,48.93,48.93,48.93,48.93,48.93,48.8,58.27,62.0,62.0,62.0,60.13,59.96,59.96,60.24,60.41,60.41,60.41,57.12,47.99,47.14,47.24,47.33,55.65,55.28,63.1,63.1,65.9,64.96,64.27,64.63,54.96,55.43,55.0,55.24,68.26,68.26,67.48,58.38,58.38,52.75,49.96,49.96,49.96,49.96]},{"panel":0,"label":"true average (the curve we set)","color":"#7d7b77","x":[5.0,5.20101,5.40201,5.60302,5.80402,6.00503,6.20603,6.40704,6.60804,6.80905,7.01005,7.21106,7.41206,7.61307,7.81407,8.01508,8.21608,8.41709,8.61809,8.8191,9.0201,9.22111,9.42211,9.62312,9.82412,10.0251,10.2261,10.4271,10.6281,10.8291,11.0302,11.2312,11.4322,11.6332,11.8342,12.0352,12.2362,12.4372,12.6382,12.8392,13.0402,13.2412,13.4422,13.6432,13.8442,14.0452,14.2462,14.4472,14.6482,14.8492,15.0503,15.2513,15.4523,15.6533,15.8543,16.0553,16.2563,16.4573,16.6583,16.8593,17.0603,17.2613,17.4623,17.6633,17.8643,18.0653,18.2663,18.4673,18.6683,18.8693,19.0704,19.2714,19.4724,19.6734,19.8744,20.0754,20.2764,20.4774,20.6784,20.8794,21.0804,21.2814,21.4824,21.6834,21.8844,22.0854,22.2864,22.4874,22.6884,22.8894,23.0905,23.2915,23.4925,23.6935,23.8945,24.0955,24.2965,24.4975,24.6985,24.8995,25.1005,25.3015,25.5025,25.7035,25.9045,26.1055,26.3065,26.5075,26.7085,26.9095,27.1106,27.3116,27.5126,27.7136,27.9146,28.1156,28.3166,28.5176,28.7186,28.9196,29.1206,29.3216,29.5226,29.7236,29.9246,30.1256,30.3266,30.5276,30.7286,30.9296,31.1307,31.3317,31.5327,31.7337,31.9347,32.1357,32.3367,32.5377,32.7387,32.9397,33.1407,33.3417,33.5427,33.7437,33.9447,34.1457,34.3467,34.5477,34.7487,34.9497,35.1508,35.3518,35.5528,35.7538,35.9548,36.1558,36.3568,36.5578,36.7588,36.9598,37.1608,37.3618,37.5628,37.7638,37.9648,38.1658,38.3668,38.5678,38.7688,38.9698,39.1709,39.3719,39.5729,39.7739,39.9749,40.1759,40.3769,40.5779,40.7789,40.9799,41.1809,41.3819,41.5829,41.7839,41.9849,42.1859,42.3869,42.5879,42.7889,42.9899,43.191,43.392,43.593,43.794,43.995,44.196,44.397,44.598,44.799,45.0],"y":[8.26017,8.35132,8.44253,8.53379,8.6251,8.71647,8.8079,8.89941,8.99098,9.08263,9.17437,9.26619,9.35811,9.45013,9.54226,9.6345,9.72687,9.81937,9.912,10.0048,10.0977,10.1909,10.2842,10.3777,10.4714,10.5653,10.6595,10.7539,10.8486,10.9436,11.0388,11.1345,11.2304,11.3268,11.4235,11.5207,11.6183,11.7164,11.815,11.9141,12.0139,12.1142,12.2153,12.317,12.4194,12.5227,12.6268,12.7318,12.8377,12.9447,13.0527,13.1618,13.2721,13.3837,13.4967,13.611,13.7268,13.8442,13.9633,14.0841,14.2067,14.3313,14.4579,14.5866,14.7175,14.8508,14.9864,15.1246,15.2654,15.4089,15.5552,15.7044,15.8566,16.0118,16.1703,16.332,16.4969,16.6653,16.837,17.0121,17.1907,17.3728,17.5583,17.7472,17.9395,18.1351,18.3339,18.5358,18.7407,18.9485,19.159,19.3719,19.5872,19.8045,20.0237,20.2445,20.4665,20.6896,20.9135,21.1378,21.3622,21.5865,21.8104,22.0335,22.2555,22.4763,22.6955,22.9128,23.1281,23.341,23.5515,23.7593,23.9642,24.1661,24.3649,24.5605,24.7528,24.9417,25.1272,25.3093,25.4879,25.663,25.8347,26.0031,26.168,26.3297,26.4882,26.6434,26.7956,26.9448,27.0911,27.2346,27.3754,27.5136,27.6492,27.7825,27.9134,28.0421,28.1687,28.2933,28.4159,28.5367,28.6558,28.7732,28.889,29.0033,29.1163,29.2279,29.3382,29.4473,29.5553,29.6623,29.7682,29.8732,29.9773,30.0806,30.183,30.2847,30.3858,30.4861,30.5859,30.685,30.7836,30.8817,30.9793,31.0765,31.1732,31.2696,31.3655,31.4612,31.5564,31.6514,31.7461,31.8405,31.9347,32.0286,32.1223,32.2158,32.3091,32.4023,32.4952,32.588,32.6806,32.7731,32.8655,32.9577,33.0499,33.1419,33.2338,33.3256,33.4174,33.509,33.6006,33.6921,33.7835,33.8749,33.9662,34.0575,34.1487,34.2398],"sx":[67.35,69.73,72.11,74.5,76.88,79.26,81.65,84.03,86.41,88.79,91.18,93.56,95.94,98.32,100.71,103.09,105.47,107.85,110.24,112.62,115.0,117.38,119.77,122.15,124.53,126.92,129.3,131.68,134.06,136.45,138.83,141.21,143.59,145.98,148.36,150.74,153.12,155.51,157.89,160.27,162.65,165.04,167.42,169.8,172.19,174.57,176.95,179.33,181.72,184.1,186.48,188.86,191.25,193.63,196.01,198.39,200.78,203.16,205.54,207.92,210.31,212.69,215.07,217.46,219.84,222.22,224.6,226.99,229.37,231.75,234.13,236.52,238.9,241.28,243.66,246.05,248.43,250.81,253.19,255.58,257.96,260.34,262.73,265.11,267.49,269.87,272.26,274.64,277.02,279.4,281.79,284.17,286.55,288.93,291.32,293.7,296.08,298.46,300.85,303.23,305.61,308.0,310.38,312.76,315.14,317.53,319.91,322.29,324.67,327.06,329.44,331.82,334.2,336.59,338.97,341.35,343.73,346.12,348.5,350.88,353.27,355.65,358.03,360.41,362.8,365.18,367.56,369.94,372.33,374.71,377.09,379.47,381.86,384.24,386.62,389.0,391.39,393.77,396.15,398.54,400.92,403.3,405.68,408.07,410.45,412.83,415.21,417.6,419.98,422.36,424.74,427.13,429.51,431.89,434.27,436.66,439.04,441.42,443.81,446.19,448.57,450.95,453.34,455.72,458.1,460.48,462.87,465.25,467.63,470.01,472.4,474.78,477.16,479.54,481.93,484.31,486.69,489.07,491.46,493.84,496.22,498.61,500.99,503.37,505.75,508.14,510.52,512.9,515.28,517.67,520.05,522.43,524.81,527.2,529.58,531.96,534.34,536.73,539.11,541.49],"sy":[184.48,184.0,183.53,183.05,182.57,182.09,181.62,181.14,180.66,180.18,179.7,179.22,178.74,178.26,177.78,177.3,176.82,176.33,175.85,175.36,174.88,174.39,173.9,173.42,172.93,172.44,171.94,171.45,170.96,170.46,169.96,169.46,168.96,168.46,167.95,167.44,166.93,166.42,165.91,165.39,164.87,164.34,163.82,163.28,162.75,162.21,161.67,161.12,160.56,160.0,159.44,158.87,158.29,157.71,157.12,156.52,155.92,155.3,154.68,154.05,153.41,152.76,152.1,151.43,150.74,150.05,149.34,148.62,147.88,147.13,146.37,145.59,144.79,143.98,143.15,142.31,141.45,140.57,139.67,138.75,137.82,136.87,135.9,134.91,133.91,132.89,131.85,130.79,129.72,128.64,127.54,126.43,125.3,124.17,123.02,121.87,120.71,119.54,118.37,117.2,116.03,114.86,113.69,112.52,111.36,110.21,109.06,107.93,106.8,105.69,104.59,103.51,102.43,101.38,100.34,99.32,98.31,97.33,96.36,95.41,94.47,93.56,92.66,91.78,90.92,90.08,89.25,88.44,87.64,86.86,86.1,85.35,84.61,83.89,83.18,82.49,81.8,81.13,80.47,79.82,79.18,78.55,77.92,77.31,76.71,76.11,75.52,74.94,74.36,73.79,73.22,72.67,72.11,71.56,71.02,70.48,69.95,69.41,68.89,68.36,67.84,67.32,66.81,66.29,65.78,65.28,64.77,64.27,63.77,63.27,62.77,62.27,61.78,61.29,60.79,60.3,59.81,59.32,58.84,58.35,57.87,57.38,56.9,56.41,55.93,55.45,54.97,54.49,54.01,53.53,53.05,52.57,52.09,51.61,51.13,50.66,50.18,49.7,49.23,48.75]},{"panel":0,"label":"80 months","color":"var(--chart-grey, #a3a19c)","x":[6.51704,6.62269,7.7587,8.01321,8.80771,9.52517,10.5997,10.782,12.7472,13.7242,14.4514,14.8354,15.0818,15.1919,15.2207,15.7113,15.8109,16.1807,16.2234,16.4715,16.9462,17.3775,18.2736,18.7289,19.0006,20.1154,20.5433,20.6432,20.8824,20.9305,21.2555,21.4122,22.404,23.0901,23.7009,24.399,25.2412,25.4513,25.4766,26.7887,27.0249,27.1805,27.6037,27.7313,27.9066,27.9175,28.4152,28.7007,28.9653,29.4023,29.5961,29.6766,29.9293,29.9424,31.2146,31.2274,31.895,32.112,32.5133,33.1036,33.2273,33.7324,33.9003,34.1156,35.0962,35.7823,35.7918,35.986,36.114,36.2805,38.6868,39.1543,40.5943,40.8139,41.4443,42.2177,42.4492,43.6154,43.8875,44.7228],"y":[11.852,8.94497,6.06014,8.74634,2.5224,7.82229,4.26322,13.8056,14.5951,15.3526,14.115,14.2192,12.2153,16.5473,13.4073,16.9551,13.6607,8.54086,12.4078,13.9045,11.7422,13.7413,11.1421,13.644,19.0833,13.759,21.5125,17.1478,18.2522,15.3974,15.2432,14.1519,17.888,19.0902,23.4932,20.7252,20.1777,22.1405,21.5406,20.5867,28.4094,19.9061,21.7259,21.965,28.3668,25.1717,18.1023,24.8201,20.3173,30.29,26.4644,26.962,25.9214,27.5054,18.7234,28.1423,28.4691,27.6798,26.8892,29.0064,32.832,26.8351,26.8618,27.1187,27.0324,31.9554,30.7908,30.2339,32.9215,35.3438,31.3188,31.1643,36.3013,32.4903,30.7639,29.6591,34.7382,29.2674,33.5172,34.6535],"sx":[85.33,86.58,100.05,103.07,112.48,120.99,133.73,135.89,159.18,170.76,179.38,183.93,186.86,188.16,188.5,194.32,195.5,199.88,200.39,203.33,208.96,214.07,224.69,230.09,233.31,246.52,251.59,252.78,255.61,256.18,260.04,261.89,273.65,281.78,289.02,297.3,307.28,309.77,310.07,325.62,328.42,330.27,335.28,336.8,338.88,339.0,344.9,348.29,351.42,356.6,358.9,359.86,362.85,363.01,378.09,378.24,386.15,388.72,393.48,400.48,401.94,407.93,409.92,412.47,424.1,432.23,432.34,434.64,436.16,438.14,466.66,472.2,489.27,491.87,499.34,508.51,511.26,525.08,528.31,538.21],"sy":[165.71,180.9,195.97,181.94,214.45,186.77,205.36,155.51,151.38,147.42,153.89,153.35,163.81,141.18,157.59,139.05,156.26,183.01,162.81,154.99,166.29,155.84,169.42,156.35,127.93,155.75,115.24,138.05,132.28,147.19,148.0,153.7,134.18,127.9,104.9,119.36,122.22,111.96,115.1,120.08,79.21,123.64,114.13,112.88,79.43,96.13,133.06,97.96,121.49,69.39,89.37,86.77,92.21,83.93,129.81,80.61,78.9,83.02,87.15,76.09,56.11,87.44,87.3,85.95,86.41,60.69,66.77,69.68,55.64,42.98,64.01,64.82,37.98,57.89,66.91,72.68,46.15,74.73,52.53,46.59]},{"panel":1,"label":"variance","color":"var(--chart-maroon, #b6262c)","x":[1.0,2.0,5.0,10.0,25.0,50.0,100.0],"y":[8.88465,6.68981,5.23468,4.71017,4.44279,4.31519,4.2034],"sx":[67.35,138.72,233.06,304.42,398.76,470.13,541.49],"sy":[320.78,364.47,393.43,403.87,409.19,411.73,413.95]},{"panel":1,"label":"bias\u00b2","color":"var(--chart-blue, #3b6ea5)","x":[1.0,2.0,5.0,10.0,25.0,50.0,100.0],"y":[0.0440803,0.0306101,0.0235476,0.0342421,0.0301286,0.0264653,0.0181032],"sx":[67.35,138.72,233.06,304.42,398.76,470.13,541.49],"sy":[496.74,497.01,497.15,496.93,497.01,497.09,497.25]}]} 2026-10-15T18:28:57.967236 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ 5 10 15 20 25 30 35 40 45 This month's volatility (% a year) 5 10 15 20 25 30 35 Next month's volatility (% a year) 1. Same 80 months: one deep tree against the average of 100 80 months one deep tree average of 100 trees true average (the curve we set) 1 2 5 10 25 50 100 Number of trees averaged (log scale) 0 2 4 6 8 Squared error on new months (volatility points²) 2. Variance falls with more trees, then levels off; bias stays flat variance bias²

  • Bias stays near zero. Averaging deep trees doesn’t make them too simple.
  • Variance halves, from 8.9 to 4.2, 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: 4.2/8.94.2 / 8.9, ignoring the small leftover term).

On this small, simple problem, the best single tree from the bias and variance post (depth 3, error 11.8) still beats 100 bagged deep trees (13.2). Bagging removes variance. It doesn’t remove the need to choose a sensible model.

On the stress-month data

Now the classification problem from the decision trees post: will next month be a stress month? Scores are AUC on the 2,405 test rows of 2022 and 2023, one per ticker per trading day (0.5 is a coin flip, 1.0 is perfect):

Base treeOne treeBag of 200Change
Fully grown0.6150.788big gain
Depth 80.7580.817good gain
Depth 50.7970.823small gain
Depth 30.8040.828small gain

This table says most of what there is to say about bagging:

  • It helps a lot when the base model is unstable (high variance), like a fully grown tree.
  • It helps less when the model is already stable. A depth-3 tree changes little between bootstrap samples, so there’s less noise to average away; it still gains about 0.02 of AUC here, because real market data is noisier than my toy curve.

And a warning about the out-of-bag estimate. From the training data alone, the bag of fully grown trees reported an AUC of 0.907\key{0.907}. Its real test score was 0.788. The estimate is far too rosy, and the reason is the data, not the method: two rows a day apart are computed from almost the same month of prices, so a row left out of a bootstrap sample has near-twins inside it, and “never seen” isn’t really true. On a time series, the only honest test is forward in time. The out-of-bag score is free and useful when rows are independent. Here it would have fooled me.

Three more experiments

On the regression version of the problem, predicting next month’s volatility as a number, the same ideas look like this.

How many trees. Fully grown trees, averaged, scored by RMSE (the typical size of a miss; lower is better) on the 2022 to 2023 rows:

Trees averaged15102050100
Test RMSE15.8711.9311.2410.6110.1910.23

The first twenty trees take a third off the error; the next eighty take nothing. That levelling off is the ρ σ2\key{\rho}\,\risk{\sigma^2} floor from the formula above, measured.

Random splits. A tree that picks each cut point at random instead of searching for the best one is weaker alone and far cheaper to build: 5.9 milliseconds against 16.5 for a fully grown tree here. On this noisy target it is also, oddly, better once leaves hold a few rows (a test RMSE of 10.24 against 12.01 at ten rows per leaf), because the search was finding cuts that fit the training noise. Twenty bagged random trees scored 9.80 against 10.61 for twenty bagged searching trees. Randomness acts as regularisation (a brake that stops a model fitting noise), and it is the trade that random forests and “extra trees” (extremely randomised trees, which pick their cut points at random as here) are built on.

Bagging a stable model. Bag twenty linear regressions and you get the single regression’s answer back, to two decimal places. A straight line barely moves between resamples of the same data, so there is nothing to average away. Bagging helps unstable learners, deep trees above all, and does nothing for stable ones.

The code

All three ideas on made-up data, so it runs as pasted (pip install numpy scikit-learn): one bootstrap sample, deep trees bagged on the made-up volatility curve from the bias and variance post, and a straight line bagged for comparison. X_train holds this month’s volatility as a one-column table, y_train next month’s.

import numpy as np
from sklearn.ensemble import BaggingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.metrics import root_mean_squared_error
from sklearn.tree import DecisionTreeRegressor

rng = np.random.default_rng(0)

# 1. One bootstrap sample: draw 8 rows, with replacement, from rows 1 to 8
rows = np.arange(1, 9)
sample = rng.choice(rows, size=8, replace=True)
print("drawn:", np.sort(sample), " left out:", np.setdiff1d(rows, sample))

n = 10_000                                            # the same on 10,000 rows
left_out = 1 - len(np.unique(rng.choice(n, size=n))) / n
print("share of rows left out:", round(left_out, 3))  # about 0.37

# 2. Bagging deep trees on a made-up curve (next month's volatility from this month's)
def true_curve(x):
    return 6 + 0.45 * x + 8 / (1 + np.exp(-(x - 25) / 3))

x_train = rng.uniform(5, 45, 300)
y_train = true_curve(x_train) + rng.normal(0, 3, 300)
x_test = rng.uniform(5, 45, 1000)
y_test = true_curve(x_test) + rng.normal(0, 3, 1000)
X_train, X_test = x_train.reshape(-1, 1), x_test.reshape(-1, 1)   # tables of one column

for B in (1, 10, 100):                                # how many trees are averaged
    bag = BaggingRegressor(DecisionTreeRegressor(), n_estimators=B, random_state=0)
    bag.fit(X_train, y_train)                         # each tree gets its own bootstrap sample
    print(f"{B:3} deep trees: test RMSE {root_mean_squared_error(y_test, bag.predict(X_test)):.2f}")

# 3. Bagging a stable model: twenty straight lines average back to one line
line = LinearRegression().fit(X_train, y_train)
bagged = BaggingRegressor(LinearRegression(), n_estimators=20, random_state=0).fit(X_train, y_train)
print("one line:", round(root_mean_squared_error(y_test, line.predict(X_test)), 2),
      " twenty bagged lines:", round(root_mean_squared_error(y_test, bagged.predict(X_test)), 2))

It prints one bootstrap sample (some rows several times, a few left out), then a left-out share of about 0.37. Then the averaging: one deep tree misses by about 4.7, ten trees by about 3.85, a hundred by about 3.8, the fast fall and then the floor from the table above. The noise added to y has a spread of 3, so 3 is the best any model can do. Last, the single line and twenty bagged lines score the same 3.37: nothing to average away.

The scripts behind the real numbers

The tables come from examples/bagging/bagging.py and, for the three experiments, from examples/machine-learning-in-ten-ideas/ten_ideas.py. The stress-month and regression numbers use the blog’s five tickers. To run it yourself, clone the examples repo: its README has a three-command Docker setup, or run uv run on it.

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 (if rows are independent)
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

References