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)
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")
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.
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.
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.
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.
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.
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.