Projet Arbre de Décision

Otmane NOKRI

23/04/2020

L’arbre de décision est un puissant classificateur non linéaire. Un arbre de décision utilise une structure arborescente pour générer des relations entre les différentes caractéristiques et les résultats potentiels. Il utilise des décisions ramifiées comme structure de base.

Ainsi, afin de réaliser cette classification nous devons prendre nos données qui sont sur PostGreSQL pour cela on utilise les deux packages suivants:

Chargement et préparation des données

library(DBI)
library(RPostgres)

En utilisant le script suivant on peut récupérer nos données grâce à la connexion établie.

m=RPostgres::Postgres()
c=dbConnect(m,dbname="stid1908")
lieux<-dbGetQuery(c,'SELECT * FROM lieux_2014 LIMIT 5000')
caracteristiques<-dbGetQuery(c,'SELECT * FROM caracteristiques_2014 LIMIT 5000')
usagers<-dbGetQuery(c,'SELECT * FROM usagers_2014 LIMIT 5000')
vehicules<-dbGetQuery(c,'SELECT * FROM vehicules_2014 LIMIT 5000')


#Commande pour changer la variable heure de la base de données en données exploitables
heure=as.numeric(substr(caracteristiques$hrmn,0,nchar(caracteristiques$hrmn)-2))
caracteristiques=cbind(caracteristiques,heure)

Premierement, on fusionne nos différentes bases de données en une seule afin de nous simplifier le travail. Pour cela on utilise la fonction merge(fusion de tables en supprimant les colonnes en double et en regroupant selon la colonne Num_Acc (clé primaire) ~ “jointures Rstudio” )

Acc=merge(x=lieux,y = usagers, by= "Num_Acc")
Acc=merge(Acc,caracteristiques, by="Num_Acc")
Acc=merge(Acc,vehicules, by="Num_Acc")

Puis, on rectifie ensuite quelques variables que l’on transforme en factor afin de pouvoir avoir un arbre décisionnel plus performant. Nous nous intérressons a la mortalité dans les accidents.

Rectification des variables

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
Acc = Acc %>% mutate(heure = case_when((heure>= 0 & heure <= 8 ) ~ "matin",
                                       (heure>= 9 & heure<= 19 ) ~ "journée",
                                       (heure>= 20) ~ "soir"))

X = Acc %>% select(grav,secu,atm,catr,heure,choc)

X = X %>%  mutate(grav = factor(X$grav, levels = c(1, 2), labels = c('Indemne','Mort')))

X = X %>%  mutate(secu = factor(X$secu, levels = c(11, 12), labels = c('CeintOui','CeintNon')))

X = X %>%  mutate(atm = factor(X$atm, levels = c(1,2,5), labels = c('Normale','Pluie','Brouillard')))

X = X %>%  mutate(catr = factor(X$catr, levels = c(1,2,3,4), labels = c('Autoroute','Nationale',
                                                                    'Departementale','VoieCommunale')))

X = X %>% mutate(choc = case_when((X$choc=="1") ~ "Avant",
                                  (X$choc=="2" | X$choc=="5" | X$choc=="7") ~ "Droite",
                                  (X$choc=="3" | X$choc=="6" | X$choc=="8") ~ "Gauche"))

X=na.omit(X)
glimpse(X)
#> Observations: 2,558
#> Variables: 6
#> $ grav  <fct> Indemne, Indemne, Indemne, Indemne, Indemne, Indemne, Indemne, …
#> $ secu  <fct> CeintOui, CeintOui, CeintOui, CeintOui, CeintOui, CeintOui, Cei…
#> $ atm   <fct> Normale, Normale, Normale, Normale, Normale, Normale, Normale, …
#> $ catr  <fct> Departementale, Departementale, Departementale, Departementale,…
#> $ heure <chr> "soir", "soir", "journée", "journée", "journée", "journée", "ma…
#> $ choc  <chr> "Avant", "Gauche", "Avant", "Droite", "Avant", "Avant", "Droite…

Apprentissage

accident <- X #Création d’un dataset d’apprentissage et d’un dataset de validation
nb_lignes <- floor((nrow(accident)*0.75)) #Nombre de lignes de l’échantillon d’apprentissage : 75%
accident <- accident[sample(nrow(accident)), ] #Ajout de numéros de lignes
accident.train <- accident[1:nb_lignes, ] #Echantillon d’apprentissage
accident.test <- accident[(nb_lignes+1):nrow(accident), ] #Echantillon de test

Arbre de décision

Voici notre arbre, celui ci se lit de cette façon :

Premierement,ce fichier d’apprentissage contient 1692+226= 1918 patientes.

Ensuite, pour chaque feuille, R indique la classe prédite, le nombre d’individus de la classe prédite à gauche et le nombre d’individus de l’autre (ou des autres) classes à droite. Par exemple, si on prend la première feuille à gauche qui correspond aux personnes portant leurs ceintures lors d’un accident qui s’est déroule en journée, la feuille contient 1681 personnes indemnes et 158 personnes décédés. Et cette sous-population est classée dans « Indemne ».

Concernant la modalité “Indemne 1692/226” cela signifie simplement qu’il y a dans le fichier d’apprentissage 1692 personnes qui sont sorti indemnes d’un accident, et 226 personnes qui elles ont perdu la vie lors d’un accident.

La variable la plus discriminante au sens de l’indice de Gini est Secu(securité), soit le pour la valeur Ceinture-Oui. A partir de cette variable discriminante le fichier peut être partagé en deux sous-fichiers qui séparent au mieux la variable-cible (Indemne/Mort). On trouve alors - à gauche (Ceinture-Oui VRAI) 1618 Indemnes + 158 Morts = 1839 personnes, dont 1618 indemnes et 158 morts - à droite (Ceinture-Oui FAUX, i.e pas de Ceinture), 11 Indemnes + 68 Morts = 79 individus.

Le sous-fichier de droite est alors partagé suivant sa variable et son seuil les plus discriminants (choc pour les valeurs “Avant” et “Droite”). A gauche, le sous-fichier est partagé suivant sa variable et son seuil les plus discriminants (heure pour la valeur “journée”), etc…

Au bout du compte, le fichier initial est “classé” en 11 classes (les 11 feuilles finales de l’arbre de décision). Les fréquences de Indemne/Mort dans ces feuilles peuvent être utilisées comme des estimations de probabilités à priori par un module de prédiction.

Validation

#Prédiction du modèle sur les données de test
Prediction <-predict(accident.Tree, accident.test, type = 'class')
#Prédiction du modèle sur les données de test
#Matrice de confusion
mc <- table(accident.test$grav, Prediction)
#Affichage de la matrice de confusion
mc
#>         Indemne Mort
#> Indemne     676    5
#> Mort         31   71
#Erreur de classement
erreur.classement<-1.0-(mc[1,1]+mc[2,2])/sum(mc)
print(erreur.classement)
#> [1] 0.04597701
#Erreur de classement
erreur.classement<-1.0-(mc[1,1]+mc[2,2])/sum(mc)
print(erreur.classement)
#> [1] 0.04597701
#Taux de prédiction
prediction=mc[2,2]/sum(mc[2,])
print(prediction)
#> [1] 0.6960784

Le taux de prédiction est ainsi de 69% ce qui est assez significatif. Après avoir obtenu des prédictions qui nous semble pertinente on peut réaliser un arbre de régression que je ne réaliserai pas lors de ce projet.