Document complémentaire au module 10 du cours SDD II de 2025-2026. Distribué sous licence CC BY-NC-SA 4.0.

Veuillez vous référer au cours en ligne pour les explications et les interprétations de cette analyse.

Installer un environnement R adéquat pour reproduire cette analyse.

Cartes auto-adaptatives (SOM)

# Configuration du dialecte SciViews::R avec le module "explore"
SciViews::R("explore", lang = "fr")
# Lecture des données zooplankton
zoo <- read("zooplankton", package = "data.io")
zoo
## # A data.trame: [1,262 Ă— 20]
##      ecd  area perimeter feret major minor  mean  mode   min   max std_dev range  size aspect elongation compactness
##    <dbl> <dbl>     <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>   <dbl> <dbl> <dbl>  <dbl>      <dbl>       <dbl>
##  1 0.770 0.465      4.45 1.32  1.16  0.509 0.363 0.036 0.004 0.908   0.231 0.904 0.837  0.437       8.50        3.38
##  2 0.700 0.385      2.32 0.728 0.713 0.688 0.361 0.492 0.024 0.676   0.183 0.652 0.700  0.965       1           1.12
##  3 0.815 0.521      4.15 1.33  1.11  0.598 0.308 0.032 0.008 0.696   0.204 0.688 0.854  0.538       6.10        2.63
##  4 0.785 0.484      4.44 1.78  1.56  0.394 0.332 0.036 0.004 0.728   0.218 0.724 0.979  0.252       8.07        3.24
##  5 0.361 0.103      1.71 0.739 0.694 0.188 0.153 0.016 0.008 0.452   0.110 0.444 0.441  0.271       4.89        2.26
##  6 0.832 0.544      5.27 1.66  1.36  0.511 0.371 0.02  0.004 0.844   0.268 0.84  0.934  0.377      10.6         4.05
##  7 1.23  1.20      15.7  3.92  1.37  1.11  0.217 0.012 0.004 0.784   0.214 0.78  1.24   0.810      49.7        16.5 
##  8 0.620 0.302      3.98 1.19  1.04  0.370 0.316 0.012 0.004 0.756   0.246 0.752 0.704  0.356      11.1         4.19
##  9 1.19  1.12      15.3  3.85  1.34  1.06  0.176 0.012 0.004 0.728   0.172 0.724 1.20   0.794      50.5        16.7 
## 10 1.04  0.856      7.60 1.89  1.66  0.656 0.404 0.044 0.004 0.88    0.264 0.876 1.16   0.396      14.8         5.37
## # ℹ 1,252 more rows
## # ℹ 4 more variables: transparency <dbl>, circularity <dbl>, density <dbl>, class <fct>
# Élimination de class, standardisation et transformation en matrice
zoo %>.%
  sselect(., -class) %>.%
  scale(.) %>.%
  as_matrix(.) ->
  zoo_mat

# Charger le package kohonen
library(kohonen)
# Grille rectangulaire 7 x 7
rect_grid_7_7 <- somgrid(7, 7, topo = "rectangular")

# Transformation en un objet de classe kohonen qui est une liste
rect_grid_7_7 %>.%
  structure(list(grid = .), class = "kohonen") %>.% # Objet de classe kohonen
  plot(., type = "property", # Graphique de propriété
    property = unit.distances(rect_grid_7_7)[25, ], # distance Ă  la cellule 25
    main = "Distance depuis la cellule centrale") # Titre du graphique

# Grille hexagonale 7 x 7
hex_grid_7_7 <- somgrid(7, 7, topo = "hexagonal")

# Transformation en un objet de classe kohonen qui est une liste
hex_grid_7_7 %>.%
  structure(list(grid = .), class = "kohonen") %>.% # Objet de classe kohonen
  plot(., type = "property", # Graphique de propriété
    property = unit.distances(hex_grid_7_7)[25, ], # distance Ă  la cellule 25
    main = "Distance depuis la cellule centrale") # Titre du graphique

# Initialisation du générateur de nombres pseudo-aléatoires
set.seed(8657)
# Analyse SOM avec grille hexagonale 7 x 7
zoo_som <- som(zoo_mat, grid = somgrid(7, 7, topo = "hexagonal"))
summary(zoo_som)
## SOM of size 7x7 with a hexagonal topology and a bubble neighbourhood function.
## The number of data layers is 1.
## Distance measure(s) used: sumofsquares.
## Training data included: 1262 objects.
## Mean distance to the closest unit in the map: 2.547.
# Évolution de l'apprentissage de notre SOM au fil des itérations
plot(zoo_som, type = "changes")

set.seed(954)
# Nouvelle SOM avec 200 itérations
zoo_som <- som(zoo_mat, grid = somgrid(7, 7, topo = "hexagonal"), rlen = 200)
plot(zoo_som, type = "changes")

# Palette de 17 couleurs distinctes
colors17 <- c("#e6194B", "#3cb44b", "#ffe119", "#4363d8", "#f58231", "#911eb4",
  "#42d4f4", "#f032e6", "#bfef45", "#fabebe", "#469990", "#e6beff", "#9A6324",
  "#fffac8", "#800000", "#aaffc3", "#808000")

# Placement des individus dans la carte avec une couleur différente pour chaque classe
plot(zoo_som, type = "mapping", shape = "straight", col = colors17[zoo$class])

# Nombre d'individus dans chaque cellule
plot(zoo_som, type = "counts", shape = "straight")

# Cellule dans laquelle chaque individu est mappé
zoo_som$unit.classif
##    [1] 32 28 20 39 12 32 23 26 23 32 37 15 28 16 39 48 25  5 23  4 47 25 47 46 10 40 32 15 32 35 26 14 32 32  1 46  3 18  2
##   [40] 20 12 35 18 19 26 40 12 26 41 33 27  7 19 26 41 19 20  8 19 26 15 14 32 16 28  8 16 35 16 19 28 14 13 31 34 48 48 28
##   [79] 26 16 32 34 28 17 42 23 13 41  9 19 42  8 42 36 35 20 20 19 20  7 20 26 20 20  2 20 19  2 17 13 17 14 27 27 20 18 12
##  [118] 20 20 20  7  7 20 19 35 19 26 26 10 20 26 26 20 14 20 19 26 27 33 20  7  2 42 49 22 37 29 23 25 28 14 17 34 16 40 45
##  [157] 15  9 40 22 17 39  7 18 34 49 33  1 32 41 18 18 26 26 32 17  2 18  2 18 27 27 19 40 19 27 27 20 33 27 27 32  4 27 18
##  [196]  2 48 39 48 33 48 33 17 47 34 15 18 20 32 27 33 20 12 32 27 16 46 18 28  2 42 41 48 33 20  7 27 33 41 33  7 49 18 18
##  [235] 18 17 18 18 27 21 18 19  7 10 18  7  7 18 27 18 17  2  7 18 27 27  2  7 18  7  2 18 18  7 35 32 18 18 30 30 29 46 46
##  [274] 29 17  9 24 47 15 46 40 45 40 26 30 27 33 29 45 30 15 24 47 40 32 20 16 16 30 17 16 40 24  9 46  2 45 16 29 46 16 15
##  [313] 22 41 24 30 29 32 30 45 10 10 12 17 10  2 26 16  7  4  7 27 27 16 17 31 32 11 17 16  2 41 26  2 33 26 15 10 10 17  3
##  [352]  2 40 20 10 11 33 27 40 33 32 32 18 27 33 10 28 24 41 46 33 27 33 46 46 33 27 18 46 32 27 45  8 40 35 46 32 48 46 46
##  [391] 46 35  4 27 40 46 33 15 46 33 28 18 33 20 20 27 27 10 27 33 27 10  1 33 33 27 40 35 47 25  9  1 16 31 49  9 15 33 17
##  [430] 17  9 15 37 26 32 12 21 22 20 47 23 24 45  5 15  6 11 21  1 46 24 42 37 15 19 15  5 11 15 49 21 33 18 21 10 21 26  3
##  [469] 21 21 33  3 10 19 15  5 12 35 15 21 19 19 19 18 12 21 21  5 17 15 10  8 12 38 21 38 19  1 15 10 21  4 12 21 18  4 33
##  [508] 19 43 43 39 43 23 44 28  8  3 21 43 47  8 44 44 47 33  6  8 21  8  8 36 12 38 19 21 35  1 20  4 20  6 40  1 19 12 48
##  [547] 44 31 21 41 44 37  9  5 32 44 45 44 21 17 40 25  8 39 36 19  5 17 19 49  6  3 18  5  3  7  3 12 21 45  8  8  3 23  4
##  [586] 22  1  1  8 37 24 43  1 26 34 38 44 36 21 21 12 12 21 19 12 12 26 38 12 31  1 12 21 12 21 21 21 21 31 21 26 21 26 12
##  [625] 31 43 38 15 21 38  8 25 24 31 13 11 15 37  5  5 13 10 38 38 43 45 38  1 14 11 10  7  2 13 12 26 26 26 38 16 15 38 38
##  [664] 11 21 31 11 25 47  3 11  5 15 38  5 48 18 26 22 44 31 21 21 21  5 39 18  1 21 21 12 11 17 21  9  4 11  4  4  3 21 30
##  [703] 20 11 30 45 26 39 13  6 24 29 23 16 14 14 30 24 39 30 24  9 24 29 47 13 24 30 13 15 14 25 30 45  6 29 40 30 24 24 31
##  [742]  6 24 14  8 11 30 15  1 26 17 16  3  1 39 13 13 26 13 12  9 11  3 17 26  6 26  9 38 38 32 11 18 49 15 32 13 13  1 37
##  [781] 39 23 13  3  6 39 14 44  6 25  1  6 14 44  6  6 48 39 39 26 38  6  1 23  8 49 49  9 16 22 25  9 49 37 15 23 15 13 26
##  [820] 12 10 49 20 19 19 26 12 18 19 13 10 12  1 15 12 19 12 10 18  2 10 49  4 13 18 13 26 26 26 26  9 15 25 32 16 44 44  8
##  [859] 32 40 18 46 32 26  8 44  9 23 46 11  8 25  8 40 25 23 32  8 25 15 16 15 47 15 10 11 18 18 10 18 46 26 10 15 17 15  4
##  [898] 40 41  3 10 18 10 18 10 19 10 10 41  9 19 12 10 17 49 15 18 31 47  8 44 48 40 15 44 40 32 10 23 48  8 23 22 25 44 15
##  [937] 38 25 44 22  9 16 16 19  8  5  9  1  9 15 22 16 16 20 10 49 12 18 41 12 18  1  5 18  3 18 19 12 10 10 10 23 25 22 47
##  [976] 32 18  5  3 48 38 23 28 47 39  8 31 39  8 31 25 22 47 16 39 31  8  1 15 25
##  [ reached getOption("max.print") -- omitted 262 entries ]
# Tableau de contingence des individus mappés dans chaque cellule
zoo_som_nb <- table(zoo_som$unit.classif)
zoo_som_nb
## 
##  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 
## 30 20 20 18 18 24 33 36 25 43 20 44 23 18 42 30 31 55 38 43 39 20 31 18 30 48 39 17  9 15 22 34 38 11 25  4  9 25 19 23 16 
## 42 43 44 45 46 47 48 49 
##  7 17 28 13 26 24 15 29
# Orientation de la carte SOM en fonction des variables
plot(zoo_som, type = "codes", codeRendering = "segments")

# Coloration de la carte variable par variable (6 variables représentées ici)
par(mfrow = c(2, 3)) # Graphiques sur 2 lignes et 3 colonnes
for (var in c("size", "mode", "range", "aspect", "elongation", "circularity"))
  plot(zoo_som, type = "property", property = zoo_som$codes[[1]][, var],
    main = var, palette.name = viridis::inferno)

Regroupements

# Configuration de R
SciViews::R("explore", lang = "fr")

# Distance euclidienne entre cellules
zoo_som_dist <- dissimilarity(as.data.frame(zoo_som$codes[[1]]),
  method = "euclidean")
# CAH avec distance de Ward D2 et pondération des cellules
# en fonction du nombre d'individus mappés
zoo_som_cah <- cluster(zoo_som_dist, method = "ward.D2", members = zoo_som_nb)

# Dendrogramme et coupure Ă  10.5
chart(zoo_som_cah) +
  geom_dendroline(h = 10.5, col = "red")

# Prédiction des groupoes à l'aide de la CAH
groupes <- predict(zoo_som_cah, h = 10.5)
groupes
##  V1  V2  V3  V4  V5  V6  V7  V8  V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 
##   1   1   1   1   1   1   1   1   1   1   1   1   1   2   1   1   2   1   1   2   2   3   3   2   2   2   2   2   3   3   3 
## V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 
##   2   2   2   2   4   5   3   2   2   2   6   5   5   3   2   2   6   6
# Visualisation du découpage par CAH sur la carte SOM
plot(zoo_som, type = "mapping", pchs = ".", main = "SOM zoo, six groupes",
  bgcol =  RColorBrewer::brewer.pal(5, "Set2")[groupes])
add.cluster.boundaries(zoo_som, clustering = groupes)