David Madore's WebLog: Jouons avec les minima et les maxima

[Index of all entries / Index de toutes les entréesLatest entries / Dernières entréesXML (RSS 1.0) • Recent comments / Commentaires récents]

↓Entry #2825 [older| permalink|newer] / ↓Entrée #2825 [précédente| permalien|suivante] ↓

(dimanche)

Jouons avec les minima et les maxima

☞ Données de températures à Paris Montsouris

En ce moment il fait chaud à Paris (et en plus notre clim est en panne), alors je suis allé récupérer des jeux de données météo, dont je m'étais plaint précédemment qu'elles n'était pas librement disponible, et qui le sont maintenant, pour faire joujou avec. En l'espèce, je suis allé récupérer[#] les températures relevées à Paris depuis 1873, spécifiquement celles à la station du parc Montsouris (ici).

[#] La source est ici (j'ai utilisé les fichiers Q_75_1816-1949_RR-T-Vent.csv.gz, Q_75_previous-1950-2023_RR-T-Vent.csv.gz et Q_75_latest-2024-2025_RR-T-Vent.csv.gz) ; je précise ça parce que c'est un vrai labyrinthe d'aller entre le site des données publiques de Météo France et l'endroit où sont vraiment les fichiers dont je parle, ça continue à ressembler à la blague avec les chaussures au Goum que j'avais raconté dans ce billet, sauf que maintenant il y a vraiment des chaussures au bout, mais elles sont introuvables depuis l'entrée. (En fait, j'avais bookmarké le lien, et je ne sais honnêtement pas comment j'ai réussi à naviguer jusque là.)

[Graphique montant les températures relevées à Paris Montsouris de 1874 à 2024 montrant, pour chaque année, la maximale, la minimale et la moyenne][Graphique montant les températures relevées à Paris Montsouris de 1874 à 2024 montrant, pour chaque année, la température moyenne]C'est un jeu de données intéressant, parce que, quand même, 152 ans d'observations continues, ce n'est pas mal du tout[#2] : il y a bien quelques jours qui manquent ou sont incomplets[#3] ou douteux (725 jours au total depuis 1873, le plus récent en 1936), et je suppose qu'il faut interpréter ces anciennes observations avec une certaine prudence, mais ça doit néanmoins être une source très précieuse pour les historiens, et en tout cas c'est très rigolo pour faire joujou avec. Faire joujou est exactement ce que je me propose de faire dans ce billet.

[#2] Ce n'est pas le plus ancien relevé que Météo France ait dans son jeu : il y a des températures mesurées à l'Observatoire de Paris qui remontent à 1816 (par exemple, on y apprend que les températures relevées pour le étaient de 20.5°C pour la minimale et 31.0°C pour la maximale, et que c'était la journée la plus chaude de ce mois-là). Mais le jeu pour Paris Montsouris a l'air d'être le plus complet qui soit.

[#3] Dans certains raisonnements mathématiques que je vais tenir ci-dessous, je vais faire comme s'il n'y avait pas ces lacunes. Il faut donc les prendre avec des pincettes (enfin, les raisonnements sont corrects, mais leur applicabilité est parfois sujette à caution). J'essaierai quand même de le resignaler de temps en temps.

☞ J'aime faire joujou avec des jeux de données

J'ai déjà dû écrire quelque part (et peut-être qu'un jour je ferai un billet entièrement sur le sujet) que j'aime beaucoup jouer avec des jeux de données : faire des stats dessus, tracer des graphes, chercher des corrélations, regarder les extrêmes, les moyennes, les écarts-types, ce genre de choses. Beaucoup de gens feraient ça avec un tableur, d'autres avec Python, moi personnellement je préfère Perl et Gnuplot[#4], mais peu importe.

[#4] J'aime bien Perl parce qu'il est vraiment efficace pour écrire du code qui lit des fichiers textes, et il a l'avantage important à mes yeux sur Python que je peux écrire directement en ligne de commande un one-liner comme perl -F';' -ane 'if ($F[0] eq "75114001" && $F[8] ne "" && $F[12] ne "" && $F[9]==1 && $F[13]==1 && $F[5] ge "18730101") { $med = ($F[16] ne "" && $F[17]==1) ? $F[16] : ($F[8]+$F[12])/2; print "$F[5]\t$F[8]\t$med\t$F[12]\n"; }' Q_75_1816-1949_RR-T-Vent.csv Q_75_previous-1950-2023_RR-T-Vent.csv Q_75_latest-2024-2025_RR-T-Vent.csv > paris-temps.dat sans avoir besoin d'ouvrir un script, de lui trouver un nom, d'indenter chaque ligne précisément comme Python le veut. Et l'avantage de mettre ça directement en ligne de commande c'est que souvent je mélange avec d'autres outils Unix (egrep, sort, awk, cut, tail, etc.) en enfilant les pipes. Par rapport à un tableur, l'avantage est surtout que n'ai pas besoin de refaire plein de manips répétitives à la souris. Pour ce qui est de Gnuplot, en revanche, je ne le recommanderais pas du tout, c'est assez merdique (l'édition de ligne de commande est complètement cassée, donc en fait je me retrouve à faire des echo machin | gnuplot complètement stupides) et c'est plutôt l'inertie qui me fait continuer à m'en servir.

J'avais fait en 2023 quelque chose d'un peu sérieux pour l'analyse des températures moyennées sur toutes la France depuis 1950 (telles qu'extraites de la réanalyse ERA5). Mais le but de ce billet est moins de parler des températures elles-mêmes (c'est plutôt un prétexte) que de parler de la notion de maximum et de minimum, qui est un des concepts mathématiques les plus simples qui soient, mais qui peuvent déjà servir d'illustration de comment un mathématicien pense le monde (cf. ce que j'écrivais dans ce billet). Et je vais en profiter pour (sans doute mal) vulgariser le théorème du minimax de von Neumann. Mais l'idée est surtout de m'amuser avec tout ça (i.e., comme le titre l'indique, ce billet n'a aucun intérêt si ce n'est de me distraire).

☞ Maximales, minimales et moyennes

Bon, la température maximale ou minimale sur une journée, ou sur une année, ou sur une longue période, je pense que tout le monde comprend ce que ça veut dire.

La température moyenne, c'est déjà un petit peu plus compliqué. Historiquement, la température moyenne sur la journée est estimée comme la moyenne entre le maximum et le minimum (je veux dire, ½·(maximum+minimum)), parce que ce n'est pas évident d'avoir un instrument qui mesure ou calcule la moyenne. Mais plus récemment (depuis 1950, on dirait ?), on s'est mis à enregistrer dans les relevés météos une vraie moyenne calculée, je crois, heure par heure (c'est encore une approximation de ce que serait une moyenne calculée de façon continue, mais c'est déjà beaucoup mieux). Il y a une parfois certaine confusion dans les jeux de données entre les deux ; et c'est déjà un premier signe d'un esprit mathématique que de comprendre la différence entre les deux et d'imaginer immédiatement à quoi ressemble une situation où elles vont différer significativement (par exemple, un pic de chaleur bref mais intense dans la journée va augmenter significativement la maximale mais beaucoup moins la vraie moyenne, donc la demi-somme ½·(maximum+minimum) sera plus élevée que la moyenne). Sur une plus longue période, la différence est moins importante.

Je précise donc que dans ce que j'utilise ci-dessous comme moyenne, c'est la moyenne rapportée par Météo France s'il y en a une, et, sinon, faute de mieux, c'est juste la demi-somme ½·(maximum+minimum) (et donc, en gros, ça semble changer en 1950).

Bref, si je dis quelque chose comme le maximum jamais enregistré à Paris Montsouris est de 42.6°C le (vers 14h30), le minimum jamais enregistré y est de −23.9°C au matin du ou la moyenne sur toute la période allant du au est de 11.5°C, je pense que tout le monde comprend bien.

☞ Maxima de minima et minima de maxima

Ça devient déjà plus compliqué si je parle de maximum du minimum ou de minimum du maximum. Par exemple : la plus haute minimale quotidienne enregistrée à Paris Montsouris est de 25.5°C le (vers 5h10), la plus basse maximale est de −10.5°C le . Il s'agit là d'un maximum (sur la période) des minima (sur la journée), et d'un minimum (sur la période) des maxima (sur la journée). Concrètement, les gens penseront au maximum des minima comme la nuit la plus chaude, mais entendons-nous bien, il ne s'agit pas d'une moyenne sur la nuit, il s'agit du point le plus froid de la journée (qui se trouve être au petit matin), et ensuite on cherche dans la période considérée la journée où ce minimum est le plus élevé.

L'idée est donc de parler ici de ce qui se passe quand on combine des minima, des moyennes et des maxima, de « toutes les manières possibles », et mon jeu de températures est juste un prétexte pour faire ça.

On peut y penser comme un tableau à deux entrées : une entrée (disons, la colonne) est l'heure du jour, et l'autre (disons, la ligne du tableau) est le jour dans la période. On cherche alors le minimum ou le maximum, ou d'ailleurs la moyenne, de chaque ligne et ensuite le maximum, le minimum, ou d'ailleurs la moyenne, de ces nouvelles valeurs. Ça nous fait neuf valeurs différentes.

Mais comme la météo a deux cycles naturels, le jour et l'année, il est en fait plus logique de considérer trois paramètres : l'année, le jour de l'année, et l'heure du jour. Et comme sur chaque paramètre on peut considérer le maximum, le minimum, ou la moyenne, ça fait 3×3×3 = 27 valeurs distinctes. Pour être bien clair, pour l'instant, je parle de prendre le maximum ou minimum ou la moyenne de la température sur la journée (i.e., sur les heures de la journée), puis de prendre le maximum ou minimum ou la moyenne de ces valeurs sur l'année (i.e., sur les jours de l'année), puis de prendre le maximum ou minimum ou la moyenne de ces valeurs-là sur l'ensemble de la période (i.e., sur les années de la période). Je parlerai après de ce qui se passe si on change l'ordre des opérations.

Bon, là il y a un petit point qu'il faut que j'évoque, c'est comment on découpe les jours et les années. Les jours, on les découpe de minuit à minuit, c'est assez naturel. C'est aussi raisonnable pour faire de la météo, parce que ni le minimum ni le maximum ne vont typiquement se produire près de minuit (enfin, c'est rare, même si ça peut arriver quand une nuit fraîche suit une nuit très chaude, si bien que le minimum sur 24h serait au début de la nuit suivante). Pour l'année, en revanche, commencer au premier janvier est une mauvaise idée, parce que le minimum sur un hiver peut facilement se produire soit en décembre soit début janvier, et il sera alors artificiellement rattaché soit à l'année N−1 soit à l'année N. (Les saisons météorologiques commencent par convention en mars, juin, septembre et décembre.) J'ai choisi de découper au premier septembre, comme ça ça colle à la fois à des saisons météorologiques mais aussi plus ou moins au calendrier universitaire ; le choix du premier décembre se serait sans doute aussi justifié. Bref, mes années vont du premier septembre au 31 août, et je rattache, par exemple, le (plus basse température maximale observée à Paris, cf. ci-dessus) à l'année 1938–1939 (celle qui va du au inclus). Dans tout ce qui suit, sauf précision du contraire, quand je parle d'années, ce sont ces années de septembre à août.

☞ 27 combinaisons

Ceci étant dit, voici les 27 combinaisons possibles de minima, moyennes et maxima (je vais commenter cette table après) :

#FormuleValeurAnnéeDate
0mina(minj(minh))−23.91879–18801879-12-10
1mina(minj(moyh))−15.11879–18801879-12-10
2mina(minj(maxh))−10.51938–19391938-12-20
3mina(moyj(minh))4.51890–1891
4mina(moyj(moyh))8.81890–1891
5mina(moyj(maxh))13.01890–1891
6mina(maxj(minh))15.81874–18751875-08-18
7mina(maxj(moyh))22.21909–19101910-07-16
8mina(maxj(maxh))29.01976–19771977-07-03
9moya(minj(minh))−7.5
10moya(minj(moyh))−4.6
11moya(minj(maxh))−2.6
12moya(moyj(minh))7.7
13moya(moyj(moyh))11.5
14moya(moyj(maxh))15.6
15moya(maxj(minh))20.2
16moya(maxj(moyh))26.4
17moya(maxj(maxh))34.2
18maxa(minj(minh))−1.01974–19751975-03-19
19maxa(minj(moyh))1.12013–20142013-12-12
20maxa(minj(maxh))4.12013–20142014-01-21
21maxa(moyj(minh))10.62023–2024
22maxa(moyj(moyh))13.92023–2024
23maxa(moyj(maxh))18.22021–2022
24maxa(maxj(minh))25.52002–20032003-08-12
25maxa(maxj(moyh))34.02018–20192019-07-25
26maxa(maxj(maxh))42.62018–20192019-07-25

(Si vous préférez une version texte brut, elle est ici. Quant aux records individuels par année, ils sont là.)

Voici comment cette table doit se lire : la formule nous dit le sens de la valeur qui suit : min, moy et max désignent, naturellement, le minimum, la moyenne et le maximum, et l'indice rappelle sur quoi il a été pris (a pour l'année dans la période, j pour le jour dans l'année, et h pour l'heure dans la journée). La colonne suivante indique l'année où la fonction extérieure est atteinte (ça n'a pas de sens pour une moyenne, donc je ne mets rien), et la suivante indique la date où la fonction du milieu est atteinte (idem, ça n'a pas de sens pour une moyenne, donc je ne mets rien).

Par exemple, rangée 7, mina(maxj(moyh)) signifie qu'on a pris la moyenne des températures sur toutes les heures de la journée, qu'on a pris le maximum de ça sur les jours de l'année, et qu'on a pris le minimum de ça sur les années de la période. Il s'agit donc de l'année ayant la plus froide journée la plus chaude en température moyenne. Donc, le , la température moyenne[#5] sur la journée vaut 22.2°C, c'est la journée la plus chaude en moyenne sur cette année-là, mais n'importe quelle autre année a une journée plus chaude que ça.

[#5] En fait, comme je l'ai déjà dit, ici c'est juste la demi-somme entre minimum et maximum parce que c'est tout ce que j'ai avant 1950.

Si on veut, les rangées 0–8 sont neuf façons différentes de définir l'année la plus froide à Paris, les 9–17 décrivent l'année moyenne à Paris selon neuf mesures différentes, et les 18–26 sont les années les plus chaudes selon neuf définitions différentes. Dans chaque bloc, les trois premières rangées concernent la journée la plus froide de l'hiver, les trois suivantes concernent la journée moyenne de l'année, et les trois suivantes concernent la journée la plus chaude de l'année. Et dans chaque bloc de trois lignes, la première concerne la température minimale dans la journée, la seconde la température moyenne de la journée, et la troisième la température maximale de la journée.

Je pense que c'est un exercice intéressant de parcourir cette table et de réfléchir à ce que chaque rangée signifie et nous donne comme information. (Par exemple, rangée 9, en moyenne, la température à Paris descend à –7.5°C au plus froid de l'hiver.) En quelque sorte, ce sont 27 nombres qui définissent assez bien le climat de Paris, et ça peut être une façon de décrire le climat d'une ville que de donner ces 27 valeurs calculées sur l'intervalle de données dont on dispose.

☞ Petit commentaire

(Ensuite, on pourrait encore ajouter une autre couche, et prendre les points d'un pays et faire le minimum, la moyenne ou le maximum de chacun de ces 27 paramètres, ce qui donnerait 81 valeurs pour le climat d'un pays ; je vais redire un mot là-dessus, mais restons à Paris pour l'instant.)

J'aime bien dire et répéter qu'il ne faut pas faire des stats sur les extrêmes, et que le réchauffement climatique se lit avant tout sur les moyennes et pas sur les extrêmes[#6], mais c'est quand même significatif que huit des neuf définitions de l'année la plus chaude (ou la moins froide) à Paris depuis 1873 (les rangées 18–26 de la table, sauf la 18, donc) sont toutes au XXIe siècle.

[#6] Ce qu'illustrent bien, je trouve, les graphes au tout début de ce billet : le réchauffement climatique est très visible sur le graphe des moyennes annuelles parce qu'elles fluctuent beaucoup moins, mais les minimales et maximales font n'importe quoi. Et le problème d'attirer l'attention du grand public sur les événements extrêmes comme les canicules, c'est qu'un jour il y aura bien une vague de froid exceptionnelle et que si on a dit et répété aux gens les canicules démontrent le réchauffement climatique, ils concluront donc cette vague de froid démontre que c'est un mensonge.

Mais cette table est aussi très révélatrice d'un certain esprit matheux : j'espère ne pas généraliser trop abusivement mon propre cas en disant qu'il y a quelque chose de très satisfaisant pour l'esprit, quand on aime les maths, de voir toutes les combinaisons de min/moy/max représentées ainsi. J'y pense à chaque fois que je vois les tableaux climatiques sur Wikipédia (ici pour Paris, je lie la version en anglais parce qu'elle a le tableau dont je parle) : il y a des lignes record high, mean daily maximum, daily mean, mean daily minimum et daily low, et à chaque fois j'ai envie de crier il me manque des infos, là !.

C'est aussi vaguement instructif informatiquement de programmer la génération de la table ci-dessus. Je pourrais utiliser ça comme exercice de code golf ou comme façon de détecter un programmeur pas trop incompétent : je vous donne un tableau de données avec, pour chaque jour, les températures minimale, moyenne et maximale (si la moyenne manque, remplacez-là par ½·(maximum+minimum)), maintenant générez-moi la table ci-dessus (sans écrire 27 bouts de code différents). Bon, mon propre code est un peu dégueu donc je n'ai pas forcément envie de le montrer, mais si quelqu'un veut montrer l'élégance de son style de programmation, ou comment faire les choses de façon concise, qu'il ne s'en prive pas.

☞ Permutation de deux fonctions

Bon, mais ce n'est pas tout. Ces 27 valeurs ne sont pas la fin de l'histoire, parce qu'on peut aussi permuter les fonctions min/moy/max. Dans la table ci-dessus, j'ai pris d'abord le min/moy/max au sein de la journée, puis le min/moy/max sur les jours de l'année, et enfin le min/moy/max sur les années de la période. Et si je faisais dans un ordre différent ?

La fonction qui porte sur l'heure il vaut mieux la laisser à l'intérieur (i.e., en premier), parce que je n'ai pas des données horaires précises sur l'heure de telle ou telle température, j'ai juste le min et le max et éventuellement la moyenne. Donc je ne peux que la laisser en premier (à l'intérieur). Mais les deux autres fonctions, celle sur le jour et celle sur l'année, on peut les permuter.

Évidemment, le max sur l'année du max sur le jour de l'année, c'est la même chose que le max sur le jour de l'année du max sur l'année : imaginez un tableau avec les années en ligne et les jours de l'année en colonne : c'est juste le plus grand nombre du tableau. Mais prendre le min sur chaque ligne et ensuite le max du résultat (ce que font les rangées 18–20 de la table ci-dessus) n'est pas pareil que de prendre le max de chaque colonne et ensuite le min du résultat. Je vais revenir là-dessus.

☞ Nouvelle table de 27 combinaisons

D'où une nouvelle table de minima, moyennes et maxima où, cette fois, après avoir pris comme avant le minimum, la moyenne ou le maximum sur les heures de la journée, je regarde l'ensemble des dates de même nom (par exemple, le 5 août) sur la période, pour faire un minimum, une moyenne ou un maximum, puis je fais le minimum, la moyenne ou le maximum sur l'ensemble des 366 jours du calendrier. Ça donne ceci :

#FormuleValeurJourDate
0minj(mina(minh))−23.912-101879-12-10
1minj(mina(moyh))−15.112-101879-12-10
2minj(mina(maxh))−10.512-201938-12-20
3minj(moya(minh))1.001-17
4minj(moya(moyh))3.401-17
5minj(moya(maxh))5.801-07
6minj(maxa(minh))9.301-262002-01-26
7minj(maxa(moyh))10.901-292013-01-29
8minj(maxa(maxh))13.101-212012-01-21
9moyj(mina(minh))−1.6
10moyj(mina(moyh))2.8
11moyj(mina(maxh))5.5
12moyj(moya(minh))7.7
13moyj(moya(moyh))11.5
14moyj(moya(maxh))15.6
15moyj(maxa(minh))15.9
16moyj(maxa(moyh))20.1
17moyj(maxa(maxh))26.1
18maxj(mina(minh))9.707-191922-07-19
19maxj(mina(moyh))14.607-311891-07-31
20maxj(mina(maxh))18.208-111902-08-11
21maxj(moya(minh))15.107-31
22maxj(moya(moyh))20.008-05
23maxj(moya(maxh))25.408-05
24maxj(maxa(minh))25.508-122003-08-12
25maxj(maxa(moyh))34.007-252019-07-25
26maxj(maxa(maxh))42.607-252019-07-25

(La colonne jour donne le jour dans le calendrier, au format MM-JJ.)

(Si vous préférez une version texte brut, elle est ici. Quant aux records individuels par jour de l'année, ils sont là.)

Par exemple, la rangée 19, maxj(mina(moyh)) signifie qu'on a pris la moyenne des températures sur toutes les heures de la journée, qu'on a pris le minimum de ça, pour chaque jour du calendrier, sur l'ensemble des années de la période, et qu'ensuite on a pris le maximum sur tous les jours du calendrier. Il s'agit donc du jour de l'année qui est le plus chaud sur l'année où il est le plus froid en température moyenne. Donc, le , la température moyenne sur la journée (en fait ½·(maximum+minimum)) vaut 14.6°C, c'est l'année la plus froide un 31 juillet (pour la température moyenne), mais n'importe quel autre jour de l'année a une année moins chaude que ça.

Pour résumer très succinctement la différence entre mes deux tables, disons qu'avant je faisais surtout des statistiques sur les années, maintenant j'en fais surtout sur les jours de l'année.

Plus précisément, si on veut, les rangées 0–8 sont neuf façons différentes de définir le jour le plus froid de l'année à Paris, les rangées 9–17 décrivent le jour moyen à Paris selon neuf mesures différentes, et les 18–26 sont les jours de l'année les plus chaudes selon neuf définitions différentes.

☞ Le lien entre ces deux tables

Mais bien sûr, c'est aussi intéressant de comparer les deux tables. Quel est le rapport entre les deux ? Autrement dit, quel est le rapport entre mvvj(muua(—)) que donne la seconde table, et muua(mvvj(—)) que donne la première ? (Où j'écris muu et mvv pour représenter soit min, soit moy, soit max.) Voilà exactement le genre de questions qu'on aime se poser en maths (bien sûr, en les généralisant).

Il faut imaginer, donc, qu'on a un tableau de 153 lignes et 366 colonnes, dont la ligne indique l'année, la colonne indique le jour de l'année, et chaque case est remplie avec une température (soit maximale, soit moyenne, soit minimale ; donc en fait trois tableaux différents, mais je vais en considérer un seul à la fois) pour ce jour-là. Pour calculer la première table ci-dessus, j'ai d'abord fait des min/moy/max ligne par ligne (i.e., année par année) de ce grand tableau de températures, puis des min/moy/max de tout ça. Dans ma seconde table, j'ai d'abord fait des min/moy/max colonne par colonne (i.e., pour chaque jour de l'année) du grand tableau, puis j'ai fait des min/moy/max de tout ça. Quel est le rapport ?

La première chose, c'est qu'un maximum de maxima est juste la plus grande valeur du tableau, et un minimum de minima est juste la plus petite valeur du tableau. Et une moyenne de moyennes est juste[#7] la moyenne de toutes les valeurs du tableau. C'est-à-dire, ici, que, minj(mina(—)) coïncide avec mina(minj(—)), ainsi que moyj(moya(—)) avec moya(moyj(—)), et maxj(maxa(—)) avec maxa(maxj(—)). Donc les rangées 0–2 (minima absolus), 12–14 (moyennes sur la totalité de la période) et 24–26 (maxima absolus) coïncident entre les deux tables ci-dessus.

[#7] Pour les moyennes, il y a une petite subtilité quand même, qui est que, comme je fais bêtement la moyenne sur les échantillons disponibles, la pondération n'est pas rigoureusement la même (notamment, le 29 février compte en gros quatre fois plus fort dans la version moyj(moya(—)) que moya(moyj(—))). Donc on aurait pu imaginer de petites différences (aussi parce qu'il manque quelques jours de données par-ci par-là).

☞ Inégalité entre max du min et min du max

Mais sinon, quel est le rapport, par exemple, entre maxj(mina(—)) et mina(maxj(—)) ? (Où ‘—’ signifie n'importe quoi.) Comme on le constate sur le tableau, on n'a pas forcément égalité, mais comme je vais l'expliquer, on a au moins des inégalités. Notamment, maxj(mina(—)) ≤ mina(maxj(—)), c'est-à-dire que les rangées 18–20 de la deuxième table sont inférieures ou égales au rangées 6–8 de la première ; et symétriquement, minj(maxa(—)) ≥ maxa(minj(—)), c'est-à-dire que les rangées 6–8 de la deuxième table sont supérieures ou égales aux rangées 18–20 du premier. On a aussi, maxj(moya(—)) ≤ moya(maxj(—)) et minj(moya(—)) ≥ moya(minj(—)).

Ça vaut vraiment la peine de se demander pourquoi ces inégalités sont vraies, et c'est là que ça devient vraiment des maths (et aussi certainement révélateur de l'esprit mathématique : je pense que s'intéresser à ce genre de questions est beaucoup plus significatif que n'importe quelle capacité à mener des calculs). Oublions si on parle du maximum, de la moyenne ou du minimum dans la journée, disons qu'on ait juste une température par jour : pourquoi est-ce que prendre le maximum sur tous les jours du calendrier du minimum sur toutes les années de la température pour un jour de ce nom donne forcément un résultat inférieur ou égal à prendre le minimum sur toutes les années du maximum sur tous les jours de cette année-là ?

Voici comment on peut le prouver (en général, donc sans avoir à regarder les nombres précis du tableau).

D'abord, abstraire le problème en le généralisant : on a juste un tableau de nombres, et on prend le minimum sur chaque colonne du tableau puis le maximum de tout ça, on veut montrer qu'on trouve forcément un résultat inférieur ou égal à ce qu'on trouve en prenant le maximum de chaque ligne du tableau puis le minimum de tout ça.

Puis on va introduire des notations pour y voir plus clair : appelons c(x,y) le nombre du tableau qui dépend de deux paramètres x (la colonne) et y (la ligne), et notre but est de se convaincre que maxx(miny(c(x,y))) ≤ miny(maxx(c(x,y))).

Ensuite, rechercher les définitions : comme maxx(miny(c(x,y))) est le maximum sur x de quelque chose, il y a un certain x₀ où il est atteint (la colonne du tableau qui a le plus grand minimum) ; et de même, comme miny(maxx(c(x,y))) est le minimum sur y de quelque chose, il y a un certain y₀ où il est atteint (la ligne du tableau qui a le plus petit maximum). Maintenant, regardons la valeur c(x₀,y₀) dans la case[#8] de la colonne x₀ et de la ligne y₀ : comme elle est sur la colonne x₀, elle est supérieure ou égale au minimum miny(c(x₀,y)) de cette colonne, qui est maxx(miny(c(x,y))) par définition de x₀ ; et d'autre part, comme elle est sur la ligne y₀, elle est inférieure ou égale au maximum maxx(c(x,y₀)) de cette ligne, qui est miny(maxx(c(x,y))) par définition de y₀. Donc en mettant tout ça ensemble :

maxx(miny(c(x,y))) = miny(c(x₀,y)) ≤ c(x₀,y₀) ≤ maxx(c(x,y₀)) = miny(maxx(c(x,y)))

Ce qui démontre l'inégalité affirmée. ∎

[#8] On remarquera que l'argument dépend du fait que la case c(x₀,y₀) existe vraiment, c'est-à-dire qu'il y a une valeur dedans. La preuve ne marche plus si le tableau de nombres comporte des trous (donc, en toute rigueur, mon tableau de températures, qui est légèrement lacunaire). Et de fait, le résultat ne vaut plus dans le cas d'un tableau à trous, comme il est facile d'en trouver un contre-exemple.

(Sur mes valeurs précises, par exemple si je veux dire que la rangée 19 de ma seconde table[#9] est inférieure ou égale à la rangée 7 de la première, ici x représente le jour et y représente l'année, et c(x,y) la température [moyenne] du jour x de l'année y. Comme y₀ vaut 1909–1910 d'après la première table et x₀ vaut le 31 juillet d'après le second, je considère la température [moyenne] le 1910-07-31, en l'occurrence 16.7°C mais peu importe : d'une part elle est supérieure ou égale à la plus faible température jamais enregistrée un 31 juillet, soit 14.6°C d'après la rangée 19 de la seconde table, et d'autre part elle est inférieure ou égale à la température la plus élevée de 1909–1910, soit 22.2°C d'après la rangée 7 de la première table. Donc 14.6 ≤ 16.7 ≤ 22.2. Évidemment, quand on a les valeurs, on n'a pas besoin de démonstration puisque c'est juste une observation, mais mon but était d'expliquer ce qui s'est passé dans la démonstration ci-dessus.)

[#9] Ayant écrit tout ce billet, je me suis rends compte que la terminologie était assez merdique parce que je parle à la fois du tableau de températures où la ligne y représente l'année et la colonne x représente le jour de l'année, et aussi des deux tables que j'ai effectivement reproduites dans ce billet où j'ai donné différentes fonctions du tableau des températures. Pour essayer de lever la confusion, j'ai remplacé pour utiliser systématiquement le mot table (et rangée de la table) pour les trucs écrits ci-dessus dans le billet, et tableau pour le tableau de toutes les températures. Mais ça reste merdique, et je ne promets pas de ne pas avoir utilisé le mauvais mot de temps en temps.

Et voici comment on peut prouver que maxx(moyy(c(x,y))) ≤ moyy(maxx(c(x,y))). Appelons x₀ la colonne du tableau qui a la plus grande moyenne (le x qui atteint maxx(moyy(c(x,y)))). Maintenant, pour n'importe quelle ligne y de cette colonne x₀, on a c(x₀,y) ≤ maxx(c(x,y) (chaque case est plus petite ou égale au maximum de la ligne) ; mais du coup, comme ceci est valable pour n'importe quelle ligne y, c'est aussi vrai en moyenne sur toutes les lignes : moyy(c(x₀,y)) ≤ moyy(maxx(c(x,y))). Or moyy(c(x₀,y)) = maxx(moyy(c(x,y))) par définition de x₀. Donc en mettant les choses ensemble, on a maxx(moyy(c(x,y))) = moyy(c(x₀,y)) ≤ moyy(maxx(c(x,y))), ce qui démontre l'inégalité affirmée. ∎

☞ Une motion de minimax symétrique

Revenons à l'inégalité maxx(miny(c(x,y))) ≤ miny(maxx(c(x,y))) qui dit que, pour n'importe quel tableau de nombres, le maximum des minima des colonnes est inférieur ou égal au minimum des maxima des lignes : elle n'est pas difficile ni très profonde, comme on l'a vu. (Néanmoins, je maintiens que c'est un bon signe d'esprit mathématique que de s'intéresser à ce genre de démonstrations, aussi faciles soient-elles.) Comme le montrent les exemples déjà donnés, elle peut être stricte, c'est-à-dire que les deux membres de l'inégalité ne sont pas forcément égaux (contrairement à la situation où on a deux max, ou deux min, ou deux moyennes). Mais il y a un résultat qui, lui, est tout à fait non-évident, et très important, qui permet d'avoir une égalité quitte à changer un peu le contexte.

Mon but, maintenant, va donc être de définir un nombre minimaxy,x(c(x,y)) qui est compris entre maxx(miny(c(x,y))) et miny(maxx(c(x,y))) (il va vérifier maxx(miny(c(x,y))) ≤ minimaxy,x(c(x,y)) ≤ miny(maxx(c(x,y)))), et dont la construction est symétrique entre x et y. (Enfin, symétrique compte tenu du fait qu'on cherche quand même à maximiser sur x et à minimiser sur y, mais il n'y aura plus d'ordre entre les deux opérations.)

Imaginons donc que je parte d'un tableau (fini) de nombres c(x,y) comme avant. Maintenant je vais le compléter en ajoutant une infinité de colonnes de la manière suivante : si x₁,x₂ sont deux colonnes du tableau de départ, je crée une nouvelle colonne ½[x₁] + ½[x₂] dont les valeurs sont la demi-somme des valeurs des colonnes x₁ et x₂, c'est-à-dire ½·c(x₁,y) + ½·c(x₂,y). Et je fais ça non seulement pour deux colonnes quelconques du tableau de départ, mais pour n'importe quel ensemble de colonnes avec n'importe quels coefficients à la place de ½, sujets seulement à la contrainte qu'ils soient positifs et de somme 1. (Comme des probabilités, donc. Et, de fait, on peut interpréter cette nouvelle colonne comme signifiant je tire au hasard une des deux colonnes x₁ et x₂ avec probabilité ½ chacune et les nombres sont les espérances des valeurs du tableau. On parle aussi de combinaisons convexes [formelles] des colonnes du tableau initial. Dans le contexte de la théorie des jeux, le terme de stratégie mixte est utilisée pour désigner ces nouvelles colonnes du tableau, les stratégies pures étant les lignes du tableau de départ. Mais peu importe.) Par exemple, si x₁,x₂,x₃ sont trois colonnes du tableau de départ je vais aussi créer une colonne ¼[x₁] + ¼[x₂] + ½[x₃] avec le nombre ¼·c(x₁,y) + ¼·c(x₂,y) + ½·c(x₃,y) à la ligne y. Bref, ceci fait une infinité (non dénombrable) de nouvelles colonnes, mais peu importe, le tableau ainsi étendu reste complètement déterminé par le tableau de départ.

Et maintenant je fais pareil pour les lignes : par exemple, si y₁,y₂ sont deux lignes du tableau de départ, je crée une nouvelle ligne ½[y₁] + ½[y₂] dont les valeurs sont les ½·c(x,y₁) + ½·c(x,y₂). Une première remarque (pas difficile) est que cette extension des lignes et cette extension des colonnes sont compatibles l'une avec l'autre au sens où ça n'a pas d'importance dans quel sens on la fait (la case de la colonne ¼[x₁] + ¼[x₂] + ½[x₃] et ligne ½[y₁] + ½[y₂] aura la valeur ⅛·c(x₁,y₁) + ⅛·c(x₂,y₁) + ¼·c(x₃,y₁) + ⅛·c(x₁,y₂) + ⅛·c(x₂,y₂) + ¼·c(x₃,y₂) par exemple). On peut aussi remarquer que le maximum ou minimum d'une ligne ou colonne du tableau étendu peut se calculer en regardant simplement la partie qui correspond aux colonnes ou lignes du tableau d'origine (je sais que ça peut superficiellement sembler contradictoire avec ce que va dire le paragraphe suivant, mais ça ne l'est pas) ; et notamment, les colonnes et lignes qui existaient déjà dans le tableau continuent à avoir les mêmes minimum et maximum dans le tableau étendu.

☞ Le théorème du minimax

Eh bien le théorème du minimax de von Neumann nous dit la chose suivante : dans ce nouveau tableau (où on a étendu les colonnes et les lignes comme je viens de l'expliquer), le maximum des minima des colonnes est égal au minimum des maxima des lignes. En fait (cela revient au même si on y réfléchit) : il y a une case du tableau (étendu) qui est à la fois minimale sur sa colonne et maximale sur sa ligne. (Je ne le démontre pas ici, mais si vous voulez voir une preuve[#10], c'est le théorème 2.3.1 des notes de mon cours de théories des jeux à Télécom Paris.)

[#10] Mais je le démontre à partir de l'existence d'équilibres de Nash, théorème 2.2.3 de mes notes (que je démontre à son tour grâce au théorème du point fixe de Brouwer, que j'admets). C'est anachronique : le théorème du minimax est historiquement antérieur à celui de Nash. Je n'ai pas regardé comment von Neumann avait démontré le résultat à l'origine.

Ce résultat est considéré comme le point fondateur de la théorie des jeux « à somme nulle ». (Pour dire en une seule phrase le rapport avec la théories des jeux : on considère le jeu où Xavier choisit une colonne du tableau et Yvonne choisit une ligne et ensuite Yvonne doit donner à Xavier la valeur c(x,y) inscrite dans le tableau, valeur que Xavier va donc chercher à rendre aussi grande que possible et Yvonne à rendre aussi petite que possible ; si Xavier fait son choix en premier puis Yvonne en connaissance de celui-ci, alors le gain de Xavier est maxx(miny(c(x,y))) puisque Xavier va faire son choix en sachant qu'Yvonne va minimiser c(x,y) derrière, et symétriquement, si Yvonne fait son choix en premier puis Xavier en connaissance de celui-ci, c'est miny(maxx(c(x,y))) ; mais si les deux font des choix simultanément, ils vont les faire selon des tirages au hasard dont les probabilités sont données par les colonne et ligne du tableau « étendu » dont j'ai parlé plus haut, et la valeur de la case correspondante s'appelle la valeur du jeu.)

Ce « minimax du tableau étendu » (max sur x et min sur y, mais qu'on peut prendre dans l'ordre qu'on veut, donc), notons-le minimaxy,x(c(x,y)), est une valeur mathématiquement naturelle et intéressante, mais je ne sais pas si on peut lui donner une interprétation concrète autrement qu'en introduisant la théorie des jeux. (Je ne sais même pas quel nom lui donner à part valeur du jeu à somme nulle dont le tableau est la matrice des gains.) Le jeu ici serait que Anne choisit une année entre 1872–1873 et 2024-2025 et Joseph, indépendamment d'elle, choisit un jour de l'année, Anne cherche à rendre la température [moyenne] aussi faible que possible tandis que Joseph cherche à la rendre aussi élevée que possible (pour reprendre mon exemple correspondant à la rangée 7 de ma première table et 18 de la seconde), et on se demande quel sera le résultat espéré s'ils jouent de façon probabiliste optimale.

Ça pourrait être intéressant[#11] à calculer cette valeur. Mais informatiquement, c'est quand même pénible : ça s'appelle de la programmation linéaire, il y a bien sûr toutes sortes d'outils existants pour la faire (et d'algorithmes fondamentaux sous-jacents comme l'algorithme du simplexe), mais pour s'en servir il faut quand même interfacer avec ces outils, et leur donner un tableau de 153 lignes et 366 colonnes (soit quelque chose comme 55k valeurs : je ne sais honnêtement pas si c'est beaucoup en programmation linéaire ; d'ailleurs il faudra décider quoi faire des quelques lacunes dans le tableau, dont je passe un peu l'existence sous silence), tout ça est un petit peu fastidieux à écrire et je ne l'ai pas fait. (Néanmoins, on peut affirmer, par exemple, sur la base des tables ci-dessus, que minimaxa,j(moyh) est compris entre maxj(mina(moyh)) qui vaut 14.6°C et mina(maxj(moyh)) qui vaut 22.2°C.)

[#11] Et les moyennes ? vous allez me dire. Pourquoi je ne parle que des minima et maxima mais plus des moyennes ? J'ai expliqué qu'on pouvait trouver une expression symétrique qui se situe entre maxx(miny(c(x,y))) et miny(maxx(c(x,y))) : mais y en a-t-il une entre maxx(moyy(c(x,y))) et moyy(maxx(c(x,y))) ? Que se passe-t-il si on étend le tableau comme ci-dessus ? Le truc c'est que maintenant, ce que je note moyy correspond simplement à une ligne particulière, appelons-la ŷ, du tableau étendu (celle dont tous les coefficients valent l'inverse du nombre de lignes), mais par ailleurs la moyenne de n'importe quoi sur les lignes du tableau étendu (correctement interprétée comme une intégrale… peu importe) est aussi celle sur le tableau de départ. Donc quand on passe au tableau étendu, maxx(moyy(c(x,y))) garde sa même valeur, qu'on peut noter maxx(c(x,ŷ)), et l'autre, moyy(maxx(c(x,y))) garde aussi sa valeur, bref, étendre le tableau ne change rien à notre inégalité, et tout ce que j'ai gagné c'est qu'on peut remarquer que minimaxy,x(c(x,y)) ≤ maxx(moyy(c(x,y))). Je ne vois rien de plus intelligent à dire à ce stade.

☞ Autres amusements possibles

Bien sûr, il y a plein d'autres choses rigolotes qu'on peut calculer sur un tableau de données. Comme on me l'a fait remarquer dans un commentaire récent sur ce billet, je pourrais calculer des choses comme quelle est la date la plus précoce possible pour le jour le plus chaud de l'année ? (bon, je réponds à ça : c'est le 24 mai, et ça s'est produit en 1922 où il a fait 34.8°C, température la plus chaude de l'année, le  ; et le plus tard c'est le 16 septembre, avec 32.6°C le , mais bon, comme mes années vont de septembre à août, le max est peut-être pris de manière un peu idiote ici ; et pour la nuit la plus froide, ça s'étale du 15 novembre, avec −4.2°C, température la plus froide de l'année, le au 19 mars, avec −1.0°C le ). Ou encore : quelle est l'année la plus ancienne possible pour un record de chaleur par date ? (réponse : en chaud, le record le plus ancien qui tienne encore est celui du 26 avril, avec 28.3°C le qui tient encore ; mais ce qui est peut-être significatif comme illustration du réchauffement, c'est qu'à part pour trois jours de l'année — le 13 mars, 24 mai et 25 mai dont les records ont tous les trois été atteints en 2013 — tous les records de froid pour un jour donné sont antérieurs à 2000).

On pourrait aussi chercher à calculer des records qui tiennent dans la durée : pour chaque n, quel est la plus haute ou plus basse maximale ou minimale qui ait été atteinte n jours consécutifs, par exemple ? Ou la plus haute ou plus basse moyenne sur n jours consécutifs ? Bon, là j'ai un peu fatigué et je n'ai pas fait le calcul. Si quelqu'un veut faire du code golf là-dessus (et surtout, trouver comment présenter les choses joliment[#12]), qu'il ne se gêne pas.

[#12] Peut-être un plot en (n,T) où un point désigne un record avec n jours dépassant (ou ne dépassant pas, selon qu'on parle en chaud ou en froid) la température T ?

Ajout () : Finalement, j'ai fait ces stats-là aussi, les résultats sont là : dans la première colonne, minmax indique la plus petite valeur sur le max de n jours consécutifs, minmoy indique la plus petite valeur pour une moyenne sur n jours consécutifs, maxmin indique la plus grande valeur sur le min de n jours consécutifs, maxmoy indique la plus grande valeur pour une moyenne sur n jours consécutifs et le min, moy ou max entre parenthèses indique s'il s'agit de la minimale quotidienne, moyenne ou maximale quotidienne, puis la colonne suivante donne le nombre n de jours consécutifs, la colonne suivante donne la valeur elle-même, et la dernière colonne donne la dernière date de l'intervalle. Par exemple, la ligne maxmin(max) 45 24.5 19110824 signifie que la plus grande valeur de la température maximale quotidienne minimale sur 45 jours consécutifs est de 24.5°C pour les 45 jours finissant le (concrètement, donc, pendant 45 jours du au inclus, chaque température maximale quotidienne a atteint au moins 24.5°C, et c'est le record pour cette durée).

Et bien sûr, ce qu'il faudrait surtout faire, c'est ne pas mettre que Paris, mais tout un tas de villes françaises, ou européennes, ou mondiales, ce qui permet d'ajouter une couche de min/max/moy sur la ville, et de jouer à toutes les façons de permuter les choses. Un peu plus sérieusement, j'aimerais beaucoup voir des cartes du mondes coloriées par température (et traçant les lignes isothermes) montrant la moyenne sur une longue période des températures maximales annuelles, la moyenne sur une longue période des températures minimales annuelles, et la moyenne sur une longue période tout court (et éventuellement en distinguant minimale, moyenne et maximale dans la journée, donc neuf cartes, correspondant aux rangée 9–17 de ma première table) : ce que je voudrais savoir, c'est comment la forme des isothermes diffère entre ces cartes. Mais là, même s'il est en principe possible d'extraire ces informations de la réanalyse ERA5, je ne sais pas trop comment m'y prendre.

Mais encore une fois, mon propos était surtout de jouer, et d'illustrer comment le matheux (non statisticien !) que je suis s'empare d'un jeu de données, avec quoi il a envie de jouer, et les questions qu'il a envie de poser (et c'est sans doute différent de ce que ferait un analyste de données, parce que je ne cherche pas tellement à faire parler les données pour comprendre le monde réel qu'à explorer un peu systématiquement tout un tas de questions qui plaisent à mon sens de la symétrie).

↑Entry #2825 [older| permalink|newer] / ↑Entrée #2825 [précédente| permalien|suivante] ↑

[Index of all entries / Index de toutes les entréesLatest entries / Dernières entréesXML (RSS 1.0) • Recent comments / Commentaires récents]