intentan maximizar la información mutua en el árbol.
De forma intuitiva, la impureza de Gini se puede entender como un criterio para minimizar la probabilidad de clasificación errónea:
De forma similar a la entropía, la impureza de Gini es máxima si las clases están perfectamente mezcladas; por ejemplo, en un ajuste de clase binaria (
Sin embargo, a la práctica, tanto la impureza de Gini como la entropía producen normalmente resultados muy similares, y a menudo no vale la pena perder el tiempo evaluando los árboles mediante diferentes criterios de impureza en lugar de experimentar con distintos cortes de poda.
Otra medida de impureza es el error de clasificación:
Se trata de un criterio muy útil para podar aunque no es recomendable para hacer crecer un árbol de decisión, puesto que es menos sensible a los cambios en las probabilidades de clase de los nodos. Podemos demostrarlo observando los dos posibles casos de división mostrados en la siguiente imagen:
Empezamos con un conjunto de datos
Sin embargo, la impureza favorecería la división en el caso B (
De forma parecida, el criterio de entropía también favorecería el caso B (
Para obtener una comparación más visual de los tres criterios distintos de impureza que acabamos de tratar, vamos a mostrar gráficamente los índices de impureza para el rango de probabilidad [0, 1] para la clase 1. Ten en cuenta que también añadiremos una versión escalada de la entropía (entropía / 2) para observar que la impureza de Gini es una medida intermedia entre la entropía y el error de clasificación. El código es el siguiente:
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> def gini(p):
... return (p)*(1 - (p)) + (1 - p)*(1 - (1-p))
>>> def entropy(p):
... return - p*np.log2(p) - (1 - p)*np.log2((1 - p))
>>> def error(p):
... return 1 - np.max([p, 1 - p])
>>> x = np.arange(0.0, 1.0, 0.01)
>>> ent = [entropy(p) if p != 0 else None for p in x]
>>> sc_ent = [e*0.5 if e else None for e in ent]
>>> err = [error(i) for i in x]
>>> fig = plt.figure()
>>> ax = plt.subplot(111)
>>> for i, lab, ls, c, in zip([ent, sc_ent, gini(x), err],
... ['Entropy', 'Entropy (scaled)',
... 'Gini Impurity',
... 'Misclassification Error'],
... ['-', '-', '--', '-.'],
... ['black', 'lightgray',
... 'red', 'green', 'cyan']):
... line = ax.plot(x, i, label=lab,
... linestyle=ls, lw=2, color=c)
>>> ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.15),
... ncol=5, fancybox=True, shadow=False)
>>> ax.axhline(y=0.5, linewidth=1, color='k', linestyle='--')
>>> ax.axhline(y=1.0, linewidth=1, color='k', linestyle='--')
>>> plt.ylim([0, 1.1])
>>> plt.xlabel('p(i=1)')
>>> plt.ylabel('Impurity Index')
>>> plt.show()
El gráfico obtenido a partir del código anterior es el siguiente:
Crear un árbol de decisión