Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Exemple de projet — Glissements de terrain en Suisse

Open in Colab Open in Kaggle Launch on Renku

Exécution dans le cloud : ce notebook peut aussi tourner dans le cloud (Colab, Kaggle, Renku). Avant de lancer les cellules, télécharge project_landslides.gpkg depuis le dossier OneDrive du cours et dépose-le dans le répertoire de travail du notebook (Colab : panneau 📁 → Upload ; Kaggle : File → Upload ; Renku : déjà dans le projet). Procédure complète : docs/cloud-badges.md.

Exemple de projet — Glissements de terrain en Suisse

Ce notebook est un exemple de projet final, qui illustre l’enchaînement d’étapes attendu pour le projet : chargement des données, analyse statistique, définition et entraînement d’un modèle avec quantification de l’erreur, puis export des résultats.

Question posée : peut-on prédire si un lieu est sujet à un glissement de terrain (présence / absence) à partir de variables topographiques simples (pente, courbure, distance aux infrastructures, etc.) — et ce modèle généralise-t-il à des régions qu’il n’a jamais vues ?

Données : tout est regroupé dans un unique fichier, project_landslides.gpkg — préparé en amont (harmonisation des systèmes de coordonnées, recadrage sur la Suisse, nettoyage) de sorte que ce notebook n’a besoin que de ce seul fichier, pas d’un dossier de shapefiles et de rasters épars.

Couche vectorielleContenu
switzerlandFrontière nationale
regions4 régions physiographiques (Alpes, Préalpes, Jura, Plateau)
landslides_chInventaire des glissements de terrain (WSL), déjà recadré sur la Suisse
cities, lakesContexte cartographique
classification_pointsRésultats de la classification (écrite en partie 5)
Table raster (100 m, déjà recadrées)Contenu
dem, slope, twi, plancurv, profcurvVariables topographiques
dist_routes, dist_autoroutes, dist_fusswegDistances aux infrastructures
flow_acc, flow_dirHydrologie
geology, landcoverVariables catégorielles
scp_mapCarte de susceptibilité de référence (contexte, non utilisée comme prédicteur)

1. Chargement des données

1.1 Couches vectorielles

Une seule source, un seul CRS : toutes les couches du GeoPackage sont déjà en LV03 (EPSG:21781), pas d’étape de préparation à refaire ici.

Suisse        (1, 12)     CRS: 21781  geom: Polygon
Régions       (4, 13)     CRS: 21781  geom: MultiPolygon
Villes        (3, 2)      CRS: 21781  geom: Point
Lacs          (69, 13)    CRS: 21781  geom: Polygon
Glissements   (3732, 21)  CRS: 21781  geom: Point

1.2 Tables raster

Les rasters vivent dans le même fichier, sous forme de tables (extension GeoPackage 2D gridded coverage). On y accède avec rasterio via une chaîne de connexion GPKG:chemin:nom_table, exactement comme on ouvrirait un .tif.

Table 'dem' : 3476 x 2198 pixels, résolution 100 m, CRS EPSG:21781

13 tables raster disponibles : dem, slope, twi, plancurv, profcurv, dist_routes, dist_autoroutes, dist_fussweg, flow_acc, flow_dir, geology, landcover, scp_map

1.3 Carte nationale, par région physiographique

<Figure size 900x600 with 1 Axes>

2. Étude statistique de l’inventaire des glissements

On explore l’inventaire avant de passer à la modélisation : répartition de l’ampleur des dommages, évolution temporelle, distribution du coût des dommages, et répartition par région.

<Figure size 1900x450 with 4 Axes>
Coût médian des dommages par catégorie d'ampleur (MCHF) :
Dmgext
Low                   0.02
Medium                0.63
Large/catastrophic    2.75
Name: Totdmg, dtype: float64

Le coût des dommages est très asymétrique (quelques évènements catastrophiques dominent le total) et n’est connu qu’aux emplacements des glissements déjà survenus. Pour la partie modélisation, on formule donc plutôt le problème comme une classification : à un emplacement donné, y a-t-il eu — ou non — un glissement de terrain ?


3. Définir le problème de classification

C’est l’approche la plus classique en cartographie de la susceptibilité aux glissements de terrain (modèle présence/absence).

3.1 Points de présence et région physiographique

Les glissements chargés en partie 1 (glissements_ch) constituent les points de présence (label = 1). La couche landslides_ch ne porte pas leur région physiographique : on la leur attribue par jointure spatiale (gpd.sjoin) — elle servira à la fois à équilibrer les pseudo-absences (§3.2) et de groupe de validation croisée (§3.6).

Glissements sans région assignée : 0
region
Alps        1986
Plateau      919
Pre-Alps     549
Jura         278
Name: count, dtype: int64

3.2 Un domaine de tirage réaliste pour les pseudo-absences

Une classification présence/absence a besoin d’exemples négatifs, qui n’existent pas tels quels dans l’inventaire — on les génère par tirage aléatoire (pseudo-absence), une pratique standard en modélisation de la susceptibilité. Mais un tirage uniforme, n’importe où, pose un problème concret ici : landslides_ch est un inventaire de dommages, donc un glissement n’y figure que s’il a endommagé quelque chose — typiquement près d’une route ou d’un bâtiment. Un premier essai avec des absences tirées au hasard partout donnerait d’ailleurs dist_routes comme variable la plus influente : le signal dominant n’étant pas le relief, mais la proximité aux infrastructures, un biais d’observation.

Deux corrections, avant le tirage :

  1. Domaine physiquement valide : on retire les lacs (lakes) et un rayon de 2 km autour des principales villes (cities) — un glissement n’y est pas plausible, ou n’y serait de toute façon pas recensé de la même façon.

  2. Fond comparable en accessibilité (« target-group background », une pratique standard en modélisation de distribution d’espèces/d’aléas à partir de données de présence seule) : on limite le tirage des absences à la même gamme de distance aux routes que celle observée pour les glissements recensés (jusqu’à leur 95ᵉ centile), pour que les deux classes soient comparables en termes d’exposition — et que le modèle soit forcé de s’appuyer sur le relief plutôt que sur la proximité aux infrastructures.

Seuil de distance aux routes (95e centile des glissements recensés) : 671 m
Points de présence : 3732   Points d'absence (pseudo) : 3732
region
Alps        1986
Plateau      919
Pre-Alps     549
Jura         278
Name: count, dtype: int64

3.3 Extraction des variables

On extrait, à chaque point (présence et absence), la valeur des tables raster du GeoPackage (§1.2) — des variables continues, plus deux variables catégorielles (géologie, occupation du sol) traitées à part en §3.4.

VariableTable rasterType
Altitudedemcontinue
Penteslopecontinue
Indice topographique d’humidité (TWI)twicontinue
Courbure planaireplancurvcontinue
Courbure de profilprofcurvcontinue
Distance aux routesdist_routescontinue
Distance aux autoroutesdist_autoroutescontinue
Distance aux chemins pédestresdist_fusswegcontinue
Accumulation de fluxflow_acccontinue
Géologiegeologycatégorielle
Occupation du sollandcovercatégorielle
Jeu de données final : 7461 points (3731 présence / 3730 absence)
Loading...

3.4 Variables catégorielles : géologie et occupation du sol — encodage one-hot

geology et landcover sont des codes entiers qui désignent des catégories, pas une échelle numérique : la classe 5 n’est ni « plus grande » ni « plus proche » de la classe 3 que ne l’est la classe 2, ce sont juste des étiquettes différentes. Utilisées telles quelles dans une régression logistique, ces valeurs seraient interprétées à tort comme un ordre ou une distance numérique qui n’a aucun sens géologique.

Le one-hot encoding (encodage disjonctif complet) règle ce problème : chaque catégorie devient sa propre colonne binaire (0/1) — « ce point est-il en classe géologique 5 ? », « en classe 3 ? », etc. Le modèle apprend alors un effet indépendant par catégorie, sans supposer d’ordre entre elles. pandas fait ça avec pd.get_dummies() ; l’option drop_first=True retire une catégorie de référence (implicite) pour éviter une redondance parfaite entre les colonnes, une pratique standard avant une régression.

Avant d’encoder, on regroupe les catégories trop rares (moins de 30 points) dans une classe Autre : une catégorie vue 2 ou 3 fois ne permet d’apprendre aucun effet fiable, et risquerait même de n’apparaître que dans une seule région — un problème pour la validation croisée par région (§3.6, où chaque région sert de test à tour de rôle).

geology    : 12 catégories conservées après regroupement des classes rares
landcover  : 8 catégories conservées après regroupement des classes rares

2 colonnes catégorielles -> 18 colonnes binaires :
['geol_11', 'geol_13', 'geol_14', 'geol_17', 'geol_2', 'geol_3', 'geol_4', 'geol_5', 'geol_6', 'geol_7', 'geol_Autre', 'lc_1', 'lc_10', 'lc_3', 'lc_4', 'lc_8', 'lc_9', 'lc_Autre']

3.5 Les variables continues distinguent-elles présence et absence ?

<Figure size 1300x1000 with 9 Axes>

3.6 Choix du mode de validation : régions comme groupes

Un partage aléatoire (train/test) mélangerait des points de toutes les régions dans les deux jeux : le modèle pourrait alors apprendre des particularités régionales (un certain type de géologie, un climat local) et sembler bien fonctionner simplement parce qu’il a déjà vu des points très proches — géographiquement et statistiquement — de ceux du test. Comme les processus de glissement diffèrent entre Alpes, Préalpes, Jura et Plateau (§2), on préfère une validation par région : LeaveOneGroupOut entraîne le modèle sur 3 régions et l’évalue sur la 4ᵉ, jamais vue, et on répète l’opération pour chacune des 4 régions à tour de rôle. C’est une mesure plus honnête de la capacité du modèle à généraliser à un nouveau territoire — au prix d’un jeu d’évaluation plus petit à chaque tour.

Nombre de variables (9 continues + indicatrices géologie/occupation du sol) : 27
Nombre de folds (= nombre de régions) : 4
  Fold 'Alps' en test : entraînement sur 3491 points, test sur 3970 points
  Fold 'Plateau' en test : entraînement sur 5623 points, test sur 1838 points
  Fold 'Pre-Alps' en test : entraînement sur 6363 points, test sur 1098 points
  Fold 'Jura' en test : entraînement sur 6906 points, test sur 555 points

4. Entraînement des modèles et quantification des erreurs

On compare un modèle paramétrique simple (régression logistique — un GLM, comme au TP-PY03) à un modèle non-paramétrique (XGBoost, comme au TP-PY04), avec la même procédure d’évaluation pour les deux.

4.1 Boucle de validation croisée par région

À chaque tour, on standardise et on entraîne les deux modèles uniquement sur les 3 régions d’entraînement (jamais sur la région de test), puis on prédit sur la région laissée de côté. On conserve à la fois les métriques par région et les prédictions hors-échantillon (chaque point est prédit une seule fois, quand sa région est le fold de test) pour une évaluation globale poolée.

Loading...

4.2 Résultats par région

Les métriques varient nettement d’une région à l’autre : c’est exactement l’information qu’un partage aléatoire aurait masquée en mélangeant les régions.

<Figure size 800x450 with 1 Axes>

4.3 Quantification globale de l’erreur (prédictions hors-échantillon poolées)

En rassemblant les prédictions hors-échantillon des 4 tours (chaque point prédit une seule fois, jamais par un modèle qui l’a vu à l’entraînement), on obtient une évaluation globale, comparable en format à un split classique : exactitude, précision, rappel, F1, et AUC.

Loading...

4.4 Matrices de confusion et courbes ROC (poolées)

<Figure size 1600x450 with 3 Axes>

4.5 Modèle final et importance des variables

La validation croisée sert à estimer l’erreur de généralisation (§4.1–4.4) ; une fois cette estimation obtenue, on ré-entraîne un dernier modèle sur toutes les données disponibles (aucune région exclue), pour l’interprétation des variables et la carte de probabilité ci-dessous — c’est ce modèle final qui serait utilisé en pratique.

<Figure size 1300x900 with 2 Axes>

4.6 Carte des probabilités prédites (hors-échantillon, XGBoost)

Pour rester honnête, la carte utilise les probabilités hors-échantillon de §4.1 (chaque point prédit par un modèle qui n’a jamais vu sa région), pas le modèle final — sinon les glissements utilisés à l’entraînement paraîtraient artificiellement bien classés.

<Figure size 900x650 with 2 Axes>

5. Export des résultats

Vecteurs de contexte et rasters étaient déjà dans project_landslides.gpkg avant même d’ouvrir ce notebook (§1) : il ne reste qu’à y ajouter les résultats de la classification. On remplace la couche classification_points (déjà présente, issue d’une exécution précédente) plutôt que de réécrire tout le fichier — GeoPackage permet de mettre à jour une seule couche sans toucher aux autres.

Couche 'classification_points' mise à jour dans project_landslides.gpkg (7461 points)

Contenu complet de project_landslides.gpkg :
 - switzerland (vecteur)
 - regions (vecteur)
 - landslides_ch (vecteur)
 - cities (vecteur)
 - lakes (vecteur)
 - classification_points (vecteur)
 - dem (raster)
 - slope (raster)
 - twi (raster)
 - plancurv (raster)
 - profcurv (raster)
 - dist_routes (raster)
 - dist_autoroutes (raster)
 - dist_fussweg (raster)
 - flow_acc (raster)
 - flow_dir (raster)
 - geology (raster)
 - landcover (raster)
 - scp_map (raster)