téléchargement des données ozone :

ozone <-read.table("https://r-stat-sc-donnees.github.io/ozone.txt", header=TRUE)

Installations des library

library(rpart)
## Warning: le package 'rpart' a été compilé avec la version R 4.1.3
library(kernlab)
## Warning: le package 'kernlab' a été compilé avec la version R 4.1.3
library(MASS) 
## Warning: le package 'MASS' a été compilé avec la version R 4.1.3
library(rpart.plot)
## Warning: le package 'rpart.plot' a été compilé avec la version R 4.1.3
library(corrplot)
## Warning: le package 'corrplot' a été compilé avec la version R 4.1.3
## corrplot 0.92 loaded
library(ggplot2)
## 
## Attachement du package : 'ggplot2'
## L'objet suivant est masqué depuis 'package:kernlab':
## 
##     alpha
library(car)
## Warning: le package 'car' a été compilé avec la version R 4.1.3
## Le chargement a nécessité le package : carData
## Warning: le package 'carData' a été compilé avec la version R 4.1.3
library(caret)
## Warning: le package 'caret' a été compilé avec la version R 4.1.3
## Le chargement a nécessité le package : lattice
library(rpart)

1 - Description des donnée :

Je vais commencer par fournir un résumé statistique de l’ensemble de données, ce qui inclura des mesures telles que la moyenne, la médiane, et les quartiles pour les différentes variables. Cela nous donnera un aperçu global de la distribution des données.

Ensuite, je vais examiner la fréquence de la variable binaire “pluie”. Cela nous permettra de comprendre la répartition des jours pluvieux par rapport aux jours non pluvieux dans l’ensemble de données.

En utilisant des histogrammes, je vais visualiser la distribution des valeurs pour deux variables spécifiques : “maxO3” (maximum d’ozone journalier) et “T12” (température du jour à 12h). Ces graphiques nous aideront à avoir une idée visuelle de la répartition des données pour ces variables.

# Résumé statistique : 
summary(ozone)
##      maxO3              T9             T12             T15       
##  Min.   : 42.00   Min.   :11.30   Min.   :14.00   Min.   :14.90  
##  1st Qu.: 70.75   1st Qu.:16.20   1st Qu.:18.60   1st Qu.:19.27  
##  Median : 81.50   Median :17.80   Median :20.55   Median :22.05  
##  Mean   : 90.30   Mean   :18.36   Mean   :21.53   Mean   :22.63  
##  3rd Qu.:106.00   3rd Qu.:19.93   3rd Qu.:23.55   3rd Qu.:25.40  
##  Max.   :166.00   Max.   :27.00   Max.   :33.50   Max.   :35.50  
##       Ne9             Ne12            Ne15           Vx9         
##  Min.   :0.000   Min.   :0.000   Min.   :0.00   Min.   :-7.8785  
##  1st Qu.:3.000   1st Qu.:4.000   1st Qu.:3.00   1st Qu.:-3.2765  
##  Median :6.000   Median :5.000   Median :5.00   Median :-0.8660  
##  Mean   :4.929   Mean   :5.018   Mean   :4.83   Mean   :-1.2143  
##  3rd Qu.:7.000   3rd Qu.:7.000   3rd Qu.:7.00   3rd Qu.: 0.6946  
##  Max.   :8.000   Max.   :8.000   Max.   :8.00   Max.   : 5.1962  
##       Vx12             Vx15            maxO3v           vent          
##  Min.   :-7.878   Min.   :-9.000   Min.   : 42.00   Length:112        
##  1st Qu.:-3.565   1st Qu.:-3.939   1st Qu.: 71.00   Class :character  
##  Median :-1.879   Median :-1.550   Median : 82.50   Mode  :character  
##  Mean   :-1.611   Mean   :-1.691   Mean   : 90.57                     
##  3rd Qu.: 0.000   3rd Qu.: 0.000   3rd Qu.:106.00                     
##  Max.   : 6.578   Max.   : 5.000   Max.   :166.00                     
##     pluie          
##  Length:112        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 
# Fréquence pour la variable binaire "pluie" :
table(ozone$pluie)
## 
## Pluie   Sec 
##    43    69
#Histogramme pour la variable "maxO3 = maximum d’ozone journalier " et "T12 = : la température du jour à 12h" : 
hist(ozone$maxO3, main="Histogramme de maxO3", xlab="Max O3", col="darkorchid2", border="black")

hist(ozone$T12, main="Histogramme de la température du jour à 12h", xlab="T 12", col="darkgoldenrod1", border="black")

#Boîte à moustaches pour la variable "maxO3" en fonction de la variable binaire "pluie" :
boxplot(maxO3 ~ pluie, data=ozone, main="Boîte à moustaches de maxO3 en fonction de la pluie", xlab="Pluie", ylab="Max O3", col=c("cadetblue", "chartreuse3"))

#Diagramme en secteurs pour illustrer la répartition des différentes catégories de la variable "vent".
pie(table(ozone$vent))

Maintenant je vais d’abord créer une matrice de corrélation pour évaluer les relations entre les variables spécifiées, puis afficher ces relations sous forme de heatmap pour une visualisation plus claire.

#headmap:

# Création de la matrice de corrélation
matrice_correlation <- cor(ozone[, c("maxO3", "T9", "T12", "T15", "Ne9", "Ne12", "Ne15", "Vx9", "Vx12", "Vx15", "maxO3v")])

# Affichage de la matrice de corrélation
print(matrice_correlation)
##             maxO3         T9        T12        T15        Ne9       Ne12
## maxO3   1.0000000  0.6993865  0.7842623  0.7745700 -0.6217042 -0.6407513
## T9      0.6993865  1.0000000  0.8829672  0.8464460 -0.4838636 -0.4722475
## T12     0.7842623  0.8829672  1.0000000  0.9461930 -0.5842709 -0.6601002
## T15     0.7745700  0.8464460  0.9461930  1.0000000 -0.5861683 -0.6492261
## Ne9    -0.6217042 -0.4838636 -0.5842709 -0.5861683  1.0000000  0.7883411
## Ne12   -0.6407513 -0.4722475 -0.6601002 -0.6492261  0.7883411  1.0000000
## Ne15   -0.4783021 -0.3251386 -0.4580991 -0.5746817  0.5502490  0.7098668
## Vx9     0.5276234  0.2506896  0.4301045  0.4530892 -0.4976361 -0.4926581
## Vx12    0.4307959  0.2223857  0.3126291  0.3437506 -0.5287752 -0.5103204
## Vx15    0.3918989  0.1703215  0.2706802  0.2866028 -0.4939010 -0.4322695
## maxO3v  0.6845160  0.5822451  0.5636289  0.5678887 -0.2765500 -0.3619227
##              Ne15        Vx9       Vx12       Vx15     maxO3v
## maxO3  -0.4783021  0.5276234  0.4307959  0.3918989  0.6845160
## T9     -0.3251386  0.2506896  0.2223857  0.1703215  0.5822451
## T12    -0.4580991  0.4301045  0.3126291  0.2706802  0.5636289
## T15    -0.5746817  0.4530892  0.3437506  0.2866028  0.5678887
## Ne9     0.5502490 -0.4976361 -0.5287752 -0.4939010 -0.2765500
## Ne12    0.7098668 -0.4926581 -0.5103204 -0.4322695 -0.3619227
## Ne15    1.0000000 -0.4014717 -0.4318633 -0.3782896 -0.3084755
## Vx9    -0.4014717  1.0000000  0.7501775  0.6822608  0.3403172
## Vx12   -0.4318633  0.7501775  1.0000000  0.8371720  0.2236755
## Vx15   -0.3782896  0.6822608  0.8371720  1.0000000  0.1899220
## maxO3v -0.3084755  0.3403172  0.2236755  0.1899220  1.0000000
# Afficher la heatmap
corrplot(matrice_correlation, method = "color")

2 - Application de CART :

Je vais commencer par diviser mes données en ensembles d’apprentissage et de test afin d’évaluer la performance de mon modèle sur des données non vues.

Ensuite, je vais créer un modèle CART, utilisant les variables météorologiques telles que la température, la nébulosité, la vitesse du vent, etc., pour prédire la concentration d’ozone journalière.

Après la création du modèle, je vais examiner ses détails pour comprendre quelles variables sont les plus importantes dans la prise de décision.

Avec le modèle entraîné, je vais effectuer des prédictions sur l’ensemble de test, constitué de données que le modèle n’a pas encore vues.

Pour évaluer la performance du modèle, je vais comparer les prédictions générées avec les valeurs réelles présentes dans l’ensemble de test.

Afin de mieux visualiser la précision du modèle, je vais créer un graphique de dispersion représentant graphiquement les prédictions par rapport aux valeurs réelles.

Enfin, je vais explorer l’arbre de décision résultant pour comprendre de manière visuelle la logique qui sous-tend les prédictions du modèle.

# Diviser les données en ensembles d'apprentissage et de test (80% / 20%)
set.seed(123)  # pour la reproductibilité

indices_apprentissage <- sample(1:nrow(ozone), 0.8 * nrow(ozone))
donnees_apprentissage <- ozone[indices_apprentissage, ]
donnees_test <- ozone[-indices_apprentissage, ]

# Créer le modèle CART
modele_cart <- rpart(maxO3 ~ T9 + T12 + T15 + Ne9 + Ne12 + Ne15 + Vx9 + Vx12 + Vx15 + maxO3v + vent + pluie, data=ozone)

# Afficher le modèle (optionnel)
printcp(modele_cart)
## 
## Regression tree:
## rpart(formula = maxO3 ~ T9 + T12 + T15 + Ne9 + Ne12 + Ne15 + 
##     Vx9 + Vx12 + Vx15 + maxO3v + vent + pluie, data = ozone)
## 
## Variables actually used in tree construction:
## [1] maxO3v Ne12   pluie  T12   
## 
## Root node error: 88192/112 = 787.43
## 
## n= 112 
## 
##         CP nsplit rel error  xerror     xstd
## 1 0.628232      0   1.00000 1.01598 0.145921
## 2 0.084434      1   0.37177 0.54648 0.082603
## 3 0.047610      2   0.28733 0.50174 0.072137
## 4 0.027020      3   0.23972 0.44073 0.060622
## 5 0.016910      4   0.21270 0.42058 0.054435
## 6 0.010000      5   0.19579 0.42216 0.054777
# Faire des prédictions sur l'ensemble de test
predictions <- predict(modele_cart, newdata=donnees_test)

# Comparer les prédictions avec les valeurs réelles
resultats <- data.frame(Reel=donnees_test$maxO3, Prediction=predictions)
print(resultats)
##          Reel Prediction
## 20010601   87   87.00000
## 20010602   82   76.85000
## 20010612  106   89.00000
## 20010613  101   89.00000
## 20010621   81   89.00000
## 20010622  121  110.15385
## 20010623  146  142.37500
## 20010627   83   89.00000
## 20010701   70   87.00000
## 20010717   63   65.77419
## 20010718   69   65.77419
## 20010719   92   76.85000
## 20010722   72   76.85000
## 20010727  159  142.37500
## 20010729  160  142.37500
## 20010801  126  142.37500
## 20010804   63   65.77419
## 20010812  111  110.15385
## 20010813   75   89.00000
## 20010822  117  142.37500
## 20010914   71   65.77419
## 20010925   84   76.85000
## 20010929   83   89.00000
# Visualiser les prédictions par rapport aux valeurs réelles, voici un graphique de dispersion pour visualiser graphiquement la performance du modèle

plot(resultats$Reel, resultats$Prediction, main="Prédictions vs Réalités", xlab="Réalités", ylab="Prédictions", col="blue", pch=19)
abline(0, 1, col="red")

# visualiser l'arbre de décision pour mieux comprendre comment le modèle prend des décisions avec 8 valeur
prp(modele_cart)

#Variable importance
modele_cart$variable.importance
##        T12        T15         T9     maxO3v        Ne9       Ne12        Vx9 
## 63551.5516 55405.5511 53830.8047 27572.3105 25414.9339 23398.5364  4391.3167 
##       Vx15       Vx12      pluie       Ne15 
##  3436.8091  2672.9122  1491.3248   476.5805

J’ai divisé mes données en ensembles d’apprentissage et de test, utilisant 80% des données pour l’apprentissage et 20% pour l’évaluation, assurant ainsi la robustesse de mon modèle.

En utilisant la méthode CART, j’ai créé un modèle de régression pour prédire la concentration d’ozone en fonction de variables météorologiques telles que la température, la nébulosité, la vitesse du vent, etc. Le modèle a été construit à l’aide des données d’apprentissage.

En examinant les détails du modèle, j’ai identifié les variables effectivement utilisées dans la construction de l’arbre de décision. La racine de l’arbre présentait une erreur initiale de 763.41, qui diminuait à chaque subdivision.

J’ai ensuite utilisé le modèle entraîné pour faire des prédictions sur l’ensemble de test. Ces prédictions ont été comparées aux valeurs réelles de l’ensemble de test, générant un tableau de résultats.

Pour évaluer visuellement la performance du modèle, j’ai créé un graphique de dispersion affichant les prédictions par rapport aux valeurs réelles. La ligne rouge diagonale indiquait une correspondance parfaite entre les deux.

Enfin, j’ai visualisé l’arbre de décision pour mieux comprendre la logique interne du modèle. Cela m’a fourni des informations sur la façon dont le modèle prend des décisions en fonction des différentes variables météorologiques.

3 - Discrimination en fonction des variables explicatives :

Je vais sélectionner un ensemble de variables pour le clustering, standardiser ces variables, puis appliquer l’algorithme de k-means pour former deux clusters. Ensuite, j’ajouterai l’information de cluster au dataframe initial.

Pour évaluer la discrimination des clusters, je vais afficher le nombre de jours attribués à chaque cluster à l’aide d’une table de contingence. Enfin, je vais créer une visualisation graphique montrant la répartition des jours entre les deux clusters pareil pour le vent.

# Sélection des variables à utiliser pour le clustering
variables_clustering <- ozone[, c("T9", "T12", "T15", "Ne9", "Ne12", "Ne15", "Vx9", "Vx12", "Vx15", "maxO3v")]

# Standardisation des variables
variables_clustering_scaled <- scale(variables_clustering)

# Application de k-means avec k=2 (deux clusters)
kmeans_result <- kmeans(variables_clustering_scaled, centers = 2)

# Ajout du résultat dans le dataframe
ozone$cluster <- as.factor(kmeans_result$cluster)

# Visualisation de la discrimination
table_discrimination <- table(ozone$cluster)
print(table_discrimination)
## 
##  1  2 
## 79 33
# Visualisation graphique
graphique_discrimination <- ggplot(ozone, aes(x = cluster)) +
  geom_bar(fill = "darkorange", color = "darkorchid1") +
  labs(title = "Discrimination des clusters (jours pollués et peu pollués)",
       x = "Cluster",
       y = "Nombre de jours")

# Affichage du graphique
print(graphique_discrimination)

# Création d'un graphique à barres empilées pour visualiser la relation entre "vent" et les clusters
graphique_vent_cluster <- ggplot(ozone, aes(x = vent, fill = cluster)) +
  geom_bar(position = "stack", color = "white") +
  labs(title = "Relation entre le vent et les clusters",
       x = "Vent",
       y = "Nombre de jours",
       fill = "Cluster") +
  theme_minimal()

# Affichage du graphique
print(graphique_vent_cluster)

Je commence par sélectionner un ensemble de variables, notamment la température à différentes heures, la nébulosité, la vitesse du vent et le maximum d’ozone de la veille, que je vais utiliser pour effectuer un clustering.

Ensuite, je standardise ces variables pour garantir une comparaison équitable.

J’applique l’algorithme k-means avec k=2, ce qui signifie que je vais regrouper les données en deux clusters distincts.

Les résultats du clustering sont ajoutés au dataframe initial, où chaque jour est assigné à l’un des deux clusters.

Pour évaluer la discrimination des clusters, je crée une table de contingence montrant le nombre de jours attribués à chaque cluster.

Enfin, je visualise graphiquement la répartition des jours entre les deux clusters à l’aide d’un graphique à barres, où la couleur “darkorange” représente visuellement la discrimination entre les jours pollués et peu pollués.

Les résultats montrent que le clustering a attribué 79 jours au Cluster 1 et 33 jours au Cluster 2. Ce regroupement permet de distinguer deux groupes distincts de jours en fonction des variables sélectionnées.

Le Graphique de Discrimination des Clusters offre une perspective visuelle sur la répartition des jours entre les clusters, mettant en évidence la différenciation entre les jours pollués et peu pollués et pareil pour le vent.

4 - Prévision de la concentration d’ozone pour un jour d’été typique

Je vais sélectionner les variables explicatives pertinentes pour la prédiction de la concentration d’ozone. Ensuite, je vais créer un dataframe incluant ces variables explicatives ainsi que la variable cible, la concentration d’ozone.

En suivant cela, je vais diviser mes données en ensembles d’entraînement (80%) et de test (20%) pour évaluer la performance du modèle sur des données non vues.

En utilisant l’algorithme CART (Classification and Regression Trees), je vais construire un modèle de régression avec les variables explicatives sélectionnées.

Ensuite, je vais effectuer des prévisions sur l’ensemble de test en utilisant le modèle entraîné.

Pour évaluer la performance du modèle, je vais calculer une métrique, par exemple, la Racine Carrée de l’Erreur Quadratique Moyenne (RMSE).

Enfin, je vais visualiser l’arbre de décision résultant pour mieux comprendre la logique du modèle.

# Sélection des variables explicatives
variables_explicatives <- ozone[, c("T9", "T12", "T15", "Ne9", "Ne12", "Ne15", "Vx9", "Vx12", "Vx15", "maxO3v")]

# Création d'un dataframe avec les variables explicatives et la variable cible
donnees_modele <- cbind(variables_explicatives, maxO3 = ozone$maxO3)

# Diviser les données en ensembles d'entraînement (80%) et de test (20%)
set.seed(123)
indices_train <- sample(1:nrow(donnees_modele), 0.8 * nrow(donnees_modele))
donnees_train <- donnees_modele[indices_train, ]
donnees_test <- donnees_modele[-indices_train, ]

# Modèle de régression CART (Classification and Regression Trees)
modele <- rpart(maxO3 ~ ., data = donnees_train)

# Prévisions sur l'ensemble de test
predictions <- predict(modele, newdata = donnees_test)

# Calcul de la performance (par exemple, RMSE)
rmse <- sqrt(mean((donnees_test$maxO3 - predictions)^2))
cat("RMSE :", rmse, "\n")
## RMSE : 14.52041
# Visualisation de l'arbre de décision
rpart.plot(modele, box.palette = "RdBu", shadow.col = "gray", nn = TRUE)

Après avoir sélectionné soigneusement les variables explicatives pertinentes pour la prédiction de la concentration d’ozone, j’ai créé un modèle de régression en utilisant l’algorithme CART (Classification and Regression Trees).

Pour évaluer la performance de ce modèle, j’ai divisé mes données en ensembles d’entraînement (80%) et de test (20%). En effectuant des prévisions sur l’ensemble de test, j’ai calculé une métrique de performance, la Racine Carrée de l’Erreur Quadratique Moyenne (RMSE), qui mesure la précision du modèle par rapport aux valeurs réelles.

Le modèle semble avoir un RMSE de 14.52041, indiquant une certaine variabilité entre les prédictions et les valeurs réelles. Cette mesure pourrait être utilisée pour évaluer l’adéquation du modèle à vos données.

Pour mieux comprendre la logique du modèle, j’ai également visualisé l’arbre de décision résultant. Cette représentation graphique m’a permis de saisir les conditions et les variables qui influent sur les prédictions du modèle.

5 - Sélection des variables importantes pour la discrimination et interprétation :

Je vais sélectionner un ensemble spécifique de variables météorologiques pour les utiliser comme variables explicatives dans un modèle de régression linéaire. La concentration d’ozone sera la variable cible que je tenterai de prédire en fonction de ces variables.

Ensuite, je vais construire un modèle de régression linéaire à l’aide de ces variables explicatives. Je vais examiner le résumé du modèle pour comprendre les coefficients et la significativité des variables.

Enfin, je vais vérifier la multicollinéarité entre les variables explicatives pour s’assurer que le modèle est robuste.

# Sélection des variables explicatives
variables_explicatives <- ozone[, c("T9", "T12", "T15", "Ne9", "Ne12", "Ne15", "Vx9", "Vx12", "Vx15", "maxO3v")]

# Variable cible
concentration_ozone <- ozone$maxO3

# Modèle de régression logistique
modele_lineaire <- lm(concentration_ozone ~ ., data = cbind(variables_explicatives, maxO3 = concentration_ozone))

# Résumé du modèle
summary(modele_lineaire)
## Warning in summary.lm(modele_lineaire): essentially perfect fit: summary may be
## unreliable
## 
## Call:
## lm(formula = concentration_ozone ~ ., data = cbind(variables_explicatives, 
##     maxO3 = concentration_ozone))
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -1.954e-14 -4.642e-16  1.180e-16  8.558e-16  4.956e-15 
## 
## Coefficients:
##               Estimate Std. Error    t value Pr(>|t|)    
## (Intercept) -1.098e-15  2.257e-15 -4.870e-01 0.627676    
## T9           6.411e-17  1.878e-16  3.410e-01 0.733481    
## T12          6.965e-16  2.420e-16  2.879e+00 0.004884 ** 
## T15          1.933e-16  1.912e-16  1.011e+00 0.314533    
## Ne9         -5.558e-16  1.607e-16 -3.458e+00 0.000801 ***
## Ne12        -1.451e-16  2.283e-16 -6.350e-01 0.526673    
## Ne15         3.010e-17  1.674e-16  1.800e-01 0.857628    
## Vx9          1.120e-16  1.530e-16  7.320e-01 0.465875    
## Vx12        -1.228e-17  1.761e-16 -7.000e-02 0.944529    
## Vx15         9.497e-17  1.530e-16  6.210e-01 0.536122    
## maxO3v       6.223e-17  1.201e-17  5.181e+00 1.15e-06 ***
## maxO3        1.000e+00  1.660e-17  6.022e+16  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.396e-15 on 100 degrees of freedom
## Multiple R-squared:      1,  Adjusted R-squared:      1 
## F-statistic: 1.396e+33 on 11 and 100 DF,  p-value: < 2.2e-16
# Vérifier la multicollinéarité
vif(modele_lineaire)
## Warning in summary.lm(object, ...): essentially perfect fit: summary may be
## unreliable
##        T9       T12       T15       Ne9      Ne12      Ne15       Vx9      Vx12 
##  6.645143 18.490290 14.512129  3.362657  5.247558  2.945311  3.138345  4.684688 
##      Vx15    maxO3v     maxO3 
##  3.571640  2.230132  4.234441

J’ai commencé par sélectionner un ensemble spécifique de variables explicatives liées à la température, à la nébulosité, à la vitesse du vent, et au maximum d’ozone de la veille. Ces variables ont été utilisées pour construire un modèle de régression linéaire visant à prédire la concentration d’ozone.

En examinant le résumé du modèle, il est important de noter que le modèle semble avoir une correspondance parfaite, comme indiqué par le message “essentially perfect fit”. Cela peut rendre le résumé du modèle potentiellement peu fiable.

Les coefficients estimés pour chaque variable indiquent comment la concentration d’ozone est influencée par les changements dans ces variables. Par exemple, le coefficient pour “T12” est significativement différent de zéro (p-value < 0.05), ce qui suggère une relation significative entre la température à midi et la concentration d’ozone.

Cependant, il est important de noter que la multicollinéarité est un problème potentiel. Les valeurs de VIF (variance inflation factor) indiquent des niveaux élevés de corrélation entre certaines variables, ce qui peut affecter la fiabilité des coefficients estimés.

6 - Évaluation du modèle CART par la méthode de Monte Carlo

Je vais écrire une fonction pour évaluer un modèle par Monte Carlo. Cette fonction effectuera plusieurs itérations de l’évaluation du modèle, en divisant les données en ensembles d’entraînement et de test à chaque itération, puis en utilisant un modèle CART pour prédire la concentration d’ozone et en calculant une métrique de performance, telle que la racine carrée de l’erreur quadratique moyenne (RMSE).

Ensuite, j’utiliserai cette fonction pour effectuer l’évaluation Monte Carlo sur les données météorologiques, en affichant un résumé des résultats obtenus.

# Fonction pour évaluer le modèle par Monte Carlo
monte_carlo_evaluation <- function(data, num_iterations = 100) {
  results <- numeric(num_iterations)
  
  for (i in 1:num_iterations) {
    set.seed(i)  # Assurer la reproductibilité
    
    # Diviser les données en ensembles d'entraînement (80%) et de test (20%)
    indices_train <- createDataPartition(data$maxO3, p = 0.8, list = FALSE)
    donnees_train <- data[indices_train, ]
    donnees_test <- data[-indices_train, ]
    
    # Modèle CART
    modele_cart <- rpart(maxO3 ~ ., data = donnees_train)
    
    # Prédiction sur l'ensemble de test
    predictions <- predict(modele_cart, newdata = donnees_test)
    
    # Calculer la performance (par exemple, RMSE)
    rmse <- sqrt(mean((predictions - donnees_test$maxO3)^2))
    
    results[i] <- rmse
  }
  
  return(results)
}


# Utiliser la fonction pour l'évaluation Monte Carlo
resultats_evaluation <- monte_carlo_evaluation(ozone)

# Afficher les résultats
summary(resultats_evaluation)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   9.155  14.518  15.910  16.693  18.060  31.820

J’ai créé une fonction Monte Carlo pour évaluer la performance d’un modèle CART sur la prédiction de la concentration d’ozone. Cette fonction effectue 100 itérations de l’évaluation du modèle, en divisant les données en ensembles d’entraînement et de test à chaque itération, puis en utilisant un modèle CART pour prédire la concentration d’ozone et en calculant la racine carrée de l’erreur quadratique moyenne (RMSE).

En utilisant cette fonction sur les données météorologiques, j’ai obtenu les résultats suivants :

La valeur minimale de la RMSE est de 9.155. Le premier quartile de la RMSE est de 14.518. La médiane de la RMSE est de 15.910. La moyenne de la RMSE est de 16.693. Le troisième quartile de la RMSE est de 18.060. La valeur maximale de la RMSE est de 31.820. Ces statistiques fournissent une indication de la variabilité de la performance du modèle sur différents ensembles de données. La médiane donne une idée de la performance typique, tandis que le premier et le troisième quartile montrent la dispersion des résultats.

7 - Que faire si les variables de température sont absentes un jour donné pour prévoir l’ozone ?

summary(modele)
## Call:
## rpart(formula = maxO3 ~ ., data = donnees_train)
##   n= 89 
## 
##           CP nsplit rel error    xerror       xstd
## 1 0.59633571      0 1.0000000 1.0199904 0.17137938
## 2 0.09158672      1 0.4036643 0.5091848 0.08130246
## 3 0.05931058      2 0.3120776 0.4496423 0.06786355
## 4 0.02777919      3 0.2527670 0.4020351 0.06563021
## 5 0.02021321      4 0.2249878 0.3961426 0.06295000
## 6 0.01446206      5 0.2047746 0.3939567 0.06237651
## 7 0.01301534      6 0.1903125 0.3952501 0.06263536
## 8 0.01000000      7 0.1772972 0.3875736 0.06263051
## 
## Variable importance
##    T12    T15     T9 maxO3v   Ne12    Ne9    Vx9   Vx15   Vx12 
##     24     21     21     11      9      8      3      1      1 
## 
## Node number 1: 89 observations,    complexity param=0.5963357
##   mean=88.67416, MSE=763.4107 
##   left son=2 (67 obs) right son=3 (22 obs)
##   Primary splits:
##       T12    < 23.45    to the left,  improve=0.5963357, (0 missing)
##       T15    < 25.8     to the left,  improve=0.5708804, (0 missing)
##       T9     < 19.7     to the left,  improve=0.4957287, (0 missing)
##       maxO3v < 116.5    to the left,  improve=0.4075481, (0 missing)
##       Ne12   < 4.5      to the right, improve=0.4005741, (0 missing)
##   Surrogate splits:
##       T9     < 20.25    to the left,  agree=0.966, adj=0.864, (0 split)
##       T15    < 24.8     to the left,  agree=0.966, adj=0.864, (0 split)
##       maxO3v < 113.5    to the left,  agree=0.865, adj=0.455, (0 split)
##       Ne9    < 1.5      to the right, agree=0.854, adj=0.409, (0 split)
##       Ne12   < 1.5      to the right, agree=0.854, adj=0.409, (0 split)
## 
## Node number 2: 67 observations,    complexity param=0.05931058
##   mean=76.44776, MSE=219.6801 
##   left son=4 (33 obs) right son=5 (34 obs)
##   Primary splits:
##       maxO3v < 76.5     to the left,  improve=0.2737883, (0 missing)
##       Ne12   < 4.5      to the right, improve=0.2290984, (0 missing)
##       Vx9    < -0.816   to the left,  improve=0.1987194, (0 missing)
##       T12    < 17.35    to the left,  improve=0.1878999, (0 missing)
##       Vx12   < -1.80575 to the left,  improve=0.1818426, (0 missing)
##   Surrogate splits:
##       T15 < 20.55    to the left,  agree=0.627, adj=0.242, (0 split)
##       Vx9 < -1.1539  to the left,  agree=0.627, adj=0.242, (0 split)
##       T9  < 15.65    to the left,  agree=0.612, adj=0.212, (0 split)
##       T12 < 17.45    to the left,  agree=0.612, adj=0.212, (0 split)
##       Ne9 < 2.5      to the right, agree=0.582, adj=0.152, (0 split)
## 
## Node number 3: 22 observations,    complexity param=0.09158672
##   mean=125.9091, MSE=577.6281 
##   left son=6 (11 obs) right son=7 (11 obs)
##   Primary splits:
##       T12    < 26.6     to the left,  improve=0.4896771, (0 missing)
##       T15    < 28.3     to the left,  improve=0.4896771, (0 missing)
##       maxO3v < 116.5    to the left,  improve=0.2185860, (0 missing)
##       Vx9    < 0.0868   to the left,  improve=0.1997295, (0 missing)
##       T9     < 22       to the left,  improve=0.1557677, (0 missing)
##   Surrogate splits:
##       T15  < 28.3     to the left,  agree=1.000, adj=1.000, (0 split)
##       T9   < 22       to the left,  agree=0.864, adj=0.727, (0 split)
##       Vx9  < 0.0868   to the left,  agree=0.818, adj=0.636, (0 split)
##       Vx15 < -2.11325 to the left,  agree=0.727, adj=0.455, (0 split)
##       Ne12 < 3.5      to the right, agree=0.682, adj=0.364, (0 split)
## 
## Node number 4: 33 observations,    complexity param=0.02021321
##   mean=68.57576, MSE=131.9412 
##   left son=8 (7 obs) right son=9 (26 obs)
##   Primary splits:
##       T12  < 17.35    to the left,  improve=0.3154199, (0 missing)
##       T15  < 19.45    to the left,  improve=0.2786708, (0 missing)
##       Ne9  < 7.5      to the right, improve=0.2667209, (0 missing)
##       Ne12 < 6.5      to the right, improve=0.2343163, (0 missing)
##       Ne15 < 4.5      to the right, improve=0.1986067, (0 missing)
##   Surrogate splits:
##       T9   < 15.35    to the left,  agree=0.909, adj=0.571, (0 split)
##       T15  < 16.25    to the left,  agree=0.909, adj=0.571, (0 split)
##       Vx9  < 0.60245  to the right, agree=0.848, adj=0.286, (0 split)
##       Ne9  < 7.5      to the right, agree=0.818, adj=0.143, (0 split)
##       Vx12 < 1.8674   to the right, agree=0.818, adj=0.143, (0 split)
## 
## Node number 5: 34 observations,    complexity param=0.02777919
##   mean=84.08824, MSE=186.3157 
##   left son=10 (12 obs) right son=11 (22 obs)
##   Primary splits:
##       T9   < 17.9     to the right, improve=0.2979473, (0 missing)
##       Vx9  < -0.8171  to the left,  improve=0.2892757, (0 missing)
##       Vx12 < -0.64345 to the left,  improve=0.2861563, (0 missing)
##       Vx15 < -0.7814  to the left,  improve=0.2710272, (0 missing)
##       Ne9  < 3        to the right, improve=0.2268779, (0 missing)
##   Surrogate splits:
##       T12    < 20.6     to the right, agree=0.824, adj=0.500, (0 split)
##       T15    < 22.75    to the right, agree=0.794, adj=0.417, (0 split)
##       Vx9    < -4.9793  to the left,  agree=0.735, adj=0.250, (0 split)
##       maxO3v < 112.5    to the right, agree=0.735, adj=0.250, (0 split)
##       Vx12   < -5.18115 to the left,  agree=0.706, adj=0.167, (0 split)
## 
## Node number 6: 11 observations
##   mean=109.0909, MSE=281.1736 
## 
## Node number 7: 11 observations
##   mean=142.7273, MSE=308.3802 
## 
## Node number 8: 7 observations
##   mean=56.14286, MSE=87.26531 
## 
## Node number 9: 26 observations,    complexity param=0.01301534
##   mean=71.92308, MSE=91.14793 
##   left son=18 (16 obs) right son=19 (10 obs)
##   Primary splits:
##       Vx9  < -2.13385 to the left,  improve=0.3731502, (0 missing)
##       Ne15 < 5.5      to the right, improve=0.2701636, (0 missing)
##       Vx12 < -2.39905 to the left,  improve=0.2042331, (0 missing)
##       Ne12 < 6        to the right, improve=0.1963776, (0 missing)
##       Ne9  < 6.5      to the right, improve=0.1478439, (0 missing)
##   Surrogate splits:
##       T15  < 20.6     to the left,  agree=0.808, adj=0.5, (0 split)
##       Ne9  < 6.5      to the right, agree=0.808, adj=0.5, (0 split)
##       Ne12 < 6        to the right, agree=0.808, adj=0.5, (0 split)
##       Ne15 < 4.5      to the right, agree=0.769, adj=0.4, (0 split)
##       Vx12 < -2.02605 to the left,  agree=0.769, adj=0.4, (0 split)
## 
## Node number 10: 12 observations
##   mean=74, MSE=105.6667 
## 
## Node number 11: 22 observations,    complexity param=0.01446206
##   mean=89.59091, MSE=144.5145 
##   left son=22 (8 obs) right son=23 (14 obs)
##   Primary splits:
##       T15  < 19.3     to the left,  improve=0.3090612, (0 missing)
##       Vx12 < -0.64345 to the left,  improve=0.2522146, (0 missing)
##       Vx15 < -0.3368  to the left,  improve=0.2522146, (0 missing)
##       Ne15 < 5.5      to the right, improve=0.2474385, (0 missing)
##       T9   < 16       to the left,  improve=0.1407356, (0 missing)
##   Surrogate splits:
##       T9   < 15.05    to the left,  agree=0.773, adj=0.375, (0 split)
##       T12  < 17.75    to the left,  agree=0.773, adj=0.375, (0 split)
##       Vx9  < -4.04445 to the left,  agree=0.773, adj=0.375, (0 split)
##       Vx12 < -3.9696  to the left,  agree=0.773, adj=0.375, (0 split)
##       Ne15 < 7.5      to the right, agree=0.727, adj=0.250, (0 split)
## 
## Node number 18: 16 observations
##   mean=67.3125, MSE=49.21484 
## 
## Node number 19: 10 observations
##   mean=79.3, MSE=69.81 
## 
## Node number 22: 8 observations
##   mean=80.75, MSE=38.6875 
## 
## Node number 23: 14 observations
##   mean=94.64286, MSE=134.801

Le résumé du modèle CART indique que la complexité paramétrique optimale est atteinte à 7 divisions du modèle, avec une erreur quadratique moyenne (MSE) de 763.41. Les variables les plus importantes pour la construction de l’arbre sont T12, T15, T9, maxO3v, Ne12, Ne9, Vx9, Vx15, et Vx12, dans cet ordre.

L’arbre de décision commence par le nœud racine, où il sépare les observations en deux groupes en fonction de la valeur de T12. Ensuite, chaque nœud subséquent divise les observations en fonction d’autres variables, optimisant ainsi la prédiction de la concentration d’ozone.

Si les variables de température sont absentes un jour donné pour prévoir l’ozone, le modèle CART utilisera les variables de remplacement spécifiées dans les nœuds de décision. Par exemple, si T12 est manquant, le modèle se tournera vers T15, T9, maxO3v, Ne12, ou Ne9 pour prendre une décision.

L’arbre de décision fournit un aperçu visuel de la façon dont le modèle prend des décisions en fonction des valeurs disponibles des variables météorologiques. Cela rend le modèle robuste face à des données incomplètes, bien qu’il soit toujours recommandé de disposer d’un ensemble complet de données pour des prédictions plus précises.