On réarrange le tableau en un tableau de variables binaires selon la convention établie sur la copie
X1 = c(1,1,0,0,1,0,0,1,1,0,1,0,0,0)
X2 = c(1,1,1,1,0,0,0,1,0,1,1,1,1,1)
X3 = c(1,1,1,1,0,0,0,1,0,0,0,0,1,0)
X4 = c(0,1,0,0,0,1,1,0,0,0,1,1,1,0)
Y = c(0,0,1,1,1,0,1,0,1,1,1,1,0,1)
donnees = data.frame(X1,X2,X3,X4,Y)
donnees
## X1 X2 X3 X4 Y
## 1 1 1 1 0 0
## 2 1 1 1 1 0
## 3 0 1 1 0 1
## 4 0 1 1 0 1
## 5 1 0 0 0 1
## 6 0 0 0 1 0
## 7 0 0 0 1 1
## 8 1 1 1 0 0
## 9 1 0 0 0 1
## 10 0 1 0 0 1
## 11 1 1 0 1 1
## 12 0 1 0 1 1
## 13 0 1 1 1 0
## 14 0 1 0 0 1
library(rpart)
?rpart
options = rpart.control(minsplit=5)
arbre = rpart(Y~X1+X2+X3+X4, donnees, control = options)
plot(arbre, branch=.3, uniform=TRUE, compress=TRUE, margin=0.1 )
text(arbre, all=TRUE, use.n=TRUE, fancy=TRUE, minlength=10)
#### Question 2
# Etape 1 : on part de {e1,e2,...,e14}
n = 14
# 1) On va effectuer un découpage suivant X1 :
# Branche X1 = 0:
ind0 = which(X1==0)
print(ind0)
## [1] 3 4 6 7 10 12 13 14
n0 = length(ind0)
print(n0)
## [1] 8
# La branche X1=0 contient donc {e3,e4,e6,e7,e10,e12,e13,e14} (8 individus)
# Valeurs de Y correspondantes :
Y[ind0]
## [1] 1 1 0 1 1 1 0 1
# nombre de Y=0 et de Y=1 parmi eux :
nY0 = sum(Y[ind0]==0)
print(nY0)
## [1] 2
nY1 = n0-nY0
I0 = 1 - (nY0/n0)^2 - (nY1/n0)^2
# branche X1=1. On repete les mêmes opérations :
ind1 = which(X1==1)
n1 = length(ind1)
nY0 = sum(Y[ind1]==0)
nY1 = n1-nY0
I1 = 1 - (nY0/n1)^2 - (nY1/n1)^2
# v aleur finale du critere :
CX1 = (n0/n)*I0 + (n1/n)*I1
print(CX1) # on obtient un critere de 0.4285
## [1] 0.4285714
Critere = function(X,Y)
{
n = length(X)
ind0 = which(X==0)
n0 = length(ind0)
nY0 = sum(Y[ind0]==0)
nY1 = n0-nY0
I0 = 1 - (nY0/n0)^2 - (nY1/n0)^2
ind1 = which(X==1)
n1 = length(ind1)
nY0 = sum(Y[ind1]==0)
nY1 = n1-nY0
I1 = 1 - (nY0/n1)^2 - (nY1/n1)^2
C = (n0/n)*I0 + (n1/n)*I1
return(C)
}
Critere(X2,Y)
## [1] 0.45
Critere(X3,Y)
## [1] 0.3154762
Critere(X4,Y)
## [1] 0.4285714
X3 donne la valeur la plus petite. on decoupe donc selon X3.
Etape 2 : on doit découper à nouveau l’arbre dans les deux branches X3=0 et X3=1
# On commence par selectionner les indices de cette branche :
ind = which(X3==0)
print(ind) # la branche est donc constituee de {e5,e6,e7,e9,e10,e11,e12,e14}
## [1] 5 6 7 9 10 11 12 14
# Puis on calcule les criteres pour les choix de decoupage selon X1, X2 ou X4:
Critere(X1[ind],Y[ind]) # on obtient un critere de 0.22
## [1] 0.2
Critere(X2[ind],Y[ind]) # on obtient un critere de 0.1875
## [1] 0.1875
Critere(X4[ind],Y[ind]) # on obtient un critere de 0.1875
## [1] 0.1875
# On va donc redecouper selon X4
ind = which(X3==1)
print(ind)
## [1] 1 2 3 4 8 13
Critere(X1[ind],Y[ind])
## [1] 0.2222222
Critere(X2[ind],Y[ind])
## [1] NaN
Critere(X4[ind],Y[ind])
## [1] 0.3333333
Si on regarde le tableau, on s’aperçoit que le decoupage suivant X2 dans la branche X3=1 n’est pas possible.
Tous les individus X3=1 ont une variable X2=1, donc on ne cree pas deux nouvelles branches en choisissant la variable. On choisit donc de decouper ici suivant X1 (valeur 0.22 la plus petite)
Suite cf pdf
load("/Users/jeremyhazan/Downloads/tennis.RData")
On souhaite utiliser la fonction rpart pour construire un arbre selon la méthode CART sur nos données tennis.
Avec l’aide de la fonction, deux options vont nous aider dans la construction de notre arbre :
minbucket : nombre minimum d’observation dans une feuille (nœud terminal)minsplit : nombre minimum d’observations qui doit exister dans un nœud pour qu’une tentative de division soit effectuéetree = rpart(Jouer~., data = tennis,minsplit = 2, minbucket = 1)
tree
## n= 14
##
## node), split, n, loss, yval, (yprob)
## * denotes terminal node
##
## 1) root 14 5 Oui (0.3571429 0.6428571)
## 2) Ciel=Ensoleille,Pluie 10 5 Non (0.5000000 0.5000000)
## 4) Humidite>=82.5 5 1 Non (0.8000000 0.2000000)
## 8) Temperature>=20.25 4 0 Non (1.0000000 0.0000000) *
## 9) Temperature< 20.25 1 0 Oui (0.0000000 1.0000000) *
## 5) Humidite< 82.5 5 1 Oui (0.2000000 0.8000000)
## 10) Temperature< 18.25 1 0 Non (1.0000000 0.0000000) *
## 11) Temperature>=18.25 4 0 Oui (0.0000000 1.0000000) *
## 3) Ciel=Couvert 4 0 Oui (0.0000000 1.0000000) *
plot(tree)
text(tree)
prp(tree)
rpart.plot(tree, main = 'Arbre tennis')
On peut dire qu’il contient 5 feuilles, et 5 nœuds purs.
On commence par créer un jeu de données train et un jeu de données test à partir des données tennis.
set.seed(25)
s = sample(x = 1:nrow(tennis), size = 11, replace = F)
train = tennis[s,]
test = tennis[-s,]
On décide ensuite de faire la prédiction :
tree = rpart(Jouer~., data = train, minsplit = 2, minbucket = 1)
prediction = predict(tree, newdata = test, type = 'class')
(table = table(prediction, test$Jouer))
##
## prediction Non Oui
## Non 0 0
## Oui 2 1
On calcule ensuite le taux d’erreur d’apprentissage :
erreur = mean(prediction!=test$Jouer)
print(erreur)
## [1] 0.6666667
On remarque que nous avons une erreur de 66% ce qui paraît assez élevé.
data("iris")
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
set.seed(25)
s = sample(x = 1:nrow(iris), size = 120, replace = F)
train = iris[s,]
test = iris[-s,]
arbre_iris = rpart(Species~., data = train, minsplit = 2, minbucket = 1)
arbre_iris
## n= 120
##
## node), split, n, loss, yval, (yprob)
## * denotes terminal node
##
## 1) root 120 78 virginica (0.31666667 0.33333333 0.35000000)
## 2) Petal.Length< 2.45 38 0 setosa (1.00000000 0.00000000 0.00000000) *
## 3) Petal.Length>=2.45 82 40 virginica (0.00000000 0.48780488 0.51219512)
## 6) Petal.Length< 4.75 39 1 versicolor (0.00000000 0.97435897 0.02564103)
## 12) Petal.Width< 1.65 38 0 versicolor (0.00000000 1.00000000 0.00000000) *
## 13) Petal.Width>=1.65 1 0 virginica (0.00000000 0.00000000 1.00000000) *
## 7) Petal.Length>=4.75 43 2 virginica (0.00000000 0.04651163 0.95348837) *
rpart.plot(arbre_iris, main = 'Arbre iris')
On remarque qu’il possède 4 feuilles, ainsi que 3 nœuds purs.
prediction = predict(arbre_iris,test, type = 'class')
erreur = mean(prediction!=test$Species)
print(erreur)
## [1] 0.1333333
On remarque donc que notre taux d’erreur est de 13% ce qui est plutôt faible, nos données sont donc plutôt bien prédite.
foret_al = randomForest(Species~., data = train)
foret_al
##
## Call:
## randomForest(formula = Species ~ ., data = train)
## Type of random forest: classification
## Number of trees: 500
## No. of variables tried at each split: 2
##
## OOB estimate of error rate: 3.33%
## Confusion matrix:
## setosa versicolor virginica class.error
## setosa 38 0 0 0.00000000
## versicolor 0 38 2 0.05000000
## virginica 0 2 40 0.04761905
On remarque que l’algorithme des forêts aléatoires produit 500 arbres. De plus, la matrice de confusion nous indique le taux de classement de chaque espèce. Ainsi l’espèce Setosa est classé à 100%, l’espèce Versicolor est classé à 97% correctement et l’espèce Virginica est classé à 90% correctement.
pred_foret_al = predict(foret_al, test, type = 'class')
erreur_2 = mean(pred_foret_al!=test$Species)
print(erreur_2)
## [1] 0.06666667
On remarque que notre taux d’erreur est de 7%.
On peut donc dire que nos données sont bien prédite.
L’erreur est plus petite que pour l’algorithme CART, il est donc plus intérressant d’utiliser les forêts aléatoires.