Entropy · Information Gain · Gini
Press Next → or use ← → arrow keys
Impurity — The Foundation Of Every Split
Impurity measures how mixed the classes are inside a group. A decision tree's entire job is to find splits that make the child groups less mixed than the parent. Entropy and Gini are the two ways to measure that mixing.
Entropy counts the yes/no questions needed to guess a sample's class. Gini asks how often you'd mislabel a random sample. Both hit zero when a node is pure and peak when the classes are perfectly balanced.
Entropy — Uncertainty Measured In Bits
H = 1 means you need exactly one yes/no question to guess the class (like a coin flip). H = 0 means you need none — you already know. H = 3 (for 8 balanced classes) means you'd need 3 questions. That's Shannon's information theory in one sentence.
Step-By-Step — Play Tennis Parent Entropy
The classic dataset: 14 days · 9 Play · 5 Don't Play. Before any split, how uncertain is the parent?
+ 1e-12) to avoid NaN when a class has zero samples.| Classes n | Max Entropy log₂(n) | Example Domain |
|---|---|---|
| 2 | 1.000 bits | Yes / No |
| 3 | 1.585 bits | Sunny · Overcast · Rain |
| 4 | 2.000 bits | Seasons |
| 10 | 3.322 bits | Digit recognition 0–9 |
The Impurity Spectrum — Pure To Chaotic
Pure → zero. Balanced → maximum. Between them they curve slightly differently — but they always agree on the winner when the choice is obvious. That's why sklearn defaults to the faster Gini, and only true information-theory work justifies switching to Entropy.
Entropy vs Gini vs Misclassification
| Property | Entropy | Gini |
|---|---|---|
| Formula | −Σ pᵢ·log₂(pᵢ) | 1 − Σ pᵢ² |
| Binary max | 1.0 bit | 0.5 |
| n-class max | log₂(n) | (n−1)/n |
| Computation | slower (log) | faster (square) |
| Sensitivity at extremes | higher | smoother |
| sklearn | criterion='entropy' | default |
Gini — The Fast Cousin
Intuition: if you pick a random sample from the node and randomly label it according to the node's class distribution, what's the probability you get it wrong? That probability is Gini.
| Classes n | Max Gini (n−1)/n | Comparison to Entropy log₂(n) |
|---|---|---|
| 2 | 0.500 | Entropy: 1.000 bits |
| 3 | 0.667 | Entropy: 1.585 bits |
| 4 | 0.750 | Entropy: 2.000 bits |
| 5 | 0.800 | Entropy: 2.322 bits |
| 10 | 0.900 | Entropy: 3.322 bits |
"Gini 0.460 vs Entropy 0.940" tells you nothing — different ranges. Only compare gain within the same metric. Both will nearly always pick the same split anyway.
Information Gain — How A Split Is Scored
Play Tennis — splitting on Outlook:
| Child | [Yes, No] | Weight | Entropy | Contribution |
|---|---|---|---|---|
| Sunny | [2, 3] | 5/14 | 0.971 | 0.347 |
| Overcast | [4, 0] | 4/14 | 0.000 | 0.000 |
| Rain | [3, 2] | 5/14 | 0.971 | 0.347 |
| Weighted child entropy | 0.694 | |||
| Information Gain | 0.940 − 0.694 = 0.246 bits | |||
The Overcast child is perfectly pure — every one of the 4 Overcast days is a "Yes". That single pure child alone recovers 25% of the parent's entropy. This is why Outlook decisively beats the alternatives.
The Winner — Information Gain Bar Chart
Temperature's 0.029 bit gain is so tiny it will never win a split anywhere in the tree. The feature-importance report will show it as zero. A powerful free feature-selection signal: drop it and retrain leaner.
Good Split vs Bad Split — Visualised
"After this split, how much less uncertain am I?" A great split turns confusion into certainty (IG large). A pointless split preserves the confusion (IG = 0). The tree tries every split and keeps only the ones that meaningfully reduce IG.
Gain Ratio — Fixing IG's Fatal Flaw
Raw Information Gain has a bias: it loves features with many unique values, even when they're useless. Add a "Day ID" column with 14 unique values, and it wins with IG = 0.940 — the maximum possible.
Any column with near-unique values per row (transaction IDs, timestamps, names) will hijack raw IG. Either drop them, bin them, or use Gain Ratio / Gini which are less susceptible to the bias.
Implementation — Entropy, Gini & IG From Scratch
import numpy as np def entropy(labels): """Shannon entropy of class labels.""" n = len(labels) if n == 0: return 0.0 _, counts = np.unique(labels, return_counts=True) probs = counts / n return -np.sum(probs * np.log2(probs + 1e-12)) # epsilon avoids NaN def gini(labels): """Gini impurity of class labels.""" n = len(labels) if n == 0: return 0.0 _, counts = np.unique(labels, return_counts=True) probs = counts / n return 1 - np.sum(probs ** 2) def information_gain(parent, children): """IG = H(parent) − weighted Σ H(child).""" n = len(parent) return entropy(parent) - sum( (len(c) / n) * entropy(c) for c in children ) # ── sklearn — swap the criterion in one word ──── from sklearn.tree import DecisionTreeClassifier dt_gini = DecisionTreeClassifier(criterion='gini').fit(X, y) # default, faster dt_ent = DecisionTreeClassifier(criterion='entropy').fit(X, y) # slightly slower
On clean datasets Gini and Entropy build identical or near-identical trees. Differences surface only on noisy, imbalanced data. Default to Gini for speed; switch to Entropy when you need extra sensitivity in the tail probabilities.
When To Use Which Metric
Balanced classes? → Gini. Imbalanced (fraud, disease)? → Entropy. Features with hugely varied cardinality? → Gain Ratio. When in doubt, run both and pick the higher validation-set score.
Common Pitfalls — What Silently Breaks Splits
+ 1e-12 inside the log to avoid NaN.class_weight='balanced'.Golden Rules — Six Habits For Impurity Metrics
Impurity — The Compass Every Tree Follows
You now understand what impurity means, why Entropy and Gini both work, how Information Gain picks the winner, and why Gain Ratio saves you from ID hijacks. Every tree-based model — Decision Tree, Random Forest, XGBoost, LightGBM — runs on these three numbers.
Study Decision Trees in depth (pruning, hyperparameters), then Random Forest (bagging), then Gradient Boosting (XGBoost / LightGBM). Practise by tracing IG calculations on Kaggle's Titanic dataset — you'll see feature importance drop out for free.
🧮 End of tutorial · Press ← to review, or click Restart