
| Petal.Length | Species | 
|---|---|
| 1.4 | setosa | 
| 1.4 | setosa | 
| 4.7 | versicolor | 
| 4.5 | versicolor | 
| 6.0 | virginica | 
| 5.1 | virginica | 
Données + cibles + règles = arbre (...hmm)
clf = sklearn.tree.DecisionTreeClassifier()
# Note : numpy.reshape nécessaire ici...
res = clf.fit(iris.data[[0,1,50,51,100,101],2],
              iris.target[[0,1,50,51,100,101]])
graphviz.Source(tree.export_graphviz(clf))
            
              ...Avec un peu d'imagination !
library(titanic) ; library(rpart)
# Sélection des variables a priori pertinentes :
# type et prix du billet, âge, sexe. Cible = survie
fit = rpart(Survived ~ Pclass+Fare+Sex+Age,
            titanic_train, method="class")
library(rpart.plot) ; rpart.plot(fit)
            
          À partir des données complètes...
...Jusqu'à ce qu'aucune division ne soit possible.
Difficulté = point 1.
| Température | Courir ? | 
|---|---|
| 12 | oui | 
| 18 | oui | 
| 25 | oui | 
| 27 | oui | 
| 20 | non | 
| 22 | non | 
| 3 | non | 
| -1 | non | 
| Température | Courir ? | 
|---|---|
| -1 | non | 
| 3 | non | 
| 12 | oui | 
| 18 | oui | 
| 20 | non | 
| 22 | non | 
| 25 | oui | 
| 27 | oui | 
Découpage entre 18 et 20 : température <= 19 ou > 19. 
              4 lignes de chaque côté : proportions 4/8 et 4/8 (0.5). 
              2 "oui" et 2 "non" de chaque côté : 
              $G = 0.5 [ (2/4)^2 + (2/4)^2 ] + 0.5 [ (2/4)^2 + (2/4)^2 ]$ 
              $\quad = 1/2$
            
Découpage entre 3 et 12 : température <= 7 ou > 7. 
              2 lignes à gauche, 6 à droite : proportions 2/8 et 6/8. 
              2 "non" à gauche, 2 "non" + 4 "oui" à droite : 
              $G = 2/8 [ (2/2)^2 + (0/2)^2 ] + 6/8 [ (2/6)^2 + (4/6)^2 ]$ 
              $\quad = 2/3 > 1/2$
            
| Température | Courir ? | 
|---|---|
| 12 | oui | 
| 18 | oui | 
| 25 | oui | 
| 27 | peut-être | 
| 20 | non | 
| 22 | non | 
| 3 | peut-être | 
| -1 | peut-être | 
| Température | Courir ? | 
|---|---|
| -1 | peut-être | 
| 3 | peut-être | 
| 12 | oui | 
| 18 | oui | 
| 20 | non | 
| 22 | non | 
| 25 | oui | 
| 27 | peut-être | 
Découpage entre 18 et 20 : température <= 19 ou > 19. 
              4 lignes de chaque côté : proportions 4/8 et 4/8 (0.5). 
            
$G = 0.5 [ (2/4)^2 + (2/4)^2 + (0/4)^2] +$ 
              $\quad\quad 0.5 [ (1/4)^2 + (1/4)^2 + (2/4)^2 ]$ 
              $\quad = 7/16$
            
Exercice : découpage entre 3 et 12 ?
| Météo | Courir ? | 
|---|---|
| soleil | oui | 
| soleil | oui | 
| nuages | oui | 
| nuages | peut-être | 
| pluie | non | 
| pluie | non | 
| neige | peut-être | 
| neige | peut-être | 
Idée 1 : division "une valeur vs. les autres". 
                exemple : nuages vs. soleil/pluie/neige.
              
Idée 2 : tester toutes les combinaisons. 
                exemple : soleil/nuages vs. pluie/neige
              
Découpage soleil/nuages vs. pluie/neige. 
              4 lignes de chaque côté : proportions 4/8 et 4/8 (0.5). 
            
$G = 0.5 [ (3/4)^2 + (1/4)^2 + (0/4)^2] +$ 
              $\quad\quad 0.5 [ (0/4)^2 + (2/4)^2 + (2/4)^2 ]$ 
              $\quad = 9/16$
            
Exercice : découpage soleil/neige vs. nuages/pluie ?
Potentiellement intéressant de découper en + d'un point, mais on se limite aux arbres binaires (plus simples, en général suffisants).
Si données manquantes :
Diviser jusqu'à ne plus pouvoir = surapprentissage. 
$\Rightarrow$ Paramètre de contrôle du nombre de divisions.
Mieux : fusionner les noeuds a posteriori
> fit = rpart(Species ~ ., iris, method="class",
              control=list(minbucket=1,minsplit=2,cp=0))
> fit$cptable
  CP      nsplit rel_error xerror  xstd
1 0.500      0      1.00   1.20 0.04898979
2 0.440      1      0.50   0.65 0.06069047
3 0.020      2      0.06   0.11 0.03192700
4 0.010      3      0.04   0.11 0.03192700
5 0.005      6      0.01   0.09 0.02908608
6 0.000      8      0.00   0.09 0.02908608
            plotcp(fit)
            
          Au lieu de prédire une classe majoritaire, prédire la moyenne des valeurs présentes à cette feuille.
Changement dans l'algorithme : on cherche à minimiser la "variance" au lieu de maximiser $\sum p_k^2$.
Considérant une division comme précédemment, 
              $V = {\displaystyle \sum_{i \in G} (y_i - m_{G})^2 + \sum_{i \in D} (y_i - m_{D})^2}$ 
              avec $m_G$ et $m_D$ moyennes à gauche et à droite.
            
| Species | Length3 | Weight | 
|---|---|---|
| Bream | 30.0 | 242 | 
| Bream | 31.2 | 290 | 
| Roach | 22.2 | 120 | 
| Roach | 23.1 | 110 | 
| Roach | 23.7 | 120 | 
| Perch | 20.2 | 80 | 
| Perch | 20.8 | 85 | 
| Perch | 21.0 | 85 | 
Poids en fonction de espèce et "longueur" ?
| Length3 | 20.2 | 20.8 | 21.0 | 22.2 | 23.1 | 23.7 | 30.0 | 31.2 | 
|---|---|---|---|---|---|---|---|---|
| Weight | 80 | 85 | 85 | 120 | 110 | 120 | 242 | 290 | 
Coupure entre 21 et 22.2 : 
                $V = (80 - m_G)^2 + 2 \times (85 - m_G)^2 +$ 
$V = $$(120 - m_D)^2 + \dots + (290 - m_D)^2$
              
Avec $m_G$ et $m_D$ moyennes à gauche / droite.
On trouve $V \simeq 28.10^3$
Coupure entre 23.7 et 30 : 
              $V = (80 - m_G)^2 + \dots + (120 - m_G)^2 +$ 
$V = $$(242 - m_D)^2 + (290 - m_D)^2$
            
On trouve $V \simeq 2900 \ll 28000$
Conclusion: on coupe à $\frac{23.7 + 30}{2} = 26.85$
| Species | Perch | Perch | Perch | Roach | Roach | Roach | Bream | Bream | 
|---|---|---|---|---|---|---|---|---|
| Weight | 80 | 85 | 85 | 120 | 110 | 120 | 242 | 290 | 
...Mène aux mêmes calculs.
# En se limitant aux variables Species et Length3
fit = rpart(Weight ~ Species + Length3, Fish, method="anova")
# Avec toutes les variables
fit = rpart(Weight ~ ., Fish, method="anova")
rpart.plot(fit)
          plotcp(fit)
            # En régression :
p <- predict(fit, newData, type="anova")
# En classification :
p <- predict(fit, newData, type="class")
          Comparez les approches $k$ plus proches voisins et arbres de décision sur les jeux de données iris puis Fish (en classification).
Dataset autos.
Récupérez le jeu de données adult (entraînement + test). L'ensemble d'entraînement comporte des données manquantes :
Dans les deux cas, il faut estimer l'erreur sur l'ensemble de test.
Conclusion ?