🧶

Les pelotes de ficelle

On attrape un bout, on tire le fil, on déroule la pelote.

← Revenir à la pelote

Mon modèle faisait brûler l’Atlantique

Deux jours pour bricoler un outil qui prévoit un incendie — et beaucoup plus longtemps à découvrir tout ce qu’il avait faux


Jeudi 23 juillet, un fourgon prend feu sur une départementale à Biscarrosse. À 15 h 45 les flammes passent au massif forestier, et en trois jours 30 000 personnes sont évacuées. Comme tout le monde, je suis ça sur des cartes de points rouges, et une question s’installe — le genre de question qu’on n’ose pas vraiment formuler tant qu’on ne sait pas y répondre : et si ça allait vers le Blayais ?

Le Blayais, c’est la centrale nucléaire posée sur la rive droite de la Gironde, à une cinquantaine de kilomètres au nord de Bordeaux. Une carte de points rouges ne répond pas à cette question. Elle montre où le feu est. Jamais où il va.

Entre les deux, il faut un modèle. J’ai voulu voir jusqu’où on pouvait en bricoler un honnête en deux jours. Le résultat existe, il tourne, et il est consultable ici :

👉 kokusho.ss2i.ca — la carte est publique et se met à jour à chaque nouveau calcul.

Outil expérimental, sans aucune valeur officielle. En cas d’incendie, la seule source qui fait foi est la préfecture.

Mais ce n’est pas la partie intéressante de l’histoire. La partie intéressante, c’est la liste de tout ce qu’il a eu faux — et surtout, par quoi chaque erreur s’est fait attraper.


La première décision est morale, pas technique

Un outil comme celui-là peut afficher deux choses très différentes. La première :

« Le feu atteindra la centrale dans 17 heures. »

C’est net. C’est actionnable. Et c’est une escroquerie. Pour écrire une phrase pareille, il faudrait connaître la position exacte du front, le vent des dix-sept prochaines heures, la sécheresse réelle des combustibles et l’efficacité des secours. Je ne connais aucun de ces quatre éléments. Personne ne les connaît.

La seconde ressemble plutôt à ça :

« Sur 200 scénarios simulés, 6 amènent le feu dans la zone élargie autour de la centrale, au plus tôt dans 29 heures. Le vent prévu est transversal à l’axe du site. Confiance faible : dernière détection satellite il y a 5 heures. »

C’est nettement moins satisfaisant à lire. C’est vrai.

Tout le reste découle de ce choix. L’outil ne trace jamais une trajectoire ; il dessine des enveloppes — le terme consacré pour ces contours qui délimitent la zone atteignable — à 6, 12, 24 et 48 heures, en trois niveaux de plausibilité décroissante : la zone atteinte dans plus d’un scénario sur deux, celle atteinte dans un sur dix, et l’enveloppe extrême qui n’est franchie que dans un scénario sur cent, celui où tout va de travers en même temps.

Et il refuse de résumer la situation en un chiffre unique. Il en donne trois, séparément : le niveau de menace, la confiance qu’on peut accorder à ce jugement, et la fraîcheur de la dernière observation. Parce qu’un « vert » calculé sur des données de quatre heures d’âge n’est pas une bonne nouvelle : c’est un trou d’information. Un satellite qui ne voit rien ne prouve pas que le feu s’est arrêté — il prouve qu’il ne voit rien.


Les briques, et ce qu’elles font vraiment

Schéma de la chaîne de traitement. Les détections thermiques des satellites NASA FIRMS, capteurs VIIRS à 375 mètres, sont regroupées par incendie puis réduites au front actif vu dans les douze dernières heures. La météo AROME de Météo-France, la végétation d'OpenStreetMap et le modèle numérique de terrain alimentent un automate cellulaire, damier de cases de 150 mètres, rejoué deux cents fois par la méthode de Monte-Carlo. Il en sort les enveloppes à 6, 12, 24 et 48 heures, puis un niveau de menace accompagné de la confiance et de la fraîcheur de la donnée

Cliquez sur les figures pour les ouvrir en grand.

Voir le feu : FIRMS et VIIRS. La NASA diffuse gratuitement, presque en temps réel, les détections thermiques de ses satellites — le service s’appelle FIRMS, et les capteurs que j’utilise, VIIRS, découpent le sol en pixels de 375 mètres. Je les préfère à MODIS, plus ancien et quatre fois plus grossier.

Il faut bien comprendre ce qu’est une détection FIRMS : un pixel dont la température de surface est anormale. Pas un contour d’incendie. Avec du retard, des trous quand aucun satellite ne passe, et rien du tout quand la fumée ou les nuages bouchent la vue. Cette nuance gouverne tout le reste de l’article.

Savoir ce qui le pousse : AROME, OSM, MNT. Trois ingrédients font avancer un feu. Le vent d’abord, qui pèse bien plus que le reste : je le prends dans AROME, le modèle à maille fine de Météo-France, et pas en un point unique mais échantillonné sur tout le domaine — un incendie de cette taille traverse plusieurs mailles, et le vent peut tourner localement. La végétation ensuite, tirée d’OpenStreetMap : une pinède sèche brûle, un étang non, une vigne à peine. Le relief enfin, via un modèle numérique de terrain — un fichier d’altitudes, tout simplement — parce qu’un feu monte une pente bien plus vite qu’il ne la descend.

Le faire avancer : l’automate cellulaire. Le cœur du calcul porte un nom savant pour une idée simple.

Automate cellulaire — on découpe l’espace en cellules régulières, ici des carrés de 150 mètres, et on donne une règle qui dit comment l’état d’une cellule dépend de ses voisines. On applique la règle partout, on avance d’un pas de temps, on recommence. Le Jeu de la vie de Conway en est l’exemple le plus connu.

Ma règle : une cellule en feu tente d’allumer ses huit voisines, d’autant plus vite que la végétation y est inflammable, que la pente y monte, et que le vent pousse dans cette direction. Le front prend spontanément une forme elliptique allongée sous le vent — ce que les pompiers observent sur le terrain, et que les modèles reproduisent depuis les années 1980.

Accepter qu’on ne sait pas : Monte-Carlo. C’est le point qui change tout.

Méthode de Monte-Carlo — plutôt que de calculer une seule fois avec les meilleures valeurs possibles, on refait le calcul des centaines de fois en tirant au sort, à chaque fois, les paramètres qu’on connaît mal. On regarde ensuite la distribution des résultats. Le nom vient du casino, et la méthode de la bombe atomique — Ulam et von Neumann, 1946.

Je lance donc 200 tirages. À chaque fois je perturbe ce qui est réellement incertain : l’erreur de prévision du vent — qui croît avec l’échéance et reste corrélée dans le temps, parce qu’une prévision fausse l’est durablement plutôt qu’une heure sur deux — l’erreur de mon propre modèle de vitesse, la sécheresse réelle des combustibles, et l’occurrence des sautes de feu, ces braises projetées en avant du front qui franchissent une route ou un coupe-feu.

Ce qu’on affiche ensuite n’est plus une prévision mais un décompte : cette cellule a brûlé dans 150 de mes 200 mondes possibles, celle-là dans 3. C’est la même logique que le cône d’incertitude des trajectoires de cyclone.

Une précision qui compte : ces fréquences ne sont pas des probabilités au sens actuariel. Ce sont des fréquences conditionnelles à mes hypothèses. Si mes hypothèses sont mauvaises, mes pourcentages le sont aussi. Gardez ça en tête — la suite de l’article ne parle pratiquement que de ça.


Premier résultat : un feu parfaitement immobile

Premier lancement sur les données réelles. Le rapport tombe : surface nouvelle brûlée au bout de 6 heures, 103,5 hectares. Au bout de 12 heures : 103,5 hectares. Au dixième d’hectare près.

Un feu qui ne gagne pas un mètre en six heures sous 17 km/h de vent, c’est faux. Et mes 200 tirages, censés explorer des mondes différents, donnaient tous rigoureusement le même résultat — ce qui est encore plus louche.

La cause tenait à un choix d’indice. Quand je calculais la vitesse de passage d’une cellule à sa voisine, je prenais la vitesse de la cellule source, celle qui brûle déjà. Or je marque toute la surface déjà parcourue comme « cicatrice », avec une vitesse de propagation quasi nulle — ce qui est correct : une zone déjà brûlée ne rebrûle pas facilement.

Sauf que le feu part forcément de la surface déjà brûlée. Toutes mes cellules sources étaient des cicatrices, donc incapables de transmettre quoi que ce soit. Le feu était prisonnier de son propre périmètre.

La correction tient en un mot : prendre la vitesse de la cellule cible, celle dont le combustible est sur le point d’être consommé. C’est d’ailleurs plus juste physiquement — un feu avance à la vitesse que lui permet ce qu’il attaque, pas ce qu’il a déjà brûlé. Bonus inattendu : ça corrige aussi la traversée des plans d’eau, qu’une cellule source combustible pouvait franchir.


Puis j’ai regardé la carte de plus près

L’outil tournait, les enveloppes s’étalaient joliment, les chiffres semblaient plausibles. Je les ai regardés un moment avant de faire ce que j’aurais dû faire d’emblée : ouvrir la carte d’entrée, celle que le modèle utilise, et la regarder vraiment.

Il y avait un problème. Le modèle faisait brûler la mer.

Et c’était vrai. Voici la carte de combustible — l’image qui dit à l’automate, pour chaque cellule, à quelle vitesse le feu peut y avancer. À gauche ce que voyait mon programme, à droite la réalité :

Deux cartes de combustible côte à côte, sur la même zone autour de Biscarrosse. À gauche, l'océan Atlantique est entièrement rendu en vert foncé, la couleur de la pinède : le modèle le traite comme un combustible. À droite, après correction, l'océan apparaît en bleu, nettement séparé du littoral, et l'on distingue les grands étangs de Cazaux-Sanguinet et de Biscarrosse-Parentis

Toute la masse vert foncé à gauche, c’est l’Atlantique. Classé pinède.

La raison est presque amusante. OpenStreetMap ne cartographie pas l’océan comme une surface. Il n’existe aucun polygone « Atlantique » : les contributeurs ont tracé le trait de côte — dans le jargon OSM, un chemin étiqueté natural=coastline — c’est-à-dire une ligne, pas une surface. Ma requête, elle, cherchait des surfaces. Elle récupérait consciencieusement les lacs, les étangs et les rivières, tous des polygones, et le large ne correspondait à rien.

Or hors polygone reconnu, mon programme suppose de la pinède. C’était un choix délibéré : dans le massif landais le pin maritime domine, et se tromper du côté « ça brûle » biaise le modèle du côté prudent. Sauf qu’appliquer cette prudence à 40 % du domaine de calcul, ça ne s’appelle plus de la prudence. Sur cette carte, l’eau passe de 3,4 % à 40,7 % une fois corrigé : plus du tiers de ma zone de travail était de l’océan inflammable.

Ma première correction récupérait le trait de côte et découpait le domaine avec — parfait sur mon test isolé. En conditions réelles, échec : trois requêtes sur douze au serveur OpenStreetMap sont revenues en erreur, le trait s’est retrouvé troué, et un trait troué ne découpe rien. La mer est redevenue combustible.

La bonne solution était ailleurs, et elle exploite une convention d’OpenStreetMap : quand on trace une côte, la terre est toujours à gauche du sens de tracé. Il suffit donc, pour chaque cellule, de trouver le segment de côte le plus proche et de regarder de quel côté on tombe — un simple produit vectoriel. À gauche la terre, à droite la mer. Un trou dans la donnée ne coûte plus que la précision locale autour du trou.

Je n’ai su que ma première correction avait échoué que parce que j’avais pris soin de faire crier le programme. Quand il n’arrivait pas à reconstituer la mer, il écrivait noir sur blanc dans son rapport : « trait de côte présent mais impossible d’en déduire l’emprise de la mer : le large risque d’être traité en combustible ». Un modèle qui échoue en silence ment. Un modèle qui échoue bruyamment se laisse réparer.


La question qui fâche : est-ce que ça marche ?

À ce stade, l’outil produisait de jolies cartes. Une jolie carte n’a jamais rien prouvé.

Et j’avais sous la main de quoi le prendre en défaut : l’incendie durait depuis plusieurs jours, donc son propre passé était disponible. Plutôt que d’attendre de voir si les prochaines prévisions tombaient juste, autant rejouer celles qu’on aurait pu faire l’avant-veille et regarder ce qu’elles valaient. C’est une méthode connue, elle porte un nom : la rétro-prévision.

Rétro-prévision (ou hindcast) — on se replace à un instant du passé, on ne garde que les données disponibles à cette date, on simule vers l’avant, puis on compare à ce qui s’est réellement produit. C’est la façon standard d’évaluer un modèle de prévision quand on ne peut pas se permettre d’attendre.

Je me replace donc au 24 juillet au matin, je jette tout ce qui a été observé après, je simule douze heures, je compare à ce qui a réellement brûlé. Puis je recommence le 25. Deux exécutions, une poignée de minutes de calcul — et de très loin le meilleur rapport entre l’effort fourni et ce que ça m’a appris.

Graphique en barres comparant, à la même échelle, la surface réellement brûlée en douze heures et celle produite par le modèle. Le 24 juillet, alors que le feu courait librement, 4 642 hectares observés contre 10 008 simulés, soit un biais de surface de 1,7. Le 25 juillet, alors que les secours tenaient le front, 1 645 hectares observés contre 22 758 simulés, soit un biais de 12,3

Le 24 au matin, quand le feu courait librement, le modèle sur-prédit d’un facteur 1,7. Pour un modèle de propagation, c’est honorable — on est dans le bon ordre de grandeur. Le 25, alors que les secours reprenaient le front en main : facteur 12,3.

Ce qui est intéressant, ce n’est pas que le modèle se trompe. C’est où passe la différence entre les deux journées. Le modèle n’est pas devenu mauvais du jour au lendemain : même code, même vent, même forêt. Ce qui a changé entre le 24 et le 25, ce sont les moyens de lutte.

Mon programme ne les voit pas. Il ne sait rien des effectifs engagés, ni des lignes d’appui — ces coupures que les pompiers ouvrent au bulldozer pour arrêter le front — ni des largages. Il calcule donc, sans que je l’aie décidé explicitement, un contrefactuel sans lutte : ce que ferait l’incendie si personne ne s’y opposait. Le 25, la physique seule donnait 22 758 hectares ; le feu n’en a parcouru que 1 645, parce que des gens l’en ont empêché.

Il y a une consolation dans ces chiffres, et elle est importante. Elle tient dans une mesure qui s’appelle l’AUC.

AUC, pour aire sous la courbe ROC — mesure la qualité d’un classement, indépendamment des valeurs absolues. Si je prends au hasard une cellule qui a brûlé et une qui n’a pas brûlé, l’AUC est la probabilité que le modèle ait mieux classé la première. 0,5 = tirage à pile ou face, 1 = classement parfait.

Mon AUC vaut 0,96 à 0,98 dans les deux cas — pendant que le biais de surface, lui, varie d’un facteur sept. Autrement dit : le modèle sait très bien où le feu va, et se trompe lourdement sur combien. C’est le meilleur mode d’échec possible, parce qu’une erreur d’échelle se calibre, alors qu’une erreur de direction condamne l’outil.

Ce qui m’amène à la décision la moins intuitive de tout ce bricolage. J’avais un facteur de calage tout prêt : ralentir la propagation de ce qu’il fallait pour retomber sur le 25 juillet. Je ne l’ai pas appliqué. Ce serait graver dans le modèle l’hypothèse « la lutte réussit toujours » — précisément celle à laquelle il ne faut pas se fier devant une centrale nucléaire. L’outil refuse d’ailleurs de lui-même de publier un facteur global quand ses cas de validation sont trop hétérogènes, et explique pourquoi plutôt que de moyenner deux régimes incomparables.


Ce qu’il ne fait pas — et c’est le plus grave

La pire limite n’est aucune de celles que je viens de raconter. Elle tient en un mot : le couplage est à sens unique. La météo pilote le feu ; le feu ne modifie jamais l’atmosphère.

Or un grand incendie fabrique sa propre météo. C’est la pyroconvection : la colonne d’air surchauffé qu’il envoie vers le ciel peut monter à plusieurs kilomètres et former un pyrocumulonimbus, un véritable nuage d’orage né du feu lui-même. Il produit de la foudre sèche qui allume des départs à des dizaines de kilomètres, et il peut s’effondrer d’un coup en rabattant au sol une rafale violente, dans une direction quelconque.

C’est exactement ce qui fait échapper les feux qu’on croyait tenus, et c’est indépendant du vent synoptique — le vent de grande échelle, celui que prévoit AROME. Donc invisible pour mon modèle. Un vrai couplage feu-atmosphère existe, il porte des noms comme Meso-NH/ForeFire ou WRF-SFIRE, et il demande des moyens de calcul de laboratoire. Hors de portée.

Le compromis : ne pas simuler le phénomène, mais en évaluer le potentiel. Il existe pour ça un indicateur, l’indice de Haines continu, qui combine l’instabilité de l’air en altitude et sa sécheresse — en somme, il dit si le ciel « fait cheminée » ce jour-là. Croisé avec la puissance radiative du feu, il me donne un score. Une fraction de mes 200 tirages, égale à ce score, bascule alors en régime pyroconvectif : direction bien plus incertaine, propagation majorée, sautes de feu plus nombreuses et plus lointaines. Ces tirages-là nourrissent naturellement l’enveloppe extrême.

Un potentiel élevé se lit donc « les enveloppes larges deviennent crédibles », jamais « il va se produire ceci ».

Autre angle mort, découvert en regardant arriver la canicule de cette semaine. Mon humidité des combustibles fins vient d’une formule classique de danger météorologique, celle de Simard, qui ne regarde que la température et l’humidité relative instantanées. Elle n’a aucune mémoire. Or trois jours à 38 °C assèchent la litière en profondeur et le sol avec. D’où ce résultat absurde : mon modèle affiche une humidité des combustibles qui remonte le jour où il fera 39,8 °C. Il sous-estime donc l’effet d’une canicule. Il faudrait des indices à mémoire, du type DMC et DC de l’indice forêt-météo canadien, qui cumulent le déficit hydrique sur des jours et des semaines. C’est le prochain chantier.


Alors, le Blayais ?

Capture de l'outil en ligne. À gauche une carte du littoral aquitain : la surface déjà parcourue en gris, le front actif en orange, et les enveloppes à 48 heures en contours jaunes autour de deux foyers. À droite un panneau qui donne pour chaque site sensible le niveau de menace, la confiance, la distance au front et les distances minimales simulées

Cliquez pour agrandir — ou allez voir la version vivante sur kokusho.ss2i.ca.

La réponse est restée la même du premier au dernier calcul : front observé à 36 kilomètres, aucun des 200 scénarios n’approchant à moins de 10 kilomètres, vent poussant à l’opposé. La centrale n’a jamais été menacée. Et l’outil le dit avec ses motifs, pas avec un verdict.

Le site réellement exposé était ailleurs : la base aérienne de Cazaux, à 7 kilomètres du foyer de Biscarrosse, avec jusqu’à 6,7 % des scénarios atteignant sa zone élargie.

Et puis il y a eu ce dernier matin où Cazaux est brusquement passé en orange, avec 96,7 % des scénarios atteignant cette même zone. Spectaculaire. Et faux.

Le satellite n’avait rien vu depuis quinze heures. Mon programme s’était rabattu sur son hypothèse de repli : faute de savoir où se trouve le front actif, considérer que tout le périmètre parcouru est actif. L’incendie se propageait donc dans toutes les directions à la fois, et mes 96,7 % ne mesuraient plus une convergence vers Cazaux — ils mesuraient mon ignorance. La vitesse de rapprochement réellement observée, elle, était nulle.

Désormais, dans ce cas précis, le niveau retombe sur « incertitude élevée, aucun rapprochement observé » au lieu de crier au feu — sauf si un rapprochement est réellement mesuré, auquel cas l’alerte tient. C’est peut-être la correction dont je suis le plus content : elle empêche l’outil de transformer une absence d’information en alerte.


Ce que j’en retiens

Tout ça a été bricolé en deux jours, et le code, je ne l’ai pas tapé : je l’ai fait écrire par une IA. Même méthode que pour le convertible tchèque il y a trois semaines, mais cette fois sur un sujet où se tromper n’est pas anodin.

Ce qui ne se délègue pas, en revanche, c’est le reste : décider qu’on afficherait des enveloppes et jamais une trajectoire, choisir les sources, exiger que le modèle soit éprouvé sur le passé de l’incendie plutôt que sur des tests de laboratoire, et rouvrir la carte d’entrée quand un résultat sentait le faux. La machine écrit vite et bien. Elle ne sait pas ce qu’il faut vérifier.

Cinq erreurs de fond ont été trouvées dans le modèle. Ce qui m’a le plus surpris, c’est de regarder par quoi :

  • le feu prisonnier de sa cicatrice : par un chiffre invraisemblable dans un rapport ;
  • la rastérisation qui s’enlisait : par un calcul qui ne rendait plus la main ;
  • la mer combustible : parce que j’ai fini par regarder la carte d’entrée, celle que personne ne pense à ouvrir ;
  • la reconstruction du littoral qui ne tenait pas en réel : par un avertissement que j’avais pris la peine d’écrire pour ce cas précis ;
  • la fausse alerte orange : en confrontant ce que disait la simulation à ce que disait l’observation.

Aucune n’a été trouvée par les tests automatiques. J’en ai soixante-quatre, et chacun de ces bugs a désormais le sien — ils empêcheront la régression. Mais aucun test ne pouvait deviner qu’OpenStreetMap ne cartographie pas l’océan. Les tests vérifient ce à quoi on a déjà pensé. Ils sont muets sur le reste.

Ce qui a marché, c’est le frottement avec le réel : les vraies données, la vraie carte, le vrai passé de l’incendie. La rétro-prévision m’a appris davantage en deux exécutions que deux jours de développement.

Et son enseignement principal n’était pas « le modèle se trompe de tant ». C’était : le modèle ne répond pas à la question que je croyais lui poser. Je lui demandais ce que cet incendie allait faire. Il me répondait ce qu’il ferait si personne ne s’y opposait.

C’est une information utile — c’est même exactement celle qu’il faut pour savoir de quoi un incendie est capable. Mais ce n’est pas celle qu’on croit lire sur une carte.


🔥 Voir l’outil en ligne — kokusho.ss2i.ca

Expérimental, sans valeur officielle. En cas d’incendie, la seule source qui fait foi est la préfecture : landes.gouv.fr · gironde.gouv.fr.