projets
Mini-projet 4 / 4 · Master Biologie

Biodiversité & écologie

D’un relevé d’occurrences à des indices de diversité (Shannon, Gini-Simpson, Jaccard) et un rapport d’étude — en Python standard, sans numpy, sans pandas.

Pré-requis

Dicts, sets, modules (ateliers 1-12) ; notions élémentaires de moyenne et logarithme.

À la fin du projet

Un script biodiversite.py qui produit, à partir d’un CSV de relevés, un rapport complet de diversité par site et inter-sites.

Étape 1 sur 8

Charger un relevé d’occurrences

CSV → liste de dicts typés

Étape 1 / 8

Charger un relevé d’occurrences

★★
Contexte

Les écologues collectent des relevés d’occurrences : quelle espèce a été observée, où, quand, en quelle quantité. La structure standard est un CSV à plusieurs colonnes : espece, site, date, abondance (parfois aussi lat/lon, observateur, météo…).

Voici un relevé pédagogique d’essences forestières sur 3 sites (A, B, C) en mai-juin 2024. Sauvegardez-le sous releve.csv :

espece,site,date,abondance
Quercus_robur,site_A,2024-05-12,18
Quercus_robur,site_A,2024-06-15,22
Quercus_robur,site_B,2024-05-12,5
Fagus_sylvatica,site_A,2024-05-12,12
Fagus_sylvatica,site_A,2024-06-15,15
Fagus_sylvatica,site_B,2024-05-12,28
Pinus_sylvestris,site_B,2024-05-12,9
Pinus_sylvestris,site_C,2024-05-12,35
Acer_pseudoplatanus,site_A,2024-05-12,4
Acer_pseudoplatanus,site_C,2024-05-12,8
Betula_pendula,site_C,2024-05-12,42
Betula_pendula,site_C,2024-06-15,38
Picea_abies,site_C,2024-05-12,11
Sorbus_aucuparia,site_B,2024-05-12,3
Corylus_avellana,site_A,2024-06-15,7
Travail à réaliser

Écrivez charger_releve(chemin) qui renvoie une liste de dicts. Chaque dict doit avoir des clés typées correctement :

{
  "espece":    "Quercus_robur",   # str
  "site":      "site_A",          # str
  "date":      "2024-05-12",      # str (ou datetime)
  "abondance": 18,                # int
}

Vérification :

15 observations chargées.
Première : Quercus_robur sur site_A (2024-05-12) -> 18 individus
Étape 2 sur 8

Espèces par site

Du relevé à un dict {site → set d’espèces}

Étape 2 / 8

Espèces par site

★★
Contexte

La donnée brute est « plate » : une ligne par observation. Mais pour l’analyse, on a besoin d’une structure pivotée : par site, quelles espèces présentes ? C’est exactement ce que fait un groupBy en SQL, ou un defaultdict(set) en Python.

Travail à réaliser

Écrivez especes_par_site(obs) qui renvoie un dict {site: set([espece1, espece2, ...])}. Puis affichez :

site_A : Acer_pseudoplatanus, Corylus_avellana, Fagus_sylvatica, Quercus_robur (4 espèces)
site_B : Fagus_sylvatica, Pinus_sylvestris, Quercus_robur, Sorbus_aucuparia (4 espèces)
site_C : Acer_pseudoplatanus, Betula_pendula, Picea_abies, Pinus_sylvestris (4 espèces)
Étape 3 sur 8

Richesse spécifique

Combien d’espèces différentes par site ?

Étape 3 / 8

Richesse spécifique

★★
Contexte

La richesse spécifique (notée S) est l’indicateur de diversité le plus simple : combien d’espèces différentes observées. C’est un proxy intuitif mais limité : un site avec 10 espèces dont 9 très rares et 1 ultra-dominante a un S = 10, mais une diversité fonctionnelle plus pauvre qu’on imagine.

Les indices de Shannon et Simpson (étapes 5 et 6) corrigent ce biais.

Travail à réaliser

Écrivez richesse(obs) qui renvoie un dict {site: nombre d'espèces}. Réutilisez especes_par_site.

Richesse spécifique S :
  site_A : 4 espèces
  site_B : 4 espèces
  site_C : 4 espèces

Sur ce mini-jeu, les 3 sites sont équivalents en richesse — c’est en regardant l’abondance qu’on les différenciera vraiment.

Étape 4 sur 8

Abondance relative

Proportions d’individus par espèce, par site

Étape 4 / 8

Abondance relative

★★
Contexte

Les indices de diversité (Shannon, Simpson) reposent sur les proportions, pas les comptes bruts. Pour chaque site, il nous faut p_i = n_i / Nn_i est le total d’individus de l’espèce i et N le total de tous individus du site.

Cette étape pose les fondations des deux suivantes.

Travail à réaliser

Écrivez abondance_totale(obs) qui renvoie un dict imbriqué {site: {espece: total_individus}} (les abondances de plusieurs dates sont sommées).

Puis proportions(abondance) qui renvoie la version normalisée {site: {espece: p_i}}.

Abondances site_A :
  Quercus_robur       : 40
  Fagus_sylvatica     : 27
  Acer_pseudoplatanus :  4
  Corylus_avellana    :  7

Proportions site_A :
  Quercus_robur       : 0.526
  Fagus_sylvatica     : 0.355
  Acer_pseudoplatanus : 0.053
  Corylus_avellana    : 0.066
Étape 5 sur 8

Indice de Shannon (H′)

Entropie d’information appliquée à l’écologie

Étape 5 / 8

Indice de Shannon (H′)

★★
Contexte

L’indice de Shannon H′ mesure l’incertitude associée à l’identité d’un individu pris au hasard dans la communauté :

H' = -Σ p_i · ln(p_i)

Plus H′ est grand, plus la communauté est diverse et équilibrée :

  • H′ ≈ 0 → une espèce domine ;
  • H′ ≈ ln(S) → toutes les espèces sont en proportions égales (cas idéal).

Forêts tempérées typiques : H′ entre 1.5 et 3.5.

Travail à réaliser

Écrivez shannon(props_site) qui prend le dict {espece: p_i} d’un site et renvoie H′ (float).

Puis shannon_tous(props) qui calcule H′ pour chaque site.

Indice de Shannon H' :
  site_A : 1.16
  site_B : 1.16
  site_C : 1.20
Étape 6 sur 8

Indice de Simpson (1 − D)

Probabilité que deux individus diffèrent

Étape 6 / 8

Indice de Simpson (1 − D)

★★
Contexte

L’indice de Simpson mesure la probabilité que deux individus prélevés au hasard appartiennent à la même espèce :

D = Σ p_i²

La forme « diversité » est l’indice de Gini-Simpson 1 − D : probabilité que les deux individus diffèrent. Entre 0 (un seul taxon présent) et près de 1 (très diversifié).

Simpson est moins sensible que Shannon aux espèces rares — il met plus de poids sur les dominantes. Les deux sont complémentaires.

Travail à réaliser

Écrivez simpson(props_site) qui renvoie 1 − D. Puis simpson_tous(props) pour tous les sites.

Indice de Gini-Simpson (1 - D) :
  site_A : 0.59
  site_B : 0.59
  site_C : 0.62
Étape 7 sur 8

Indice de Jaccard

Comparer deux sites par leur composition

Étape 7 / 8

Indice de Jaccard

★★
Contexte

Comment savoir si deux sites partagent des espèces ? L’indice de Jaccard est la mesure historique :

J(A, B) = |A ∩ B| / |A ∪ B|

Entre 0 (aucune espèce en commun) et 1 (composition identique). C’est le même indice utilisé en machine learning pour comparer des ensembles ou en bibliométrie pour des listes de mots-clés.

Travail à réaliser

Écrivez jaccard(set_a, set_b) qui renvoie un float entre 0 et 1.

Puis matrice_jaccard(par_site) qui renvoie un dict de dicts {site_a: {site_b: J}} pour toutes les paires.

Matrice de Jaccard :
           site_A   site_B   site_C
site_A     1.000    0.286    0.143
site_B     0.286    1.000    0.143
site_C     0.143    0.143    1.000
Étape 8 sur 8

Pipeline CLI : biodiversite.py

Rapport complet de diversité à partir d’un CSV

Étape 8 / 8

Pipeline CLI : biodiversite.py

★★★
Contexte

Sept briques posées. Reste à les assembler en un script de terrain : prendre n’importe quel CSV d’occurrences au format espece,site,date,abondance et produire un rapport de diversité utilisable dans un mémoire ou un rapport d’étude d’impact.

Travail à réaliser

Rassemblez tout dans biodiversite.py. main() doit :

  1. charger le CSV passé en argument,
  2. imprimer un résumé : nombre d’observations, sites, espèces total,
  3. par site : richesse, Shannon, Simpson, top 3 espèces,
  4. matrice de Jaccard entre tous les sites,
  5. identifier les espèces rares (1 seul site, < 5 individus).
$ python biodiversite.py releve.csv