Académique Documents
Professionnel Documents
Culture Documents
1. Échantillonnage
set.seed(1)
Npop<-1000
taille.test<-200
test.ind<-sample(1:Npop,taille.test)
appr.ind<-setdiff(1:Npop,test.ind)
Pour effectuer des tirages avec remise (utiles pour le bootstrap), il faut ajouter l’argument replace=TRUE.
sort(sample(1:10,10))
sort(sample(1:10,10,replace=TRUE))
On va travailler sur les données iris présentes dans R. La méthode des k plus proches voisins est réalisée
par la fonction knn du package class.
library(class)
#données
data<-iris
#on fixe les paramètres
Npop<-nrow(iris)
taille.test<-Npop/3
K<-3
#création du découpage apprentissage-test
test.ind<-sample(1:Npop,taille.test)
appr.ind<-setdiff(1:Npop,test.ind)
#réalisation de la prédiction
knn.pred<-knn(iris[appr.ind,-5],iris[test.ind,-5],iris[appr.ind,5],k=K)
#matrice de confusion
table(iris[test.ind,5],knn.pred)
#taux d'erreur
mean(iris[test.ind,5]!=knn.pred)
On répète grâce à une boucle for le découpage des données et l’estimation de l’erreur de prédiction. Puis on
représente les estimations obtenues avec un diagramme en boîte.
err.at<-NULL
for (i in 1:100){
test.ind<-sample(1:Npop,taille.test)
appr.ind<-setdiff(1:Npop,test.ind)
knn.pred<-knn(iris[appr.ind,-5],iris[test.ind,-5],iris[appr.ind,5],k=K)
err.at[i]<-mean(iris[test.ind,5]!=knn.pred)
}
boxplot(err.at)
Méthode bootstrap
K<-3
err.boot<-NULL
for (i in 1:100){
boot.ind<-sample(1:Npop,Npop,replace=TRUE)
test.ind<-setdiff(1:Npop,boot.ind)
knn.pred<-knn(iris[boot.ind,-5],iris[test.ind,-5],iris[boot.ind,5],k=K)
err.boot[i]<-mean(iris[test.ind,5]!=knn.pred)
}
boxplot(err.boot)
Validation croisée
Une autre méthode d’estimation est la validation croisée. On va réaliser une validation croisée en 5 groupes.
groupes<- sample(rep(1:5,each=30))
k<-3
err.cv<-NULL
for (g in 1:5){
sample1 <- iris[which(groupes!=g),-5] #pour l'apprentissage
sample2 <- iris[which(groupes==g),-5] #pour les prédictions
class1 <- iris[which(groupes!=g),5]
pred <- knn(sample1,sample2,class1,k=k)
err.cv[g]<-mean(iris$Species[which(groupes==g)]!=pred)
}
err.cv
mean(err.cv)
Répétez cela pour différentes valeurs du paramètre k afin de choisir celui fournissant le meilleur modèle.
La fonction tune
La fonction tune du package e1071 permet de sélectionner les paramètres des modèles fournissant la
plus petite estimation de l’erreur de prédiction que ce soit par validation croisée, bootstrap ou découpage
apprentissage-test.
Répetez les estimations faites précédemment en utilisant tune. Pour cela vous pouvez consulter l’aide des
commandes tune et tune.control.
Choisissez une autre base de données (autre cours, semestre 1, etc.). Découpez les données en un échantillon
de test et un échantillon d’apprentissage.
Choisissez à l’aide des données d’apprentissage le meilleur modèle de la famille des k plus proches voisins.
Estimez l’erreur de prédiction de ce modèle sur l’ensemble de test et gardez cette valeur en mémoire.
3. Arbre de décision
Nous allons utilisé le package rpart et découvrir comment il fonctionne en travaillant sur les données iris.
Puis vous appliquerez cela pour la détection de spams.
Première réalisation
Npop<-nrow(iris)
taille.test<-Npop/3
#création du découpage apprentissage-test
test.ind<-sample(1:Npop,taille.test)
appr.ind<-setdiff(1:Npop,test.ind)
##
library(rpart)
control.max<-rpart.control(cp=0,max.depth=0,minbucket=1,minsplit=1)
tree<-rpart(Species~. ,data=iris[appr.ind,],control=control.max,
parms=list(split="information"))
plot(tree)
text(tree)
tree
À quoi servent les différents arguments dans rpart.control ? Que signifie split="information" ?
Estimation et élagage
Les informations sur le paramètre de complexité s’obtient avec les commandes suivantes.
plotcp(tree)
tree$cp
Une fois la valeur optimale du paramètre de complexité choisie, il faut construire le nouvel arbre.
treebis<-rpart(Species~. ,data=iris[appr.ind,],
control=rpart.control(cp=0.12),parms=list(split="information"))
plot(treebis)
text(treebis)
library(rpart.plot)
prp(treebis,type=0,extra=0,split.box.col="lightblue",cex=0.6)
prp(treebis,type=1,extra=1,split.box.col="lightblue",cex=0.6)
pred.tree<-predict(treebis, newdata=iris[test.ind,-5],type="class")
table(pred.tree,iris[test.ind,5])
mean(pred.tree!=iris[test.ind,5])
N’hésitez pas à essayer à construire et tester d’autres modèles sur ces données (analyse discriminante linéaire,
quadratique, etc.) pour comparer les méthodes.
1. Arbres de classification
On va travailler sur les données OJ, contenues dans le package ISLR, concernant les ventes de jus d’orange.
Le package permettant de réaliser une forêt aléatoire ou un bagging d’arbres CART est le package
randomForest. La synthaxe est la même que pour la commande de construction des arbres de décision.
Voici la commande de base pour la réalisation d’une forêt aléatoire.
rf<-randomForest(Purchase~.,data=data.train,method="class",parms=list(split="gini"))
Pour réaliser un bagging d’arbres, il suffit de spécifier que l’on garde toutes les variables via l’argument mtry.
nvar<-ncol(OJ)-1
bag<-randomForest(Purchase~.,data=data.train,method="class",parms=list(split="gini"),
mtry=nvar)
Étudions maintenant plus en détails les sorties de ces commandes et tentons d’améliorer ces modèles.
1. Observer les différentes sorties notamment : oob.times, err.rate, votes.
2. Représenter sur le même graphique les erreurs OOB des forêts aléatoires et des bagging construits.
3. Faire varier le nombre de variables choisies à chaque cission et visualiser les erreurs OOB.
4. Faire varier la profondeur des arbres construits (avec maxnodes) dans le modèle de bagging et visualiser
les erreurs OOB.
5. Faire la même chose pour les modèles de forêts aléatoires et visualiser les erreurs OOB.
6. Récupérer la taille de forêt minimisant l’erreur OOB.
7. On s’intéresse maintenant aux variables les plus importantes dans la construction des arbres. Pour
obtenir cela effectuer les commandes suivantes.
1.4. Boosting
On peut réaliser du boosting d’arbres de classification avec l’algorithme AdaBoost en utilisant le package
ada.
library(ada)
boost<-ada(Purchase~.,data=data.train,type="discrete",loss="exponential",
control=rpart.control(cp=0),iter=200,nu=1,
test.y=data.test[,1],test.x=data.test[,-1])
plot(boost,test=T)
mean(predict(boost, newdata=data.test[,-1])!=data.test[,1])
En jouant sur l’argument control de ada, réaliser un boosting sur des stumps, c’est-à-dire des arbes à 2
feuilles.
Puis essayer d’améliorer vos modèles en intégrant une pénalisation.
Afin de trouver les meilleures valeurs pour les paramètres dont le paramètre de pénalisation, on va faire
appel au package caret. Vous pouvez trouver beaucoup d’informations sur l’utilisation du package caret
sur ce lien : https://topepo.github.io/caret/index.html.
Il est utilisable avec de très nombreux modèles et on peut contrôler beaucoup de choses. De plus, il permet
d’effectuer assez aisément les calculs en parallèle afin de diminuer les temps de calculs.
Exemple d’utilisation :
library(parallel)
#detection du nombre de coeurs
detectCores(logical=FALSE)
detectCores(logical=TRUE)
#enregistrement d'un cluster avec le package doParallel
library(doParallel)
registerDoParallel(cores=3)
#lancement de la commande à l'identique
system.time(caretada<-train(Purchase~.,data=data.train,method="ada",
trControl=ctrlCv,tuneGrid=adaGrid))
#fermeture du cluster
stopImplicitCluster()
ou
À l’aide des données de test laissées de côté en début de procédure, estimer les erreurs de prédiction des
différents modèles sélectionnés.
On pourrait également représenter les courbes ROC des différents modèles.
2. Arbres de régression
On va travailler avec les données Boston concernant les valeurs des maisons à Boston contenu dans le package
MASS.
Commencer par découper vos données en une partie apprentissage et une partie test/validation.
1. Construire un premier arbre de régression élagué dans le but de prévoir la variable medv représentant la
valeur d’une maison.
2. Utiliser le package e1071 ou le package caret pour obtenir les meilleurs paramètres. Par exemple, avec
les commandes suivantes :
library("e1071")
system.time(treetune<-tune.rpart(medv~. ,data=data.train,cp=seq(0.001,0.1,0.001)))
treetune$best.performance
treetune$best.parameter
plot(treetune)
Par défaut, la méthode d’estimation de l’erreur est une validation croisée en 10 groupes. On peut modifier
cela de la façon suivante.
tctrlboot<-tune.control(sampling="bootstrap",nboot=50)
system.time(treetune<-tune.rpart(medv~. ,data=data.train,tunecontrol=tctrlboot,
cp=seq(0.001,0.1,0.001)))
treetune$best.performance
treetune$best.parameter
plot(treetune)
On va maintenant essayer de voir si le boosting nous permet d’obtenir un meilleur modèle. Pour cela on va
utiliser la fonction gbm du package gbm. Voici un exemple d’utilisation.
library(gbm)
system.time(boost<-gbm(medv~.,data=data.train,distribution="gaussian",
n.trees=1000,interaction.depth=4,shrinkage=1,cv.folds=5))
ntree.opt<-gbm.perf(boost,plot.it=TRUE,method="cv")
Le modèle obtenu n’est pas très bon pour un modèle de boosting. Il faut sûrement utiliser la pénalisation.
Afin de trouver les meilleures valeurs pour les paramètres dont le paramètre de pénalisation, on va faire
appel au package caret.
library(caret)
gbmGrid<-expand.grid(interaction.depth=(1:5)*2, n.trees=(1:10)*25,
shrinkage=c(0.01,0.05,0.1),n.minobsinnode=(1:3)*2)
ctrlCv<-trainControl(method="repeatedcv",repeats=3)
system.time(gbmcaret<-train(medv~.,data=data.train,method="gbm",distribution="gaussian",
trControl=ctrlCv,tuneGrid=gbmGrid))
gbmcaret
gbmcaret$bestTune
gbmcaret$finalModel
pred.gbmopt<-predict(gbmcaret$finalModel,newdata=data.test,
n.trees=gbmcaret$bestTune$n.trees)
À l’aide des données de test laissées de côté en début de procédure, estimer les erreurs de prédiction des
différents modèles sélectionnés.