APPRENTISSAGE AVEC PYTHON ET SICKIT LEARN
Master 1 Business Analytics & Data Science
TP6 : Forêts aléatoires
Mounira Ilahi Amri
Objectifs
L’objectif de ce TP est de montrer l’utilisation des méthodes
d’agrégation (bagging, forêts aléatoires, boosting) pour
les
problèmes de classification et de régression, en python avec Sciki-
learn. La documentation en ligne de scikit-learn est complète et
devra être consultée chaque fois que nécessaire.
Références externes utiles :
Documentation NumPy
Documentation SciPy
Documentation MatPlotLib
Site scikit-learn
Site langage python
** Ce tp est insipré d'un travail de Marin FERECATU
- Ce TP est à rendre avant mercredi prochain 23h55
Enoncé du TP
Méthodes d’agrégation
Les méthodes ensemblistes (ou d’agrégation) pour les algorithmes d’apprentissage
statistique (en anglais : ensemble learning) sont basées sur l’idée de combiner les
prédictions de plusieurs prédicteurs (ou classifieurs) pour une meilleure généralisation et
pour compenser les défauts éventuels de prédicteurs individuels.
En général, on distingue deux familles de méthodes de ce type :
- Méthodes par moyennage (bagging, forêts aléatoires) où le principe est de faire la
moyenne de plusieurs prédictions en espérant un meilleur résultat suite à la
1
réduction de variance de l’éstimateur moyenne.
- Méthodes adaptatives (boosting) où les paramètres sont itérativement adaptés
pour produire un meilleur mélange.
Scikit-learn,
implémentées
de bagging sont
les méthodes
Dans la suite nous explorerons chacune de ces classes d’algorithme en Scikit-learn et
présenterons quelques comparaisons.
Bagging
Les méthodes de type bagging construisent plusieurs instances d’un estimateur, calculées
Publicité
sur des échantillons aléatoires tirés de la base d’apprentissage (et éventuellement une
partie des attributs, également sélectionnés de façon aléatoire), et ensuite combine les
prédictions individuelles en réalisant leur moyenne pour réduire la variance de
l’estimateur. Leur avantage principal réside dans le fait qu’ils construisent une version
améliorée de l’algorithme de base, sans demander de modification de cet algorithme. Le
prix à payer est un coût de calcul plus élevé. Comme elles réduisent le sur-apprentissage,
les méthodes bagging fonctionnent très bien avec des prédicteurs « forts ». Par contraste,
les méthodes boosting sont mieux adaptées à des prédicteurs faibles (weak learners).
Dans
la
via
classe BaggingClassifier et BaggingRegressor. Les constructeurs prennent en paramètres
un estimateur de base et la stratégie de sélection des points et attributs :
base_estimator : optionnel (default=None). Si None alors l’estimateur est un arbre de
décision.
max_samples : la taille de l’échantillon aléatoire tiré de la base d’apprentissage.
max_features : le nombre d’attributs tirés aléatoirement.
bootstrap : boolean, optionnel (default=True). Tirage des points avec remise ou non.
bootstrap_features : boolean, optionnel (default=False). Tirage des attributs avec remise
ou non.
oob_score : boolean. Estimer ou non l’erreur de généralisation OOB (Out of Bag).
type
Le code suivant construit un ensemble des classifieurs de base de
KNeighborsClassifier, chacun utilisant un échantillon de 50% de points d’apprentissage
et 50% des attributs (features) :
from sklearn.ensemble import BaggingClassifier
from sklearn.neighbors import KNeighborsClassifier
bagging = BaggingClassifier(KNeighborsClassifier(), max_samples=0.5, max_features=0.5)
Dans cet exemple nous allons utiliser la base de données digits, qui contient 10 classes
(images des chiffres en écriture manuscrite). Il y a 1797 éléments, chaque élément a 64
attributs.
from sklearn.datasets import load_digits
digits = load_digits()
2
print(digits.data.shape)
afficher une des images
import matplotlib.pyplot as plt
plt.gray()
plt.matshow(digits.images[1])
plt.show()
Publicité
Le classifieur de base est un arbre de décision :
import numpy as np
from sklearn import tree
from sklearn.ensemble import BaggingClassifier
digits = load_digits()
X=digits.data
y=digits.target
clf = tree.DecisionTreeClassifier()
clf.fit(X, y)
accuracy=clf.score(X,y)
Sur la base d’apprentissage accuracy = 1. Pour plus de réalisme, on découpe la base en
apprentissage/test afin de voir le comportement de l’arbre sur des données différentes des
celles d’apprentissage :
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.90)
clf = tree.DecisionTreeClassifier()
clf.fit(X_train, y_train)
Z = clf.predict(X_test)
accuracy=clf.score(X_test,y_test)
Question 1:
Construire la variance de la valeur accuracy sur 100 tirages pour la séparation
apprentissage/test. Que pouvons-nous conclure ?
Pour comparer, on va construire un classifieur bagging sur nos données avec un classifieur
de base DecisionTreeClassifier :
clf = BaggingClassifier(tree.DecisionTreeClassifier(), max_samples=0.5, max_features=0.5,
n_estimators=200)
clf.fit(X_train, y_train)
Z = clf.predict(X_test)
accuracy=clf.score(X_test,y_test)
3
Question 2:
Calculer la variance de la valeur accuracy sur 100 tirages pour la séparation
apprentissage/test. Comparer avec la variance du classifieur de base. Que pouvons-nous
conclure ?
Question 3:
Construire le graphique accuracy vs n_estimators. Que constatez-vous ?
Question 4:
Faites varier les parametres max_samples et max_features. Pour quelles valeurs on obtient
le meilleur résultat ?
Forêts aléatoires
Publicité
L’algorithme forêts aléatoires propose une optimisation des arbres de décision. Il utilise
le même principe que le bagging, mais avec une étape supplémentaire de randomisation
dans la sélection des attributs des nœuds dans le but de réduire la variance de l’estimateur
forêts aléatoires
obtenu. Les deux objets Python qui
sont RandomForestClassifier et RandomForestRegressor. Les paramètres
les plus
importants sont :
implémentent
les
n_estimators : integer, optional (default=10). Le nombre d’arbres.
max_features : le nombre d’attributs à considérer à chaque split.
max_samples : la taille de l’échantillon aléatoire tiré de la base d’apprentissage.
min_samples_leaf : le nombre minimal d’éléments dans un nœud feuille.
oob_score : boolean. Estimer ou non l’erreur de généralisation OOB (Out of Bag).
Par la suite nous allons refaire la classification sur la base Digits en utilisant un
classifieur RandomForestClassifier :
from sklearn.ensemble import RandomForestClassifier
import numpy as np
from sklearn import tree
digits = load_digits()
X=digits.data
y=digits.target
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.90)
clf = RandomForestClassifier(n_estimators=200)
clf.fit(X_train, y_train)
Z = clf.predict(X_test)
accuracy=clf.score(X_test,y_test)
Question 5:
4
Comment la valeur de la variable accuracy se compare avec le cas bagging qui utilise le
même nombre d’arbres (200 dans notre cas) ?
Question 6:
Construire la variance de la valeur accuracy sur 100 tirages pour la séparation
apprentissage/test. Que pouvons-nous conclure en comparant avec la séction précedente
(bagging) ?
Question 7:
Construire le graphique accuracy vs n_estimators. Que constatez-vous ? A partir de
quelle valeur on n’améliore plus ?
Publicité
Question 8:
Regardez dans la documentation les ExtraTreesClassifier et refaites la classification avec
ce type de classifieur. Comparez avec RandomForestClassifier.
Boosting
Le principe du boosting est d’évaluer une séquence de classifieurs faibles (weak learners)
sur plusieurs versions légèrement modifiées des données d’apprentissage. Les décisions
obtenues sont alors combinées par une somme ponderée pour obtenir le modèle final.
En Scikit-learn c’est la classe AdaBoostClassifier qui implemente l’algorithme. Les
paramètres les plus importants sont :
n_estimators : integer, optional (default=10). Le nombre de classifieurs faibles.
learning_rate : contrôle la vitesse de changement des poids par itération.
base_estimator : (default=DecisionTreeClassifier) le classifieur faible utilisé.
Dans la suite nous allons refaire la classification sur la base Digits en utilisant un
classifieur RandomForestClassifier :
from sklearn.ensemble import AdaBoostClassifier
import numpy as np
from sklearn import tree
digits = load_digits()
X=digits.data
y=digits.target
=
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.90)
clf
n_estimators=200, learning_rate=2)
clf.fit(X_train, y_train)
Z = clf.predict(X_test)
AdaBoostClassifier(base_estimator=tree.DecisionTreeClassifier(max_depth=5),
5
accuracy=clf.score(X_test,y_test)
Question 9:
Le paramètre max_depth contrôle la profondeur de l’arbre. Essayez plusieurs valeurs pour
voir l’impact de l’utilisation d’un classiffieur faible vs plus fort (max_depth élevé ou
éliminer le paramètre). Testez aussi l’effet du paramètre learning_rate et le nombre de
classifieurs.
6