☞ 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à.)
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
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
(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
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
complètement stupides) et c'est plutôt l'inertie
qui me fait continuer à m'en servir.echo machin |
gnuplot
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) :
# | Formule | Valeur | Année | Date |
---|---|---|---|---|
0 | mina(minj(minh)) | −23.9 | 1879–1880 | |
1 | mina(minj(moyh)) | −15.1 | 1879–1880 | |
2 | mina(minj(maxh)) | −10.5 | 1938–1939 | |
3 | mina(moyj(minh)) | 4.5 | 1890–1891 | |
4 | mina(moyj(moyh)) | 8.8 | 1890–1891 | |
5 | mina(moyj(maxh)) | 13.0 | 1890–1891 | |
6 | mina(maxj(minh)) | 15.8 | 1874–1875 | |
7 | mina(maxj(moyh)) | 22.2 | 1909–1910 | |
8 | mina(maxj(maxh)) | 29.0 | 1976–1977 | |
9 | moya(minj(minh)) | −7.5 | ||
10 | moya(minj(moyh)) | −4.6 | ||
11 | moya(minj(maxh)) | −2.6 | ||
12 | moya(moyj(minh)) | 7.7 | ||
13 | moya(moyj(moyh)) | 11.5 | ||
14 | moya(moyj(maxh)) | 15.6 | ||
15 | moya(maxj(minh)) | 20.2 | ||
16 | moya(maxj(moyh)) | 26.4 | ||
17 | moya(maxj(maxh)) | 34.2 | ||
18 | maxa(minj(minh)) | −1.0 | 1974–1975 | |
19 | maxa(minj(moyh)) | 1.1 | 2013–2014 | |
20 | maxa(minj(maxh)) | 4.1 | 2013–2014 | |
21 | maxa(moyj(minh)) | 10.6 | 2023–2024 | |
22 | maxa(moyj(moyh)) | 13.9 | 2023–2024 | |
23 | maxa(moyj(maxh)) | 18.2 | 2021–2022 | |
24 | maxa(maxj(minh)) | 25.5 | 2002–2003 | |
25 | maxa(maxj(moyh)) | 34.0 | 2018–2019 | |
26 | maxa(maxj(maxh)) | 42.6 | 2018–2019 |
(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 :
# | Formule | Valeur | Jour | Date |
---|---|---|---|---|
0 | minj(mina(minh)) | −23.9 | 12-10 | |
1 | minj(mina(moyh)) | −15.1 | 12-10 | |
2 | minj(mina(maxh)) | −10.5 | 12-20 | |
3 | minj(moya(minh)) | 1.0 | 01-17 | |
4 | minj(moya(moyh)) | 3.4 | 01-17 | |
5 | minj(moya(maxh)) | 5.8 | 01-07 | |
6 | minj(maxa(minh)) | 9.3 | 01-26 | |
7 | minj(maxa(moyh)) | 10.9 | 01-29 | |
8 | minj(maxa(maxh)) | 13.1 | 01-21 | |
9 | moyj(mina(minh)) | −1.6 | ||
10 | moyj(mina(moyh)) | 2.8 | ||
11 | moyj(mina(maxh)) | 5.5 | ||
12 | moyj(moya(minh)) | 7.7 | ||
13 | moyj(moya(moyh)) | 11.5 | ||
14 | moyj(moya(maxh)) | 15.6 | ||
15 | moyj(maxa(minh)) | 15.9 | ||
16 | moyj(maxa(moyh)) | 20.1 | ||
17 | moyj(maxa(maxh)) | 26.1 | ||
18 | maxj(mina(minh)) | 9.7 | 07-19 | |
19 | maxj(mina(moyh)) | 14.6 | 07-31 | |
20 | maxj(mina(maxh)) | 18.2 | 08-11 | |
21 | maxj(moya(minh)) | 15.1 | 07-31 | |
22 | maxj(moya(moyh)) | 20.0 | 08-05 | |
23 | maxj(moya(maxh)) | 25.4 | 08-05 | |
24 | maxj(maxa(minh)) | 25.5 | 08-12 | |
25 | maxj(maxa(moyh)) | 34.0 | 07-25 | |
26 | maxj(maxa(maxh)) | 42.6 | 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
[#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).