TIG’R
  • Introduction
  • Modules
  • Données
  • Ressources
  • Crédits
  1. Statistique
  2. Classif. Asc. Hiérarch.
  • Introduction

  • Import de données
    • Toutes les leçons
    • Import & export
    • Web Scraping
  • Manipulation
    • Toutes les leçons
    • Manipulation de tableau
    • L’écosystème tidyverse
  • Statistique
    • Toutes les leçons
    • Statistique Descriptive
    • Classif. Asc. Hiérarch.
  • Graphique
    • Toutes les leçons
    • Graphique R-base
    • Le package ggplot2
    • ggplot2 et la grammaire graphique
  • Réseau
    • Réseau avec igraph
  • Géomatique
    • Toutes les leçons
    • Données vectorielles
    • Données Raster
    • OpenStreetMap & R
  • Cartographie
    • Cartographie mapsf
  • Reproductibilité
    • Toutes les leçons
    • Le package miniCRAN
    • PL et Notebook (Rmd)
    • PL et Notebook (Quarto)

  • Données utilisées
  • Ressources annexes

Sur cette page

  • Introduction
    • Préparation des données
  • 1. Matrice de distance
  • 2. Regroupement Hiérarchique
  • 3. Partitionnement
  • 4. Caractérisation & représentation
    • Profil des classes
    • Cartographie
  • Exercice

Classification Ascendante Hiérarchique

  • Montrer tout le code
  • Cacher tout le code

  • Voir les sources

Construire une CAH avec des fonctions R-base

Auteur·rice·s

Hugues pecout

Justin Dansou

Date de publication

30 octobre 2023

Introduction

La Classification Ascendante Hiérarchique (CAH) est l’une des techniques statistiques les plus utilisées pour segmenter une population en différentes classes ou sous-groupes. Son objectif est de regrouper les individus similaires tout en maintenant une grande dissimilarité entre ces classes.

Le principe de la CAH se déroule en trois étapes :

  1. Calcul d’une matrice de distances qui mesure la distance entre chaque paire d’individus. Lorsque deux observations sont identiques, leur distance est nulle. Plus les observations sont différentes, plus la distance est grande.

  2. Regroupement hiérarchique des individus par itération. Cette classification est ascendante car elle part des observations individuelles. Elle est hiérarchique car elle engendre des classes ou groupes de plus en plus larges (incluant des sous-groupes en leur sein) en fonction des distances calculée entre les individus.

  3. Découpage du dendrogramme (ou arbre de classification) à une certaine hauteur pour obtenir la partition souhaitée.


Préparation des données

Pour ce cours nous utiliserons les données DEV_AFRICA_2018.

data <- read.csv2(file = "data/DEV_AFRICA_2018/afrika_don.csv")

Pour réaliser une CAH, il est nécessaire de préparer le tableau de données. Commencez par séléctionner uniquement les variables qui vous souhaitez utiliser.

# Liste des variable à supprimer
var_to_del <- c("iso3", "name", "nom", "SUBREG")

# Supression des variables
data_clean <- data[,!names(data) %in% var_to_del]

Afin de pouvoir manipuler correctement des données qualitatives, convertissez-les en facteur.

liste_var_quali <-  c("LOCKED", "COLFRA", "COLGBR", "LANGFR", "LANGEN")

# Transformation des variables qualitatives en `factor`
data_clean[,liste_var_quali] <- data.frame(lapply(data_clean[,liste_var_quali], factor))

Il est indispensable de bien nommer les lignes du tableau afin d’identifier facilement les individus.

# Utilisation du code ISO des pays en nom de lignes
row.names(data_clean) <- data[,"iso3"] 

Tableau de données préparé pour la CAH :

POP PIB IDH ADOFEC CO2HAB EMPAGR EMPSER INTERN ESPVIE AGEMED TELMOB MORINF TXMIGR DVIEUX TUBERC URBANI DJEUNE LOCKED COLFRA COLGBR LANGFR LANGEN
AGO 31.317543 6793.7085 0.5815 152.635250 1.1209815 50.4490 41.3865 14.33910 60.9660 16.677 43.1305 51.58504 0.211 4.3225 355 65.85 91.4625 0 0 0 0 0
BDI 11.352978 756.5941 0.4320 56.227500 0.0466776 92.0170 6.4980 2.66075 61.4135 17.320 56.5347 40.99260 0.181 4.3610 111 13.20 86.9555 1 0 0 1 0
BEN 11.643093 3224.0433 0.5430 87.379625 0.6224791 38.9125 42.1465 20.00000 61.6200 18.781 82.3843 60.53574 -0.176 5.9895 56 47.60 77.7865 0 1 0 1 0
BFA 20.036424 2160.5895 0.4475 105.713875 0.1973980 25.5640 40.8700 16.00000 61.3770 17.551 97.9123 49.00709 -1.282 4.5605 48 29.70 84.9065 1 1 0 1 0
BWA 2.278885 17700.3152 0.7325 46.322125 2.9573642 20.8570 61.0040 47.00000 69.4325 24.044 150.0060 29.98541 1.341 6.9540 275 69.80 54.9450 1 0 1 0 1
CAF 4.705777 938.9888 0.3960 130.247875 0.0650827 77.4450 17.1505 4.33925 53.0425 17.611 27.6743 84.46370 -8.581 5.3140 540 41.60 83.1095 1 1 0 1 0
CIV 25.392890 5133.5905 0.5360 118.475250 0.3346972 40.4840 46.5020 46.82370 57.6010 18.854 134.8580 59.40349 -0.323 5.1820 142 51.00 75.6240 0 1 0 1 0
CMR 25.546324 3628.1177 0.5615 107.694875 0.3226965 43.7520 41.3510 23.20300 59.1055 18.688 69.0854 50.55533 -0.193 4.9770 186 56.70 77.5825 0 1 0 1 1
COD 85.429330 1091.9213 0.4790 124.860500 0.0242292 65.6135 24.6615 8.61990 60.5240 16.988 43.3822 68.18008 0.288 5.9285 321 44.75 90.5395 0 0 0 1 0
COG 5.312434 3356.2418 0.5735 112.993625 0.6161096 34.3665 43.7460 8.65000 64.4300 19.204 95.3405 36.18735 -0.771 4.8545 375 67.15 74.8465 0 1 0 1 0
DJI 0.966240 5366.7107 0.5210 19.199875 0.6717953 33.5180 53.5140 55.68140 66.8460 26.570 41.1959 49.80543 0.947 6.9175 260 77.85 44.5025 0 1 0 1 0
DZA 42.640735 11414.5995 0.7470 10.256625 3.6876905 9.9395 59.2890 59.57970 76.7865 28.521 121.9320 20.14982 -0.239 10.2195 69 72.90 48.0295 0 1 0 1 0
EGY 99.405839 11564.7950 0.7040 54.061500 2.4264069 24.0700 48.5100 46.92430 71.9075 24.606 95.2866 18.10248 -0.391 8.6215 12 42.70 55.5010 0 0 1 0 0
ERI 3.474957 NA 0.4575 53.523500 0.2143515 61.4155 30.1295 1.30891 66.1305 19.209 20.3640 31.34800 -11.571 8.3650 89 40.40 77.5595 0 0 1 0 1
ETH 110.651568 2161.6109 0.4815 68.133375 0.1367414 66.4175 23.4770 18.61810 66.4200 19.466 36.2007 39.14908 0.278 6.2735 151 21.00 72.5195 1 0 0 0 1
GAB 2.145926 14806.5905 0.7000 97.469375 2.5283647 33.0875 56.1695 62.00000 66.3285 22.511 138.2810 32.69746 1.562 5.9895 525 89.55 62.5225 0 1 0 1 0
GHA 30.092483 5303.5336 0.6085 67.256625 0.6147189 29.8490 48.7120 39.00000 63.9250 21.507 137.5170 34.91044 -0.339 5.1870 148 56.40 63.0600 0 0 1 0 1
GIN 12.592769 2531.2341 0.4750 136.616375 0.2561000 62.0070 31.8645 18.00000 61.3925 18.020 96.1150 64.93173 -0.326 5.4930 176 36.30 81.7180 0 1 0 1 0
GMB 2.313894 2175.5690 0.4915 79.773500 0.2678091 27.4370 56.9305 19.83650 61.8925 17.844 139.5290 39.03308 -1.371 4.8385 174 61.60 83.0380 0 0 1 0 1
GNB 1.897611 1969.2724 0.4760 105.195125 0.1811767 68.3180 24.6825 3.93051 58.1615 18.833 78.9889 54.01618 -0.755 5.1780 361 43.60 76.9380 0 0 0 0 0
GNQ 1.332474 19458.9245 0.5870 157.016250 4.3449264 42.2215 38.3485 26.24000 58.5710 22.335 45.1669 62.62024 12.443 4.0325 201 72.35 61.1900 0 0 0 1 0
KEN 51.983269 4266.8368 0.6000 76.462375 0.3597057 54.7625 37.9840 17.82710 66.5210 20.119 96.3202 30.62253 -0.197 4.0970 292 27.25 67.9330 0 0 1 0 1
LBR 4.878175 1462.4118 0.4800 136.347000 0.3234092 43.3515 46.3395 7.98448 63.9150 19.411 56.5690 53.48219 -1.049 5.8600 308 51.40 73.3800 0 1 0 0 1
LBY 6.728009 15096.0769 0.7225 5.813500 8.0879274 18.6690 58.9090 21.75890 72.8170 28.817 91.4793 10.24269 -0.301 6.5675 40 80.25 41.8425 0 0 0 0 0
LSO 2.116797 2758.1290 0.5245 92.261750 1.2613313 8.6585 49.0890 29.00000 54.0175 24.010 113.8310 65.66614 -4.783 7.8615 611 28.40 52.1515 1 0 1 0 1
MAR 36.250428 7476.1792 0.6830 31.357000 1.8404515 34.9720 43.3205 64.80390 76.5665 29.538 124.1720 19.22586 -1.437 10.8840 99 62.75 41.1950 0 1 0 1 0
MDG 26.615810 1629.6623 0.5275 110.895250 0.1630207 64.4480 26.6110 9.80000 66.8605 19.568 40.5703 38.18323 -0.058 5.3400 233 37.55 71.7550 0 1 0 1 0
MLI 19.367889 2305.2361 0.4325 170.349250 0.1866153 62.7985 29.5865 13.00000 59.1015 16.347 115.0850 61.96196 -2.123 4.9950 53 42.75 94.7075 1 1 0 1 0
MOZ 29.931026 1284.9965 0.4540 149.940875 0.2809194 70.4610 21.1085 10.00000 60.5065 17.620 47.7158 54.01829 -0.172 5.4845 551 36.25 84.6455 0 0 0 0 0
MRT 4.464505 5119.7260 0.5440 72.045000 0.6044313 51.6650 35.5065 20.80100 64.8170 20.114 103.7060 51.54291 1.150 5.5370 93 54.10 70.3175 0 1 0 0 0
MWI 18.385982 1051.1249 0.4805 134.117500 0.0761111 43.8895 42.2905 13.78220 64.0290 18.080 39.0058 35.31582 -0.895 4.9260 181 17.05 81.3985 1 0 1 0 1
NAM 2.471412 9784.5769 0.6455 65.546375 1.7450469 22.3620 61.3915 51.00000 63.5415 21.832 112.7020 28.96725 -1.979 6.0905 524 50.50 62.0615 0 0 0 0 1
NER 22.876775 1207.7762 0.3925 188.313625 0.1033337 75.1875 17.6130 5.25049 62.2220 15.151 40.6385 47.98493 0.181 5.4660 87 16.45 105.1010 1 1 0 1 0
NGA 198.419144 5145.2871 0.5365 108.545000 0.6498757 35.3355 52.4380 42.00000 54.5110 18.064 88.1842 75.67151 -0.310 5.1335 219 50.75 81.8610 0 0 1 0 1
RWA 12.464453 2157.3935 0.5415 39.292875 0.0912374 62.8260 28.3825 21.76760 68.8600 20.039 78.8541 27.02078 -0.740 5.2205 59 17.25 69.7705 1 0 0 1 1
SDN 42.307384 4059.5331 0.5080 65.994875 0.5034768 40.0230 43.4995 30.87030 65.2025 19.659 72.0079 42.14203 -1.208 6.4285 71 34.75 71.9420 0 0 1 0 0
SSD 11.019019 NA 0.4310 64.044250 0.1704093 57.2935 28.9535 7.97743 57.7270 19.040 33.4630 63.69163 -15.902 6.1685 146 19.75 75.9210 1 0 1 0 0
SEN 16.075343 3354.8272 0.5140 74.084500 0.7386566 30.3755 56.1710 46.00000 67.8025 18.514 104.4510 31.82667 -1.277 5.7315 118 47.45 79.5920 0 1 0 1 0
SLE 7.731678 1690.8316 0.4495 114.548500 0.1409384 55.2475 38.3540 9.00000 54.5045 19.402 88.4699 78.47719 -0.554 5.2665 298 42.30 72.8270 0 0 1 0 1
SOM 15.225566 NA NA 101.371375 0.0465698 83.1580 13.2430 2.00405 57.2340 16.683 48.7964 76.57223 -2.694 5.6895 262 45.30 91.7805 0 0 1 0 1
SWZ 1.142203 8647.0887 0.6080 77.084375 1.0549327 12.5695 63.5180 47.00000 59.7955 20.729 93.5273 43.02284 -7.378 6.9180 329 23.90 65.4575 1 0 1 0 1
TCD 15.712305 1577.9727 0.3975 163.231250 0.0655329 76.6500 21.2380 6.50000 54.1085 16.554 45.1237 71.42419 0.131 4.9190 142 23.20 92.9445 1 1 0 1 0
TGO 7.985727 1574.2385 0.5125 89.421750 0.4332564 37.9915 49.1365 12.36020 60.9000 19.350 77.8861 47.36163 -0.256 5.1440 36 41.95 73.5720 0 1 0 1 0
TUN 11.629962 10759.6827 0.7390 7.809625 2.7303114 13.1830 54.1790 64.19080 76.6025 32.835 127.7070 14.60544 -0.348 12.5545 35 69.10 35.9300 0 1 0 1 0
TZA 57.159453 2625.1980 0.5265 118.981875 0.2219524 65.5295 27.7440 25.00000 65.2375 17.992 77.2414 37.60541 -0.721 4.8875 253 34.15 82.3155 0 0 1 0 1
UGA 43.499310 2151.6788 0.5410 120.467500 0.1350604 72.7705 20.6300 23.70650 63.1715 16.733 57.2726 33.80762 4.018 3.8020 200 24.10 91.0075 1 0 1 0 1
ZAF 58.175393 12556.2802 0.7080 68.416500 8.0903570 5.1275 71.8460 56.16740 63.9935 27.621 153.2500 28.49095 2.536 8.1795 520 66.65 44.2375 0 0 1 0 1
ZMB 17.606374 3500.5119 0.5830 122.185000 0.3012960 49.0500 40.0920 14.30000 63.7000 17.592 89.1570 40.44662 -0.467 3.9620 346 43.80 84.0360 1 0 1 0 1
ZWE 14.542143 2982.9890 0.5700 88.973500 0.8492879 66.4255 26.8395 27.05550 61.3425 18.668 89.4049 33.90040 -8.150 5.4055 210 32.20 77.2085 1 0 1 0 1


1. Matrice de distance

La ressemblance des individus est évaluée par la distance mathématique entre chaque observation. Plusieurs distances peuvent être calculées en fonction du type de données utilisées. Voici quelques exemples :

Calcul d’une matrice de distance pour des variables quantitatives.

La fonction dist() permet dans calculer plusieurs distances mathématiques (euclidiennes, Maximum, Manhattan, Canberra…) pour les variables quantitatives

# Sélection des variables quantitatives
var_quanti <- data_clean[,c(1:17)] 

# Calcul de la matrice de distances (euclidienne)
md_eucli <- dist(var_quanti, method = "euclidean")

Calcul d’une matrice de distance pour des variables qualitatives.

Pour des variables qualitatives, une matrice de distances du χ² peut-être obtenue par l’intermédiaire d’une Analyse à Correspondance Multiple (ACM) avec la fonction dudi.acm(), puis de la la fonction dist.dudi() du package ade4.

La distance utilisée dans les analyses de correspondance multiples (ACM) est une variante de la distance du χ².

# Sélection des variables qualitatives
var_quali <- data_clean[,c(18:22)] 

library (ade4)
# Calcul ACM
acm <- dudi.acm(var_quali, scannf = FALSE, nf = 5)

# Calcul matrice distance du χ²
md_chi2 <- dist.dudi(acm)

Calcul d’une matrice de distance pour des variables qualitatives et quantitatives.

La distance de Gower peut être utilisée pour un ensemble de variables qualitatives et quantitatives. Pour cela, vous pouvez utilisez la fionction daisy() du package cluster.

library(cluster)
md_gower <- daisy(data_clean, metric = "gower")


2. Regroupement Hiérarchique

Il faut ensuite choisir une méthode d’agrégation pour construire le dendrogramme. De nombreuses solutions existent (single linkage, average linkage, ward linkage…). Les différentes méthodes de regroupement hiérarchique utilisent des critères différents pour évaluer la distance entre les groupes et peuvent donner des résultats (dendogramme) légèrement différents en termes de structure des clusters formés.

Par exemple, la méthode complete linkage (liaison complète) est une des techniques couramment utilisées pour réaliser le regroupement hiérarchique lors de la CAH. Cette méthode consiste à calculer la distance entre deux groupes de données en se basant sur les distances maximales entre tous les points des deux groupes. Concrètement, lors du regroupement hiérarchique, la distance entre deux groupes est déterminée en trouvant la distance maximale entre les points de chaque groupe. Ainsi, la distance entre deux groupes est définie par la paire d’observations qui sont les plus éloignées l’une de l’autre parmi toutes les paires possibles d’observations entre les deux groupes. Cette approche est souvent utilisée lorsque l’on souhaite privilégier la formation de clusters compacts et bien séparés les uns des autres, car la distance choisie est la plus grande possible entre les groupes. Elle peut être utile lorsque l’on s’intéresse à des sous-groupes distincts et bien définis dans les données.

La fonction R-base pour le calcul d’un dendrogramme à partir d’une matrice de distances est hclust(). La méthode d’aggrégation souhaitée peut être précisé avec l’argument method. Quelques exemple d’application :

  • Variables quantitatives
  • Variables qualitatives
  • Toutes les variables (quantitatives et qualitatives)

Aggrégation des individus par la méthode de Ward appliquée au carré des distances (“ward.D2”)

hc_eucli_ward2 <- hclust(md_eucli, method = "ward.D2")

Visualisation du dendogramme (arbre de classification) avec la fonction plot().

plot(hc_eucli_ward2, main = "Distance euclidienne + Méthode de Ward2")

Aggrégation des individus par la méthode de liason complète (“complete”)

hc_chi2_complete <- hclust(md_chi2, method = "complete")

Visualisation du dendogramme (arbre de classification) avec la fonction plot().

plot(hc_chi2_complete, main = "Distance chi2 + Méthode de liasion complète")

Aggrégation des individus par la méthode de liason moyenne (“average”)

hc_gower_average <- hclust(md_gower, method = "average")

Visualisation du dendogramme (arbre de classification) avec la fonction plot().

plot(hc_gower_average, main = "Distance de Gower + Méthode de liaison moyenne")

Important

En fonction de vos données et de vos objectifs, vous pouvez réaliser plusieurs dendrogramme différents jusqu’à obtenir une classification qui fait « sens ».


3. Partitionnement

Il ne reste plus qu’à découper le dendrogramme obtenu à une certaine hauteur pour obtenir une partition des individus. La qualité d’une partition se traduit mathématiquement par une petite variabilité intra-classe et une grande variabilité inter-classes. La forme et les sauts d’inertie du dendogramme permettent d’apprécier l’évolution de ces variabilités en fonction du nombre de partitions. Par exemple :

  • Forme de l’arbre
  • Sauts d’inertie

L’analyse de la forme du dendogramme fournit des indications sur le nombre de classes à retenir. Deux branches bien distinctes apparaissent sur l’arbre. Ces deux branches se subdivisent ensuite en 4 sous-groupes. Les partitions suivantes semblent beaucoup moins marquées.

L’inertie de l’arbre renvoyée par la fonction hclust() est l’inertie inter-classe qui traduit la séparation et la compacité des classes. Elle est calculée à partir des distances entre les centres des classes formés à chaque étape du regroupement. Une inertie inter-classe élevée indique que les clusters sont bien séparés, ce qui est généralement considéré comme souhaitable lors de la formation de groupes homogènes. En visualisant l’évolution de l’inertie selon le nombre de classes, on peut ainsi évaluer la qualité de la partition et choisir le nombre optimal de classes pour créer des groupes homogènes et bien distincts.

L’inertie du dendogramme est stockée dans l’élément height d’un objet hclust. Il est facile de représenter les sauts d’inertie avec la fonction plot().

# Récupération et tri croissant de l'inertie de chaque partition
inertie <- sort(hc_eucli_ward2$height, decreasing = TRUE)

# Représentation graphique de l'inertie en fonction du nombre de classe
plot(inertie[1:13], type = "s", xlab = "Nombre de classes", ylab = "Inertie")

La fonction rect.hclust() permet de visualiser les différentes partitions directement sur le dendrogramme.

plot(hc_eucli_ward2, main = "Distance euclidienne + Méthode de Ward2")
rect.hclust(hc_eucli_ward2, 2, border = "green4") # Partition en 2 classes
rect.hclust(hc_eucli_ward2, 3, border = "blue4") # Partition en 3 classes
rect.hclust(hc_eucli_ward2, 4, border = "red4") # Partition en 4 classes

La fonction cutree() permet de récupérer la partition des individus suivant le nombre de classes souhaitées. Elle renvoie un vecteur contenant la classe d’appartrenance de chaque individu. l’ordre des individus étant identique à celui du tableau de départ, la classe d’appartenance des individus peut facilement être ajoutée dans une nouvelle colonne du tableau de départ.

# k = Nombre de classes souhaitées
classes <- cutree(hc_eucli_ward2, k = 4)

# Création d'une nouvelle colonne avec la classe d'appartenance
var_quanti$CLASSE <- classes
POP PIB IDH ADOFEC CO2HAB EMPAGR EMPSER INTERN ESPVIE AGEMED TELMOB MORINF TXMIGR DVIEUX TUBERC URBANI DJEUNE CLASSE
AGO 31.317543 6793.7085 0.5815 152.635250 1.1209815 50.4490 41.3865 14.33910 60.9660 16.677 43.1305 51.58504 0.211 4.3225 355 65.85 91.4625 1
BDI 11.352978 756.5941 0.4320 56.227500 0.0466776 92.0170 6.4980 2.66075 61.4135 17.320 56.5347 40.99260 0.181 4.3610 111 13.20 86.9555 2
BEN 11.643093 3224.0433 0.5430 87.379625 0.6224791 38.9125 42.1465 20.00000 61.6200 18.781 82.3843 60.53574 -0.176 5.9895 56 47.60 77.7865 3
BFA 20.036424 2160.5895 0.4475 105.713875 0.1973980 25.5640 40.8700 16.00000 61.3770 17.551 97.9123 49.00709 -1.282 4.5605 48 29.70 84.9065 2
BWA 2.278885 17700.3152 0.7325 46.322125 2.9573642 20.8570 61.0040 47.00000 69.4325 24.044 150.0060 29.98541 1.341 6.9540 275 69.80 54.9450 4
CAF 4.705777 938.9888 0.3960 130.247875 0.0650827 77.4450 17.1505 4.33925 53.0425 17.611 27.6743 84.46370 -8.581 5.3140 540 41.60 83.1095 2
CIV 25.392890 5133.5905 0.5360 118.475250 0.3346972 40.4840 46.5020 46.82370 57.6010 18.854 134.8580 59.40349 -0.323 5.1820 142 51.00 75.6240 3
CMR 25.546324 3628.1177 0.5615 107.694875 0.3226965 43.7520 41.3510 23.20300 59.1055 18.688 69.0854 50.55533 -0.193 4.9770 186 56.70 77.5825 3
COD 85.429330 1091.9213 0.4790 124.860500 0.0242292 65.6135 24.6615 8.61990 60.5240 16.988 43.3822 68.18008 0.288 5.9285 321 44.75 90.5395 2
COG 5.312434 3356.2418 0.5735 112.993625 0.6161096 34.3665 43.7460 8.65000 64.4300 19.204 95.3405 36.18735 -0.771 4.8545 375 67.15 74.8465 3
DJI 0.966240 5366.7107 0.5210 19.199875 0.6717953 33.5180 53.5140 55.68140 66.8460 26.570 41.1959 49.80543 0.947 6.9175 260 77.85 44.5025 3
DZA 42.640735 11414.5995 0.7470 10.256625 3.6876905 9.9395 59.2890 59.57970 76.7865 28.521 121.9320 20.14982 -0.239 10.2195 69 72.90 48.0295 1
EGY 99.405839 11564.7950 0.7040 54.061500 2.4264069 24.0700 48.5100 46.92430 71.9075 24.606 95.2866 18.10248 -0.391 8.6215 12 42.70 55.5010 1
ERI 3.474957 NA 0.4575 53.523500 0.2143515 61.4155 30.1295 1.30891 66.1305 19.209 20.3640 31.34800 -11.571 8.3650 89 40.40 77.5595 2
ETH 110.651568 2161.6109 0.4815 68.133375 0.1367414 66.4175 23.4770 18.61810 66.4200 19.466 36.2007 39.14908 0.278 6.2735 151 21.00 72.5195 2
GAB 2.145926 14806.5905 0.7000 97.469375 2.5283647 33.0875 56.1695 62.00000 66.3285 22.511 138.2810 32.69746 1.562 5.9895 525 89.55 62.5225 4
GHA 30.092483 5303.5336 0.6085 67.256625 0.6147189 29.8490 48.7120 39.00000 63.9250 21.507 137.5170 34.91044 -0.339 5.1870 148 56.40 63.0600 3
GIN 12.592769 2531.2341 0.4750 136.616375 0.2561000 62.0070 31.8645 18.00000 61.3925 18.020 96.1150 64.93173 -0.326 5.4930 176 36.30 81.7180 2
GMB 2.313894 2175.5690 0.4915 79.773500 0.2678091 27.4370 56.9305 19.83650 61.8925 17.844 139.5290 39.03308 -1.371 4.8385 174 61.60 83.0380 2
GNB 1.897611 1969.2724 0.4760 105.195125 0.1811767 68.3180 24.6825 3.93051 58.1615 18.833 78.9889 54.01618 -0.755 5.1780 361 43.60 76.9380 2
GNQ 1.332474 19458.9245 0.5870 157.016250 4.3449264 42.2215 38.3485 26.24000 58.5710 22.335 45.1669 62.62024 12.443 4.0325 201 72.35 61.1900 4
KEN 51.983269 4266.8368 0.6000 76.462375 0.3597057 54.7625 37.9840 17.82710 66.5210 20.119 96.3202 30.62253 -0.197 4.0970 292 27.25 67.9330 3
LBR 4.878175 1462.4118 0.4800 136.347000 0.3234092 43.3515 46.3395 7.98448 63.9150 19.411 56.5690 53.48219 -1.049 5.8600 308 51.40 73.3800 2
LBY 6.728009 15096.0769 0.7225 5.813500 8.0879274 18.6690 58.9090 21.75890 72.8170 28.817 91.4793 10.24269 -0.301 6.5675 40 80.25 41.8425 4
LSO 2.116797 2758.1290 0.5245 92.261750 1.2613313 8.6585 49.0890 29.00000 54.0175 24.010 113.8310 65.66614 -4.783 7.8615 611 28.40 52.1515 2
MAR 36.250428 7476.1792 0.6830 31.357000 1.8404515 34.9720 43.3205 64.80390 76.5665 29.538 124.1720 19.22586 -1.437 10.8840 99 62.75 41.1950 1
MDG 26.615810 1629.6623 0.5275 110.895250 0.1630207 64.4480 26.6110 9.80000 66.8605 19.568 40.5703 38.18323 -0.058 5.3400 233 37.55 71.7550 2
MLI 19.367889 2305.2361 0.4325 170.349250 0.1866153 62.7985 29.5865 13.00000 59.1015 16.347 115.0850 61.96196 -2.123 4.9950 53 42.75 94.7075 2
MOZ 29.931026 1284.9965 0.4540 149.940875 0.2809194 70.4610 21.1085 10.00000 60.5065 17.620 47.7158 54.01829 -0.172 5.4845 551 36.25 84.6455 2
MRT 4.464505 5119.7260 0.5440 72.045000 0.6044313 51.6650 35.5065 20.80100 64.8170 20.114 103.7060 51.54291 1.150 5.5370 93 54.10 70.3175 3
MWI 18.385982 1051.1249 0.4805 134.117500 0.0761111 43.8895 42.2905 13.78220 64.0290 18.080 39.0058 35.31582 -0.895 4.9260 181 17.05 81.3985 2
NAM 2.471412 9784.5769 0.6455 65.546375 1.7450469 22.3620 61.3915 51.00000 63.5415 21.832 112.7020 28.96725 -1.979 6.0905 524 50.50 62.0615 1
NER 22.876775 1207.7762 0.3925 188.313625 0.1033337 75.1875 17.6130 5.25049 62.2220 15.151 40.6385 47.98493 0.181 5.4660 87 16.45 105.1010 2
NGA 198.419144 5145.2871 0.5365 108.545000 0.6498757 35.3355 52.4380 42.00000 54.5110 18.064 88.1842 75.67151 -0.310 5.1335 219 50.75 81.8610 3
RWA 12.464453 2157.3935 0.5415 39.292875 0.0912374 62.8260 28.3825 21.76760 68.8600 20.039 78.8541 27.02078 -0.740 5.2205 59 17.25 69.7705 2
SDN 42.307384 4059.5331 0.5080 65.994875 0.5034768 40.0230 43.4995 30.87030 65.2025 19.659 72.0079 42.14203 -1.208 6.4285 71 34.75 71.9420 3
SSD 11.019019 NA 0.4310 64.044250 0.1704093 57.2935 28.9535 7.97743 57.7270 19.040 33.4630 63.69163 -15.902 6.1685 146 19.75 75.9210 2
SEN 16.075343 3354.8272 0.5140 74.084500 0.7386566 30.3755 56.1710 46.00000 67.8025 18.514 104.4510 31.82667 -1.277 5.7315 118 47.45 79.5920 3
SLE 7.731678 1690.8316 0.4495 114.548500 0.1409384 55.2475 38.3540 9.00000 54.5045 19.402 88.4699 78.47719 -0.554 5.2665 298 42.30 72.8270 2
SOM 15.225566 NA NA 101.371375 0.0465698 83.1580 13.2430 2.00405 57.2340 16.683 48.7964 76.57223 -2.694 5.6895 262 45.30 91.7805 2
SWZ 1.142203 8647.0887 0.6080 77.084375 1.0549327 12.5695 63.5180 47.00000 59.7955 20.729 93.5273 43.02284 -7.378 6.9180 329 23.90 65.4575 1
TCD 15.712305 1577.9727 0.3975 163.231250 0.0655329 76.6500 21.2380 6.50000 54.1085 16.554 45.1237 71.42419 0.131 4.9190 142 23.20 92.9445 2
TGO 7.985727 1574.2385 0.5125 89.421750 0.4332564 37.9915 49.1365 12.36020 60.9000 19.350 77.8861 47.36163 -0.256 5.1440 36 41.95 73.5720 2
TUN 11.629962 10759.6827 0.7390 7.809625 2.7303114 13.1830 54.1790 64.19080 76.6025 32.835 127.7070 14.60544 -0.348 12.5545 35 69.10 35.9300 1
TZA 57.159453 2625.1980 0.5265 118.981875 0.2219524 65.5295 27.7440 25.00000 65.2375 17.992 77.2414 37.60541 -0.721 4.8875 253 34.15 82.3155 2
UGA 43.499310 2151.6788 0.5410 120.467500 0.1350604 72.7705 20.6300 23.70650 63.1715 16.733 57.2726 33.80762 4.018 3.8020 200 24.10 91.0075 2
ZAF 58.175393 12556.2802 0.7080 68.416500 8.0903570 5.1275 71.8460 56.16740 63.9935 27.621 153.2500 28.49095 2.536 8.1795 520 66.65 44.2375 1
ZMB 17.606374 3500.5119 0.5830 122.185000 0.3012960 49.0500 40.0920 14.30000 63.7000 17.592 89.1570 40.44662 -0.467 3.9620 346 43.80 84.0360 3
ZWE 14.542143 2982.9890 0.5700 88.973500 0.8492879 66.4255 26.8395 27.05550 61.3425 18.668 89.4049 33.90040 -8.150 5.4055 210 32.20 77.2085 3


4. Caractérisation & représentation

Dans l’objectif de caractèriser et de nommer les différentes classes détéctées, il peut être intérressant de faire un résumé statistique de chaque variable pour toutes les classes. Le package gtsummary et sa fonction tbl_summary est parfaite pour cela.

library(gtsummary)
tbl_summary(var_quanti, by = CLASSE)
Characteristic 1, N = 81 2, N = 241 3, N = 131 4, N = 41
POP 34 (9, 47) 14 (7, 24) 18 (12, 30) 2 (2, 3)
PIB 10,272 (8,354, 11,452) 1,691 (1,285, 2,162) 4,060 (3,356, 5,134) 16,398 (15,024, 18,140)
    Unknown 0 3 0 0
IDH 0.69 (0.64, 0.72) 0.48 (0.44, 0.50) 0.54 (0.54, 0.57) 0.71 (0.67, 0.73)
    Unknown 0 1 0 0
ADOFEC 60 (26, 71) 113 (87, 135) 87 (72, 109) 72 (36, 112)
CO2HAB 2.13 (1.59, 2.97) 0.17 (0.09, 0.23) 0.61 (0.36, 0.65) 3.65 (2.85, 5.28)
EMPAGR 18 (12, 27) 64 (52, 71) 40 (34, 49) 27 (20, 35)
EMPSER 57 (47, 62) 28 (21, 39) 43 (40, 49) 58 (52, 59)
INTERN 54 (47, 61) 10 (6, 18) 27 (20, 42) 37 (25, 51)
ESPVIE 68 (63, 77) 61 (58, 64) 64 (61, 65) 68 (64, 70)
AGEMED 26.1 (21.6, 28.8) 18.0 (17.2, 19.4) 18.9 (18.7, 20.1) 23.3 (22.5, 25.2)
TELMOB 117 (95, 125) 57 (41, 81) 89 (82, 104) 115 (80, 141)
MORINF 24 (19, 32) 51 (39, 65) 42 (35, 52) 31 (25, 40)
TXMIGR -0.4 (-1.6, -0.1) -0.7 (-1.6, 0.0) -0.3 (-0.8, -0.2) 1.5 (0.9, 4.3)
DVIEUX 8.40 (6.71, 10.39) 5.29 (4.92, 5.73) 5.19 (4.98, 5.73) 6.28 (5.50, 6.66)
TUBERC 214 (61, 396) 179 (106, 301) 186 (118, 260) 238 (161, 338)
URBANI 64 (49, 67) 36 (23, 42) 51 (44, 56) 76 (72, 83)
DJEUNE 52 (43, 63) 82 (74, 88) 76 (70, 78) 58 (52, 62)
1 Median (IQR)

Profil des classes

L’intérprétation des profil des classes peut être facilitée par la représentation graphique. Pour cela, commencez par standardiser les valeurs avec la fonction scale()

scaled_var <- scale(var_quanti[-18])

# Matrice to dataframe
scaled_var <- as.data.frame(scaled_var)

# Récupération des classe d'appartenance
scaled_var$CLASSE <- as.factor(classes)

Regrouper ensuite les individus par classe d’appartenance en calculant les moyennes (ou médiannes) de chaque indicateur avec la fonction aggregate().

# Regroupement individus par classe + calcul moyennes
Profil_classe <- aggregate(scaled_var[, -18],
                           by = list(CLASSE = scaled_var$CLASSE),
                           mean, na.rm = TRUE)
CLASSE POP PIB IDH ADOFEC CO2HAB EMPAGR EMPSER INTERN ESPVIE AGEMED TELMOB MORINF TXMIGR DVIEUX TUBERC URBANI DJEUNE
1 0.2576714 0.9831468 1.3558610 -0.7955726 0.9931544 -1.1334637 1.0549772 1.3282362 0.9815592 1.2790957 0.7319400 -0.9742460 -0.0063041 1.4317306 0.1309541 0.6079127 -1.0991077
2 -0.0979426 -0.7091511 -0.7708391 0.4098541 -0.4901452 0.6113731 -0.6549051 -0.7021380 -0.4003301 -0.5200337 -0.5014697 0.4125525 -0.2335242 -0.2781355 0.0149935 -0.6187286 0.5494495
3 0.2237703 -0.2049346 0.0852618 -0.1520631 -0.2974752 -0.1834640 0.2727221 0.2532384 -0.0592075 -0.1520919 0.2736590 0.0360333 0.0585430 -0.3544520 -0.1825306 0.2339907 0.0072599
4 -0.6549404 2.4227871 1.4435022 -0.3737746 1.9213565 -0.8050529 0.9331295 0.7333309 0.6312865 1.0563097 0.6555464 -0.6439315 1.2234886 -0.0426795 0.2413550 1.7360767 -1.1220766


Une dernière étape est nécessaire pour représenter les profil de classe avec ggplot2. Tranformez le tableau en format long en utilisant la fonction pivot_longer() du package tidyr.

library(tidyr)
Profil_classe_lg <- Profil_classe |>
                      pivot_longer(!CLASSE, names_to = "variable", values_to = "value")
CLASSE variable value
1 POP 0.2576714
1 PIB 0.9831468
1 IDH 1.3558610
1 ADOFEC -0.7955726
1 CO2HAB 0.9931544
1 EMPAGR -1.1334637
1 EMPSER 1.0549772
1 INTERN 1.3282362
1 ESPVIE 0.9815592
1 AGEMED 1.2790957
1 TELMOB 0.7319400
1 MORINF -0.9742460
1 TXMIGR -0.0063041
1 DVIEUX 1.4317306
1 TUBERC 0.1309541
1 URBANI 0.6079127
1 DJEUNE -1.0991077
2 POP -0.0979426
2 PIB -0.7091511
2 IDH -0.7708391
2 ADOFEC 0.4098541
2 CO2HAB -0.4901452
2 EMPAGR 0.6113731
2 EMPSER -0.6549051
2 INTERN -0.7021380
2 ESPVIE -0.4003301
2 AGEMED -0.5200337
2 TELMOB -0.5014697
2 MORINF 0.4125525
2 TXMIGR -0.2335242
2 DVIEUX -0.2781355
2 TUBERC 0.0149935
2 URBANI -0.6187286
2 DJEUNE 0.5494495
3 POP 0.2237703
3 PIB -0.2049346
3 IDH 0.0852618
3 ADOFEC -0.1520631
3 CO2HAB -0.2974752
3 EMPAGR -0.1834640
3 EMPSER 0.2727221
3 INTERN 0.2532384
3 ESPVIE -0.0592075
3 AGEMED -0.1520919
3 TELMOB 0.2736590
3 MORINF 0.0360333
3 TXMIGR 0.0585430
3 DVIEUX -0.3544520
3 TUBERC -0.1825306
3 URBANI 0.2339907
3 DJEUNE 0.0072599
4 POP -0.6549404
4 PIB 2.4227871
4 IDH 1.4435022
4 ADOFEC -0.3737746
4 CO2HAB 1.9213565
4 EMPAGR -0.8050529
4 EMPSER 0.9331295
4 INTERN 0.7333309
4 ESPVIE 0.6312865
4 AGEMED 1.0563097
4 TELMOB 0.6555464
4 MORINF -0.6439315
4 TXMIGR 1.2234886
4 DVIEUX -0.0426795
4 TUBERC 0.2413550
4 URBANI 1.7360767
4 DJEUNE -1.1220766


Représentation graphique des profils de classe avec ggplot2 :

library(ggplot2)
ggplot(Profil_classe_lg) +
  geom_bar(aes(x = variable, y = value, fill =  CLASSE), stat = "identity") +
  scale_fill_manual(values = c("lightblue3", "red3", "yellow3", "blue4")) +
  facet_wrap(~CLASSE) +
  coord_flip() + theme_bw()

Cartographie

Si vous souhaitez cartographier les résultat, vous pouvez utiliser le package mapsf. Commencez par importer un fond de carte, puis réalisez une jointure avec le tableau de données final contenant les classes d’appartenances.

# Import d'une couche géoghraphique des pays africains 
library(sf)
pays_afrique <- st_read("data/GADM_AFRICA_2020/afrika_map.shp",  quiet = TRUE)

# Jointure Fond de carte - tableau
pays_afrique <-merge(pays_afrique,var_quanti, by.x="iso3", by.y=0, all.x=TRUE)

Puis cartographiez la classification avec la fonction mapsf() :

library(mapsf)
mf_map(x = pays_afrique, 
       var = "CLASSE", 
       type = "typo",
       pal = c("lightblue3", "red3", "yellow3", "blue4"),
       leg_title = "Classes")

mf_layout(
  title = "CAH (distance euclidienne + méthode Ward.2)",
  credits = "H. Pecout; Sources: Human Development Report 2020 & GADM 2023"
)


Exercice

1. Créez un projet Rstudio

File/New Project/New Directory…

2. Téléchargez les données suivantes :

Intitulé Téléchargement
Données pays africains (UN-CEPII) Download
Fond de carte Afrique (GADM 2020) Download

3. Placez les données (décompressées) dans le répertoire de votre projet, de la façon suivante :

4. Importez les fichiers suivants en utilisant les fonctions adéquates :

  • data/DEV_AFRICA_2018/afrika_don.csv
  • data/GADM_AFRICA_2020/afrika_map.shp

Vous pouvez également importer le dictionnaire des variables afrika_don_meta.csv.

Un peu d’aide ?
# Pour importer le fichier csv (afrika_don.csv)
read.csv2()
read.csv()

# Pour importer le fichier ESRI Shapefile (afrika_map.shp)
library(sf)
st_read()

5. Explorez les potentielles corrélations entre les différentes variables quantitatives du tableau “afrika_don”

Pour cela, utilisez la représentation graphique en nuage de point et le calul de coefficient de corrélation. Quelle(s) variable(s) pourraient-on exclure de la CAH ?

Un peu d’aide ?
# Nuages de points multiples  
pairs()
# Corrélation multiple
cor()

# Nuages de points 1 vs 1
plot()
# Corrélation 1 vs 1
cor_test()

5. Préparez le tabmeau de données pour réalisez un CAH.

  1. Assignez les valeurs de la variable “iso3” comme noms des lignes du tableau

  2. Sélectionnez uniquement les 10 variables suivantes :“POP”, “PIB”, “ADOFEC”, “EMPAGR”, “INTERN”, “ESPVIE”, “TXMIGR”, “DVIEUX”, “TUBERC”, “URBANI”

Un peu d’aide ?
# 1. Ajout de noms de ligne 
row.names(tableau) <- tabelau$...

# 2. Sélection des colonnes
New_tab <- tableau[ , ... ]

6. Calculez une matrice de distance euclidienne entre toutes les variables.

Un peu d’aide ?
dist()

7. Réalisez un regroupement hiérarchique avec la méthode “ward.d2” puis affichez le dendogramme

Un peu d’aide ?
# Regroupement hiérarchique
hclust()

# Affichage de l'arbre
plot()

7. Representez l’inertie intra-classe en fonction du partitionnement de l’arbre

A quelle hauteur pouvons nous découper le dendogramme ? Combien de classes bien disctinctes pouvons-vous créer ?

Un peu d’aide ?
# Récupération et tri croissant de l'inertie de chaque partition
... <- sort(...$..., decreasing = TRUE)

# Représentation graphique de l'inertie en fonction du nombre de classe
plot(...)

8. Découpez le dendogramme en 3 classes et assignez le résultat de la classification dans une nouvelle colonne du tableau de données

Un peu d’aide ?
# Découpage de l'arbre et assignation de la classification dans une nouvelle colonne
...$... <- cutree()

9. Cartographiez le résultat

Un peu d’aide ?
# Joignez le tableau de données au fond de carte
merge()

# Construisez une carte de typologie - Une couleur par classe détéctée
library(mapsf)
mf_map()
mf_layout()


Corrigé



Statistique Descriptive
Toutes les leçons
Code source
---
title: "Classification Ascendante Hiérarchique"
subtitle: "Construire une CAH avec des fonctions R-base"
author: 
- Hugues pecout
- Justin Dansou
date: last-modified
ordre: 02
code-fold: true
code-tools: true
format:
  html:
    theme: cosmo
    code-copy: true
    embed-resources: TRUE
---

## Introduction

La Classification Ascendante Hiérarchique (CAH) est l'une des techniques statistiques les plus utilisées pour segmenter une population en différentes classes ou sous-groupes. Son objectif est de regrouper les individus similaires tout en maintenant une grande dissimilarité entre ces classes.

**Le principe de la CAH se déroule en trois étapes :**

1.  **Calcul d'une matrice de distances** qui mesure la distance entre chaque paire d'individus. Lorsque deux observations sont identiques, leur distance est nulle. Plus les observations sont différentes, plus la distance est grande.

2.  **Regroupement hiérarchique** des individus par itération. Cette classification est ascendante car elle part des observations individuelles. Elle est hiérarchique car elle engendre des classes ou groupes de plus en plus larges (incluant des sous-groupes en leur sein) en fonction des distances calculée entre les individus.

3.  **Découpage du dendrogramme** (ou arbre de classification) à une certaine hauteur pour obtenir la partition souhaitée.

\

### Préparation des données

Pour ce cours nous utiliserons les données ***DEV_AFRICA_2018***.

```{r}
#| code-fold: FALSE
 
data <- read.csv2(file = "data/DEV_AFRICA_2018/afrika_don.csv")


```

Pour réaliser une CAH, il est nécessaire de préparer le tableau de données. Commencez par séléctionner uniquement les variables qui vous souhaitez utiliser.

```{r}
#| code-fold: FALSE
 
# Liste des variable à supprimer
var_to_del <- c("iso3", "name", "nom", "SUBREG")

# Supression des variables
data_clean <- data[,!names(data) %in% var_to_del]

```

Afin de pouvoir manipuler correctement des données qualitatives, convertissez-les en facteur.

```{r}
#| code-fold: FALSE
 
liste_var_quali <-  c("LOCKED", "COLFRA", "COLGBR", "LANGFR", "LANGEN")

# Transformation des variables qualitatives en `factor`
data_clean[,liste_var_quali] <- data.frame(lapply(data_clean[,liste_var_quali], factor))

```

Il est indispensable de bien nommer les lignes du tableau afin d'identifier facilement les individus.

```{r}
#| code-fold: FALSE

# Utilisation du code ISO des pays en nom de lignes
row.names(data_clean) <- data[,"iso3"] 


```

**Tableau de données préparé pour la CAH :**

```{r echo = FALSE, include = TRUE, eval = TRUE, warning= FALSE}
#| code-fold: FALSE

library(knitr)
library(kableExtra)

data_clean %>% 
  kable %>%
  kable_styling("striped", full_width = F) %>% 
  scroll_box(height = "400px") 


```

\

## 1. Matrice de distance

La ressemblance des individus est évaluée par la distance mathématique entre chaque observation. Plusieurs distances peuvent être calculées en fonction du type de données utilisées. Voici quelques exemples :

**Calcul d'une matrice de distance pour des variables quantitatives.**

La fonction `dist()` permet dans calculer plusieurs distances mathématiques (euclidiennes, Maximum, Manhattan, Canberra...) pour les variables quantitatives

```{r, eval=TRUE}
#| code-fold: FALSE

# Sélection des variables quantitatives
var_quanti <- data_clean[,c(1:17)] 

# Calcul de la matrice de distances (euclidienne)
md_eucli <- dist(var_quanti, method = "euclidean")
```

**Calcul d'une matrice de distance pour des variables qualitatives.**

Pour des variables qualitatives, une matrice de distances du χ² peut-être obtenue par l'intermédiaire d'une Analyse à Correspondance Multiple (ACM) avec la fonction `dudi.acm()`, puis de la la fonction `dist.dudi()` du package `ade4`.

La distance utilisée dans les analyses de correspondance multiples (ACM) est une variante de la distance du χ².

```{r, eval=TRUE}
#| code-fold: FALSE


# Sélection des variables qualitatives
var_quali <- data_clean[,c(18:22)] 

library (ade4)
# Calcul ACM
acm <- dudi.acm(var_quali, scannf = FALSE, nf = 5)

# Calcul matrice distance du χ²
md_chi2 <- dist.dudi(acm)

```

**Calcul d'une matrice de distance pour des variables qualitatives et quantitatives.**

La distance de Gower peut être utilisée pour un ensemble de variables qualitatives et quantitatives. Pour cela, vous pouvez utilisez la fionction `daisy()` du package `cluster`.

```{r, eval=TRUE}
#| code-fold: FALSE

library(cluster)
md_gower <- daisy(data_clean, metric = "gower")

```

\

## 2. Regroupement Hiérarchique

Il faut ensuite choisir une méthode d'agrégation pour construire le dendrogramme. De nombreuses solutions existent (*single linkage*, *average linkage*, *ward linkage*...). Les différentes méthodes de regroupement hiérarchique utilisent des critères différents pour évaluer la distance entre les groupes et peuvent donner des résultats (dendogramme) légèrement différents en termes de structure des clusters formés.

Par exemple, la méthode *complete linkage* (liaison complète) est une des techniques couramment utilisées pour réaliser le regroupement hiérarchique lors de la CAH. Cette méthode consiste à calculer la distance entre deux groupes de données en se basant sur les distances maximales entre tous les points des deux groupes. Concrètement, lors du regroupement hiérarchique, la distance entre deux groupes est déterminée en trouvant la distance maximale entre les points de chaque groupe. Ainsi, la distance entre deux groupes est définie par la paire d'observations qui sont les plus éloignées l'une de l'autre parmi toutes les paires possibles d'observations entre les deux groupes. Cette approche est souvent utilisée lorsque l'on souhaite privilégier la formation de clusters compacts et bien séparés les uns des autres, car la distance choisie est la plus grande possible entre les groupes. Elle peut être utile lorsque l'on s'intéresse à des sous-groupes distincts et bien définis dans les données.

La fonction R-base pour le calcul d'un dendrogramme à partir d'une matrice de distances est `hclust()`. La méthode d'aggrégation souhaitée peut être précisé avec l'argument `method`. Quelques exemple d'application :

::: panel-tabset
## Variables quantitatives

Aggrégation des individus par la méthode de *Ward* appliquée au carré des distances ("ward.D2")

```{r}
#| code-fold: FALSE
hc_eucli_ward2 <- hclust(md_eucli, method = "ward.D2")
```

Visualisation du dendogramme (arbre de classification) avec la fonction `plot()`.

```{r}
#| code-fold: FALSE
plot(hc_eucli_ward2, main = "Distance euclidienne + Méthode de Ward2")

```

## Variables qualitatives

Aggrégation des individus par la méthode de liason complète ("complete")

```{r}
#| code-fold: FALSE
hc_chi2_complete <- hclust(md_chi2, method = "complete")
```

Visualisation du dendogramme (arbre de classification) avec la fonction `plot()`.

```{r}
#| code-fold: FALSE
plot(hc_chi2_complete, main = "Distance chi2 + Méthode de liasion complète")
```

## Toutes les variables (quantitatives et qualitatives)

Aggrégation des individus par la méthode de liason moyenne ("average")

```{r}
#| code-fold: FALSE
hc_gower_average <- hclust(md_gower, method = "average")
```

Visualisation du dendogramme (arbre de classification) avec la fonction `plot()`.

```{r}
#| code-fold: FALSE
plot(hc_gower_average, main = "Distance de Gower + Méthode de liaison moyenne")
```
:::

::: callout-important
En fonction de vos données et de vos objectifs, vous pouvez réaliser plusieurs dendrogramme différents jusqu'à obtenir une classification qui fait « sens ».
:::

\

## 3. Partitionnement

Il ne reste plus qu'à découper le dendrogramme obtenu à une certaine hauteur pour obtenir une partition des individus. La qualité d'une partition se traduit mathématiquement par une petite variabilité intra-classe et une grande variabilité inter-classes. La forme et les sauts d'inertie du dendogramme permettent d'apprécier l'évolution de ces variabilités en fonction du nombre de partitions. Par exemple :

::: panel-tabset
## Forme de l'arbre

L'analyse de la forme du dendogramme fournit des indications sur le nombre de classes à retenir. Deux branches bien distinctes apparaissent sur l'arbre. Ces deux branches se subdivisent ensuite en 4 sous-groupes. Les partitions suivantes semblent beaucoup moins marquées.

```{r}
#| code-fold: FALSE
#| echo: FALSE
plot(hc_eucli_ward2, main = "Distance euclidienne + Méthode de Ward2")
```

## Sauts d'inertie

L'inertie de l'arbre renvoyée par la fonction `hclust()` est l'**inertie inter-classe** qui traduit la séparation et la compacité des classes. Elle est calculée à partir des distances entre les centres des classes formés à chaque étape du regroupement. Une inertie inter-classe élevée indique que les clusters sont bien séparés, ce qui est généralement considéré comme souhaitable lors de la formation de groupes homogènes. En visualisant l'évolution de l'inertie selon le nombre de classes, on peut ainsi évaluer la qualité de la partition et choisir le nombre optimal de classes pour créer des groupes homogènes et bien distincts.

L'inertie du dendogramme est stockée dans l'élément `height` d'un objet `hclust`. Il est facile de représenter les sauts d'inertie avec la fonction `plot()`.

```{r}
#| code-fold: FALSE

# Récupération et tri croissant de l'inertie de chaque partition
inertie <- sort(hc_eucli_ward2$height, decreasing = TRUE)

# Représentation graphique de l'inertie en fonction du nombre de classe
plot(inertie[1:13], type = "s", xlab = "Nombre de classes", ylab = "Inertie")

```
:::

La fonction `rect.hclust()` permet de visualiser les différentes partitions directement sur le dendrogramme.

```{r}
#| code-fold: FALSE

plot(hc_eucli_ward2, main = "Distance euclidienne + Méthode de Ward2")
rect.hclust(hc_eucli_ward2, 2, border = "green4") # Partition en 2 classes
rect.hclust(hc_eucli_ward2, 3, border = "blue4") # Partition en 3 classes
rect.hclust(hc_eucli_ward2, 4, border = "red4") # Partition en 4 classes


```

La fonction `cutree()` permet de récupérer la partition des individus suivant le nombre de classes souhaitées. Elle renvoie un vecteur contenant la classe d'appartrenance de chaque individu. l'ordre des individus étant identique à celui du tableau de départ, la classe d'appartenance des individus peut facilement être ajoutée dans une nouvelle colonne du tableau de départ.

```{r}
#| code-fold: FALSE

# k = Nombre de classes souhaitées
classes <- cutree(hc_eucli_ward2, k = 4)

# Création d'une nouvelle colonne avec la classe d'appartenance
var_quanti$CLASSE <- classes


```

```{r}
#| code-fold: FALSE
#| echo: FALSE

var_quanti %>% 
  kable %>%
  kable_styling("striped", full_width = F) %>% 
  scroll_box(height = "400px")

```

\

## 4. Caractérisation & représentation

Dans l'objectif de caractèriser et de nommer les différentes classes détéctées, il peut être intérressant de faire un résumé statistique de chaque variable pour toutes les classes. Le package `gtsummary` et sa fonction `tbl_summary` est parfaite pour cela.

```{r, warning=FALSE, message = FALSE}
#| code-fold: FALSE
library(gtsummary)
tbl_summary(var_quanti, by = CLASSE)
```

### Profil des classes

L'intérprétation des profil des classes peut être facilitée par la représentation graphique. Pour cela, commencez par standardiser les valeurs avec la fonction `scale()`

```{r, warning=FALSE}
#| code-fold: FALSE

scaled_var <- scale(var_quanti[-18])

# Matrice to dataframe
scaled_var <- as.data.frame(scaled_var)

# Récupération des classe d'appartenance
scaled_var$CLASSE <- as.factor(classes)

```

Regrouper ensuite les individus par classe d'appartenance en calculant les moyennes (ou médiannes) de chaque indicateur avec la fonction `aggregate()`.

```{r, warning=FALSE}
#| code-fold: FALSE

# Regroupement individus par classe + calcul moyennes
Profil_classe <- aggregate(scaled_var[, -18],
                           by = list(CLASSE = scaled_var$CLASSE),
                           mean, na.rm = TRUE)

```

```{r echo = FALSE, include = TRUE, eval = TRUE, warning= FALSE}
#| code-fold: FALSE
Profil_classe %>% 
  kable %>%
  kable_styling("striped", full_width = F) 
```

\

Une dernière étape est nécessaire pour représenter les profil de classe avec `ggplot2`. Tranformez le tableau en format long en utilisant la fonction `pivot_longer()` du package `tidyr`.

```{r, warning=FALSE}
#| code-fold: FALSE

library(tidyr)
Profil_classe_lg <- Profil_classe |>
                      pivot_longer(!CLASSE, names_to = "variable", values_to = "value")

```

```{r echo = FALSE, include = TRUE, eval = TRUE, warning= FALSE}
#| code-fold: FALSE
Profil_classe_lg %>% 
  kable %>%
  kable_styling("striped", full_width = F) %>% 
  scroll_box(height = "300px") 
```

\

Représentation graphique des profils de classe avec `ggplot2` :

```{r, warning=FALSE}
#| code-fold: FALSE

library(ggplot2)
ggplot(Profil_classe_lg) +
  geom_bar(aes(x = variable, y = value, fill =  CLASSE), stat = "identity") +
  scale_fill_manual(values = c("lightblue3", "red3", "yellow3", "blue4")) +
  facet_wrap(~CLASSE) +
  coord_flip() + theme_bw()
```

### Cartographie

Si vous souhaitez cartographier les résultat, vous pouvez utiliser le package `mapsf`. Commencez par importer un fond de carte, puis réalisez une jointure avec le tableau de données final contenant les classes d'appartenances.

```{r, warning=FALSE, message=FALSE}
#| code-fold: FALSE

# Import d'une couche géoghraphique des pays africains 
library(sf)
pays_afrique <- st_read("data/GADM_AFRICA_2020/afrika_map.shp",  quiet = TRUE)

# Jointure Fond de carte - tableau
pays_afrique <-merge(pays_afrique,var_quanti, by.x="iso3", by.y=0, all.x=TRUE)

```

Puis cartographiez la classification avec la fonction `mapsf()` :

```{r, warning=FALSE, message=FALSE}
#| code-fold: FALSE


library(mapsf)
mf_map(x = pays_afrique, 
       var = "CLASSE", 
       type = "typo",
       pal = c("lightblue3", "red3", "yellow3", "blue4"),
       leg_title = "Classes")

mf_layout(
  title = "CAH (distance euclidienne + méthode Ward.2)",
  credits = "H. Pecout; Sources: Human Development Report 2020 & GADM 2023"
)

```

\

## <i class="bi bi-person-workspace"></i> Exercice {.title .exo-title}

::: {#exo}
[1. Créez un projet Rstudio]{.question}

*File/New Project/New Directory...*

[2. Téléchargez les données suivantes :]{.question}

|             Intitulé              |                                                                     Téléchargement                                                                      |
|:-----------------:|:---------------------------------------------------:|
| Données pays africains (UN-CEPII) | <a href="https://bit.ly/3DaCAkX" class="btn btn-outline-warning" role="button" aria-disabled="true"><i class="bi bi-cloud-arrow-down"></i> Download</a> |
| Fond de carte Afrique (GADM 2020) | <a href="https://bit.ly/3DaAUb2" class="btn btn-outline-warning" role="button" aria-disabled="true"><i class="bi bi-cloud-arrow-down"></i> Download</a> |

[3. Placez les données (décompressées) dans le répertoire de votre projet, de la façon suivante :]{.question}

```{r, echo=FALSE, out.width="70%", fig.align='center'}
knitr::include_graphics("../img/folder3.png")
```

[4. Importez les fichiers suivants en utilisant les fonctions adéquates :]{.question}

-   data/DEV_AFRICA_2018/**afrika_don.csv**\
-   data/GADM_AFRICA_2020/**afrika_map.shp**\

Vous pouvez également importer le dictionnaire des variables **afrika_don_meta.csv**.

```{r warning = FALSE, message = FALSE , eval = FALSE}
#| code-summary: "Un peu d'aide ?"
  
# Pour importer le fichier csv (afrika_don.csv)
read.csv2()
read.csv()

# Pour importer le fichier ESRI Shapefile (afrika_map.shp)
library(sf)
st_read()


```

[5. Explorez les potentielles corrélations entre les différentes variables quantitatives du tableau "afrika_don"]{.question}

Pour cela, utilisez la représentation graphique en nuage de point et le calul de coefficient de corrélation. Quelle(s) variable(s) pourraient-on exclure de la CAH ?

```{r warning = FALSE, message = FALSE , eval = FALSE}
#| code-summary: "Un peu d'aide ?"

# Nuages de points multiples  
pairs()
# Corrélation multiple
cor()

# Nuages de points 1 vs 1
plot()
# Corrélation 1 vs 1
cor_test()


```

[5. Préparez le tabmeau de données pour réalisez un CAH.]{.question}

1.  Assignez les valeurs de la variable "iso3" comme noms des lignes du tableau

2.  Sélectionnez uniquement les 10 variables suivantes :"POP", "PIB", "ADOFEC", "EMPAGR", "INTERN", "ESPVIE", "TXMIGR", "DVIEUX", "TUBERC", "URBANI"

```{r warning = FALSE, message = FALSE , eval = FALSE}
#| code-summary: "Un peu d'aide ?"

# 1. Ajout de noms de ligne 
row.names(tableau) <- tabelau$...

# 2. Sélection des colonnes
New_tab <- tableau[ , ... ]

```

[6. Calculez une matrice de distance euclidienne entre toutes les variables.]{.question}

```{r warning = FALSE, message = FALSE , eval = FALSE}
#| code-summary: "Un peu d'aide ?"

dist()

```

[7. Réalisez un regroupement hiérarchique avec la méthode "ward.d2" puis affichez le dendogramme]{.question}

```{r warning = FALSE, message = FALSE , eval = FALSE}
#| code-summary: "Un peu d'aide ?"

# Regroupement hiérarchique
hclust()

# Affichage de l'arbre
plot()

```

[7. Representez l'inertie intra-classe en fonction du partitionnement de l'arbre]{.question}

A quelle hauteur pouvons nous découper le dendogramme ? Combien de classes bien disctinctes pouvons-vous créer ?

```{r warning = FALSE, message = FALSE , eval = FALSE}
#| code-summary: "Un peu d'aide ?"

# Récupération et tri croissant de l'inertie de chaque partition
... <- sort(...$..., decreasing = TRUE)

# Représentation graphique de l'inertie en fonction du nombre de classe
plot(...)

```

[8. Découpez le dendogramme en 3 classes et assignez le résultat de la classification dans une nouvelle colonne du tableau de données]{.question}

```{r warning = FALSE, message = FALSE , eval = FALSE}
#| code-summary: "Un peu d'aide ?"

# Découpage de l'arbre et assignation de la classification dans une nouvelle colonne
...$... <- cutree()

```

[9. Cartographiez le résultat]{.question}

```{r warning = FALSE, message = FALSE , eval = FALSE}
#| code-summary: "Un peu d'aide ?"

# Joignez le tableau de données au fond de carte
merge()

# Construisez une carte de typologie - Une couleur par classe détéctée
library(mapsf)
mf_map()
mf_layout()

```

------------------------------------------------------------------------

\

::: center
<a href="/correction/CAH.zip" class="btn btn-outline-warning" role="button" aria-disabled="true"><i class="bi bi-cloud-arrow-down"></i> Corrigé</a>
:::
:::

\
\

<!-- ::: center -->

<!-- <a href="/import.pdf" class="btn btn-info" role="button" aria-disabled="true"><i class="bi bi-file-pdf"></i> Télécharger ce document format PDF</a> -->

<!-- ::: -->
 
Ecole d’été CIST·2023 - licensebuttons by-sa - Ouidah, Bénin