Lesson 3 of 3

Train, tune and read a forest in R

You understand why a forest works. Now you will build one for real, tune it without a test set, and learn to read what it tells you.

The story so far: a single tree overfits (Lesson 1); bootstrap, random features and averaging fix it (Lesson 2). This lesson turns that understanding into working R and the few knobs that actually matter.

  • Get a free test set from the forest itself (OOB error)
  • Tune mtry and trees on a live model and see the sweet spot
  • Read variable importance, and know the limits

Prerequisites: Lessons 1 and 2 (trees, and how bootstrap + random features build a forest).

A free test set

Out-of-bag error

Remember the ~37% of rows each tree never saw (its bootstrap left them out)? Here is the payoff. To score the forest, run every row through only the trees that did not train on it, and average. No data held back, no separate test split needed.

Key Insight
OOB error is an honest, almost-free estimate of test performance, computed during training. On most problems it lands very close to a proper cross-validation, for a fraction of the work.
In R

Train one in five lines

First, the churn data we will model. Each lesson runs in a fresh R session, so we build it right here (run this once):

RInteractive R
set.seed(42) n <- 800 train <- data.frame( tenure = round(runif(n, 0, 60)), monthly = round(runif(n, 20, 120), 1), total_spend = round(runif(n, 50, 6000)), support_calls = rpois(n, 1.5), contract = factor(sample(c("monthly", "annual"), n, TRUE)), has_addons = rbinom(n, 1, 0.4), paperless = rbinom(n, 1, 0.6), senior = rbinom(n, 1, 0.16) ) risk <- plogis(-1.2 + 1.6 * (train$tenure < 8) + 1.1 * (train$monthly > 85) + 0.35 * train$support_calls - 0.03 * train$tenure) train$churned <- factor(ifelse(runif(n) < risk, "yes", "no"))

  

The randomForest package then fits a forest and reports its out-of-bag (OOB) error directly:

RInteractive R
library(randomForest) set.seed(42) rf <- randomForest( churned ~ ., # predict churn from all columns data = train, ntree = 500, # more is safer, never overfits mtry = 3, # features tried per split (about sqrt of p) importance = TRUE ) rf # prints the out-of-bag (OOB) error estimate

  

Two numbers in that call decide everything: ntree and mtry. Let us feel what they do.

The tuning bench

Turn the two knobs

This is a live forest on the churn data. Drag trees to move along the OOB curve; drag mtry to shift the whole curve up or down. Find the lowest the error will go.

What you just felt

The only knobs worth turning

  1. ntree: more is safe. Error falls then flattens. Use as many as you can afford (300 to 1000). Extra trees never overfit, they just cost time.
  2. mtry: the one real dial. Too low starves each tree; too high re-correlates them. Start near \(\sqrt{p}\) for classification (\(p/3\) for regression) and search a small range around it.
  3. nodesize: light touch. Larger values grow shallower trees. The default is usually fine; nudge it only if a forest overfits a small, noisy dataset.
Your turn

Set mtry by the rule of thumb

You have 8 predictors and a classification problem. Fill in mtry with the \(\sqrt{p}\) starting value (round to a whole number), then check it.

That is it: round(sqrt(8)) = 3.sqrt(8) is about 2.83, which rounds to 3. Set mtry = 3.
Show answer
rf <- randomForest(churned ~ ., data = train,
                   ntree = 500,
                   mtry = 3)   # round(sqrt(8)) = 3
Reading the forest

Which features mattered?

Because every tree records how much each split improved purity, a forest can rank features for free. Sum those gains across all trees and you get variable importance, the first thing to look at after training. The chart below shows a typical ranking for the churn model: tenure dominates, then monthly and total spend.

Warning
Importance says a feature was useful for splitting, not that it causes the outcome, and impurity importance can inflate high-cardinality features. For decisions that matter, confirm with permutation importance or SHAP.
Check yourself

Quick question

You raise num.trees from 100 to 500 and the OOB error barely moves. What does that tell you?

Right. Past convergence more trees neither help nor hurt accuracy. And error will not reach zero: it settles at the forest's floor for this data and mtry.
A flat curve is healthy, not broken: it means the forest has converged.
Know your tool

Where forests shine, where they do not

A random forest is the strongest model you can train with almost no tuning. But it is not magic, and knowing the edges is what separates a practitioner from a button-pusher.

Strengths

  • Strong accuracy out of the box with minimal tuning
  • Handles mixed numeric and categorical features
  • Robust to outliers and irrelevant features
  • Free OOB error and feature importance, computed during training

Limits

  • Less interpretable than a single tree
  • Cannot extrapolate beyond the training range
  • Big models are memory-heavy and slower to predict
  • Gradient boosting often edges it out when carefully tuned
Go deeper

References

Module complete

You built a random forest from the ground up, the tree, the forest, and the tuning, and you can read what it tells you. That is the real thing.

You learned: a single tree (greedy Gini splits, high variance), the forest (bootstrap plus random features plus averaging turns that variance into accuracy), and the practice (OOB error to score, mtry and trees to tune, importance to interpret).

Random Forests is one of the graded modules in the Data Scientist track. Pass the assessment and it goes on your verified certificate, with a portfolio build to match.