Skip to content

Commit 89c2dce

Browse files
committed
B02Lb_reg_poly revised
1 parent 243081f commit 89c2dce

File tree

2 files changed

+72
-69
lines changed

2 files changed

+72
-69
lines changed

inst/tutorials/B02Lb_reg_poly/B02Lb_reg_poly.Rmd

Lines changed: 72 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,16 @@ SciViews::R("model", lang = "fr")
1818
1919
# datasets
2020
reddrum <- read("reddrum", package = "UsingR")
21-
reddrum$length <- reddrum$length*0.0254
21+
reddrum$length <- reddrum$length * 0.0254
2222
reddrum <- labelise(reddrum,
23-
label = list(length = "Longueur totale", age = "Age"),
24-
units = list(length = "m"))
23+
label = list(length = "Longueur", age = "Âge"),
24+
units = list(length = "m", age = "années"))
2525
2626
lm1 <- lm(data = reddrum, length ~ age)
2727
lm2 <- lm(data = reddrum, length ~ age + I(age^2))
2828
lm3 <- lm(data = reddrum, length ~ age + I(age^2) + I(age^3))
29-
3029
lm_poly_coef <- tidy(lm3)
3130
lm_poly_param <- glance(lm3)
32-
33-
#chart(data = reddrum, length ~ age) +
34-
# geom_point()
3531
```
3632

3733
```{r, echo=FALSE}
@@ -46,45 +42,43 @@ BioDataScience2::learnr_server(input, output, session)
4642

4743
## Objectifs
4844

49-
La première partie de ce module vous a permis de vous familiariser avec la régression linéaire multiple. L'objectif de ce tutoriel est :
50-
51-
- Maîtriser la régression linéaire polynomiale dans R avec la fonction `lm()`.
45+
L'objectif de ce tutoriel est de vous exercer à réaliser une régression polynomiale dans R avec la fonction `lm()`.
5246

5347
## Description des données
5448

55-
Le tableau de données `reddrum` traite de la croissance de *Sciaenops ocellatus* (L., 1766), un poisson da la famille des Scianidae. Sur base des études Porch et Nieland (2002), le tableau comprend des données simulées de la relation de la longueur en fonction de l'âge. Le tambour rouge est un poisson ayant une longueur totale moyenne de 1 mètre adulte. L'individu le plus long recensé mesurait 1.55 mètre et l'individu le plus âgé avait 50 ans. On le retrouve dans l'océan atlantique, le long des côtes est de l'Amérique du Nord et dans le golfe du Mexique.
49+
Le jeu de données `reddrum` traite de la croissance de l'ombrine tachetée *Sciaenops ocellatus* (L., 1766), un poisson da la famille des Scianidae qui vit sur la côte américaine de l'Océan Atlantique, du Massachusetts jusqu'au nord du Mexique. Les données de la longueur du poisson en fonction de son âge sont simulées sur base de mesures réalisées par Porch, Wilson et Nieland (2002). Cette espèce peut atteindre 1,5 mètre et peut vire plusieurs dizaines d'années jusqu'à 50 ou 60 ans.
5650

57-
```{r, echo = TRUE}
51+
Voir Porch, C., C.A. Wilson & D. Nieland (2002). A new growth model for red drum (*Scianops ocellatus*) that accommodates seasonal and ontogenic changes in growth rates. Fish. Bull., 100:149-152.
52+
53+
![Ombrine tachetée, avec son ocelle caractéristique à la base de la nageoire caudale.](images/reddrum.jpg)
54+
55+
```{r, echo=TRUE}
5856
SciViews::R("model",lang = "fr") # Configuration du système
5957
6058
# Importation des données
6159
reddrum <- read("reddrum", package = "UsingR")
6260
# Conversion de pouce en mètre
63-
reddrum$length <- reddrum$length*0.0254
61+
reddrum$length <- reddrum$length * 0.0254
6462
# Ajout des labels et unités
6563
reddrum <- labelise(reddrum,
66-
label = list(length = "Longueur totale", age = "Age"),
67-
units = list(length = "m", age = "Année"))
64+
label = list(length = "Longueur", age = "Âge"),
65+
units = list(length = "m", age = "années"))
6866
6967
skimr::skim(reddrum)
7068
```
7169

72-
Les données employées sont une simulation basée sur le papier suivant :
73-
74-
- Porch, Clay & C.A., Wilson & Nieland, David. (2002). A new growth model for red drum (Scianops ocellatus) that accommodates seasonal and ontogenic changes in growth rates. Fishery Bulletin- National Oceanic and Atmospheric Administration. 100. 149-152
75-
7670
## Modélisation
7771

78-
Vous allez modéliser la longueur (m) des poissons en fonction de leur âge. Le graphique ci-dessous vous propose à nouveau le nuage de points correspondant.
72+
Vous allez modéliser la longueur (m) de l'ombrine tachetée en fonction de son âge dont voici la représentation graphique.
7973

8074
```{r, echo=TRUE}
8175
chart(data = reddrum, length ~ age) +
8276
geom_point()
8377
```
8478

85-
La croissance de ces poissons est particulière. Les juvéniles ont une croissance très rapide et les adultes croient très lentement. La modélisation de cette relation s'annonce une tâche complexe.
79+
La croissance de ces poissons est particulière. Les juvéniles ont une croissance très rapide et ensuite, la croissance ralentit nettement sans jamais devenir nulle. La forme du nuage de points est telle qu'il est difficile, voire impossible de trouver une transformation capable de le linéariser. Commencez, à titre de référence, par ajuster une régression linéaire sur les données non transformées.
8680

87-
```{r reglin_h2, exercise = TRUE}
81+
```{r reglin_h2, exercise=TRUE}
8882
reddrum_lm1 <- lm(data = ___, ___ ~ ___)
8983
# Résumé du modèle
9084
summary(___)
@@ -112,9 +106,11 @@ chart(reddrum_lm1)
112106
```
113107

114108
```{r reglin_h2-check}
115-
grade_code("Voici notre régression linéaire. Le R^2 est de 0.82. On pourrait penser que ce modèle est très intéressant, si on se limite à cette valeur. Cependant, en visualisant notre droite sur le graphique, on observe un problème d'ajustement du modèle pour les jeunes individus. Interprétez chaque graphique de l'analyse des résidus pour déterminer si la régression linéaire est justifiée ici.")
109+
grade_code("Voici notre régression linéaire. Le R^2 est de 0.82. On pourrait penser que ce modèle est très intéressant, si on se limite à cette valeur. Cependant, en visualisant notre droite sur le graphique, on observe un problème d'ajustement du modèle pour les jeunes individus.")
116110
```
117111

112+
Afin de compléter notre analyse, voici les graphiques des résidus.
113+
118114
```{r}
119115
chart$residuals(lm1)
120116
```
@@ -149,9 +145,11 @@ chart(reddrum_lm2)
149145
```
150146

151147
```{r regpoly_h2-check}
152-
grade_code("Voici notre parabole ajustée dans les données... Est-ce mieux que la droite ? Visuellement, on peut observer que notre modèle est meilleur. Cela n'empêche pas d'étudier le résumé du modèle et d'étudier les graphiques de l'analyse des résidus")
148+
grade_code("Cette fois-ci, nous avons ajusté une parabole dans les données... C'est déjà mieux, mais insuffisant.")
153149
```
154150

151+
Analyse des résidus pour le modèle polynomial d'ordre 2.
152+
155153
```{r}
156154
chart$residuals(lm2)
157155
```
@@ -186,24 +184,25 @@ chart(reddrum_lm3)
186184
```
187185

188186
```{r regpoly3_h2-check}
189-
grade_code(" Est-ce mieux que la la régression linéaire ou que la régression linéaire polynomiale d'ordre 2 ? Visuellement, on peut observer que notre modèle semble meilleur. Attention, vous devez toujours étudier le résumé du modèle et étudier les graphiques de l'analyse des résidus")
187+
grade_code("Observez comme la courbe devient de plus en plus flexible à mesure que l'ordre du polynome augmente.")
190188
```
191189

190+
Analyse des résidus pour la régression polynomiale d'ordre 3.
191+
192192
```{r}
193193
chart$residuals(lm3)
194194
```
195195

196-
Étudiez la régression polynomiale d'ordre 3 et répondez aux questions ci-dessous.
196+
Étudiez les résultats obtenus et répondez aux question ci-dessous.
197197

198198
```{r qu_regpoly}
199199
quiz(
200-
question(text = "Quelle est la valeur de l'ordonnée à l'origine pour la régression polynomiale d'ordre 3 ?",
201-
answer(sprintf("%.4f", lm_poly_coef$estimate[1]), correct = TRUE),
200+
question(text = "Quelle est la valeur du paramètre pour le terme d'ordre 2 ?",
201+
answer(sprintf("%.4f", lm_poly_coef$estimate[1])),
202202
answer(sprintf("%.4f", lm_poly_coef$estimate[2])),
203-
answer(sprintf("%.4f", lm_poly_coef$std.error[1])),
204-
answer(sprintf("%.4f", lm_poly_coef$std.error[2])),
205-
answer(sprintf("%.4f", lm_poly_coef$statistic[1])),
203+
answer(sprintf("%.4f", lm_poly_coef$estimate[3]), correct = TRUE),
206204
answer(sprintf("%.4f", lm_poly_coef$statistic[2])),
205+
answer(sprintf("%.4f", lm_poly_coef$statistic[3])),
207206
answer(sprintf("%.4f", lm_poly_param$r.squared[1])),
208207
allow_retry = TRUE, random_answer_order = TRUE
209208
),
@@ -220,12 +219,13 @@ quiz(
220219
)
221220
```
222221

223-
## Etude complémentaire
222+
## Choix du meilleur modèle
224223

225-
Nous avons pu observer que notre modèle s'ajustait de mieux en mieux en augmentant l'ordre de notre polynôme. Une méthode consiste à augmenter l'ordre du polynôme de manière itérative jusqu'à ce que les variables du modèle ne soient plus significatives. Nous ne détaillons pas chaque modèle. Voici le polynome d'ordre 6.
224+
Nous avons pu observer que notre modèle s'ajuste de mieux en mieux en augmentant l'ordre de notre polynôme. Une méthode consiste à augmenter l'ordre du polynôme de manière itérative jusqu'à ce que le paramètre relatif au terme d'ordre maximum ne soit plus significativement différent de zéro. Ici, cela implique de tester aussi un modèle polynomial d'ordre 4, 5, 6, 7... Nous ne détaillons pas chaque modèle, mais voici ce que donne le polynôme d'ordre 6.
226225

227-
```{r, echo = TRUE}
228-
reddrum_lm6 <- lm(data = reddrum, length ~ age + I(age^2) + I(age^3) + I(age^4) + I(age^5) + I(age^6))
226+
```{r, echo=TRUE}
227+
reddrum_lm6 <- lm(data = reddrum, length ~ age + I(age^2) + I(age^3) +
228+
I(age^4) + I(age^5) + I(age^6))
229229
summary(reddrum_lm6)
230230
chart(reddrum_lm6)
231231
```
@@ -236,71 +236,74 @@ Tous les termes du modèle sont significatifs au seuil alpha de 5%. La valeur de
236236
chart$residuals(reddrum_lm6)
237237
```
238238

239-
```{r, echo = TRUE}
240-
reddrum_lm7 <- lm(data = reddrum, length ~ age + I(age^2) + I(age^3) + I(age^4) + I(age^5) + I(age^6) + + I(age^7))
239+
Voici à présent le résultat pour un polynôme d'ordre 7.
240+
241+
```{r, echo=TRUE}
242+
reddrum_lm7 <- lm(data = reddrum, length ~ age + I(age^2) + I(age^3) +
243+
I(age^4) + I(age^5) + I(age^6) + I(age^7))
241244
summary(reddrum_lm7)
242245
chart(reddrum_lm7)
243246
```
244247

245-
Jusqu'à la régression polynomiale d'ordre 7, toutes les variables de nos modèles successifs sont significatives au seuil alpha de 5%. À partir de ce dernier, nous avons franchi la limite. Les variables du modèle ne sont plus significatives. Le meilleur modèle polynomial est le polynôme d'ordre 6.
248+
Nous voyons ici que le paramètre du terme en puissance 7 n'est plus significativement différent de zéro au seuil alpha de 5%. Nous avons franchi la limite. Nous en concluons donc que le meilleur modèle polynomial est ici le polynôme d'ordre 6.
246249

247250
Poussons notre réflexion encore un peu plus loin. Si nous calculons une régression polynomiale d'ordre n-1. La courbe va s'adapter parfaitement à la distribution de nos observations. La valeur de R^2^ sera de 1. Ce modèle ne sera d'aucune utilité. Nous seront dans un cas de surajustement. Il ne contient plus aucune information pertinente.
248251

249-
Voici une analyse de la régression linéaire simple à la régression polynomiale d'ordre 9.
252+
Voici une analyse de la régression linéaire simple à la régression polynomiale d'ordre 9. Au lieu d'utiliser `age + I(age^2) + I(age^3) + ...`, ce qui devient rapidement fastidieux, nous utilisons ici `poly(x, n, raw = TRUE)`, avec `n`, l'ordre du polynôme (l'explication relative à `raw = TRUE` sort du cadre de ce cours, mais `raw = FALSE`, la valeur par défaut, conduit à transformer le polynôme de sorte que ses paramètres soient orthogonaux l'un à l'autre, ce qui leurs confère plus de stabilité).
250253

251254
```{r, echo=TRUE}
252-
# Création successive des modèles
253-
lm1 <- lm(data = reddrum, length ~ age)
254-
lm2 <- lm(data = reddrum, length ~ age + I(age^2))
255-
lm3 <- lm(data = reddrum, length ~ age + I(age^2) + I(age^3))
256-
lm4 <- lm(data = reddrum, length ~ age + I(age^2) + I(age^3) + I(age^4))
257-
lm5 <- lm(data = reddrum, length ~ age + I(age^2) + I(age^3) + I(age^4) + I(age^5))
258-
lm6 <- lm(data = reddrum, length ~ age + I(age^2) + I(age^3) + I(age^4) + I(age^5) + I(age^6))
259-
lm7 <- lm(data = reddrum,
260-
length ~ age + I(age^2) + I(age^3) + I(age^4) + I(age^5) + I(age^6) + I(age^7))
261-
lm8 <- lm(data = reddrum,
262-
length ~ age + I(age^2) + I(age^3) + I(age^4) + I(age^5) + I(age^6) + I(age^7) + I(age^8))
263-
lm9 <- lm(data = reddrum,
264-
length ~ age + I(age^2) + I(age^3) + I(age^4) + I(age^5) + I(age^6) + I(age^7) + I(age^8) + I(age^9))
255+
# Ajustement des différents modèles au sein d'une liste
256+
models <- list(
257+
lm1 = lm(data = reddrum, length ~ age),
258+
lm2 = lm(data = reddrum, length ~ poly(age, 2, raw = TRUE)),
259+
lm3 = lm(data = reddrum, length ~ poly(age, 3, raw = TRUE)),
260+
lm4 = lm(data = reddrum, length ~ poly(age, 4, raw = TRUE)),
261+
lm5 = lm(data = reddrum, length ~ poly(age, 5, raw = TRUE)),
262+
lm6 = lm(data = reddrum, length ~ poly(age, 6, raw = TRUE)),
263+
lm7 = lm(data = reddrum, length ~ poly(age, 7, raw = TRUE)),
264+
lm8 = lm(data = reddrum, length ~ poly(age, 8, raw = TRUE)),
265+
lm9 = lm(data = reddrum, length ~ poly(age, 9, raw = TRUE))
266+
)
265267
```
266268

267-
Nous pouvons extraire les paramètres du modèle avec la fonction glance() et le fonction rmse().
269+
Nous pouvons extraire les paramètres du modèle en utilisant `glance()` et nous utilisons `rmse()` pour calculer une métrique, **l'erreur quadratique moyenne**, qui quantifié l'ajustement du modèle.
268270

269271
```{r, echo=TRUE}
270-
# Combinaison des modèles dans un liste
271-
models <- list(lm1, lm2, lm3, lm4, lm5, lm6, lm7, lm8, lm9)
272-
names(models) <- c("lm", paste0("poly_", 2:9))
273-
274-
# Extraction en série des paramètres du modèle grâce à la fonction glance().
275-
models %>.%
276-
purrr::map_dfr(., glance) -> mod_params
272+
# Extraction en série des paramètres des modèles grâce à glance()
273+
mod_params <- purrr::map_dfr(models, glance)
274+
# Ajout de RMSE selon le même principe
277275
mod_params$rmse <- purrr::map_dbl(models, rmse, data = reddrum)
276+
# Ajout du nom des modèles
278277
mod_params$model <- names(models)
279-
278+
# Visualisation des résultats
280279
mod_params[ , c("model", "adj.r.squared", "rmse")]
281280
```
282281

283-
> Le chunk ci-dessus mérite une petite explication. Nous avons neuf modèles. Tous ces modèles sont regroupés dans une liste nommée `models`. La fonction glance() et la fonction rmse() vous permettent d'extraire les paramètres d'un modèle. Ici, nous souhaitons extraire en série ces paramètres. Les fonctions map() du package {purrr} vont exécuter une fonction à chaque élément d'une liste ou d'un vecteur. Grâce à ces fonctions, on obtient un tableau `mod_params` qui comprend tous les paramètres des neuf modèles.
282+
> Le chunk ci-dessus mérite une petite explication. Nous avons neuf modèles. Tous ces modèles sont regroupés dans une liste nommée `models`. `purrr::map()` et ses variantes `map_dfr()`, `map_dbl()` exécutent une fonction donnée en second argument sur chaque élément de la liste en premier argument, c'est-à-dire, sur chacun des neuf modèles que notre liste contient. Une liste est renvoyée, ou un data frame pour `map_dfr()`, ou un vecteur de valeurs numériques doubles pour `map_dbl()`.
284283
285-
```{r}
284+
Voici un graphique de la variation du R^2^ et de l'erreur quadratique moyenne en fonction de l'ordre du polynôme ajusté :
285+
286+
```{r, echo=TRUE}
286287
a <- chart(data = mod_params, adj.r.squared ~ model) +
287-
geom_line(group=1) +
288+
geom_line(group = 1) +
288289
geom_point()
289290
290291
b <- chart(data = mod_params, rmse ~ model) +
291-
geom_line(group=1) +
292+
geom_line(group = 1) +
292293
geom_point()
293294
294-
combine_charts(list(a,b), ncol = 1)
295+
combine_charts(list(a, b), ncol = 1)
295296
```
296297

297-
Les graphiques ci-dessus nous montrent les variations du R^2^ (A) et de l'erreur quadratique moyenne (B). On observe un gain de performance des modèles jusqu'au modèle polynomial d'ordre 5 ou 6. Ensuite, ces gains deviennent quasi nuls.
298+
Nous pouvons observer un gain de performance des modèles jusqu'au modèle polynomial d'ordre 5 ou 6. Ensuite, ces gains deviennent nuls ou quasi nuls. Ceci confirme qu'il est inutile d'augmenter l'ordre du polynôme au delà de 6 et cela valide aussi la première méthode itérative que nous avons utilisée qui consiste à s'arrêter juste avant que le paramètre du terme de plus forte puissance ne s'annule.
299+
300+
> Pour le polynôme d'ordre 2, il est intéressant de déterminer si nous pouvons laisser tomber le terme de puissance 1 et simplifier le modèle. Cela signifie alors utiliser `y = a*x^2 + b`, soit une droite dans les données après avoir élevé `x` au carré. Pour les polynômes d'ordre plus élevé, il faut considérer le modèle comme un tout. Analysez-le sur base du paramètre de puissance la plus élevée uniquement, comme nous l'avons fait ici, et n'essayer pas de simplifier si des termes intermédiaires apparaissent non significatifs.
298301
299-
**La visualisation du modèle, l'étude du résumé du modèle, l'analyse des résidus et l'étude des indicateurs de performances forment un tout. Vous devez maîtriser l'ensemble des outils pour valider la pertinence d'un modèle et ensuite comparer des modèles entre eux.**
302+
**La visualisation du modèle, l'étude du résumé du modèle, l'analyse des résidus et l'étude des indicateurs de performances forment un tout. Vous devez maîtriser l'ensemble des outils pour être capable de valider la pertinence d'un modèle et pour pouvoir comparer des modèles entre eux.**
300303

301304
## Conclusion
302305

303-
Vous venez de terminer ce tutoriel sur la régression polynomiale. La régression polynomiale d'ordre 6 nous a permis de proposer un modèle qui s'ajuste correctement à la croissance des tambours rouges. Vous devez cependant être très vigilant au surajustement.
306+
Vous venez de terminer ce tutoriel sur la régression polynomiale. La régression polynomiale d'ordre 6 nous a permis d'ajuster un modèle dans ces données malgré la forme non linéaire du nuage de points. Ce genre de modèle est utile dans un but de prédiction, mais il n'est d'aucune utilité pour aider à expliquer le mécanisme de la croissance de ce poisson. Pour cela, nous devrons nous tourner vers des modèles non linéaires spécialisés (modèles de croissance) que nous étudierons au module 5. Avec le modèle polynomial, vous devez rester très vigilant à deux aspects : le surajustement, car un polynome d'ordre suffisamment élevé peut, à la limite, passer par tous les points mais il inclut alors l'erreur de mesure ce qui est contre-productif, et (2) ne jamais faire des extrapolations lors de prédictions car la courbe polynomiale s'écarte généralement très rapidement du "vrai modèle" aux deux extrémités.
304307

305308
```{r comm_noscore, echo=FALSE}
306309
question_text(
23.4 KB
Loading

0 commit comments

Comments
 (0)