|
| 1 | +--- |
| 2 | +title: "Classification hiérarchique" |
| 3 | +author: "Guyliann Engels, Raphael Conotte & Philippe Grosjean" |
| 4 | +description: "**SDD II Module 5** Application des concepts à la classification hiérarchique." |
| 5 | +tutorial: |
| 6 | + id: "B05La_CAH" |
| 7 | + version: 2.0.0/10 |
| 8 | +output: |
| 9 | + learnr::tutorial: |
| 10 | + progressive: true |
| 11 | +runtime: shiny_prerendered |
| 12 | +--- |
| 13 | + |
| 14 | +```{r setup, include=FALSE} |
| 15 | +BioDataScience2::learnr_setup() |
| 16 | +SciViews::R() |
| 17 | +library(ade4) |
| 18 | +data("doubs") |
| 19 | +enviro <- doubs$env |
| 20 | +fish <- doubs$fish |
| 21 | +``` |
| 22 | + |
| 23 | +```{r, echo=FALSE} |
| 24 | +BioDataScience2::learnr_banner() |
| 25 | +``` |
| 26 | + |
| 27 | +```{r, context="server"} |
| 28 | +BioDataScience2::learnr_server(input, output, session) |
| 29 | +``` |
| 30 | + |
| 31 | +---- |
| 32 | + |
| 33 | +## Objectifs |
| 34 | + |
| 35 | +- Comprendre la notion de distance et la matrice de distances. |
| 36 | + |
| 37 | +- Savoir calculer des matrices de distances avec la fonction `vegdist()` |
| 38 | + |
| 39 | +- Appréhender la classification hiérarchique et le dendrogramme. |
| 40 | + |
| 41 | +- Maîtriser l'utilisation de la fonction `hclust`. |
| 42 | + |
| 43 | +- Être capable d’effectuer un regroupement pertinent des individus d’un jeu de données multivarié à l’aide de ces techniques. |
| 44 | + |
| 45 | +Vous devez avoir étudié le contenu du [module 5](https://wp.sciviews.org/sdd-umons2/?iframe=wp.sciviews.org/sdd-umons2-2020/hierarchique.html) du cours. |
| 46 | + |
| 47 | +## Abondance d'espèces de poissons |
| 48 | + |
| 49 | +Des scientifiques ont réalisé des mesures d'abondance d'espèces de poissons et des mesures physico-chimiques sur 30 stations différentes. |
| 50 | + |
| 51 | +L'objet `doubs` du package `ade4` est une liste qui contient 4 jeux de donnnées. Dans un premier temps, vous allez vous intéresser aux données sur l'abondance de 27 espèces de poissons sur les 30 sites. Ces données, présentent dans l'objet `fish`, sont présentées ci-dessous. |
| 52 | + |
| 53 | +```{r} |
| 54 | +head(fish) |
| 55 | +``` |
| 56 | + |
| 57 | +### Choix de l'indice |
| 58 | + |
| 59 | +```{r qu_indice1} |
| 60 | +question("À partir des données du tableau présenté ci-dessus, vous souhaitez réaliser un matrice de distance avec l'indice le plus adapté. Quel indice choississez vous ? (plusieurs réponses peuvent être sélectionnés)", |
| 61 | + answer("Indice de Bray-Curtis", correct = TRUE), |
| 62 | + answer("Indice de Canberra", correct = TRUE), |
| 63 | + answer("Distance Euclidienne"), |
| 64 | + answer("Indice de Manhattan"), |
| 65 | + allow_retry = TRUE, random_answer_order = TRUE) |
| 66 | +``` |
| 67 | + |
| 68 | +### Indice de Bray-Curtis |
| 69 | + |
| 70 | +A partir des données contenues dans `fish`, calculez la matrice de distances en utilisant l'indice de Bray_Curtis utilisé par défaut dans la fonction `vegdist()`. |
| 71 | + |
| 72 | +```{r bray_h2, exercise = TRUE} |
| 73 | +fish_dist <- <- ___(___) |
| 74 | +# Afficher la matrice de distances arrondie à 2 décimales |
| 75 | +___(___, ___) |
| 76 | +``` |
| 77 | + |
| 78 | +```{r bray_h2-hint-1} |
| 79 | +enviro_dist <- vegan::vegdist(DF) |
| 80 | +# Afficher la matrice de distances arrondie à 2 décimales |
| 81 | +round(OBJECT_DIST, ___) |
| 82 | +
|
| 83 | +#### ATTENTION: Hint suivant = solution !#### |
| 84 | +``` |
| 85 | + |
| 86 | +```{r bray_h2-solution} |
| 87 | +fish_dist <- vegan::vegdist(fish) |
| 88 | +# Afficher la matrice de distances arrondie à 2 décimales |
| 89 | +round(fish_dist, 2) |
| 90 | +``` |
| 91 | + |
| 92 | +```{r bray_h2-check} |
| 93 | +grade_code("Bravo ! Vous venez de réaliser votre première matrice de distances. Savez-vous qu'il existe d'autres indices ? Vous pouvez facilement changer de methode de calcul en utilisant l'argument `method =` de la fonction `vegdist()` en précisant entre guillements l'indice que vous souhaitez utiliser ("canberra" pour l'indice de Canberra, "euclidean" pour la distance Euclidienne et "manhattan" pour la distance de Manhattan.)") |
| 94 | +``` |
| 95 | + |
| 96 | +### Indice de Canberra |
| 97 | + |
| 98 | +A partir des données contenues dans `fish`, calculez la matrice de distances en utilisant l'indice de Canberra pour l'argument `method =` dans la fonction `vegdist()`. |
| 99 | + |
| 100 | +```{r canberra_h2, exercise = TRUE} |
| 101 | +fish_dist <- <- ___(___, ___) |
| 102 | +# Afficher la matrice de distances arrondie à 2 décimales |
| 103 | +___(___, ___) |
| 104 | +``` |
| 105 | + |
| 106 | +```{r canberra_h2-hint-1} |
| 107 | +enviro_dist <- vegan::vegdist(DF, method = ___) |
| 108 | +# Afficher la matrice de distances arrondie à 2 décimales |
| 109 | +round(OBJECT_DIST, ___) |
| 110 | +
|
| 111 | +#### ATTENTION: Hint suivant = solution !#### |
| 112 | +``` |
| 113 | + |
| 114 | +```{r canberra_h2-solution} |
| 115 | +fish_dist <- vegan::vegdist(fish, method = "canberra") |
| 116 | +# Afficher la matrice de distances arrondie à 2 décimales |
| 117 | +round(fish_dist, 2) |
| 118 | +``` |
| 119 | + |
| 120 | +```{r canberra_h2-check} |
| 121 | +grade_code("Facile non ! Notez aussi que les matrices de distances ne sont pas prévues pour être imprimées et visualisées telles quelles. Ils constituent la première étape vers une représentation utile à l’aide de la classification hiérarchisée. Réprésentation qui sera abordée un peu plus loin dans ce learnr !") |
| 122 | +``` |
| 123 | + |
| 124 | +## Données environnementales |
| 125 | + |
| 126 | +En plus des données sur l'abondance de 27 espèces de poisson, l'objet `doubs` du package `ade4` contient également les données portant sur les mesures environnementales. Le tableau présenté ci-dessous comprend 30 sites d'échantillonages avec 11 mesures environnementales. |
| 127 | + |
| 128 | +Voici une courte description des variables étudiées (en anglais). Ces informations proviennent de la page d'aide `?ade4::doubs` |
| 129 | + |
| 130 | +- dfs : distance from the source (km * 10), |
| 131 | +- alt : altitude (m), |
| 132 | +- slo : (log(x + 1) where x is the slope (per mil * 100), |
| 133 | +- flo : minimum average stream flow (m3/s * 100), |
| 134 | +- pH : pH, |
| 135 | +- har : total hardness of water (mg/l of Calcium), |
| 136 | +- pho : phosphates (mg/l * 100), |
| 137 | +- nit : nitrates (mg/l * 100), |
| 138 | +- amm : ammonia nitrogen (mg/l * 100), |
| 139 | +- oxy : dissolved oxygen (mg/l * 10), |
| 140 | +- bdo : biological demand for oxygen (mg/l * 10) |
| 141 | + |
| 142 | +```{r} |
| 143 | +head(enviro) |
| 144 | +``` |
| 145 | + |
| 146 | +### Choix de l'indice |
| 147 | + |
| 148 | +```{r qu_indice2} |
| 149 | +question("Vous souhaitez réaliser un matrice de distances sur les données présentent dans ce tableau. Quels sont les indices le plus adapté.?", |
| 150 | + answer("Indice de Bray-Curtis"), |
| 151 | + answer("Indice de Canberra"), |
| 152 | + answer("Distance Euclidienne", correct = TRUE), |
| 153 | + answer("Indice de Manhattan", correct = TRUE), |
| 154 | + allow_retry = TRUE, random_answer_order = TRUE) |
| 155 | +``` |
| 156 | + |
| 157 | +### Distance Euclidienne 1 |
| 158 | + |
| 159 | +A partir des données contenues dans `enviro`, calculez la matrice de distances en utilisant la distance Euclidienne. |
| 160 | + |
| 161 | +```{r euclidean1_h2, exercise = TRUE} |
| 162 | +enviro_dist <- ___(___, ___) |
| 163 | +# Afficher la matrice de distances arrondies à 2 décimales |
| 164 | +___(___, ___) |
| 165 | +``` |
| 166 | + |
| 167 | +```{r euclidean1_h2-hint-1} |
| 168 | +enviro_dist <- vegan::vegdist(DF, method = ___) |
| 169 | +# Afficher la matrice de distance arrondies à 2 décimales |
| 170 | +round(OBJECT_DIST, ___) |
| 171 | +
|
| 172 | +#### ATTENTION: Hint suivant = solution !#### |
| 173 | +``` |
| 174 | + |
| 175 | +```{r euclidean1_h2-solution} |
| 176 | +enviro_dist <- vegan::vegdist(enviro, method = "euclidean") |
| 177 | +# Afficher la matrice de distance arrondies à 2 décimales |
| 178 | +round(enviro_dist, 2) |
| 179 | +``` |
| 180 | + |
| 181 | +```{r euclidean1_h2-check} |
| 182 | +grade_code("Très bien ! Mais les unités respectives de vos variables n'ont pas été considérées. L'altidude en (m) ou la concentration en nitrates (mg/l * 100), par exemple, ne sont pas mesurées dans les mêmes unités. Le risque est alors de donner plus de poids aux valeurs élevées. Il est donc préférable de commencer par standardiser le tableau (moyenne de zéro et écart type de un) selon les colonnes avant d’effectuer le calcul. La fonction `scale()` permet de le faire et c'est ce que vous allez réaliser dans l'exercice suivant.") |
| 183 | +``` |
| 184 | + |
| 185 | +### Distance Euclidienne 2 |
| 186 | + |
| 187 | +Calculez une nouvelle matrice de distances, mais cette fois après avoir standardisé les données avec la fonction `scale()`. Convertisser ensuite la matrice obtenue avec la fonction `as_tibble()` avant de procéder au calcul de la matrice de distances en utilisant la distance Euclidienne. |
| 188 | + |
| 189 | +```{r euclidean2_h2, exercise = TRUE} |
| 190 | +___%>.% |
| 191 | + # Standardisation des 11 colonnes |
| 192 | + ___(___) %>.% |
| 193 | + # Conversion de la matrice en data.frame + tibble |
| 194 | + ___(___) %>.% |
| 195 | + # Calcul de la matrice de distances |
| 196 | + ___(___, ___) -> enviro_dist |
| 197 | +# Afficher la matrice de distance arrondies à 2 décimales |
| 198 | +___(___, ___) |
| 199 | +``` |
| 200 | + |
| 201 | +```{r euclidean2_h2-hint-1} |
| 202 | +DF %>.% |
| 203 | + # Standardisation des 11 colonnes |
| 204 | + scale(___) %>.% |
| 205 | + # Conversion de la matrice en data.frame + tibble |
| 206 | + as_tibble(___) %>.% |
| 207 | + # Calcul de la matrice de distances |
| 208 | + vegan::___(___, method = ___) -> enviro_dist |
| 209 | +# Afficher la matrice de distances arrondie à 2 décimales |
| 210 | +round(OBJECT_DIST, ___) |
| 211 | +
|
| 212 | +#### ATTENTION: Hint suivant = solution !#### |
| 213 | +``` |
| 214 | + |
| 215 | +```{r euclidean2_h2-solution} |
| 216 | +enviro %>.% |
| 217 | + # Standardisation des 11 colonnes |
| 218 | + scale(.) %>.% |
| 219 | + # Conversion de la matrice en data.frame + tibble |
| 220 | + as_tibble(.) %>.% |
| 221 | + # Calcul de la matrice de distances |
| 222 | + vegan::vegdist(., method = "euclidean") -> enviro_dist |
| 223 | +# Afficher la matrice de distances arrondie à 2 décimales |
| 224 | +round(enviro_dist, 2) |
| 225 | +``` |
| 226 | + |
| 227 | +```{r euclidean2_h2-check} |
| 228 | +grade_code("Félicitiation, vous gérez vraiment bien les matrices de distances. Vous pourriez aussi essayer une autre méthode sur ces données standardisées comme la distance de Manhattan en utilisant `method = "manhattan"`.") |
| 229 | +``` |
| 230 | + |
| 231 | +## Classification hiérarchique |
| 232 | + |
| 233 | +Maintenant que vous maitrisez le calcule des matrices de distances, vous pouvez obtenir facilement une matrice de distances entre toutes les paires de stations présentent dans le jeu de données `enviro`. Vous pouvez dès lors essayer de les regrouper en fonction de leur ressemblance. |
| 234 | +Vous allez maintenant apprendre à représenter graphiquement ces regroupements en utilisant un **dendrogramme**. |
| 235 | + |
| 236 | +```{r hac_prep} |
| 237 | +enviro %>.% |
| 238 | + scale(.) %>.% |
| 239 | + as_tibble(.) %>.% |
| 240 | + vegan::vegdist(., method = "euclidean") -> enviro_dist |
| 241 | +``` |
| 242 | + |
| 243 | +### Dendrogramme 1 |
| 244 | + |
| 245 | +Commencez par calculer le dendgrogramme à l'aide de la fonction `hclust()` et de la matrice de distance `enviro_dist` que vous avez à disposition et qui correspond à la matrice calculée dans l'exercice précédant. |
| 246 | + |
| 247 | +Utiliser ensuite la fonction `plot()` pour tracer le dendrogramme. |
| 248 | + |
| 249 | +```{r hclust1_h2, exercise = TRUE, exercise.setup = "hac_prep"} |
| 250 | +enviro_clust <- ___(___) |
| 251 | +___(___) |
| 252 | +``` |
| 253 | + |
| 254 | +```{r hclust1_h2-hint-1} |
| 255 | +enviro_clust <- hclust(___) |
| 256 | +plot(___) |
| 257 | +
|
| 258 | +#### ATTENTION: Hint suivant = solution !#### |
| 259 | +``` |
| 260 | + |
| 261 | +```{r hclust1_h2-solution} |
| 262 | +enviro_clust <- hclust(enviro_dist) |
| 263 | +plot(enviro_clust) |
| 264 | +``` |
| 265 | + |
| 266 | +```{r hclust1_h2-check} |
| 267 | +grade_code("Félicitation ! Vous venez de réaliser votre premier dendrogramme. Savez-vous qu'il existe plusieurs stratégies possibles pour comparer les distances ? Utiliser l'argument `method =` de la fonction `hclust()` pour changer de méthode. Par défaut, c'est la méthode des liens complets qui est utilisée `method = "complete"`.") |
| 268 | +``` |
| 269 | + |
| 270 | +### Dendrogramme 2 |
| 271 | + |
| 272 | +Réalisez un nouveau dendrogramme à partir de l'objet `enviro_dist` mais cette fois, utilisez la méthode de Ward `method = "ward.D2"` dans la fonction `hclust()`. |
| 273 | + |
| 274 | +Utilisez la fonction `ggdendro::ggdendrogram()` pour visualiser le dendrogramme. |
| 275 | + |
| 276 | +```{r hclust2_h2, exercise = TRUE, exercise.setup = "hac_prep"} |
| 277 | +enviro_clust <- ___(___, ___) |
| 278 | +___(___) |
| 279 | +``` |
| 280 | + |
| 281 | +```{r hclust2_h2-hint-1} |
| 282 | +enviro_clust <- hclust(___, method = ___) |
| 283 | +ggdendro::ggdendrogram(___) |
| 284 | +
|
| 285 | +#### ATTENTION: Hint suivant = solution !#### |
| 286 | +``` |
| 287 | + |
| 288 | +```{r hclust2_h2-solution} |
| 289 | +enviro_clust <- hclust(enviro_dist, method = "ward.D2") |
| 290 | +ggdendro::ggdendrogram(enviro_clust) |
| 291 | +``` |
| 292 | + |
| 293 | +```{r hclust2_h2-check} |
| 294 | +grade_code("Très bien ! Regardez comme cette technique vous a permis d'obtenir des groupess bien individualisés. Il existe bien d'autres méthodes que vous pouvez utilser pour calculer votre dendrogramme. Utiliser l'aide de la fonction `hclust()` pour voir comment les renseigner dans l'argument `method = `.") |
| 295 | +``` |
| 296 | + |
| 297 | +### Dendrogramme 3 |
| 298 | + |
| 299 | +```{r group_prep} |
| 300 | +enviro %>.% |
| 301 | + scale(.) %>.% |
| 302 | + as_tibble(.) %>.% |
| 303 | + vegan::vegdist(., method = "euclidean") -> enviro_dist |
| 304 | +enviro_clust <- hclust(enviro_dist, method = "ward.D2") |
| 305 | +``` |
| 306 | + |
| 307 | +Réprésentez avec la fonction `plot()` le dendrogramme que vous venez de calculer dans l'exercice précédant. Matérialisez ensuite sur ce graphique une coupure en traçant un trait horizontal rouge avec la fonction `abline()` à une hauteur de 8. Vous avez à disposition l'objet `enviro_clust`. |
| 308 | + |
| 309 | +```{r hclust3_h2, exercise = TRUE, exercise.setup = "group_prep"} |
| 310 | +___(___) |
| 311 | +___(___,___) |
| 312 | +``` |
| 313 | + |
| 314 | +```{r hclust3_h2-hint} |
| 315 | +___(OBJET_CLUST) |
| 316 | +abline(h = ___, col = ___) |
| 317 | +``` |
| 318 | + |
| 319 | +```{r hclust3_h2-solution} |
| 320 | +plot(enviro_clust) |
| 321 | +abline(h = 8, col = "red") |
| 322 | +``` |
| 323 | + |
| 324 | +```{r hclust3_h2-check} |
| 325 | +grade_code("Bravo. Une coupure à ce niveau permet de former 4 groupes.") |
| 326 | +``` |
| 327 | + |
| 328 | +### Dendrogramme 4 |
| 329 | + |
| 330 | +Utilisez la fonction `cutree()` l'objet `enviro_clust`. Cela vous permettra d'obtenir pour chacunes des stations le numéros du groupe dans lequelle elle se trouve dans l'ordre de notre tableau de donnée. |
| 331 | + |
| 332 | +Ajoutez ces regroupements dans le tableau `enviro` en les transformant en facteur avec la fonction `as.factor()`. |
| 333 | + |
| 334 | +Terminez en réalisant, un graphique en nuage de points de l'altidude (`alt`) en fonction de la distance de la source (`dfs`) en utilisant la variable groupe que vous venez de créer pour la couleur. |
| 335 | + |
| 336 | +```{r hclust4_h2, exercise = TRUE, exercise.setup = "group_prep"} |
| 337 | +group <- ___(___, ___) |
| 338 | +enviro$group <- ___(___) |
| 339 | +chart(___, ___ ~ ___ ) + |
| 340 | + ___() |
| 341 | +``` |
| 342 | + |
| 343 | +```{r hclust4_h2-hint-1} |
| 344 | +group <- cutree(OBJET_CLUST, h = ___) |
| 345 | +enviro$group <- as.factor(___) |
| 346 | +chart(data = DF, VARNUM ~ VARNUM %col=% ___) + |
| 347 | + geom_point() |
| 348 | +``` |
| 349 | + |
| 350 | +```{r hclust4_h2-solution} |
| 351 | +group <- cutree(enviro_clust, h = 8) |
| 352 | +enviro$group <- as.factor(group) |
| 353 | +chart(data = enviro, alt ~ dfs %col=% group) + |
| 354 | + geom_point() |
| 355 | +``` |
| 356 | + |
| 357 | +```{r hclust4_h2-check} |
| 358 | +grade_code("Félicitation ! Vous venez de réaliser une étude complète en utilisant la **classification ascendante hiérarchique**. ") |
| 359 | +``` |
| 360 | + |
| 361 | +## Conclusion |
| 362 | + |
| 363 | +Bravo ! Vous venez de terminer votre auto-évaluation relative aux matrices de distances et à la classification hiérarchique. |
| 364 | + |
| 365 | +```{r comm_noscore, echo=FALSE} |
| 366 | +question_text( |
| 367 | + "Laissez-nous vos impressions sur cet outil pédagogique", |
| 368 | + answer("", TRUE, message = "Pas de commentaires... C'est bien aussi."), |
| 369 | + incorrect = "Vos commentaires sont enregistrés.", |
| 370 | + placeholder = "Entrez vos commentaires ici...", |
| 371 | + allow_retry = TRUE |
| 372 | +) |
| 373 | +``` |
0 commit comments