Tree-Based Algorithms
Lesson 1Decision Trees
Grow a classifier by asking the most informative question first
A decision tree is the simplest model that still feels like reasoning. It asks a sequence of yes or no questions about the features, "is petal length below 2.5 cm?", "is income above 60k?", and each answer walks you down to a leaf that holds a prediction. No weights, no gradient descent, no calculus at inference time. Just a nested set of if statements the model discovered on its own.
That simplicity is not a toy. The ensembles built from trees, random forests and gradient boosting, still win the majority of Kaggle competitions on tabular data and quietly power fraud detection, credit scoring, and ranking systems in production. Before you can understand those ensembles, you have to understand the single tree they are made of. This lesson is that tree: how it picks a split, the two classic recipes for scoring a split (Gini and entropy), the knobs that stop it from memorizing the training set, and the failure modes a deep-learning engineer needs to name in an interview.
The one question every tree keeps asking
Growing a tree is a single operation applied over and over: take a group of samples and split it into two groups that are each more "pure" than the parent. A pure group is one where almost every sample shares the same label, because then the tree can confidently predict that label and stop.
So the whole algorithm reduces to two questions:
- How do we measure how mixed a group of labels is? (impurity)
- How do we compare candidate splits so we can pick the best one? (information gain)
Answer those two and you have built a decision tree.
1. Impurity
A number that is high when a node is a 50/50 mess and 0 when it is one pure class.
2. Split & score
Try a feature and a threshold; measure how much impurity the split removes.
3. Recurse
Keep the best split, then repeat inside each child until a stopping rule fires.
Play with the split step directly. In the builder below, pick a feature and drag the threshold. Each cut carves the plane into two axis-aligned regions, and the readout shows the impurity of each region and the information gain the cut buys you. Press Find best split to let the greedy search scan every candidate and land on the largest gain, exactly what the algorithm does at each node.
🌳 Decision Tree Builder
Click a region, pick an axis, drag the split line, then Apply — greedy impurity cuts carve the plane into rectangles.
Each split is chosen to maximize information gain = drop in impurity. Recursively splitting leaves partitions feature space into axis-aligned rectangles, each predicting its majority class.
Notice three things while you play. First, the split lines are always axis-aligned: a tree can only ask about one feature at a time, so its regions are rectangles, never diagonals. Second, the best cut is the one that leaves each side as pure as possible. Third, once you split, you can split again inside a region, and that recursion is what lets a shallow-looking tree carve out surprisingly complex shapes.
Measuring impurity: Gini and entropy
We need a function that takes the class proportions in a node and returns a single "how mixed is this" score. Two functions dominate, and they agree on the essentials.
Let a node hold samples from classes, and let be the fraction of the node that belongs to class .
Gini impurity is the probability that you misclassify a random sample if you label it by drawing from the node's own class distribution:
Entropy is the average number of bits needed to encode the class of a sample, borrowed straight from information theory:
For a two-class node with positive fraction , these become and . Both share the same shape: zero at a pure node ( or ) and maximum at a perfect 50/50 mix. Gini tops out at ; entropy tops out at bit. Drag the mix below and watch both rise and fall together.
⚖️ Impurity Meter — Gini vs. Entropy
Drag the mix. Both impurity measures peak at a 50/50 split and fall to 0 when the node is pure.
Maximally mixed (≈50/50). Both measures are at their peak — this node is the most "confused".
The two curves almost never disagree about which split is better, so the choice between them is rarely about accuracy. Gini is slightly cheaper (no logarithm) and is scikit-learn's default; entropy is the one from classic information theory and the original ID3 algorithm. Treat them as two dialects of the same idea: lower is purer.
Information gain: scoring a split
Impurity scores a single node. To score a split, we compare the parent's impurity against the combined impurity of its children, weighted by how many samples fall into each:
Here is the number of samples at the parent, the number in child , and can be entropy (for information gain proper) or Gini (then it is usually called the "Gini decrease"). The weighting matters: a split that produces one tiny pure child and one huge messy child barely helps, and the factors say so. The greedy tree evaluates this quantity for every feature and every candidate threshold, then keeps the split with the largest gain.
One split, computed by hand
Take a node of 10 samples: 6 positive (churned) and 4 negative (stayed). We test the split "tenure months?" which sends 5 samples left and 5 right.
| Node | Samples | Positive | Negative | Composition |
|---|---|---|---|---|
| Parent | 10 | 6 | 4 | 60% / 40% |
| Left (tenure ≤ 12) | 5 | 1 | 4 | 20% / 80% |
| Right (tenure > 12) | 5 | 5 | 0 | 100% / 0% |
Step 1, parent impurity. With :
Step 2, child impurities. The left child is and the right child is pure:
Step 3, weight and subtract. Each child holds half the samples, so the weights are :
Both scores agree the split is excellent: it drops Gini by and buys bits of information, largely because it isolates a perfectly pure right child. This is the exact arithmetic the builder above runs for every candidate cut. You can reproduce it in NumPy in a few lines:
CART vs ID3: two recipes, one idea
The measurement and the search combine into named algorithms. You will hear two in interviews.
CART
Classification and Regression Trees
- Impurity: Gini by default.
- Splits are strictly binary (two children per node).
- Handles numeric features via thresholds; does regression too (splits on variance reduction).
- The algorithm behind scikit-learn's tree.
ID3 / C4.5
Iterative Dichotomiser
- Impurity: entropy, split score is information gain.
- Original ID3 makes one branch per category (multi-way splits).
- Classic teaching algorithm; C4.5 is its successor (gain ratio, pruning).
- Foundational, but production tools use CART-style binary trees.
The important takeaway is that they differ in the impurity function and the branching style, not in the core loop. Both are greedy: at each node they pick the single best split available right now and never look back.
Because a tree can only cut on one axis at a time, the boundary it learns is a staircase of rectangles. That is worth seeing directly. The visual below shows how a set of axis-aligned decisions partitions a 2D feature space, the same rectangular carving the builder produced, now on a denser problem.
The knobs: hyperparameters that stop overfitting
Left alone, a tree will keep splitting until every leaf is pure, which usually means one training point per leaf. That tree has memorized the training set and will generalize terribly. The cure is to constrain it. These are the hyperparameters a deep-learning engineer reaches for most:
max_depth
The hard cap on how many questions deep any path can go. Small depth = a coarse, high-bias tree; large depth = a fine, high-variance tree that can carve out one rectangle per point. The single most important knob.
min_samples_leaf / min_samples_split
Refuse to create a leaf (or split a node) unless it holds at least this many samples. Forces every prediction to rest on a meaningful chunk of data, not a single lucky point.
ccp_alpha (cost-complexity pruning)
Grow the tree fully, then prune back branches whose accuracy gain does not justify their added complexity. It minimizes impurity + alpha x (number of leaves): a larger alpha means a smaller, simpler tree.
The first two are pre-pruning (stop early); ccp_alpha is post-pruning (grow, then cut back). Post-pruning often generalizes better because a split that looks weak on its own can enable a strong split beneath it, and pre-pruning would never discover it.
Watch overfitting appear as you unleash depth. The playground below sweeps max_depth on a noisy make_moons problem and prints train and test accuracy side by side. Train accuracy climbs monotonically toward 1.0; test accuracy peaks and then sags. That gap is the tree memorizing noise.
See the whole thing run: fit, score, and read the tree
Here is a full decision tree end to end in scikit-learn: fit on the two-moons dataset, print train and test accuracy, then plot both the axis-aligned decision regions and the tree itself with plot_tree. Read the tree from the root: each box shows the split test, the Gini impurity, the sample count, and the class distribution. Change max_depth and rerun to watch the regions get jagged.
Where a single tree breaks
Trees are interpretable and fast, but a lone tree has real weaknesses. Naming them is standard interview fare, and every one of them motivates the ensembles later in this section.
Greedy, not optimal
Each split is chosen for immediate gain. A locally weak split might have enabled a much stronger one below it, but the greedy search never explores that path. Finding the globally optimal tree is NP-hard.
High variance / instability
Change a few training points and the top split can flip, reshaping the entire tree below it. This sensitivity is exactly what bagging and random forests are built to average away.
Overfitting
Unconstrained, a tree drives training impurity to zero by memorizing points. Depth limits, leaf minimums, and pruning are the only things standing between it and a lookup table.
Bias to high-cardinality features
A feature with many distinct values (an ID, a zip code) offers many candidate thresholds and can score a high gain by chance. Impurity-based splitting is biased toward such features, which is why gain ratio and permutation importance exist.
Check your understanding
1 / 4A parent node has Gini 0.50. Which candidate split is best?
Interview readiness
Why does a decision tree overfit, and what are three ways to prevent it?
A node has 8 samples: 4 positive and 4 negative. A split sends {3 positive, 1 negative} left and {1 positive, 3 negative} right. Compute the Gini information gain.