The idea
A decision tree predicts by asking a sequence of threshold questions — is income below 40k? is age above 30? — until it reaches a leaf, which outputs the majority class (or mean) of the training points that landed there. Training is greedy recursive partitioning: at each node, try every feature and threshold, score each candidate by how much it reduces impurity, take the best, recurse.
Gini and entropy agree almost always; Gini skips the logarithm. The split's score is the impurity decrease: parent impurity minus the child impurities weighted by the fraction of samples each child receives.
Trees are loved for the wrong reason in production and the right reason in interviews: no scaling needed (splits are monotone-invariant), native handling of mixed feature types and interactions, and total interpretability — but grown unconstrained they are low-bias, high-variance learners. Greediness makes it worse: perturb the data, an early split flips, and everything below it reshuffles.
Random forests: average away the variance. Train deep trees, each on a bootstrap resample (bagging), each split restricted to a random feature subset (max_features / mtry), and average (or vote). The payoff is the one formula worth memorizing — variance of an average of identically distributed trees with variance and pairwise correlation :
- kills the second term — so more trees never overfit; error converges.
- The floor is untouched by — the only way past it is decorrelating the trees, which is the entire purpose of bootstrap noise and feature subsampling. Restrict features per split and a dominant feature can no longer captain every tree.
- Bias stays roughly that of a single deep tree (low). Bagging is a pure variance play — which is why it does little for already-stable learners like linear regression.
Two freebies: OOB error (each tree misses ~36.8% of rows in its bootstrap; validate on those — a built-in CV substitute) and feature importances (impurity-based ones are biased toward high-cardinality features; prefer permutation importance on held-out data).
Worked example
A node holds 10 samples: 6 positive, 4 negative.
Candidate split: left child gets 4 samples (4+, 0−), right child gets 6 samples (2+, 4−).
Weighted child impurity and gain:
The tree computes this for every feature-threshold candidate and keeps the max. (Entropy version: bits — same ranking of splits here.)
Forest arithmetic: suppose single deep trees have test-MSE variance and average pairwise correlation . With trees:
A 3.3x variance cut — but notice 0.3 of it is the correlation floor. Doubling to gives 0.3035 (nothing); cutting to 0.15 via stronger feature subsampling gives — decorrelation is worth more than tree count once is large.
Cheat sheet
Impurity: Gini ; entropy ; split gain = parent − weighted children. Regression trees: variance / MSE reduction.
Forest variance: → trees kill the right term, decorrelation (bagging + max_features) kills the left.
| Knob | Moves | Direction |
|---|---|---|
| max_depth, min_samples_leaf | per-tree bias/variance | shallower = more bias, less variance |
| max_features (mtry) | tree correlation | smaller = less correlated, sometimes more per-tree bias |
| n_estimators | uncorrelated variance term only | more never overfits; returns diminish |
| ccp_alpha (pruning, single tree) | tree size | CV-tune it |
- Defaults worth knowing: classification mtry , regression .
- Trees need no feature scaling; handle interactions natively; extrapolate FLAT outside the training range (regression gotcha).
- Greedy = locally optimal splits; XOR-style patterns can be missed.
- OOB error CV estimate, free ( of rows out-of-bag per tree).
- Impurity importance is biased (high-cardinality features win by chance); use permutation importance on validation data.
- Bagging reduces variance, not bias — pair with LOW-bias base learners (deep trees). Boosting is the bias-reducing counterpart.
- Class imbalance: forests inherit it — use class_weight or balanced bootstraps.