DM Classification

Exercice 1

Question 1

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)
}
  1. Decoupage suivant X2, X3, X4 :
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

  1. dans la branche X3=0
# 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
  1. Dans la branche X3=1
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

Exercice 2

Question 1

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)
    Si on ne règle pas ces options notre arbre ne pourra pas grandir et il n’y aura qu’un seul nœud (nœud racine).
  • minsplit : nombre minimum d’observations qui doit exister dans un nœud pour qu’une tentative de division soit effectuée
tree = rpart(Jouer~., data = tennis,minsplit = 2, minbucket = 1)

Question 2

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.

Question 3

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é.

Exercice 3

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

Question 1

set.seed(25)
s = sample(x = 1:nrow(iris), size = 120, replace = F)
train = iris[s,]
test = iris[-s,]

Question 2 CART

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) *
Affichage de l’arbre pour les données iris
rpart.plot(arbre_iris, main = 'Arbre iris')

On remarque qu’il possède 4 feuilles, ainsi que 3 nœuds purs.

Prédiction
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.

Question 3 : Algorithme des forêts aléatoires

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.

Prédiction

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.