A decision tree predicts by asking a sequence of questions.
An ensemble combines several models so their different strengths and mistakes can produce a better final prediction.
Lesson details
- Module
- Classical machine learning
- Lesson
- 3 · Trees & ensembles
- Difficulty
- Beginner
- Learning time
- 65 minutes
Before you start
- Features, targets, classification, regression, and validation
- Probabilities, entropy, residuals, and gradients
Skills you will gain
- Trace a prediction from a tree root to a leaf
- Calculate Gini impurity, entropy, and information gain
- Control tree depth and leaf size to reduce overfitting
- Explain bootstrap sampling, bagging, and random forests
- Trace residual correction in gradient boosting
- Compare XGBoost, LightGBM, and CatBoost without treating one as universally best
- Design leakage-safe stacking with out-of-fold predictions
Why this matters
Tabular business data often contains thresholds and interactions: an account may be risky only when it is both new and experiencing repeated failures.
Trees discover such branching patterns without requiring every interaction to be written manually. Ensembles make individual trees more stable or more accurate.
Plain-English mental model
Part 1 — Anatomy of a decision tree
A tree contains:
- root node: the first question;
- internal node: another feature question;
- branch: one answer path;
- leaf: terminal prediction;
- depth: number of splits along a longest root-to-leaf path.
For a numeric feature, a question is commonly:
failed_attempts < 2.5?
Thresholds between observed values are considered during training.
For classification, a leaf stores training class counts or proportions. For regression, it commonly predicts the mean target of training rows in that leaf.
Prediction is deterministic traversal
def predict_urgency(failed_attempts, account_age_days):
if failed_attempts < 3:
return 0.10
if account_age_days < 7:
return 0.80
return 0.375
print(predict_urgency(4, 2))
print(predict_urgency(1, 100))This code represents a fitted tree. Training is the process that selected features, thresholds, and leaf values.
Part 2 — Trees search for cleaner children
A classification node is pure when every row has the same class.
ImpurityImpurityA score describing how mixed the target classes are inside a tree node. A pure classification node contains one class; Gini impurity and entropy are common measures. measures class mixing.
Gini impurity
Gini impurityGini impurityOne minus the sum of squared class proportions in a node. It is zero for a pure node and estimates how often a randomly labelled item would be misclassified under the node proportions. is:
Gini = 1 - Σ p_k²
For 6 urgent and 4 not urgent:
p_urgent = 0.6
p_not = 0.4
Gini = 1 - 0.6² - 0.4² = 0.48
A pure binary node has Gini 0. A perfectly balanced binary node has Gini 0.5.
Entropy
Entropy is:
entropy = -Σ p_k log₂(p_k)
A pure node has entropy 0. A balanced binary node has entropy 1 bit.
Gini and entropy often select similar trees, but not always. Neither is a guarantee of product value.
Part 3 — Information gain scores a split
Children of different sizes must be weighted:
weighted child impurity
= (n_left/n_parent)×impurity_left
+ (n_right/n_parent)×impurity_right
Information gainInformation gainParent impurity minus the child impurities weighted by child size. A tree prefers candidate splits that produce the largest reduction under its chosen impurity measure. is:
gain = parent impurity - weighted child impurity
Higher gain means the split reduced impurity more.
Expected output:
0.5 0.1
1.5 0.25
2.5 0.5
3.5 0.25
4.5 0.1
Important lines
gini(labels)- Converts class proportions into one mixing score.
value < threshold- Sends each row to exactly one candidate child.
len(child) / len(rows)- Weights child impurity by the number of rows it represents.
parent_impurity - weighted- Measures improvement from this split. Training chooses the best permitted candidate, then repeats recursively.
Part 4 — Regression trees reduce numerical error
A regression tree asks the same feature questions but works with numerical targets.
Common leaf prediction:
leaf prediction = mean target in leaf
Candidate splits can minimise weighted squared error or variance.
Example targets:
left child: [10, 12, 14] → prediction 12
right child: [40, 45] → prediction 42.5
Regression-tree predictions are piecewise constant. They do not extrapolate a trend beyond observed leaves the way a line can.
Part 5 — Why one deep tree overfits
A tree can keep splitting until leaves contain one row.
Training error may become zero, but tiny data changes can produce a different upper split and a very different tree. This is high variance.
Control complexity with:
- maximum depth;
- minimum rows required to split;
- minimum rows per leaf;
- maximum number of leaves;
- minimum impurity decrease;
- pruning after growth.
Choose these with validation or cross-validation, not test data.
Shallow trees may underfit. Deep trees may memorise. There is no universal ideal depth.
Part 6 — Trees handle features differently from linear models
Advantages:
- capture thresholds and interactions;
- usually do not require standardisation;
- can mix nonlinear feature effects;
- paths can be inspected;
- support classification and regression.
Limitations:
- greedy splitting does not guarantee the globally best tree;
- small data changes can alter structure;
- axis-aligned splits may approximate smooth diagonal boundaries inefficiently;
- leaf probabilities can be poorly calibrated;
- standard implementations vary in missing and categorical handling;
- feature importance can mislead.
Never encode a nominal category such as red/green/blue as 1/2/3 unless the implementation treats it categorically; otherwise numeric thresholds invent an order.
Part 7 — Bootstrap sampling creates varied training sets
A bootstrap sampleBootstrap sampleA dataset formed by drawing the same number of rows from a source dataset with replacement, so some rows repeat and others are omitted. Bagging trains each base learner on a different bootstrap sample. draws n rows from n training rows with replacement.
Some rows appear multiple times. Others are absent.
Expected output:
1 ['B', 'A', 'B', 'A', 'A'] omitted: ['C', 'D', 'E']
2 ['C', 'E', 'E', 'D', 'B'] omitted: ['A']
3 ['C', 'B', 'A', 'A', 'B'] omitted: ['D', 'E']
Rows omitted from one tree’s bootstrap sample are out-of-bag for that tree and can support an internal performance estimate. Keep a genuine final test set.
Part 8 — Bagging averages unstable models
Bootstrap aggregatingBaggingBootstrap aggregating trains models independently on resampled training datasets and averages or votes over their predictions, mainly reducing variance when base models make partly different errors., shortened to bagging:
- Draw many bootstrap samples.
- Fit one base model independently to each sample.
- Average regression predictions or vote/average classification probabilities.
If models make partly independent errors, averaging reduces variance.
Bagging helps unstable learners such as deep trees. Bagging nearly identical models with perfectly correlated errors provides little benefit.
Part 9 — Random forests decorrelate trees
A random forestRandom forestA bagged collection of decision trees that also considers random feature subsets at splits, encouraging diverse trees whose averaged predictions are more stable than one deep tree. adds another source of variation:
- bootstrap rows for each tree;
- consider only a random subset of features at each split.
Why random features?
If one strong feature dominates, every bagged tree may choose it at the root and become similar. Random feature subsets force alternative useful structures. Averaging diverse trees can be more stable.
Important settings:
- number of trees;
- features considered per split;
- maximum depth;
- minimum leaf size;
- class weights;
- bootstrap choice.
More trees generally stabilise the average but increase compute and memory. They do not fix biased data or an overfitting split protocol.
Part 10 — Feature importance needs caution
Common tree importance methods:
- impurity importance: total weighted impurity reduction attributed to a feature;
- permutation importance: measure validation-score decrease after shuffling one feature.
Impurity importance can favour continuous or high-cardinality features with more split opportunities.
Permutation importance can understate correlated features because a partner still supplies similar information. It must be calculated on held-out data with a meaningful metric.
Importance means the model used a feature for prediction under this data—not that the feature causes the outcome.
Part 11 — Boosting learns sequential corrections
BoostingBoostingA sequential ensemble strategy in which each new weak learner focuses on errors or loss gradients left by the current ensemble, and the learners are combined into one additive prediction. combines weak learners sequentially.
For squared-error gradient boostingGradient boostingBoosting that fits each new learner to the negative gradient of a differentiable loss with respect to current predictions. For squared error, that negative gradient is the residual.:
- Start with a baseline, often mean target.
- Calculate residuals.
- Fit a small tree to those residuals.
- Add a shrunken version of its prediction.
- Recalculate residuals.
- Repeat.
new_prediction
= old_prediction + learning_rate × new_tree_prediction
For other differentiable losses, each tree fits the negative gradient—often called a pseudo-residual.
Worked residual correction
Targets:
[10, 20, 30]
Initial prediction is mean 20:
predictions = [20, 20, 20]
residuals = [-10, 0, 10]
Suppose a stump predicts residual corrections [-8, 0, 8] and learning rate is 0.5:
new predictions = [16, 20, 24]
new residuals = [-6, 0, 6]
The next tree focuses on what remains.
Small trees and learning rates regularise the sequence. Too many boosting rounds can overfit.
Part 12 — XGBoost, LightGBM, and CatBoost
These are optimised gradient-boosted tree libraries, not three completely different learning paradigms.
XGBoost
XGBoost provides a regularised gradient-boosting objective, second-order gradient information, sparsity-aware processing, column sampling, and efficient parallel systems.
It is a mature general-purpose baseline with extensive tooling.
LightGBM
LightGBM uses histogram-based splits and commonly grows trees leaf-wise by expanding the leaf with greatest gain.
Leaf-wise growth can reduce loss quickly but may overfit small datasets unless leaf count, depth, and minimum leaf data are controlled.
It also includes optimisations such as gradient-based one-side sampling and exclusive feature bundling.
CatBoost
CatBoost is designed for strong handling of categorical features. Ordered target statistics and ordered boosting reduce leakage and prediction shift that naive target encoding can introduce.
Do not precompute category target means using all rows; that leaks labels regardless of library.
Choose by evidence
Compare:
- data size and sparsity;
- categorical feature needs;
- missing-value semantics;
- training and inference constraints;
- validation quality;
- probability calibration;
- reproducibility and deployment environment.
Tune equivalent capacity, not just default settings. No library wins every dataset.
Part 13 — Stacking learns how to combine models
StackingStackingTraining a meta-model to combine predictions from several base models. Meta-training features must be created out of fold so the base predictions for each row come from models that did not train on that row. uses predictions from base models as inputs to a meta-model.
Example base models:
- logistic regression;
- random forest;
- gradient boosting.
Correct training:
- Divide training data into folds.
- For each fold, fit base models on other folds.
- Predict the held-out fold.
- Concatenate out-of-fold predictions.
- Fit the meta-model on those predictions and targets.
- Refit each base model on all training data.
- At inference, send base predictions into the meta-model.
If the meta-model sees in-sample base predictions, it learns from base-model memorisation and fails on unseen inputs.
Stacking adds latency, operational dependencies, and debugging complexity. It must beat the best single model meaningfully.
Worked example — triage ticket urgency
1. Evidence
Split by customer and time. Features must exist at ticket creation. Keep latest months sealed for test.
2. Single tree
Fit a shallow classification tree. Inspect paths and minimum leaf counts. It exposes candidate interactions but may vary across folds.
3. Random forest
Fit many bootstrapped trees with random feature subsets. Compare validation recall, precision, calibration, latency, and group slices.
4. Gradient boosting
Fit shallow boosted trees with a small learning rate and early stopping on validation data. Avoid using the test set for the stopping round.
5. Select
If boosting improves the declared metric but is poorly calibrated, calibrate with separate validation evidence. If the forest is nearly as good and easier to operate, simpler may win.
6. Explain honestly
Show validated feature dependence and representative paths, but do not claim one tree explains the entire ensemble or proves causality.
In a real AI system
Common mistakes
Growing a tree until every training leaf is pure.
Fix — Use validation-selected depth, leaf size, pruning, and minimum gain; inspect variance across folds.
Comparing child impurity without weighting by child size.
Fix — Multiply each child impurity by its fraction of parent rows before calculating gain.
Encoding unordered categories as arbitrary integers.
Fix — Use explicit categorical handling or a leakage-safe encoding fitted inside training folds.
Assuming hundreds of nearly identical trees remove variance.
Fix — Bagging needs diversity; bootstrap rows and random feature subsets help decorrelate tree errors.
Calling boosted trees parallel bagging.
Fix — Boosting is sequential: each learner depends on the current ensemble's residuals or gradients.
Treating default XGBoost, LightGBM, or CatBoost as a universal winner.
Fix — Compare tuned capacity, data handling, calibration, latency, and deployment constraints on valid splits.
Training a stacking meta-model on in-sample base predictions.
Fix — Create out-of-fold predictions so each meta-training row was predicted by base models that did not fit that row.
Reading feature importance as causal impact.
Fix — Describe model reliance under this dataset; inspect bias, correlation, stability, and causal assumptions separately.
Exercises
A node contains six positive and four negative rows. Calculate its Gini impurity.
Reveal solution
The proportions are 0.6 and 0.4. Gini is 1 - 0.6² - 0.4² = 1 - 0.36 - 0.16 = 0.48.
A parent node has Gini 0.5 and 20 rows. A split creates a 12-row child with Gini 0.25 and an 8-row child with Gini 0.375. Calculate weighted child impurity and gain.
Reveal solution
Weighted child impurity is (12/20)×0.25 + (8/20)×0.375 = 0.15 + 0.15 = 0.30. Gain is 0.50 - 0.30 = 0.20.
Explain why training a stacking meta-model on base-model predictions from the same rows those base models fitted is leakage. Describe the correction.
Reveal solution
In-sample base predictions are unrealistically strong because each base model has already seen those targets. The meta-model learns from a signal unavailable for truly unseen rows. Create out-of-fold predictions: for each fold, fit every base model on the other folds and predict the held-out fold. Concatenate those held-out predictions to train the meta-model, then refit base models on all training data for deployment.
Knowledge check
Knowledge check
Practice activity
Practice · 10–20 minutes
Choose the best first split
Goal: Calculate weighted Gini gain for candidate thresholds and turn the winner into a decision stump.
- Run the starter data through the supplied Gini helper.
- Generate thresholds halfway between adjacent unique feature values.
- Split labels at each threshold.
- Calculate weighted child impurity and gain.
- Select the highest-gain threshold.
- Calculate each leaf's positive-class probability.
- Write a prediction function and state one limitation.
Expected result: For the supplied ordered data, threshold 2.5 has gain 0.5 and produces pure leaves with probabilities 0 and 1.
Optional challenge: Change one label, recalculate all gains, and explain why the best split or leaf probabilities changed.
Reveal solution
rows = [(0, 0), (1, 0), (2, 0), (3, 1), (4, 1), (5, 1)]
def gini(labels):
positive = sum(labels) / len(labels)
return 1 - positive ** 2 - (1 - positive) ** 2
# Generate midpoint thresholds and calculate gain.rows = sorted(rows)
labels = [label for _, label in rows]
parent = gini(labels)
thresholds = [
(left[0] + right[0]) / 2
for left, right in zip(rows, rows[1:])
if left[0] != right[0]
]
best = None
for threshold in thresholds:
left = [label for value, label in rows if value < threshold]
right = [label for value, label in rows if value >= threshold]
weighted = (
len(left) / len(rows) * gini(left)
+ len(right) / len(rows) * gini(right)
)
gain = parent - weighted
candidate = (gain, threshold, sum(left) / len(left), sum(right) / len(right))
if best is None or candidate > best:
best = candidate
gain, threshold, left_probability, right_probability = best
print("threshold:", threshold)
print("gain:", gain)
print("leaf probabilities:", left_probability, right_probability)Expected output:
threshold: 2.5
gain: 0.5
leaf probabilities: 0.0 1.0Limitation: this perfect separation is based on only six training rows. It needs protected validation evidence and minimum-leaf safeguards.
Key takeaways
- A tree routes one row through feature questions to a leaf prediction.
- Gini and entropy measure class mixing; information gain compares a parent with size-weighted children.
- Deep trees are flexible but unstable, so depth and leaf size need validation control.
- Bagging averages independently varied models; random forests also randomise candidate features.
- Boosting adds learners sequentially to correct current residuals or loss gradients.
Flashcards
Flashcards
1 of 10Revision and interview questions
- Calculate Gini, entropy, weighted child impurity, and gain for a proposed split.
- Compare one tree, bagged trees, and a random forest in terms of bias, variance, and diversity.
- Trace two rounds of squared-error gradient boosting from baseline through residual corrections.
- Compare XGBoost, LightGBM, and CatBoost without claiming a universal winner.
- Design an out-of-fold stacking pipeline and identify its latency and leakage risks.
One-page sketchnote summary
Print me · one-page revision sheet
Trees & ensembles
Main idea
Trees learn nonlinear branching rules. Bagging stabilises varied trees, boosting adds corrections sequentially, and stacking learns a combination from predictions that must be generated out of fold.
Core terms
- Node — feature question
- Leaf — terminal prediction
- Gini/entropy — class mixing
- Bagging — parallel averaging
- Boosting — sequential correction
- Stacking — learned model combination
One picture
Code pattern
gain = impurity(parent) - weighted_impurity(children)
forest = average(independent_tree_predictions)
boosted += learning_rate * next_correction
meta.fit(out_of_fold_predictions, targets)Watch out
- Do not grow pure singleton leaves blindly
- Do not forget child-size weights
- Do not ordinal-encode nominal categories
- Do not call importance causal
- Do not stack in-sample predictions
Remember
- One row follows one path
- Choose splits by impurity reduction
- Average diverse trees for stability
- Boost residuals in small steps
- Use out-of-fold meta-features
Three quick questions
- How many rows reach this leaf?
- Are these ensemble errors diverse?
- Was this meta-feature out of fold?
Lesson checklist
0 of 9 completeResources
- docsscikit-learn — decision treesOfficial guide to classification and regression trees, complexity, and implementation considerations.
- docsscikit-learn — ensemble methodsOfficial overview of forests, bagging, gradient boosting, and stacking.
- docsXGBoost documentationOfficial API and algorithm documentation for regularised gradient-boosted trees.
- docsLightGBM documentationOfficial documentation for histogram learning, leaf-wise growth, and categorical features.
- docsCatBoost documentationOfficial documentation for ordered boosting and native categorical-feature handling.