5.2 Distance entre individus

Vous êtes en train d’analyser des données concernant les échantillons de plancton que vous avez prélevé sur votre lieu de recherche. Ce plancton a été numérisé (photo de chaque organisme) et les images ont été traitée avec un logiciel qui mesure automatiquement une vingtaine de variables telles que la surface de l’objet sur l’image, son périmètre, sa longueur, … Vous vous trouvez donc face à un jeu de données qui a une taille non négligeable : 20 colonnes par 1262 lignes, soit le nombre d’individus mesurés dans vos échantillons.

zoo <- read("zooplankton", package = "data.io")
zoo
# # A tibble: 1,262 x 20
#      ecd  area perimeter feret major minor  mean  mode   min   max std_dev
#    <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
#  2 0.700 0.385      2.32 0.728 0.713 0.688 0.361 0.492 0.024 0.676   0.183
#  3 0.815 0.521      4.15 1.33  1.11  0.598 0.308 0.032 0.008 0.696   0.204
#  4 0.785 0.484      4.44 1.78  1.56  0.394 0.332 0.036 0.004 0.728   0.218
#  5 0.361 0.103      1.71 0.739 0.694 0.188 0.153 0.016 0.008 0.452   0.110
#  6 0.832 0.544      5.27 1.66  1.36  0.511 0.371 0.02  0.004 0.844   0.268
#  7 1.23  1.20      15.7  3.92  1.37  1.11  0.217 0.012 0.004 0.784   0.214
#  8 0.620 0.302      3.98 1.19  1.04  0.370 0.316 0.012 0.004 0.756   0.246
#  9 1.19  1.12      15.3  3.85  1.34  1.06  0.176 0.012 0.004 0.728   0.172
# 10 1.04  0.856      7.60 1.89  1.66  0.656 0.404 0.044 0.004 0.88    0.264
# # … with 1,252 more rows, and 9 more variables: range <dbl>, size <dbl>,
# #   aspect <dbl>, elongation <dbl>, compactness <dbl>, transparency <dbl>,
# #   circularity <dbl>, density <dbl>, class <fct>

Vous voulez regrouper votre plancton en fonction de la ressemblance entre les organismes, c’est-à-dire, en fonction des écarts entre les mesures effectuées pour les 19 variables quantitatives, à l’exclusion de la vingtième colonne class qui est une variable factor). En raison de la taille du tableau, il est évident que cela ne pourra pas se faire de manière manuelle. Nous pouvons raisonnablement considérer que plus les mesures sont similaires entre deux individus, plus ils ont des chances d’être semblables, c’est-à-dire, d’appartenir au même groupe taxonomique. Mais comment faire pour synthétiser l’information de similarité ou différence contenue dans 19 paires de valeurs (une paire par variable)  ? Nous avons besoin d’une mesure de distance qui quantifie la similarité (ou à l’inverse la dissimilarité) en un seul nombre. Celle qui vient naturellement à l’esprit est la distance euclidienne. Prenons un cas simplifié. Quelle est la distance qui sépare deux individus A et B par rapport à trois variables x, y, z ? Ici, nous pouvons représenter l’information graphiquement dans un espace à trois dimensions. La distance qui nous intéresse est la distance linéaire entre les deux points dans l’espace. Autrement dit, c’est la longueur du segment de droite qui relie les deux points dans l’espace. Cette distance, nous pouvons la calculer à l’aide de la formule suivante (problème de niveau lycée, voir par exemple ici pour une résolution dans le plan) :

\[\mathrm{D_{Euclidean}}_{A, B} = \sqrt{(x_A - x_B)^2 + (y_A - y_B)^2 + (z_A - z_B)^2}\]

Notez que cette formule se généralise à n dimensions et s’écrit alors, pour n’importe quelle paire d’individus indicés j et k dans notre tableau et pour les différentes mesures de 1 à i notées yi :

\[\mathrm{D_{Euclidean}}_{j, k} = \sqrt{\sum_{i=1}^{n}(y_{ij}-y_{ik})^2}\]

C’est la racine carré de la somme dans les n dimensions des écarts entre les valeurs au carré pour toutes les variables yi. Plus sa valeur est grande, plus les individus sont éloignés (différents). Pour cette raison, nous appelerons cette distance, une mesure de dissimilarité.

5.2.1 Matrice de distances

Nous avons maintenant la possibilité de quantifier la similitude entre nos organismes plactoniques… mais nous en avons un grand nombre. Cela va être impossible à gérer autant de mesures qu’il y a de paires possibles parmi 1262 individus12. La matrice de distance est une matrice ici 1262 par 1262 qui rassemble toutes les valeurs possibles. Notez que sur la diagonale, nous comparons chaque individu avec lui-même. La distance euclidienne vaut donc systématiquement zéro sur la diagonale.

\[\mathrm{D_{Euclidean}}_{j, j} = 0\]

De plus, de part et d’autre de cette diagonale, nous trouvons les paires complémentaires (j versus k d’un côté et k versus j de l’autre). Or qu’elle soit mesurée dans un sens ou dans l’autre, la distance du segment de droite qui relie deux points dans l’espace est toujours la même.

\[\mathrm{D_{Euclidean}}_{j, k} = \mathrm{D_{Euclidean}}_{k, j}\]

Par conséquent, seulement une portion (soit le triangle inférieur, soit le triangle supérieur hors diagonale) est informative. La diagonale ne porte aucune informartion utile, et l’autre triangle est redondant. Nous avons donc pour habitude de ne calculer et représenter que le triangle inférieur de cette matrice. Maintenant que cela est clair, nous pouvons créer un objet dist qui contiendra notre matrice de distances enclidiennes. Il suffit d’utiliser la fonction dist(), ou mieux vegan::vegdist() qui offre plus de possibilités13. Comme cela prendrait trop de place d’imprimer la matrice complète, nous allons réaliser le travail sur seulement les six premiers individus de notre tableau (et nous devons aussi éliminer la colonne class qui ne contient pas de données numériques et qui ne nous intéresse pas pour le moment) :

zoo %>.%
  select(., -class) %>.% # Elimination de la colonne class
  head(., n = 6) -> zoo6 # Récupération des 6 premiers individus
zoo6_dist <- vegan::vegdist(zoo6, method = "euclidean")
zoo6_dist # En pratique, on n'imprime généralement ce genre d'objet !
#            1          2          3          4          5
# 2  8.2185826                                            
# 3  2.5649705  5.7320911                                 
# 4  0.8582142  7.8813537  2.2220079                      
# 5  4.8478629  4.2950067  3.0119468  4.6148173           
# 6  2.4269520 10.6197317  4.9228255  2.8477882  7.1766853

Nous voyons bien ici que R n’imprime que le triangle inférieur de notre matrice 6 par 6. Notez aussi que les objets dist de tailles plus réalistes que vous génèrerez dans vos analyses ne sont prévue pour être imprimées et visualisées telles quelles. Il s’agit seulement de la première étape vers une représentation utile qui sera réalisée à la page suivante, à l’aide de la classification hiérarchisée.

Félicitations ! Vous venez de calculer votre première matrice de distances. Nous verrons à la page suivante comment nous pouvons utiliser l’information qu’elle contient pour regrouper les individus de manière pertinente. Mais avant cela, nous avons besoin d’un peu de théorie pour bien comprendre quelle métrique choisir pour calculer nos distances et pourquoi. On parle aussi d’indices de similarité ou dissimilarité.

Attention : nous n’avons pas considéré ici les unités respectives de nos variables. Une surface (mm2) ou une longeur (mm) ne sont pas mesurées dans les mêmes unités. Nous risquons alors de donner plus de poids aux valeurs élevées. Nous aurions le même effet si nous décidions par exemple d’exprimer une mesure longitudinale en µm au leiu de l’exprimer en mm. Dans ce cas, il vaut mieux standardiser d’abord le tableau (moyenne de zéro et écart type de un) selon les colonnes avant d’effectuer le calcul. Ceci sera fait à la page suivante.

5.2.2 Indices de (dis)similarité

Un indice de similarité (similarity index en anglais) est une descripteur statistique (nombre unique) de la similitude de deux échantillons ou individus représentés par plusieurs variables dans un échantillon multivarié. Un indice de similarité prend une valeur comprise entre 0 (différence totale) et 1 ou 100% (similitude totale). Un indice de dissimilarité} est le complément d’un indice de similarité (dis = 1 – sim); sa valeur est comprise entre 100% (différence totale) et 0 (similitude totale).

Attention : dans certains cas, un indice de dissimilarité peut varier de 0 à +\(\infty\)**. Il n’existe alors pas d’in,dice de similarité complémentaire. C’est le cas précisément de la distance euclidienne que nous avons exploré jusqu’ici.

Tous les indices de similarité / dissimilarité peuvent servir à construire des matrices de distances.

5.2.2.1 Indice de Bray-Curtis

L’indice de dissimilarité de Bary-Curtis, aussi appelé coefficient de Czecanowski est calculé comme suit :

\[\mathrm{D_{Bray-Curtis}}_{j,k}=\frac{\sum_{i=1}^{n}\left|y_{ij}-y_{ik}\right|}{\sum_{i=1}^{n}(y_{ij}+y_{ik})}\]

Dans R nous utiliserons vegan::vegdist(DF, method = "bray").Il s’utilise pour mesurer la similitude entre échantillon sur base du dénombrement d’espèces. Si le nombre d’individus est très variable (espèces dominantes versus espèces rares), nous devons transformer les données pour éviter de donner trop de poids aux espèces les plus abondantes (ex: \(log(x+1)\), double racine carrée, …).

Une caractéristique essentielle de cet indice (contrairement à la distance euclidienne) est que toute double absence n’est pas prise en compte dans le calcul. C’est souvent pertinent dans le cadre de son utilisation comme le dénombrement d’espèces. En effet, quelle information utile retire-t-on de doubles zéros dans un tableau répertoriant la faune belge pour le crocodile du Nil et le tigre de Sibérie par exemple ? Aucune ! Ils sont tous deux systématiquement absents des dénombrements, mais cette double absence n’apporte aucune information utile pour caractériser la faune belge par ailleurs.

L’indices de similarité de Bray-Curtis (sim) est complémentaire à l’indices de dssimilarité correspondant (dis tel que calculé ci-dessus) :

\[sim = 1 – dis\]

5.2.2.2 Indice de Canberra

L’indice de dissimilarité de Canberra est similaire à l’indice de Bray-Curtis mais il pondère les espèces en fonction du nombre d’occurrences afin de donner le même poids à chacune dans le calcul. Il se calcule comme suit :

\[\mathrm{D_{Canberra}}_{j,k}=\frac{1}{nz}\sum_{i'=1}^{nz}\frac{\left|y_{i'j}-y_{i'k}\right|}{\left|y_{i'j}\right|+\left|y_{i'k}\right|}\]

\(nz\) est le nombre de valeurs non nulles simultanément dans le tableau de départ. Toutes les espèces contribuent ici de manière égale. C’est un point positif, mais il faut faire attention à ce que cet indice a souvent tendnace à donner une surimportance aux espècces très rares observées une seule fois ou un petit nombre de fois ! Dans R, nous utiliserons vegan::vegdist(DF, method = "canberra").

Toute double absence n’est pas prise en compte ici aussi. Seuls les indices ne dépendant pas des doubles zéros sont utilisables pour des dénombrements d’espèces ou des présence-absence. Ainsi pour ce type de données, notre choix se portera sur :

  • Bray-Curtis si l’on souhaite que le résultat soit dominé par les espèces les plus abondantes.

  • Canberra si notre souhait est de donner la même importance à toutes les espèces, mais avec un risque de domination des espèces rares.

  • Bray-Curtis sur données transformées (\(log(x+1)\) ou double racine carrée) pour un compromis entre les deux avec prise en compte de toutes les espèces, mais domination partielle des espèces les plus abondantes. C’est souvent un bon compromis.

Attention : Si les volumes échantillonnés entre stations ne sont pas comparables, il faut standardiser (moyenne nulle et écart type un) les données selon les échantillons avant de faire les calculs de distances.

De même que pour Bray-Curtis, l’indice de similarité sim se calcule à partir de l’indice de dissimilarité dis tel que ci-dessus comme \(sim = 1 - dis\).

5.2.2.3 Distance Euclidienne

Nous savons déjà que c’est la distance géométrique entre les points dans un espace à n dimensions :

\[\mathrm{D_{Euclidean}}_{j,k}=\sqrt{\sum_{i=1}^{n}(y_{ij}-y_{ik})^2}\]

Dans R, cette distance peut être calculée avec dist(DF) ou vegan::vegdist(DF, method = "euclidean"). Cet indice de dissimilarité est utile pour des mesures quantitatives, pour des données environnmentales, etc. Il faut que les mesures soient toutes effectuées dans les mêmes unités. Si ce n’est pas le cas, penser alors à standardiser les mesures avant le calcul comme nous l’avons fait plus dans l’exemple sur le zooplancton. Il n’existe pas d’indice de similarité complémentaire.

5.2.2.4 Distance de Manhattan

La distance de Manhattan, encore appelée “city-block distance” est un indice de dissimilarité qui, contrairement à la distance euclidienne ne mesure pas la distance géométrique entre les points en ligne droite, mais via un trajet qui suit les parallèmes aux axes. C’est comme si la distance euclidenne reliait les points à vol d’oiseau, alors qu’avec la distance de Manhattan, on devait contourner les blocs de maisons du quartier pour aller d’un point A à un point B (d’où le nom de cette métrique). Elle se calcule comme suit :

\[\mathrm{D_{Manhattan}}_{j,k}=\sum_{i=1}^{n}|y_{ij}-y_{ik}|\]

Dans R, nous utiliserons vegan::vegdist(DF, method = "manhattan"). Ici aussi, seul l’indice de dissimilarité est défini. L’indice de similarité complémentaire n’existe pas car la valeur de l’indice de dissimlarité n’est pas borné à droite et peut varier de zéro (dissimilarité nulle, les deux individus soint identiques) à l’infini pour une différence maximale.

5.2.3 Utilisation des indices

  • Les distances euclidienne ou de Manhattan sont à préférer pour les mesures environnementales ou de manière générale pour les variables quantitatives continues.

  • Les distances de Bray-Curtis ou Canberra sont meilleure pour les dénombrements d’espèces (nombreux double zéro), ou de manière générale, pour les variables quantitatives discrètes prenant des valeurs nulles ou positives.

5.2.4 Propriétés des indices

Les indices varient en 0 et 1 (0 et 100%), mais les distances sont utilisées aussi comme indices de dissimilarité et varient entre 0 et \(+\infty\).

Un indice est dit métrique si :

  • Minimum 0 : \(I_{j, k} = 0\) si \(j = k\)

  • Positif : \(I_{j, k}>0\) si \(j \neq k\)

  • Symétrique : \(I_{j, k}=I_{k, j}\)

  • Inégalité triangulaire : \(I_{j, k} + I_{k, l} >= I_{j, l}\)

La dernière propriété d’inégalité triangulaire est la plus difficile à obtenir, et n’est pas toujours nécessaire. Nous pouvons montrer que certains indices qui ne respectent pas cette dernière propriété sont pourtant utiles dans le contexte. Nous dirons alors d’un indice que c’est une semi-métrique s’il répond à toutes les conditions sauf la quatrième. Enfin, un indice est dit non métrique dans tous les autres cas. Le tableau suivant reprend les métriques que nous avons vu jusqu’ici, et rajoute d’autres candidats potentiels (la distance Chi carré, l’indice de correlation ou de variance/covariance) en indiquant leur type :

Distance Type
Bray-Curtis semi-métrique
Canberra métrique
Euclidienne métrique
Manhattan métrique
Chi carré métrique
(correlation) (non métrique)
(variance/covariance) (non métrique)
Pour en savoir plus
  • Vous pouver aussi transposer le tableau pour calculer la distance entre les variables en utilisant la fonction t() dans R (dist(t(DF))). Par exemple, dans le cas d’un tableau “espèces - station” (dénombrement d’espèces en différentes stations), nous pouvons souhaiter comparer les stations du point de vue de la composition en espèces, mais nous pouvons aussi comparer les espèces du point de vue de leur répartition entre les stations. Pour passer d’un calcul à l’autre, nous transposerons donc le tableau (les colonnes deviennent les lignes et inversément) avant d’utiliser dist() ou vegan::vegdist().

  • Pour bien comprendre la logique derrière les indices, il est utile de comprendre les équations correspondantes. Si ces équations sont pour vous trop abstraites, une façon efficace de comprendre consiste à faire le calcul à la main. Par exemple dans le cas de l’indice de Canberra, la notion de nombre de données non nulles \(nz\) n’est pas évident. Effectuons un calcul à la main détaillé sur le tableau fictif suivant concernant trois espèces A, B, et C dénombrées en trois stations Sta1, Sta2 et Sta3 dans le tableau nommé ex1 :

    A B C
    Sta1 4 0 2
    Sta2 3 0 10
    Sta3 1 8 0

Pour rappel, la dissimilarité de Canberra se calcule comme suit:

\[\mathrm{D_{Canberra}}_{j,k}=\frac{1}{nz}\sum_{i'=1}^{nz}\frac{\left|y_{i'j}-y_{i'k}\right|}{y_{i'j}+y_{i'k}}\]

où:

  • nz est le nombre d’observations non nulles simultanément dans les deux vecteurs comparés (les doubles zéros ne sont pas pris en compte)
  • i’ est l’itérateur sur toutes les valeurs non double zéros

Voici le détail du calcul (notez bien comment le double zéro pour l’espèce B entre les stations 1 et 2 est pris en compte dans le calcul) :

Sta1_2 <- (1/2) * ((abs(4 - 3)) / (4 + 3) + (abs(2 - 10)) / (2 + 10))
round(Sta1_2, 2)
# [1] 0.4
Sta1_3 <- (1/3) * (abs(4 - 1) / (4 + 1) + abs(0 - 8) / (0 + 8) +
  abs(2 - 0) / (2 + 0))
round(Sta1_3, 2)
# [1] 0.87
Sta2_3 <- (1/3) * (abs(3 - 1) / (3 + 1) + abs(0 - 8) / (0 + 8) +
  abs(10 - 0) / (10 + 0))
round(Sta2_3, 2)
# [1] 0.83

La matrice finale est la suivante :

#      Sta1 Sta2
# Sta2 0.40     
# Sta3 0.87 0.83

Vérifions en laissant R faire le calcul :

vegan::vegdist(ex1, method = "canberra") %>.%
  round(., 2)
#      Sta1 Sta2
# Sta2 0.40     
# Sta3 0.87 0.83

Attention ! dist(, method = "canberra") ne multiplie pas la somme par \(1/nz\), mais par \(n/nz\) (variante). Ainsi, nous obtenons des distances trois fois plus grandes ici avec dist() qu’avec vegan::vegdist(), mais les deux calculs restent valables car les écarts relatifs au sein de la matrice de distance sont les mêmes.

dist(ex1, method = "canberra") %>.%
  round(., 2)
#      Sta1 Sta2
# Sta2 1.21     
# Sta3 2.60 2.50
A vous de jouer !
  • Réalisez le tutoriel afin de vérifier votre bonne compréhension des matrices de distance.

Démarrez la SciViews Box et RStudio. Dans la fenêtre Console de RStudio, entrez l’instruction suivante suivie de la touche Entrée pour ouvrir le tutoriel concernant les bases de R :

BioDataScience2::run("05a_distance_matrix")
N’oubliez pas d’appuyer sur la touche ESC pour reprendre la main dans R à la fin d’un tutoriel dans la console R.
  • Réalisez un carnet de note par binôme sur le transect entre Nice et Calvi. Lisez attentivement le README

Vous avez à votre disposition une assignation GitHub Classroom.

Pour l’année académique 2019-2020, les URLs à utiliser pour accéder à votre tâche sont les suivants :

Lisez le README afin de prendre connaissance de l’exercice.


  1. Le nombre de paires uniques et distinctes (pas j, j ou k, k) possibles parmi n items est \(n(n-1)/2\), soit ici pour 1262 éléments nous avons 795.691 paires.

  2. La fonction dist() ne propose par exemple pas la méthode de Bray-Curtis qui est fréquemment utilisée en biologie et en écologie, contrairement à vegan::vegdist(method = "bray").