Machine learningLoading progress…

Impurity

Choose a split by impurity reduction and distinguish bagging, random forests and boosting.

How mixed is a node?

When you cut, you want the two sides to be cleaner than the whole. To compare cuts you need a number for how mixed a node is. Two classics:

  • Gini impurity: pick two examples at random (with replacement) from the node; this is the chance they have different classes. With class fractions pk it is 1 − Σ pk².
  • Entropy: −Σ pk log₂ pk, measured in bits. It is the average number of yes/no questions needed to find the class of a random example if you ask smartly.

Both are 0 for a pure node, both are largest for an even mix, and they only look at the class fractions: not at what the classes mean or how important they are. Edit the counts below and compare.

AAAB
00.5100.51fraction of class A in the nodeentropy (bits)Gini
4 examplesclass A fraction 0.75
Gini 1 - (3/4)² - (1/4)² = 1 - 0.5625 - 0.0625 = 0.375 Entropy -(0.75 × log2(0.75) + 0.25 × log2(0.25)) = 0.8113 bits

Both curves are 0 at the ends (a pure node), peak at a 50/50 mix, and are symmetric: swapping the names of the classes changes nothing. Gini peaks at 0.5, entropy at 1 bit.

Change the counts of two classes. The dots on the curves mark the node you built.

Worked numbers

A node with 3 red and 1 blue example has fractions 0.75 and 0.25. Gini = 1 − 0.75² − 0.25² = 0.375. Entropy = −(0.75 log₂ 0.75 + 0.25 log₂ 0.25) = 0.8113 bits. A 50/50 node scores Gini 0.5 and entropy exactly 1 bit. For a two-class node the largest Gini is 0.5, but with K equally likely classes Gini can reach 1 − 1/K and entropy log₂ K.

Predict first. Node A holds 9 examples of one class and 1 of another. Node B holds 5 and 5. Which is purer, and roughly by how much in Gini?

The common mistake

Impurity measures class mixture, and nothing else. A leaf with Gini 0 on the training data is not necessarily reliable (it might contain two examples), and a high-impurity node is not necessarily an unimportant one. Also, an empty node has no fractions at all: dividing by a count of zero gives a nan, so code must return 0 for it explicitly. Likewise, in entropy a class with count 0 must be skipped, because log₂ 0 is undefined.

>>> import numpy as np
>>> p = np.array([0.0, 1.0])
>>> -np.sum(p * np.log2(p))     # 0 * log2(0) is nan
nan                              # (plus a RuntimeWarning)
>>> p = p[p > 0]                 # keep only the classes present
>>> -np.sum(p * np.log2(p))
-0.0
Chapter context

A decision tree recursively asks questions that partition data. An ensemble combines many models to improve behavior, but the way those models are trained determines what kind of errors the combination can reduce.

Chapter reference: math, worked example & code

This section belongs to the whole chapter, so it is the same on every lesson in it and may cover a different lesson's topic. The code for the experiment you just ran is inside the experiment itself.

Math and notation

G(p)=1−∑kpk2,ΔG=Gparent−nLnGL−nRnGR.G(p)=1-\sum_kp_k^2,\quad \Delta G=G_{parent}-\frac{n_L}{n}G_L-\frac{n_R}{n}G_R.

A boosted additive model has the form Ft+1(x)=Ft(x)+ηht(x)F_{t+1}(x)=F_t(x)+\eta h_t(x). The stage target depends on the loss and boosting method.

Worked example

A parent contains three red examples and one blue example. Its Gini is 1−0.75²−0.25²=0.375. Split into a left child with two red examples and a right child with one red and one blue. Weighted child Gini is 2/4×0 + 2/4×0.5 = 0.25, giving gain 0.125.

Reference code

The following example uses the Python standard library and does not call a remote service.

from math import isclose
gini = lambda counts: 1-sum((n/sum(counts))**2 for n in counts)
parent = gini([3,1])
children = .5*gini([2,0]) + .5*gini([1,1])
assert isclose(parent, .375)
assert isclose(children, .25)
assert isclose(parent-children, .125)

Python examples are provided for study and local execution; this page does not execute Python.

Common mistakes

Feature importance is not causal influence. A pure training leaf need not generalize. Bagging and boosting are different training strategies, not interchangeable names for averaging.