Nous allons traiter le problème de classification binaire.
Pour cela, nous allons utiliser un jeu de données provenant du site “Institute for Digital Research and Education”, de l’Université de Californie à Los Angeles. Ce jeu de données concerne 400 candidats et s’intéresse à leur admission, ou non, dans une école supérieure.Nous allons télécharger les données sur le site https://stats.idre.ucla.edu/stat/data/binary.csv
# importation de la base
base <- read.csv("https://stats.idre.ucla.edu/stat/data/binary.csv")
Le jeu de données comporte une variable réponse de type binaire (variable admit), et trois variables prédictives :gre (graduate record exam score),gpa (grade point average),rank(prestige of the undergraduate institution) qui va de 1(meilleur prestige) à 4 (prestige plus faible). Notre base de donnée est composée de 400 observations
# visualisation de la structures des données
str(base)
## 'data.frame': 400 obs. of 4 variables:
## $ admit: int 0 1 1 1 0 1 1 0 1 0 ...
## $ gre : int 380 660 800 640 520 760 560 400 540 700 ...
## $ gpa : num 3.61 3.67 4 3.19 2.93 3 2.98 3.08 3.39 3.92 ...
## $ rank : int 3 3 1 4 4 2 1 2 3 2 ...
L’admission correspond à valeur 1 de la variable admit.
Afin d’utiliser ce jeu de données dans un algorithme de classification binaire, nous allons passer les variables admit et rank en facteurs.
base$rank <- as.factor(base$rank)
base$admit <- as.factor(base$admit)
Nous allons chercher à vérifier si notre base de données ne comporte pas de valeur manquante.La fonction summary,nous permet de vérifier cela.
summary(base)
## admit gre gpa rank
## 0:273 Min. :220.0 Min. :2.260 1: 61
## 1:127 1st Qu.:520.0 1st Qu.:3.130 2:151
## Median :580.0 Median :3.395 3:121
## Mean :587.7 Mean :3.390 4: 67
## 3rd Qu.:660.0 3rd Qu.:3.670
## Max. :800.0 Max. :4.000
Il s’agit ici d’entraîner un modèle de classification afin de prédire l’admission, ou non, des candidats en fonction des variables gre, gpa, et rank.
Pour cela, Nous choisions d’utiliser un modèle de régression logistique car il s’agit d’un modèle relativement simple et répandu.
Pour utiliser l’algorithme de régression logistique, le package caret à besoin du package e1071 ; il est donc nécessaire de l’importer également. Une fois importés (comme expliqué plus haut), les packages doivent être chargés dans R, à l’aide de la fonction library().
library(caret) # sert à charger le package caret préalablement installé
## Loading required package: ggplot2
## Loading required package: lattice
library (e1071)# sert à charger le package e1071 préalablement installé
** diviser notre base de donnée en deux partie**
Nous choisions d’utiliser une approche de cross validation de type “Valiation set approach”. Cela consiste à séparer, aléatoirement le jeu de données en 2 parties, avec une stratification sur la variable réponse (pour obtenir environ les mêmes pourcentages d’admission et non admission dans les deux parties). La première partie, appelée “training” contiendra 70% des données et servira à l’apprentissage du modèle de régression logistique. Le second, nommé “testing”, sera constitué des 30% de données restantes et servira à évaluer la qualité de prédiction du modèle en comparant l’admission prédite avec l’admission réelle des candidats.
La fonction createDataPartition() est utilisée pour créer la partition du jeu de données. Cette fonction renvoi un vecteur d’indices des observations qui feront partie de la partie “training”.
set.seed(2) #sert à fixer le graine du tirage aléatoire
training.idx <- createDataPartition(base$admit, p=0.7, list = FALSE)
training <- base[training.idx,] # creation du jeu de données "train"
testing <- base[-training.idx,] # creation du jeu de données "test"
dim(training)
## [1] 281 4
round(table(training$admit)/nrow(training),2)
##
## 0 1
## 0.68 0.32
Le jeu de données “training”, comporte 281 données. Les pourcentages d’admission et de non-admission sont respectivement de 32 et 68%.
dim(testing)
## [1] 119 4
round(table(testing$admit)/nrow(testing),2)
##
## 0 1
## 0.68 0.32
Le jeu de données “training”, comporte 119 données, avec des pourcentages d’admission et de non-admission identiques à ceux de la partie training.
La seconde étape consiste à entraîner le modèle avec les données “training”. Pour cela, on utilise la fonction train.
logit.fit <- train(admit ~ ., data = training,method="glm")
summary(logit.fit) # Les coefficients du modèle, et d’autres informations, peuvent être consultés avec la fonction summary
##
## Call:
## NULL
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.5077 -0.8631 -0.6687 1.1553 2.1081
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -4.400802 1.371154 -3.210 0.00133 **
## gre 0.001576 0.001308 1.205 0.22838
## gpa 0.979762 0.417346 2.348 0.01889 *
## rank2 -0.386809 0.379228 -1.020 0.30773
## rank3 -1.185382 0.409420 -2.895 0.00379 **
## rank4 -1.061189 0.481667 -2.203 0.02758 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 350.9 on 280 degrees of freedom
## Residual deviance: 327.1 on 275 degrees of freedom
## AIC: 339.1
##
## Number of Fisher Scoring iterations: 4
La variable gre et la variable rank 2 n’est pas gnificatives au seuil de 5%.
La troisième étape consiste à réaliser les prédictions sur le jeu de données testing, comme cela :
pred <- predict(logit.fit,newdata=testing)
table(pred)
## pred
## 0 1
## 102 17
Il s’agit enfin d’évaluer le modèle de classification, en créant une matrice de confusion (tableau à double entrée, celle des observations et celle des prédictions), et en calculant divers paramètres statistiques associés. Cela se fait très simplement à l’aide de la fonction confusionMatrix, comme cela :
mat <- confusionMatrix(data=pred,reference=testing$admit)
mat
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 76 26
## 1 5 12
##
## Accuracy : 0.7395
## 95% CI : (0.6511, 0.8156)
## No Information Rate : 0.6807
## P-Value [Acc > NIR] : 0.099091
##
## Kappa : 0.2977
##
## Mcnemar's Test P-Value : 0.000328
##
## Sensitivity : 0.9383
## Specificity : 0.3158
## Pos Pred Value : 0.7451
## Neg Pred Value : 0.7059
## Prevalence : 0.6807
## Detection Rate : 0.6387
## Detection Prevalence : 0.8571
## Balanced Accuracy : 0.6270
##
## 'Positive' Class : 0
##
Le paramètre “Accuracy” nous indique que 73% des prédictions sont correctes. Néanmoins, nous pouvons voir que la spécificité (la capacité du test à prédire une admission quand celle-ci a réellement eu lieu), est faible, puisqu’elle est seulement de l’ordre de 9,9% ! Le jeu de données testing comportait 38 admissions, le modèle n’en a prédit que 12.
Il est alors très facile d’essayer un autre algorithme de classification. Dans notre cas , nous utiliserons une classification naïve. bayésienne.
nb.fit <- naiveBayes(admit ~ ., data = training)
nb.pred <- predict(nb.fit,newdata=testing)
table(nb.pred)
## nb.pred
## 0 1
## 101 18
nb.mat <- confusionMatrix(data=nb.pred,reference=testing$admit)
nb.mat
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 75 26
## 1 6 12
##
## Accuracy : 0.7311
## 95% CI : (0.6421, 0.8082)
## No Information Rate : 0.6807
## P-Value [Acc > NIR] : 0.1392145
##
## Kappa : 0.281
##
## Mcnemar's Test P-Value : 0.0007829
##
## Sensitivity : 0.9259
## Specificity : 0.3158
## Pos Pred Value : 0.7426
## Neg Pred Value : 0.6667
## Prevalence : 0.6807
## Detection Rate : 0.6303
## Detection Prevalence : 0.8487
## Balanced Accuracy : 0.6209
##
## 'Positive' Class : 0
##
Le taux de prédiction est à peu près identiques , mais la spécificité est la même ; ici 12 admissions ont été prédites sur les 38 réelles.