Introduction aux forêts aléatoires en R
Introduction aux forêts aléatoires en R
Forêts aléatoires
Les commandes utilisées dans ce chapitre font appel aux packages suivants
> #library(randomForest)
> library(ranger)
> library(kernlab)
> library(OOBCurve)
> library(tidymodels)
> library(vip)
> library(rpart)
Les forêts aléatoires sont des algorithmes réputés pour leur capacité à proposer
des prévisions efficaces sur de nombreux jeux de données. Fernández-Delgado
et al. (2014) ont montré à travers une étude comparative de 179 algorithmes sur
121 jeux de données que les forêts aléatoires arrivent régulièrement parmi les
meilleurs algorithmes prédictifs. Cette famille de méthodes possède de plus un
nombre de paramètres restreint qui contribue à faciliter le travail de calibration.
La construction de forêts aléatoires sera illustrée à travers le jeu de données
spam présenté dans la section 1.2.4
> data(spam)
> dim(spam)
## [1] 4601 58
> summary(spam$type)
## nonspam spam
## 2788 1813
Le problème est de prédire la variable binaire type par les 57 autres variables
du jeu de données.
168 Machine learning avec R
11.1 Bagging
Le terme bagging (Breiman (1996)) vient de la contraction de Bootstrap AGGrega-
tING et désigne un ensemble de méthodes permettant d’obtenir des algorithmes
de prévision en agrégeant d’autres algorithmes entraînés sur des échantillons
bootstrap. Considérons un algorithme de prévision
1 ÿ
B
fn (x) = Tb (x)
B
b=1
qui s’écrit comme la moyenne d’autres algorithmes T1 (x), . . . , TB (x). Il est bien
entendu possible d’utiliser plusieurs types algorithmes Tb : une régression linéaire
pour T1 , un arbre pour T2 , une SVM pour T3 , etc. . . Un tel procédé laisse
beaucoup liberté à l’utilisateur pour entraîner les différents algorithmes et rend
l’analyse de l’estimateur final très complexe. C’est pourquoi nous proposons de
construire les Tb de la même façon et sans ajouter de source d’aléa (pour l’instant).
Chaque Tb peut par exemple désigner la règle du 1 plus proche voisin, un arbre
CART utilisant une unique procédure pour choisir la profondeur. . . Sous ce
schéma, les variables aléatoires Tb sont identiquement distribuées. Nous proposons
d’évaluer l’intérêt de ce procédé d’agrégation en comparant les performances de
fn (l’algorithme final) à celles des Tb (les algorithmes que l’on agrège). Rappelons
qu’un algorithme peut être vu comme l’estimateur d’une fonction inconnue, par
exemple la fonction de régression E[Y |X = x] en régression ou les probabilités a
posteriori P(Y = k|X = x), k = 1, . . . , K en classification. La performance d’un
estimateur s’analyse souvent à travers l’étude du compromis biais/variance, nous
proposons donc d’étudier ces quantités pour fn et les Tb . Les Tb , b = 1, . . . , B
étant de même loi, elles possèdent le même biais, la même variance et on montre
que (voir exercice 11.1).
1 ≠ fl(x)
E[fn (x)] = E[T1 (x)] et V[fn (x)] = fl(x)V[T1 (x)] + V[T1 (x)],
B
(11.1)
où fl(x) = corr(T1 (x), T2 (x)) est le coefficient de corrélation entre les prévisions
de 2 algorithmes au même point x. Plusieurs messages importants se déduisent de
ces résultats. Du point de vue du biais, la procédure d’agrégation n’est d’aucun
intérêt puisque l’espérance de l’algorithme agrégé est la même que celle des
algorithmes qu’on agrège. L’éventuel gain se mesure donc à travers la variance.
Lorsque B est grand on a V[fn (x)] ¥ fl(x)V[T1 (x)], cela signifie que la variance
des Tb (x) est diminué d’un facteur proportionnel à fl(x) qui varie entre 0 et 1
(voir exercice 11.1).
Considérons deux scénarios extrêmes :
1. Les Tb sont tous entraînés sur l’échantillon initial. Si il n’y a pas d’aléa
supplémentaire dans la construction des Tb , ils vont tous renvoyer les mêmes
prévisions, fn est alors équivalent à T1 et l’agrégation n’est d’aucune utilité.
Chapitre 11. Forêts aléatoires 169
Nous avons écrit la sortie comme une moyenne des prévisions de chaque algo-
rithme. Il convient de l’adapter au type de prévision souhaité : valeur numérique
en régression, groupe ou probabilité en classification. Nous distinguerons ces trois
cas dans la section suivante pour l’algorithme des forêts aléatoires. L’écriture
T (., ◊b , Dn ) permet de distinguer les deux sources d’aléas de l’algorithme : l’aléa
traditionnel des données avec Dn et l’aléa des tirages bootstrap avec ◊b . Ce
dernier aléa implique qu’on peut obtenir des prévisions différentes en lançant
deux fois cet algorithme sur les mêmes données. La loi des grands nombre permet
de nuancer ce constat, en effet
1 ÿ
B
lim T (x, ◊b , Dn ) = E◊ [T (x, ◊, Dn )] = f¯n (x, Dn )
Bæ+Œ B
b=1
plus grand possible afin de contrôler l’aléa bootstrap. L’utilisateur doit également
choisir l’algorithme à entraîner sur les échantillons bootstrap. Nous avons vu
que les prévisions sont d’autant plus performantes que la corrélation fl(x) =
corr(T (x, ◊1 , Dn ), T (x, ◊2 , Dn )) est petite. La seule différence entre T (x, ◊1 , Dn )
et T (x, ◊2 , Dn ) est le tirage bootstrap. Ces deux prévisions sont issues du même
algorithme entraîné sur des échantillons obtenus en dupliquant et supprimant
quelques observations dans l’échantillon initial. Utiliser des algorithmes robustes
vis-à-vis de légères perturbations de l’échantillon sera donc d’une utilité limitée
puisque les prévisions de tels algorithmes sont peu affectées par les tirages
bootstrap. Les régressions linéaires et logistiques sont par exemple connues pour
posséder une telle robustesse et il n’est pas courant de les bagger (voir exercice
11.2). Un des reproches souvent fait aux arbres est justement une instabilité
par rapport à de légères perturbations de l’échantillon. En effet les arbres sont
construits en répétant des coupures binaires de Rp . Perturber les données peut
engendrer des changements de coupure en haut de l’arbre qui vont donc modifier
les coupures suivantes et par conséquent toute la structure de l’arbre. Cette
instabilité devient un avantage pour le bagging, les arbres sont en effet souvent
utilisés pour cette procédure. Les forêts aléatoires présentées dans la section
suivante s’inscrivent dans ce cadre.
Lorsqu’on souhaite prédire les probabilités P(Y = k|X = x), chaque arbre
estime ces probabilités par la proportion d’observations du groupe k dans le
nœud terminal qui contient x et la forêt fait la moyenne de ces probabilités
estimées :
1 ÿ
B
Sn,k (x) = T (x, ◊b , Dn ), k = 1, . . . , K.
B
b=1
Les packages randomForest et ranger peuvent être utilisés pour ajuster des
forêts aléatoires. randomForest est le plus ancien et certainement encore le plus
172 Machine learning avec R
utilisé. Le package ranger, codé en C++, se révèle plus efficace au niveau des
temps de calcul. Les syntaxes sont proches, nous proposons d’illustrer la méthode
avec ranger.
> [Link](12345)
> foret <- ranger(type~.,data=spam)
> foret
## Ranger result
##
## Call:
## ranger(type ~ ., data = spam)
##
## Type: Classification
## Number of trees: 500
## Sample size: 4601
## Number of independent variables: 57
## Mtry: 7
## Target node size: 1
## Variable importance mode: none
## Splitrule: gini
## OOB prediction error: 4.59 %
Le groupe est prédit par défaut. Si on souhaite estimer les probabilités d’appar-
tenance aux groupes, il faut utiliser l’option probability=TRUE dans ranger :
> [Link](123)
> [Link] <- ranger(type~.,data=spam,probability=TRUE)
> predict([Link],data=[Link])$predictions
Chapitre 11. Forêts aléatoires 173
## nonspam spam
## [1,] 0.91243622 0.08756378
## [2,] 0.03554603 0.96445397
auc mmce
0.14
0.12
0.95
0.10
valeur
0.08
0.90
0.06
0.85 0.04
0 100 200 300 400 500 0 100 200 300 400 500
ntrees
Figure 11.1 – AUC (gauche) et erreurs de classification (droite) en fonction du
nombre d’arbres.
On observe sur la figure 11.1 que les erreurs sont stables, nous pouvons donc
considérer que 500 arbres sont suffisants. Les autres paramètres méritent plus
174 Machine learning avec R
d’attention. Nous avons représenté sur la figure 11.2 des erreurs de classification
estimées par validation hold out pour des forêts aléatoires utilisant différentes
valeurs de mtry et [Link]. Ces erreurs ont été calculées sur les données
spam en séparant les données en un échantillon d’apprentissage de taille 3000 et
un échantillon test de taille 1601. Ce processus a été répété sur 150 coupures
différentes pour stabiliser les erreurs.
0.09
[Link]
1
0.08
5
Erreur
15
0.07
50
100
0.06 500
0.05
1 3 10 30
mtry
Figure 11.2 – Erreurs de classification en fonction de mtry et de la profondeur
des arbres.
— mtry petit signifie que peu de variables sont candidates pour découper
les nœuds. La variable de coupure est même choisie au hasard lorsque
mtry=1. Il est donc plus difficile pour chaque arbre de la forêt de bien
ajuster les données, notamment celles qui ne sont pas dans l’échantillon
bootstrap. C’est pourquoi l’erreur d’ajustement (voir figure 11.3), et donc
le biais, sont élevés lorsque mtry est petit. Au niveau de la variance, on
peut faire le constat que V[T (x, ◊, Dn )] sera toujours élevée car les arbres
sont profonds, quel que soit mtry. Néanmoins, utiliser des petites valeurs
pour mtry permet de diminuer la corrélation entre deux arbres de la forêt
et par conséquent la variance de la forêt ;
— mtry grand signifie à l’inverse qu’un grand nombre de variables sont
candidates pour découper les nœuds. Cela permet aux arbres de mieux
ajuster les données et donc de diminuer le biais. On a en revanche une
corrélation entre deux arbres d’une même forêt plus élevée, ce qui augmente
la variance de la forêt.
0.08
0.06
Erreur
0.04 ajustement
prevision
0.02
0.00
1 3 10 30
mtry
Figure 11.3 – Erreur de prévision (calculées sur les données test) et d’ajustement
(calculées sur les données d’apprentissage) en fonction de mtry.
Le sur-ajustement risque Ô donc d’apparaître lorsque mtry est (trop) grand. Les
valeurs par défaut sont d pour la classification et d/3 pour la régression mais
il est recommandé de tester plusieurs valeurs pour calibrer ce paramètre. Cela se
fait généralement à partir des méthodes classiques d’estimation de risques de
prévision par ré-échantillonnage qui ont été présentées dans le chapitre ??. À
titre d’illustration, nous proposons de choisir les paramètres nodesize et mtry
dans la grille suivante :
176 Machine learning avec R
On retrouve bien des petites valeurs pour min_n : il faut des arbres profonds
pour que la forêt soit performante. Les valeurs optimales de mtry se situent
autours de la valeur par défaut (7 ici). On peut donc conserver cette valeur pour
ré-ajuster la forêt sur toutes les données :
> foret_finale <- rf_wf %>%
+ finalize_workflow(list(mtry=7,min_n=1)) %>%
+ fit(data=spam)
Le choix des paramètres de la forêt n’est donc pas un problème très difficile :
il faut prendre B grand, [Link] petit et tester quelques valeurs pour
mtry. Malgré cette simplicité, les forêts aléatoires font régulièrement partie des
meilleurs algorithmes de prévision dans les compétitions de type kaggle. On
propose une comparaison entre les performances prédictives des forêts aléatoires
et celles des arbres dans l’exercice 11.3 sur les données spam. Il y est conclut
Chapitre 11. Forêts aléatoires 177
sans surprise que les forêts sont supérieures pour ce jeu de données.
OOB(i) = {b Æ B : i œ
/ Ib }
1 ÿ
fn,OOB(i) (xi ) = T (xi , ◊b , Dn )
|OOB(i)|
bœOOB(i)
la prévision de la forêt en ne considérant que les arbres pour lesquels i n’est pas
dans le tirage bootstrap. Même si cette prévision, n’est pas calculée à partir de
tous les arbres de la forêt, elle présente l’avantage de n’utiliser que des arbres qui
n’ont pas été entraîné avec i. L’erreur de la forêt est alors estimée en confrontant
ces prévisions aux valeurs observées. Le type d’erreur dépend une fois de plus de
la prévision. La fonction ranger renvoie
1ÿ
n
(yi ≠ mn,OOB(i) (xi ))2 .
n i=1
1ÿ
n
1g (x )”=y .
n i=1 n,OOB(i) i i
1 ÿÿ
n K
(Sn,k,OOB(i) (xi ) ≠ 1yi =k )2 .
2n i=1
k=1
178 Machine learning avec R
avec
OOBb = {i Æ n : i œ
/ Ib }.
Err(OOBb ) est l’erreur quadratique de l’arbre b calculée sur les individus qui
n’ont pas servi à la construction de cet arbre. Afin d’évaluer l’importance de la
variable Xj , j = 1, . . . , d, on effectue une permutation aléatoire de la j e colonne
des observations de l’échantillon OOBb comme représentée sur la figure 11.4.
Chapitre 11. Forêts aléatoires 179
2 3 2 3
x11 . . . x1j . . . x1d x11 . . . x3j ... x1d
6x21 . . . x2j . . . x2d 7 6x21 . . . x5j ... x2d 7
6 7 6 7
6x51 . . . x3j . . . x3d 7 =) 6x51 . . . x1j ... x3d 7
6 7 6 7
4x41 . . . x4j . . . x4d 5 4x41 . . . x2j ... x4d 5
x51 . . . x5j . . . x5d x51 . . . x4j ... x5d
Figure 11.4 – Exemple de permutation de la j e colonne pour un échantillon
OOB de taille 5.
On note x̃ji les individus de l’échantillon OOBb permuté (x̃j1 correspond par
exemple au premier individu de l’échantillon de droite sur la figure 11.4) et on
recalcule l’erreur OOB avec ce nouvel échantillon :
1 ÿ
Err(OOBjb ) = (yi ≠ T (x̃ji , ◊b , Dn ))2 .
|OOBb |
iœOOBb
Les variables ne sont pas classées dans le même ordre en fonction du score utilisé.
On observe néanmoins des tendances similaires puisque 7 variables se retrouvent
dans le top 10 des deux scores.
En plus d’aider à l’interprétation, ces scores peuvent être utilisés pour sélectionner
des variables. Des procédures de type backward sont par exemple proposées par
Gregorutti et al. (2017). L’approche consiste à ordonner les variables en fonction
180 Machine learning avec R
charExclamation capitalLong
charDollar hp
remove charExclamation
free remove
capitalAve capitalAve
your capitalTotal
capitalLong charDollar
hp free
capitalTotal your
money george
de leur score d’importance et à les retirer une à une jusqu’à ce que le retrait
n’apporte plus de gain à l’algorithme en terme d’erreur de prévision.
11.5 Exercices
Exercice 11.1 (Biais et variance des algorithmes bagging).
Montrer les égalités (11.1). On prendra également soin de discuter du signe de
fl(x).
Pour simplifier les notations on considère T1 , . . . , TB B variables aléatoires de
même loi et de variance ‡ 2 . Il est facile de voir que E[T̄ ] = E[T1 ]. Pour la
Chapitre 11. Forêts aléatoires 181
variance on a
C B D S T
1 1 Uÿ
ÿ V ÿ
V[T̄ ] = 2 V Ti = 2 V[Ti ] + Cov(Ti , Tj )V
B B
i=1 i=1 i”=j
1 # $ 1≠fl 2
= 2 B‡ 2 + B(B ≠ 1)fl‡ 2 = fl‡ 2 + ‡ .
B B
Considérons fl Æ 0. On déduit de l’équation précédente que B Æ 1 ≠ 1/fl. Par
exemple si fl = ≠1, B doit être inférieur ou égal à 2. Il n’est en effet pas possible
de considérer 3 variables aléatoires de même loi dont les corrélations 2 à 2 sont
égales à -1. De même si fl = ≠1/2, B Æ 3. . .
0.6
0.4
cor
0.2
0.0
arbre logit
Algo
Figure 11.6 – Corrélations bootstrap pour algorithmes logistique et arbres.
On crée une fonction spécifique à chaque algorithme qui calculera les prévisions de
nouveaux individus :
> [Link] <- function(df,newX){
+ arbre <- rpart(type~.,data=df,cp=1e-8,minsplit=15)
+ cp_opt <- arbre$cptable %>% [Link]() %>%
+ filter(xerror==min(xerror)) %>%
+ dplyr::select(CP) %>% slice(1) %>% [Link]()
+ [Link] <- prune(arbre,cp=cp_opt)
+ predict(arbre,newdata=newX,type="prob")[,2]
+ }
+ }
+ foret <- ranger(type~.,data=df,probability=TRUE,
+ mtry=[Link][[Link](err)])
+ predict(foret,data=newX,type="response")$predictions[,2]
+ }
1.00
0.75
Methode
sensitivity
0.50 arbre
foret
0.25
0.00
0.00 0.25 0.50 0.75 1.00
1 − specificity
Figure 11.7 – Courbes ROC.
Chapitre 11. Forêts aléatoires 185
et l’accuracy
> score1 %>% group_by(Methode) %>% accuracy(obs,class)
## # A tibble: 2 x 4
## Methode .metric .estimator .estimate
## <chr> <chr> <chr> <dbl>
## 1 arbre accuracy binary 0.919
## 2 foret accuracy binary 0.939