Machine Learning · Machine Learning Core
Random Forests
Bagging and random forests average many trees on bootstrap samples and random feature subsets — stabler than one deep tree, at the cost of a single readable path.
One deep tree memorises quirks; a forest averages many trees grown on bootstrap samples and random feature subsets so those quirks cancel. This lesson locks bagging and forest intuition, then compares an unlimited tree to a 50-tree forest on the same hold-out in the browser.
- Machine Learning
- Medium level
- 5 concepts
- 10 practice questions
1Bagging and forests
Imagine you are about to buy a used car, and you want an answer to one question: will this car break down within a year? You could ask a single mechanic who has memorised every car he has ever worked on. The trouble with that mechanic is that he memorised too well — he fixates on quirks. "The last silver 2014 hatchback I saw was a lemon, so this one must be too." That is exactly what a single decision tree does when you let it grow as deep as it likes: it keeps splitting until it has memorised the training data, real patterns and meaningless quirks alike, and the quirks come along for the ride on new cars.
A better plan is to assemble a committee — say, 100 mechanics — and let them vote. But here is the catch a beginner should pause on: a committee only helps if its members disagree in useful ways. If all 100 mechanics trained on the same records in the same way, they would all inherit the same quirks and repeat the same mistake, just 100 times louder. So the whole trick of this lesson is to deliberately train each committee member a little differently. Random forests do this in two ways, and each has a name worth learning.
Figure. One mechanic who memorised too well carries his quirks onto the next car, and a committee of 100 identically trained mechanics just repeats the same mistake 100 times louder. The committee only helps when each member is deliberately trained a little differently.
| Who judges the car | What goes wrong or right | Outcome |
|---|---|---|
| One mechanic who memorised too well | Fixates on quirks — "the last silver 2014 hatchback was a lemon, so this one must be too" | Quirks ride along onto new cars |
| 100 mechanics trained on the same records the same way | All inherit the same quirks | Same mistake, 100 times louder |
| 100 mechanics each trained a little differently | Members disagree in useful ways | The vote actually helps — this is the forest's whole trick |
What is the primary motivation for aggregating predictions across a random forest of 100 trees rather than relying on one deep tree?
- A forest trains 100 times faster than fitting a single decision tree
- A forest converts non-linear relationships into exact linear equations
- A forest eliminates the need to hold out any validation or test data
- Averaging decorrelated trees reduces variance and curbs the severe overfitting of single deep trees
Individual deep trees have low bias but high variance. Averaging an ensemble of diverse trees reduces variance without increasing bias.
2Two ways to make trees disagree
The first source of disagreement is the bootstrap sample — the rows each tree gets to study. Suppose you have a pile of 1000 past car records. To build one mechanic's study pile, you draw one record at random, copy it into their pile, and then put it back before drawing again. "With replacement" means exactly that putting-back step. After 1000 draws, that mechanic's pile also holds 1000 records, but some records were drawn twice or three times, and roughly a third of the originals were never drawn at all. Do this separately for every mechanic and each one has studied a different remix of the same history. Training many models on bootstrap samples and then combining their answers is called bagging — short for "bootstrap aggregating".
The second source of disagreement is the random feature subset. A feature is just one column of the data — mileage, age, brand, engine size. Every time a tree is about to ask a splitting question ("is mileage above 80,000?"), a random forest hands it only a random handful of the columns to choose from: this split it may look at mileage and age, the next split perhaps brand and engine size. Why do that? Because if one column is very strong, every tree would otherwise open with the same question and grow into near-copies of each other — and near-copies are exactly the useless committee from before. Hiding some columns at each split forces the trees down genuinely different paths.
Figure. One mechanic's study pile comes from 1000 draws with replacement over the 1000 original records: some records land in the pile twice or three times, while roughly a third are never drawn at all — so each mechanic studies a different remix of the same history.
| Source | What is randomised | Why trees end up different |
|---|---|---|
| Bootstrap sample (bagging) | Rows: 1000 draws with replacement — some records copied twice or thrice, roughly a third never drawn | Each mechanic studies a different remix of the same history |
| Random feature subset | Columns offered at each split — mileage and age this split, brand and engine size the next | A strong column can no longer make every tree open with the same question and grow near-copies |
One bag, drawn by hand
Shrink the workshop's history to a toy table of 8 past car records, labelled A to H, so every draw can be watched by hand. Build the bootstrap sample — the "bag" of records one tree gets to study — by drawing 8 times with replacement; the draws come up C, F, A, C, H, F, F, B. Then grow five trees on five such bags and let the committee vote on one incoming car, where each tree's call on "breaks down within a year?" is: yes, no, yes, yes, no.
- Write down the bag. Each draw copies one record into the pile and puts the original back, so after 8 draws the bag reads C, F, A, C, H, F, F, B8 slots, only 5 different records: A, B, C, F, H
- Spot the repeats: C was drawn twice and F three times3 of the 8 slots are repeat copies
- Spot the missing: D, E and G were never drawn, so this tree never studies them3 of 8 records are "out-of-bag" for this tree
- Is 3 missing typical? The chance one record dodges all 8 draws is (7/8)^8 \approx 0.344, so expect about 8 \times 0.344 \approx 2.75 records out of the bag3 observed — right on script
- Five trees, each grown on its own bag, call the incoming car: yes, no, yes, yes, no3 votes yes, 2 votes no
- Majority vote decides the committee's answerforest predicts: breaks down within a year
Pro tip. The "roughly a third missing" is not a quirk of the tiny table: the same arithmetic at 1000 records gives (1 - 1/1000)^{1000} \approx 1/e \approx 0.368, so drawing with replacement always leaves about a third of the records out of any one bag, whatever the table size. Those left-out records are exactly the out-of-bag rows a forest can later use as a free check on that tree — a hold-out it never had to set aside.
"Every tree in a random forest trains on exactly the full training set, once." What is wrong with that claim?
- Nothing — that is what bagging means
- Trees see only the test fold, never the training set
- Each tree draws a bootstrap sample with replacement — some rows repeat, some are left out entirely
- Each tree sees exactly half the rows, split evenly
Bagging resamples rows with replacement per tree, and forests also try a random feature subset at each split — both make the trees disagree so the average is stabler.
3The committee hands in its answer
Now the committee answers. Each tree hands in its own prediction for the car in front of you. The symbol \hat{y} — read "y-hat" — is the standard shorthand for a model's guess at the true answer y, so in the diagram tree 1's guess is \hat{y}_1, tree 2's is \hat{y}_2, tree 3's is \hat{y}_3. For a classification question (breaks down: yes or no) the forest takes a majority vote: if 70 of 100 trees say "breaks down", the forest says "breaks down". For a regression question (predict a number, like resale price) there is nothing to vote on, so the forest simply averages the 100 numbers.
Figure. Three shallow trees each cast one prediction; bagging's vote or average turns those disagreeing calls into a single forest ŷ, so one overgrown path cannot dominate.
- Bootstrap rowsDraw each tree's training set with replacement — some rows repeat, some are left out.
- Grow diverse treesRandom feature subsampling at each split keeps trees from copying the same path.
- Vote or averageClassification uses majority vote; regression averages the tree outputs.
A resale price from five trees
The workshop's committee is now asked a number question, not a yes/no one: what resale price will this used car fetch? Five trees, each grown on its own bootstrap bag of past sale records, hand in their predictions in thousands of rupees: 452, 461, 448, 500 and 439. The 500 is a quirk — that tree's bag happened to draw one overpriced sale three times, so it studied the same fluke thrice. Five different numbers hold no majority to count, so the forest averages. Compute the committee's answer, then measure how far the quirky tree managed to drag it.
- Add the five predictions: 452 + 461 + 448 + 500 + 4392300
- Average over the 5 trees: 2300/5the committee answers 460 thousand rupees
- What the other four agree on, leaving the quirky tree out: (452 + 461 + 448 + 439)/4 = 1800/4450 thousand rupees
- The quirky tree sits 500 - 450 = 50 above that consensus, yet inside the committee it moved the answer only 460 - 45010 — the other four voices absorbed four-fifths of its error
- Scale the committee up: in a 100-tree forest, the same 50-thousand quirk shifts the average by only 50/100half a thousand rupees — barely a nudge
Pro tip. With numbers there is nothing to vote on: no two trees name exactly the same price, so "most common answer" would be meaningless. Averaging is the vote's counterpart for regression, and it disciplines a quirk the same way a vote does — one loud voice, divided by the size of the committee.
In a Random Forest regressor with 50 trees, how is the final continuous prediction assembled from individual tree outputs?
- By computing the arithmetic mean of the predictions produced by all 50 individual trees
- By taking the prediction of the single tree that had the lowest training error
- By selecting the median tree and discarding the remaining 49 predictions
- By multiplying the predictions of all trees together sequentially
In regression forests, the ensemble averages the numeric outputs of all member trees.
4What averaging buys, and what it costs
Why does averaging disagreeing trees help? The failure it attacks is called variance — how much a model's answers would wobble if you re-collected the training data and trained again. One overgrown tree has high variance: change a few rows and its memorised path changes wildly. But each tree's quirks came from its own remixed pile and its own hidden columns, so the quirks point in different directions — and when you vote or average, quirks pointing in different directions largely cancel, while the real pattern, which every tree saw, survives. One tree's weird path is diluted by hundreds of others.
There is a price, and it is honesty to name it: interpretability. With a single tree you could point at one readable path — "high mileage, then old battery, therefore lemon" — and show a customer exactly why. With 100 trees there is no single path to point at; the answer is a vote. Forests offer feature-importance scores as a consolation (a summary of which columns the trees split on most usefully), but treat those as a sketch that guides your attention, not a proof of what causes what.
| Property | Single tree | Forest |
|---|---|---|
| Variance | High if deep | Lower (averaged) |
| Readable path | Yes | No — many trees |
| Extra knobs | Depth, leaf size | n_estimators, max_features |
Measuring the wobble the forest buys off
Variance is wobble under re-collection — so stage the re-collection. The workshop's history is gathered three separate times, three different years of past sale records, and after each collection both models are retrained from scratch and asked to price the same used car, in thousands of rupees. The lone unlimited-depth tree answers 430, then 500, then 420 across the three retrains. The 50-tree forest answers 456, then 449, then 445. Compute each model's average answer and its average wobble around that answer, and say which of those numbers tells the variance story.
- Lone tree's average answer over its three retrains: (430 + 500 + 420)/3 = 1350/3450 thousand rupees
- Its wobbles around that 450: -20, +50 and -30; average wobble size (20 + 50 + 30)/3 = 100/3about 33 thousand rupees per retrain
- Forest's average answer: (456 + 449 + 445)/3 = 1350/3450 — the very same centre as the lone tree
- Its wobbles around 450: +6, -1 and -5; average wobble size (6 + 1 + 5)/3 = 12/34 thousand rupees per retrain
- Compare the two wobbles, not the two centres: 33/4about 8 — a customer quoted by the lone tree gets an answer that swings roughly eight times as widely, depending on nothing but which year's records happened to be collected
Pro tip. Neither model is wrong on average — both centre on the same 450. Variance is not about the centre; it is about which answer you happen to receive on the one training history you actually have. The steadiness is what averaging buys, and its price is the one named in this concept: no single readable path produced the forest's 449 — the answer is a vote you can no longer point at.
What trade-off is commonly accepted when moving from a single interpretable decision tree to a Random Forest?
- Training memory decreases while the model becomes strictly linear
- Predictive accuracy and stability improve significantly at the cost of losing a simple inspectable flowchart
- Inference latency drops to zero while feature importance cannot be measured
- The model becomes vulnerable to underfitting on high-dimensional inputs
A forest trades the simple, human-readable flowchart of a single tree for superior predictive accuracy and robustness.
5Lab: tree vs forest
Now watch the committee beat the lone expert with your own eyes. The lab fits two models on exactly the same data: a DecisionTreeClassifier with max_depth=None, which is the memorising mechanic — a tree allowed to grow without any depth limit — and a RandomForestClassifier with n_estimators=50. That last name deserves a plain-words gloss: n_estimators is simply the number of trees in the committee, so this forest is 50 trees, each grown on its own bootstrap sample with random feature subsets at each split.
Where does the data come from? The function make_classification manufactures a practice table on the spot: 600 rows, 8 feature columns, and a 0-or-1 label for each row. In the code, X is that table of input columns and y is the list of correct labels — the same X-and-y convention every sklearn model uses. Because the table is synthetic, the columns have no real-world meaning, and that is fine here: the point of this lab is to compare two models on identical ground, not to learn about cars.
Before either model is fitted, train_test_split sets aside 25% of the rows as a test fold — rows neither model is allowed to see while training. Why insist on that? Because scoring a model on rows it trained on is like grading a student on questions they studied with the answer key attached: the memorising tree would look perfect and you would learn nothing. Calling .score(X_test, y_test) afterwards returns the fraction of those never-seen rows each model predicts correctly, which is the number that actually matters.
The lab runs as two cells, and the mechanics are worth spelling out. Cell 1 builds the data, fits both models, and prints both scores. Every variable it creates — forest, X, tree_score, forest_score — stays alive in the shared kernel, which is the Python session running behind all the cells. That is why Cell 2 can draw a bar chart of tree_score against forest_score without refitting anything: it just reads the numbers still sitting in the kernel. Want a different title or different bar colours? Edit Cell 2 and re-run only that cell — Cell 1's work is untouched.
What should you expect to see? The forest's test score should match or beat the unlimited tree's, and — if you re-run Cell 1 with a different random_state — the forest's score should wobble less from run to run, because averaging 50 trees is exactly the variance cure the previous concept promised. Two ground rules while you experiment: keep n_samples in the hundreds so the browser runtime stays responsive, and never score either model on rows it was fitted on — the test fold exists precisely so you don't.
No diagram — the score comparison is drawn by the coding lab plot, not a static figure.
- Fit a lone treeTrain DecisionTreeClassifier with no depth cap on the same split — note train vs test gap.
- Fit the forestTrain RandomForestClassifier(n_estimators=50) on identical X_train, y_train.
- Compare hold-outForest test score should beat or match the single tree with less variance run to run.
| Step | Why |
|---|---|
| Hold out a test fold | Score must use rows the fit never saw |
| Fit unlimited tree + forest | Same split; forest averages many trees |
| Bar-plot both scores | See whether averaging beat the single tree |
Coding lab. Compare a tree to a random forest runs in the app, with checks on your output.
Comparing an unlimited-depth tree to a 50-tree forest on the same hold-out, what should you expect across re-runs?
- The lone tree wins, because forests underfit by design
- Both scores are identical — the forest is just the tree repeated
- The forest always scores exactly 50 times better
- The forest matches or beats the lone tree, with less score wobble from run to run
Averaging bootstrap-grown trees cuts variance: one overgrown tree's weird path is diluted, so the forest's hold-out score is typically as good or better, and steadier.
Notes
- Bagging trains many models on bootstrap samples (rows drawn with replacement) and averages their votes or predictions.
- Random forests also try a random feature subset at each split, so trees disagree more and the average is stabler.
- The cost is interpretability — you no longer point at a single path; feature-importance summaries are a sketch, not a proof.
Exam traps & shortcuts
- Keep lab datasets under 2000 rows in the browser runtime.
- Split train and test before fitting any model that sees labels.
Recap
This lesson in brief:
- Bagging
- Bagging trains many models on bootstrap samples (rows drawn with replacement) and averages their votes or predictions.
- Random feature subsets
- Random forests also try a random feature subset at each split, so trees disagree more and the average is stabler.
- Variance vs path
- Variance drops because one overgrown tree's weird path is diluted by hundreds of others — but you lose a single readable path.
Practise Random Forests
Reading is free and needs no account. Practice, mocks and progress live in the app.
- 10 exam-style questions on this topic, with explanations
- A 5-question practice set that ends the chapter
- Timed mocks scored with the real marking scheme
- Readiness tracked per topic, kept on your device