Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Arbres de décision : entropie et gain

Après cette leçon: Je peux choisir la question qui sépare le mieux des données grâce au gain d’information.

Leçon de 60 min1 commandeLab JupyterLab de science des données : pandas, Matplotlib et scikit-learn dans le navigateur

Comment un arbre de décision choisit-il ?

Un arbre de décision est un modèle qui pose une suite de questions simples, comme « l’étudiant est-il assidu ? », pour arriver à une réponse. Pour le construire, il faut savoir quelle question poser en premier.

On mesure le désordre d’un groupe avec l’entropie, puis la meilleure question avec le gain d’information.

À la fin de cette leçon

Remarque

Je peux choisir la question qui sépare le mieux des données grâce au gain d’information.

Mots clés

MotCe que ça veut direExemple
Arbre de décisionune suite de questions qui mène à une réponse
Étiquettela réponse que l’arbre doit prédireréussit
Entropiela mesure du désordre des étiquettes d’un groupe
Gain d’informationla baisse d’entropie après une question
Feuillele bout d’une branche, où l’arbre répond

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

L’entropie mesure le désordre d’un groupe

Dix étudiants passent une épreuve. Cinq réussissent et cinq échouent. Si l’on pioche un étudiant, on ne peut rien prévoir : le désordre est maximal et l’entropie vaut 1.

Si tous réussissent, on sait déjà la réponse : l’entropie vaut 0. Entre les deux, plus un groupe est mélangé, plus son entropie est haute.

Exemple travaillé : l’entropie de quelques groupes

GroupeRéussitesÉchecsEntropie
Tous pareils500
Presque pareils410,722
Un peu mélangés310,811
Mélangés420,918
Moitié-moitié551

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Calculer l’entropie et le gain

Code: python
import math

def entropie(etiquettes):
    total = len(etiquettes)
    comptes = {}
    for e in etiquettes:
        if e in comptes:
            comptes[e] = comptes[e] + 1
        else:
            comptes[e] = 1
    resultat = 0
    for e in comptes:
        p = comptes[e] / total
        resultat = resultat - p * math.log2(p)
    return resultat

# La réussite de dix étudiants, puis des deux groupes de la question « assidu ? ».
tous = ["oui", "oui", "oui", "non", "oui", "non", "non", "oui", "non", "non"]
assidus = ["oui", "oui", "oui", "non", "oui"]
absents = ["non", "non", "oui", "non", "non"]
print("entropie de départ", round(entropie(tous), 3))
apres = 5 / 10 * entropie(assidus) + 5 / 10 * entropie(absents)
print("entropie après la question", round(apres, 3))
print("gain", round(entropie(tous) - apres, 3))

Le gain d’information compare avant et après

Une question coupe le groupe en parties. On calcule l’entropie de chaque partie, puis on fait la moyenne en pesant chaque partie par sa taille.

Le gain d’information est l’entropie de départ moins cette moyenne. La meilleure question est celle dont le gain est le plus grand : elle range le mieux.

Exemple travaillé : deux questions comparées

QuestionGroupesEntropie moyenneGain
Assidu ?oui : 4 et 1, non : 1 et 40,7220,278
A révisé ?oui : 4 et 2, non : 1 et 30,8750,125

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Dans le labo, quelle question sépare les jours ?

Revenons aux jours de hires.csv, où un jour est « plein » à 300 locations ou plus. La commande suivante affiche quatre nombres.

Le premier est l’entropie de l’année. Les trois autres sont les gains de trois questions : « est-ce un week-end ? », « fait-il 15 degrés ou plus ? » et « quelle est la météo ? ». Elle ne modifie aucun fichier.

Comparer trois questions sur les jours

Commande
docker exec jupyter python3 -c "import csv, math; L = list(csv.DictReader(open('hires.csv'))); n = len(L); busy = lambda g: sum(1 for r in g if int(r['hires']) >= 300); H = lambda g: -sum(p * math.log2(p) for p in (busy(g) / len(g), 1 - busy(g) / len(g)) if p > 0); gain = lambda gs: H(L) - sum(len(g) / n * H(g) for g in gs); W = [r for r in L if r['weekday'] in ('Sat', 'Sun')]; T = [r for r in L if float(r['temp_c']) >= 15]; print(round(H(L), 3), round(gain([W, [r for r in L if r not in W]]), 3), round(gain([T, [r for r in L if r not in T]]), 3), round(gain([[r for r in L if r['weather'] == w] for w in ('sunny', 'cloudy', 'rainy')]), 3))"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Un arbre répète son choix à chaque branche

On choisit la question au plus grand gain, on coupe les données en branches, puis on recommence dans chaque branche. On s’arrête quand un groupe est pur ou trop petit.

Au bout de chaque branche, la feuille répond avec l’étiquette la plus fréquente. Pour prévoir un nouveau cas, on suit les réponses de la racine jusqu’à une feuille.

Une erreur fréquente

Attention

Beaucoup pensent qu’un arbre plus profond est toujours meilleur. Un arbre qui pose une question par ligne donne une entropie de zéro sur ses données. Pourtant il a seulement appris le bruit par cœur. On limite la profondeur et on le juge sur des données gardées de côté.

Pour aller plus loin

Dans votre carnet, changez le seuil de température de 15 à 10, puis à 20. Calculez à chaque fois le gain avec la même méthode que la commande.

Dites quel seuil sépare le mieux les jours pleins des jours calmes, et pourquoi.

À propos de ce labo et de sa source: Lab JupyterLab de science des données : pandas, Matplotlib et scikit-learn dans le navigateur

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.