Dans cette section, nous appliquerons la méthode CART pour prédire
les délais de paiement en utilisant le langage statistique
R et l’IDE RStudio. Nous construirons un arbre
de régression sur le jeu de données ModeleDuree pour
modéliser la variable continue “DP”. Les données seront
divisées en ensembles d’entraînement et de test, l’arbre sera construit
avec l’ensemble d’entraînement, et ses performances seront évaluées sur
l’ensemble de test.
library(rpart)
library(caret)
library(vip)
library(rpart.plot)
library(partykit)
library(ISLR)
library(dplyr)
library(lubridate)
library(ggparty)
library(readr)
library(ineq)Les méthodes basées sur les arbres segmentent l’espace des prédicteurs en régions simples pour la classification et la régression. Les arbres de décision sont non paramétriques et visent à maximiser l’exactitude en classification ou à minimiser l’erreur en régression. Chaque nœud est défini par une règle “si/alors” basée sur une variable de division et un point de division. Les modèles CART sont préférés aux LM, GLM ou GAM lorsque les relations entre les variables prédictives sont complexes et non linéaires, ou lorsque les interactions entre les variables sont non additives ou nombreuses. Par exemple, nous utiliserons l’ensemble de données Carseats pour illustrer un arbre de classification et un arbre de régression.
Chargement des données.
set.seed(454564)
ModeleDuree <- read_csv("C:/Users/JKLEVINE/Desktop/Memoire/MODELEDURE.csv")
names(ModeleDuree) <- c("CG", "AB", "SB", "RB", "CB", "TC", "TP", "PS", "PP", "DP", "RO") Les modalités catégorielles sont codées en valeurs entières selon leur fréquence d’apparition.
ModeleDuree <- ModeleDuree %>%
mutate(
SB = match(SB, names(sort(table(SB), decreasing = TRUE))) - 1,
CB = match(CB, names(sort(table(CB), decreasing = TRUE))) - 1,
CG = match(CG, names(sort(table(CG), decreasing = TRUE))) - 1,
TC = match(TC, names(sort(table(TC), decreasing = TRUE))) - 1,
TP = match(TP, names(sort(table(TP), decreasing = TRUE))) - 1,
RB = match(RB, names(sort(table(RB), decreasing = TRUE))) - 1
)L’étude de la base de données de prédictions a déjà été réalisée et peut être consultée dans le fichier Analyse des données. Avant de commencer l’analyse, il est nécessaire de séparer la base de données en deux ensembles : une base de test et une base d’apprentissage. À cette fin, la base de test comprendra 30 % des données, tandis que la base d’apprentissage sera constituée des 70 % restants.
Train = sample(1:nrow(ModeleDuree), nrow(ModeleDuree)*0.7, replace = FALSE)
ModeleCARTTrain = ModeleDuree[Train,]
ModeleCARTTest = ModeleDuree[-Train,]Il est essentiel de régler soigneusement les hyperparamètres avant de lancer le modèle. Une fois cette étape complétée, la modélisation peut commencer..
Terminologie et éléments de sortie des arbres de décision de cart sont :
Nœud racine : Représente l’ensemble de la population d’échantillon et est ensuite divisé en deux ou plusieurs groupes homogènes.
split : Le critère utilisé pour diviser un nœud en deux ou plusieurs sous-nœuds.
n : Le nombre d’observations dans un nœud.
loss : C’est le nombre total de lignes qui seront mal classifiées si la classe prédite pour le nœud est appliquée à toutes les lignes.
yval : La prédiction globale pour la branche (Oui ou Non). En général, il s’agit de la valeur de réponse moyenne pour ce sous-ensemble.
yprob : La fraction d’observations dans cette branche qui prennent les valeurs Oui et Non.
Élagage (Pruning) : Le processus de suppression des sous-nœuds d’un nœud de décision. L’élagage est une solution au problème de surajustement.
Complexité : Le paramètre de complexité est utilisé pour établir un niveau de contrôle qui détermine si une division contribue à un meilleur ajustement du modèle. Toute division qui améliore l’ajustement du modèle par un facteur supérieur au paramètre de complexité défini est tentée. La meilleure valeur de cp a la plus faible erreur de validation croisée (xerror).
La complexité cp est automatiquement ajustée dans la
fonction rpart à l’aide d’algorithmes. Plusieurs valeurs de
cp sont testées, et il suffit de sélectionner celle qui
minimise l’erreur xerror.
On commence par construire un arbre avec les paramètres par défaut de
rpart
fit0_cart <- rpart(DP~CG+AB+SB+RB+CB+TC+TP+PS+RO, data = ModeleCARTTrain,
parms=list(split="information"), method = "anova")et on étudie la suite d’arbres emboîtés
##
## Regression tree:
## rpart(formula = DP ~ CG + AB + SB + RB + CB + TC + TP + PS +
## RO, data = ModeleCARTTrain, method = "anova", parms = list(split = "information"))
##
## Variables actually used in tree construction:
## [1] CG TP
##
## Root node error: 9695210/291230 = 33.291
##
## n= 291230
##
## CP nsplit rel error xerror xstd
## 1 0.745000 0 1.00000 1.00001 0.00157552
## 2 0.011788 1 0.25500 0.25500 0.00085199
## 3 0.010000 2 0.24321 0.24322 0.00081596
L’erreur d’ajustement (rel.error) diminue normalement,
tout comme l’erreur de prévision (xerror). Cela suggère que
fit0_cart est suffisamment profond pour être élagué. Par
précaution, il peut être utile de considérer un arbre légèrement plus
profond.
fit0_cart <- rpart(DP~CG+AB+SB+RB+CB+TC+TP+PS+RO, data = ModeleCARTTrain,
minsplit=10,cp=1e-5, method = "anova")
plotcp(fit0_cart)La valeur de prudence considérée ne donne pas les meilleurs résultats ; au contraire, elle conduit à une erreur relativement élevée.
## CP nsplit rel.error xerror xstd
## 527 1e-05 826 0.1920386 0.2029038 0.0007240722
La valeur choisie donne nsplit = 5346, ce qui entraîne
une trop grande division avec un xerror de 0.5387785. La
valeur minimale de xerror est atteinte pour
cp = 3.707713e-05.
## CP nsplit rel.error xerror xstd
## 305 1.455363e-05 432 0.1967011 0.2016001 0.0007095772
Le modèle avec l’erreur xerror la plus faible est obtenu
avec nsplit = 315.
## CP nsplit rel.error xerror xstd
## 527 1e-05 826 0.1920386 0.2029038 0.0007240722
Cependant, pour l’erreur rel.error, notre valeur de
cp de prudence minimise l’erreur avec un très grand nombre
de divisions. Nous conservons donc la valeur de cp qui
offre la plus petite xerror.
On recupere le modele ajusté avec la meilleure valeur de
cp.
Il est difficile d’examiner l’arbre de régression en raison de son grand nombre de branches. Faire un zoom sur les 10 premières branches permet d’observer :
Il est également difficile d’observer les variables de découpage de l’arbre.
La visualisation de l’arbre aide à interpréter l’algorithme mais ne hiérarchise pas les variables par importance. Une mesure, le score d’importance, évalue chaque variable selon son utilité dans l’arbre. Chaque coupure maximise le gain d’impureté. Le score d’importance d’une variable est la somme des gains d’impureté qu’elle génère.
Soit \(T\) un arbre avec \(|T|\) nœuds terminaux et \(|T| - 1\) nœuds internes. Le gain d’impureté au nœud interne \(t\) est noté \(g_t\), et \(X_c(t)\) est la variable utilisée pour cette coupure. L’importance de la variable \(X_j\) est :
\[ I_j(T) = \sum_{t=1}^{|T|-1} g_t \cdot 1_{c(t)=j} \]
La fonction rpart calcule automatiquement ces scores
pour l’arbre optimal.
La variable TP se distingue nettement avec le score
d’importance le plus élevé. Elle est essentielle pour prédire les délais
de paiement. Elle est suivie de loin par le montant de remboursement
(RO) et le grand groupe de code (CG).
Le type de paiement (TP) et le type de code acte
(CG) jouent un rôle crucial dans la détermination des
montants des paiements. Le montant de remboursement (RO) a
également un impact significatif sur les délais de paiement, soulignant
son importance dans notre modèle de prédiction.
En revanche, le sexe du bénéficiaire SB et le type de
contrat TC ont une influence marginale sur les prédictions,
montrant qu’ils contribuent peu aux résultats du modèle.
Nous allons utiliser plusieur indicateurs pour calculer les performances predictives du modele.
Le coefficient de détermination \(R^2\) représente le pourcentage de variance expliquée par le modèle. Il est défini par :
\[ R^2 = 1 - \frac{\sum_{i=1}^{n} (y_i - \hat{y}_i)^2}{\sum_{i=1}^{n} (y_i - \bar{y})^2} \]
Dans de nombreux cas, \(R^2\) est égal au carré du coefficient de corrélation \(R\).
R2=function(actuals, predictions){
R2 <- var(predictions)/var(actuals)
return(R2)
}
print(R2(actuals, predictions))## [1] 0.8033088
Le \(R^2\) de 0.8033088 indique que notre modèle de GLM n’explique qu’environ 80.33% de la variance totale des données. Cela suggère que le modèle capture une bonne partie de la relation entre les variables explicatives et la variable dépendante. C’est élévé, mais pas assez suffisant compte tenu de la précision à laquelle nous aspirons.
Le RMSE (Root Mean Squared Error) est une mesure de l’erreur moyenne entre les valeurs prédites par le modèle et les valeurs réelles de la variable cible. Il calcule la racine carrée de la moyenne des carrés des différences entre les prédictions et les valeurs réelles. Il est défini par :
\[ \text{RMSE} = \sqrt{\frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2} \]
Le RMSE est souvent utilisé pour évaluer à quel point les prédictions du modèle sont proches des valeurs réelles. Un RMSE plus bas indique une meilleure performance du modèle, car cela signifie que les prédictions sont plus proches des valeurs réelles.
RMSE <- function(actuals, predictions){
RMSE <- sqrt((mean((actuals - predictions)^2)))
return(RMSE)
}
print(RMSE(actuals, predictions)) ## [1] 2.588005
Notre RMSE est assez faible, c’est assez bon.
le Mean Relative Error (MRE) est une mesure de la précision d’un modèle de prédiction. Il calcule la moyenne des erreurs absolues relatives entre les valeurs prédites et les valeurs réelles, par valeur réelles. Il est défini par :
\[ \text{MRE} = \frac{1}{n} \sum_{i=1}^{n} \frac{\left|y_i - \hat{y}_i \right| }{\left|y_i\right|} \]
Le MRE est utile pour évaluer la performance d’un modèle en termes de pourcentage d’erreur, ce qui facilite la comparaison entre différents modèles ou différentes séries de données.
MRE=function(actuals, predictions){
relative_errors = abs((actuals - predictions)/ actuals)
MRE = mean(relative_errors)
return(MRE)
}
MRE(actuals, predictions)## [1] 0.8391236
Un MRE de 44% % reste peu convaincant, car cela signifie que jusqu’à 44 % des valeurs prédites peuvent contenir des erreurs significatives par rapport aux valeurs réelles. En d’autres termes, près de la moitié des données pourrait être mal prédite, ce qui indique une performance relativement faible du modèle.
Le MAE, ou Erreur Absolue Moyenne, est une mesure de la précision d’un modèle de prédiction. Il calcule la moyenne des valeurs absolues des erreurs entre les valeurs prédites et les valeurs réelles. L’erreur absolue pour chaque observation est définie comme suit :
\[ \text{MAE} = \frac{ \sum_{i=1}^{N} |y_{i} - \hat{y}_{i}|}{N} \]
Le MAE est la moyenne de ces erreurs absolues sur toutes les observations et donne une indication générale de l’erreur moyenne en unités de la variable mesurée.
MAE=function(actuals, predictions){
absolute_errors <- abs(actuals - predictions)
MAE <- mean(absolute_errors)
return(MAE)
}
print(MAE(actuals, predictions))## [1] 1.988904
L’erreur relative mesure la différence entre les valeurs prédites et les valeurs réelles en termes proportionnels. Elle est calculée en utilisant la formule suivante :
\[ \text{Erreur relative} = \frac{\sum_{i=1}^{n} \left| y_i - \hat{y}_i \right|}{\sum_{i=1}^{n} y_i} \]
Cette formule calcule la somme des erreurs absolues pour chaque observation, divisée par la somme des valeurs réelles. L’erreur relative donne une mesure proportionnelle des erreurs par rapport aux valeurs réelles.
relative_error <- function(actuals, predictions){
relative_error <- sum(actuals - predictions)/sum(actuals)
return(relative_error)
}
print(relative_error(actuals, predictions))## [1] -0.0009656672
L’erreur relative positive est interprétée comme une sous-estimation. Dans ce cas, nous observons donc une sous-estimation.
La courbe de Lorenz fournit une visualisation de la capacité du modèle à discriminer efficacement entre les valeurs moyennes plus ou moins élevées de la réponse (dans le cas où les réponses sont dans l’intervalle [0, +∞[). Classiquement, on considère un échantillon de test \((y_i, x_i)_{i \in I_{\text{Test}}}\) indépendant de l’échantillon utilisé pour l’ajustement du modèle. La courbe est obtenue de la manière suivante :
En général, les coordonnées u et v sont normalisées respectivement par la somme des expositions et des réponses totales.
La courbe de Lorenz (en noir plus foncé) représente la part de patrimoine détenue par les bénéficiaires lorsqu’ils sont classés par ordre croissant de délais de paiement. Plus les courbes s’éloignent de la diagonale (en noir), plus la distribution est inégale. Dans notre cas, les courbes montrent que les distributions ne sont pas particulièrement inégalitaires.
L’examen graphique des résidus vise à :
residuals <- predict(fit0_cart.opt, newdata = ModeleCARTTrain) - ModeleCARTTrain$DP
hist(residuals,
main = "Histogramme des résidus de fit1 avec densité normale",
xlab = "Résidus",
col = "skyblue",
border = "white",
prob = TRUE # Utilisation de la densité de probabilité
)
curve(dnorm(x, mean = mean(residuals), sd = sd(residuals)),
add = TRUE, col = "darkblue", lwd = 2)# 2. QQ-plot
par(mfrow = c(1, 2)) # Pour afficher deux graphiques côte à côte
qqnorm(residuals)
qqline(residuals, col = "red")
#png("C:/Users/JKLEVINE/Desktop/JUDE KLEVINE/qq_plot_residus.png", width = 800, height = 600)
# Réinitialiser le paramètre de par
par(mfrow = c(1, 1))## [1] 3.544497e-15
## [1] 6.548314
Les résidus sont alignés sur la droite rouge et semblent suivre une distribution normale. Nous avons une moyenne nulle, mais la variance de notre modèle est différente de 1.