4) Meteo et machine learning.

Alors petit récapitulatif des épisodes précédents, et de la finalité voulue pour notre projet:

Avec ça:

et un peu de ça:

sans oublier:

L’objectif c’est d’obtenir (dans les grandes lignes):

……….Ou tout du moins un modèle prédictif de météo sur pc puis sur raspberry pi, ce sera déjà pas trop mal, pour faire une station météo.

Les articles précédents datent un peu, mais cette fois je voulais prendre mon temps pour avoir le meilleur résultat possible et éviter de raconter ou faire trop de conneries. Il y a encore des choses à travailler mais nous en reparlerons pendant la conclusion.

PARTIE 1: traitement des données brutes(MeteoNet)

Précédemment, pour rappel on avait téléchargé gratuitement sur notre pc l’utilitaire Anaconda (plate-forme python, c’est un peu la boîte à outils du datascientist) et des données de Meteo France sur 3 ans via Kaggle (c’est le jeu de données MeteoNet). Pourquoi ? Pour au final bidouiller une station météo « intelligente », ou tout du moins pas trop conne et capable de prévoir raisonnablement la météo dans les heures qui suivent la collecte des données nécessaires à cette prévision, et ce pour le Nord Ouest de La France (Meteo France fournit aussi un jeu de données pour le Sud Est).

Anaconda est une plate-forme de machine learning faite pour des trucs comme ça. On a vu que le modèle des forêts aléatoires était à priori le plus intéressant grâce à ses scores et aussi le peu d’hyperparamètres…A paramétrer. Jusque là on a pas trop lorgné du côté du deep learning que nous explorerons avec keras et tensorflow (si mon pc a assez de patate).

Pour la direction et la force du vent on avait conclut d’après les courbes d’apprentissages et les scores que niveau nombre d’échantillons c’était juste. D’ailleurs on avait juste cherché à prévoir ces 2 variables. On va donc partir à la pêche aux échantillons et prévoir deux variables supplémentaires pour notre station: les précipitations pour savoir quand je peux sortir le cleb’s ou faire griller mes merguez (ou les deux), et la température pour savoir si je tond ma pelouse plutôt en slip ou plutôt en moufles. Il est possible de prévoir d’autres variables mais en se focalisant déjà sur celles-là on a du boulot.

I. Rédiger un module comprenant une classe pour faciliter le traitement des données.

Alors suite à tout ça, la meilleure solution à mon sens ça a été de rédiger un module (Meteo_terre_traitement) avec inclus dedans une classe (Meteo_Data_View) capable à partir des fichiers csv de meteo france de sortir des données prêtes et cuites à point pour sklearn. Le principe est très simple: on rentre les paramètres suivants:

  • heures: (défaut=1) indique combien on veut garder d’heures de relevé dans chaque journée. Par exemple 3 signifie que l’on utilise que des données toutes les trois heures. Donc plus on augmente ce paramètre, moins le dataset aura de dimensions par échantillon.

  • jours: (défaut=1) indique le nombre de jours par échantillon. Plus on met de jours, plus on augmente les dimensions du dataset tout en diminuant le nombre d’échantillons (on va diminuer le nombre de chances de trouver plusieurs jours à la suite sans données manquantes), et si on en met moins c’est l’inverse.

  • var_corbeille: (défaut=[], une liste vide ) indique les variables dont on veut se débarrasser (direction, force, humidité, précipitation, pression, temperature, point de rosée…) dans notre dataset. Plus on fournit cette liste et plus on réduit les dimensions/variables, en prenant toutefois le risque de perdre de l’information utile en route, mais en échange on va avoir des modèles moins gourmands en mémoire.

  • vue: (defaut=12) indique l’heure de la prévision meteo. Par défaut la prévision est réglée pour dans les 12 heures, mais on peut changer ça. Cette donnée doit être un multiple du paramètre « heures ». Si on paramètre pour avoir une vue dans 10 heures mais que l’on agence ses données toutes les 6 heures, ça va afficher un message d’erreur. On ne peut calibrer ce paramètre que entre une vue d’une heure et 23 heures pour une journée dans l’échantillon, jusqu’à 47 heures pour 2 jours dans un échantillon etc….

  • cible: indique quelle est la variable que l’on veut prédire; ça peut-être ‘direction’ pour la direction du vent, ‘force’ pour sa force, ‘température’ , ‘pluie’, ‘point_rosée’, ‘pression’, ‘humidité’, ‘direction’. Par défaut c’est la direction qui sera intégrée.

J’oubliai, on a ajouté également une variable temps dans notre dataset. C’est un numéro indiquant à quel mois l’échantillon a été enregistré.

Cette classe a des attributs pour récupérer les données traitées:

  • nom_objet.data_good_shape: contient le dataset prêt pour sklearn.
  • nom_objet.target: données cibles sélectionnées par le paramètre ‘cible’.

Tout ça donne au final des tableaux array au format int32 pour prendre moins de place sur le disque dur.

Au regard de mon pc (très bon marché), mes compétences (très limitées) et mon temps libre dédié à la bidouille (résultant d’un combat quotidien et acharné contre la procrastination, le curling sur béton, les convenances sociales et les tournois de water-jokari), l’instance la plus efficace que j’ai trouvé est d’utiliser les trois années avec des données toutes les heures, 3 jours par échantillon sans virer une seule variable. Ca donne un dataset ‘optimal’ de 508 dimensions et environ 180000 échantillons. Bien plus fournit que précédemment !

Au début j’avais pensé ajouter un paramètre supplémentaire dans la classe meteo_Data_View, pour interpoler sur certaines variables et donc augmenter le nombre d’échantillons. Par exemple une station meteo à moins de 20 km d’une autre mais avec des données de température manquantes serait complétée par les données de l’autre station. Au final je l’ai pas fait car déjà avec les données traitées mon pc est un peu limite niveau capacités et puissance, et aussi ça aurait risqué une corruption des données, mais bon à voir ça pourrait être intéressant à ajouter pour ceux qui ont un gros pc de gamer.

Le module est accessible via le site de votre humble bricoleur et aussi sur github à l’adresse suivante:

https://github.com/HarryTutle/meteo_forecast_NO_France

Si vous voyez des coquilles, des améliorations, surtout faites remonter l’info !

II. Pour ne pas avoir de surprises avec le matos…

J’ai oublié de préciser, par rapport aux articles précédents j’ai du changer de pc car pour manipuler des gros fichiers csv confortablement, faire du machine learning et du deep learning c’est incontournable. Je suis donc passé sur un optiplex 9020 i7 240Go avec 8Go de RAM SSD…Et après avoir cramé le disque dur et écouté un conseil avisé je l’ai chargé avec un disque dur de 1 To SSD et 16 Go de RAM supplémentaire et là ça le fait. Pour le disque dur le SSD c’est bien, HDD ça rame trop, en même temps sans surprise (le format HDD est plutôt fait pour stocker plus d’info au détriment de la vitesse de traitement, en gros, contrairement au SSD).

Le disque dur a cramé lorsque j’ai utilisé la commande ‘n_jobs’ (parallélise les calculs sur plusieurs coeurs du processeur pour aller plus vite) pour entrainer mon modele de foret aléatoire sur les trois ans. J’ai mis tout les coeurs en même temps sur les calculs, le pc a fait un bruit de décollage d’avion tel un Concorde prêt à s’élancer sans avoir lacé ses chaussures…Dorénavant je limite n_jobs à 2 coeurs en même temps.

III. Les forêts aléatoires

Avant d’aller plus loin je vous laisse un lien youtube qui explique bien le fonctionnement de ces forêts:

Alors bien que ce modèle de machine learning ne charge pas la mule niveau hyperparamètres, il en a quand même un paquet, cependant je me suis focalisé sur 3 d’entre eux; n_estimators, max_features et max_depth.

En utilisant Gridsearchcv de façon parcimonieuse (une trop grande grille rend le pc bègue, amorphe et incontinent) j’ai trouvé que pour mon pc et le dataset optimal la meilleure config c’est n_estimators=150, max_features=’auto’ et max_depth=None. Mais quand j’augmente les arbres à 150, je ne peut plus traiter toutes mes données sur mon pc du coup je suis resté à un réglage standard de 100 arbres.

n_estimators augmente le nombre d’arbres et baisse le risque de surapprentissage, max_features indique le maximum de variables que chaque arbre utilise pour se construire (auto correspond à la racine carrée du nombre de variables total du dataset) et max_depth indique la profondeur de l’arbre (None signifie que l’arbre sera approfondit jusqu’à avoir des feuilles ‘pures’, c’est à dire à catégorie unique, mais on peut stopper avant.

Niveau résultats sur les données test ça donne donc des scores autour de ça en arrondissant (tout les scores sur les train set donnent 99.8%, 3 jours par échantillons, données toutes les heures) :

vue :3h6h12h
direction du vent67.8%67.6%67.6%
force du vent75.5%74.8%74.8%
pluie99.9%99.9%99.9%
température86%86%86%
scores 3 jours/échantillon

Nom d’un bigorneau ! Mais ça prévoit la pluie à presque 100% !!! Hé bien…Pas vraiment. Après vérif, il y a en fait très peu de cas où dans notre array cible on a 1 (il pleut); on a très majoritairement des 0 (il pleut pas); donc le modèle va quasiment toujours prévoir 0….Va falloir trouver un autre moyen pour prévoir les précipitations, on verra ça à la fin.

Autre soucis; entre 6h et 12h les scores de prévision ne baissent quasiment pas hors ça devrait être le cas puisque c’est plus difficile de prévoir une météo à plus long terme…On va utiliser un autre dataset pour pas se planter.

PARTIE II : dataset des bouées marines et confirmation de nos résultats.

En continuant entre deux de fouiller les données en libre accès sur le net, je découvre avec un intérêt non dissimulé d’autres données libres de meteo france mais côté mer cette fois (hé hé !!). En effet on peut accéder aux données des bouées marines principales des zones maritimes françaises, les bouées dérivantes et aussi les relevés météo de certains navires de passage. On va se focaliser sur les données des bouées Brittany (large de Brest) et Gascogne (je vous laisse deviner où elle est). Ces données sont disponibles de 1996 à maintenant via quelques clicks de souris. Je n’ai pas pris en compte les données des navires et des bouées mouvantes, bref de tout ce qui bouge, car je me suis dit que le mouvement, surtout si il est rapide, pouvait biaiser la formulation de notre modèle au regard des déplacements des dépressions et autres systèmes météo.

Ce dataset est très similaire au premier, cependant il possède un nombre de variables plus conséquent (taille des vagues, nébulosité…); mais comme notre station sera limitée à quelques capteurs, donc quelques variables, on va en virer pas mal pour garder les même que notre premier dataset. Seule la variable précipitation sera manquante. J’ai aussi enlevé la nébulosité, pourtant intégrable via une diode photosensible car pour ces 2 bouées on n’a pas assez de données sur ce champ, malheureusement.

Ce second dataset va nous servir de test pour voir si on a pas merdé au premier. En effet, une fois les données fournies par meteo france sur les bouées traitées, on obtient des datasets plus compacts que le premier, donc moins énergivores et chronophages en traitement. Comment savoir si on est dans les clous et pas à côté de l’assiette ? Hé bien on va formuler des hypothèses de vérification:

  • Si on obtient des scores tout pétés (dans les 80/90%) pour la force ou la direction…A moins d’être bien prétentieux ou de croire encore au père noel, ça doit pas être bon !
  • Si on augmente le paramètre « vue », le score de prévision devrait normalement baisser au fur et à mesure; plus on cherche à connaitre la météo dans le futur et moins ce sera précis.
  • On devrait obtenir des scores assez similaires au premier dataset.
  • Pour chaque prévision, les variables les plus utilisées devraient être celles qui sont à la fin de l’échantillon (si l’échantillon est une journée simple et que la vue est à 12 heures avec comme cible la force du vent, normalement le modèle va surtout utiliser la dernière force du vent enregistrée car c’est cette donnée qui aura le moins de chances de bouger)

I.Rédiger un module pour le traitement de données

Comme précédemment, j’ai repris le même module que j’ai légèrement modifié pour pouvoir traiter ce nouveau jeu de données. Cette fois les heures ne sont plus dans les paramètres de la classe car de toute façon on peut toutes les traiter et changer ce paramètre fait baisser le niveau de perf.

Pour importer les données, il y a du nouveau; j’ai utilisé le module glob pour importer les dossiers mensuels rangés dans un dossier dans python via du regex, puis j’ai convertit chaque dossier en dataframe via le module gzip et pandas.

Le fonctionnement de ce module est exactement pareil que le précédent, il acouche des mêmes objets et attributs. Egalement téléchargeable sur le site (au bout de 10000 téléchargements, un magnifique cendrier en coquillage de saint-Jacques peint à la main vous sera gracieusement offert) et sur github:

https://github.com/HarryTutle/meteo-marine

II.Résultats du dataset des bouées.

Pour ce dataset on va prédire seulement la direction et la force du vent, puis la température. Je vous laisse vous amuser avec le reste si ça vous branche (attention toutefois à ce qu’on veut prédire, pour les variables qui sont des classes on prendra un modèle « classifieur » et pour les variables continues il faudra faire une régression). Pour ce qui va suivre train_test_split et les modèles sont réglés avec random_state=0. Les paramètres sont ceux par défaut avec max_depth=None et max_features=None également (feuilles pures et toutes les variables prises en compte pour faire l’arbre).

A. Avec le modèle de l’arbre de décision.

Avant de poursuivre je vous met un lien qui synthétise bien ce modèle:

Les histogrammes des degrés d’utilisation des variables

Ces histogrammes indiquent l’importance des caractéristiques pour chaque arbre selon la prévision demandée (type et projection dans le temps). La somme des variables est ici toujours égale à 1. Pour les trois variables on observe les changements à une heure, douze heures et vingt trois heures (vue) pour des échantillons d’une journée.

pour la direction du vent:

1 jour, une heure
1 jour, 12 heures
1 jour, 23 heures

Clairement, la variable la plus utilisée est le dernier relevé de la direction du vent. Plus la prévision avance dans le temps, plus l’importance de cette variable diminue alors que celle des autres augmente. Mais l’écart reste très flagrant entre cette variable et les autres.

Et maintenant la force du vent:

1 jour, une heure
1jour, 12 heures
1 jour, 23 heures

On constate grosso modo la même chose que précédemment.

Et enfin la température:

1 jour, une heure
1 jour, 12 heures
1 jour, 23 heures

Ici on ne remarque pas de changement drastique. Le modèle utilisera principalement la dernière mesure de la température comme référence dans sa prédiction.

Pour le moment ça colle avec nos hypothèses de départ.

Quelques petits essais avec cette fois le nombre de jours que l’on augmente par échantillon:

direction, 2 jours et 12 heures
direction, 3 jours et 12 heures

J’ai fait le même essai avec la température et la force, et on remarque la même chose: a partir de 3 jours, le modèle n’utilise plus la variable dernièrement mesurée de façon dominante.

Les scores (1 jour par échantillon)

Voilà les scores en conservant toutes les variables:

vue:1h2h3h8h16h23h
Force du vent59%56%55%51%51%52%
direction du vent66%63%62%58%58%58%
température94%93%92%91%90%90%
pourcentage de prédictions réussies

On remarque que l’efficacité de la prévision décroit à mesure qu’on avance dans le temps, surtout les trois premières heures. ça a l’air de se stabiliser ensuite. On ne contredit toujours pas nos hypothèses, c’est cool ça fait plaisir.

Et maintenant les scores en s’amusant à garder seulement la variable ‘prédominante » à savoir pour chaque ligne du tableau la force, direction et température précédemment enregistrées et en fourrant le reste dans la liste « var_corbeille »:

vue:1h2h3h8h16h23h
force du vent54%49%45%35%30%27%
direction du vent62%57%53%40%31%28%
température93%92%91%86%83%81%
pourcentage de prédictions réussies

Pour la première heure ça ne change pas beaucoup les résultats même si ils sont moins bons qu’avec toutes les variables, par contre ça se casse la figure assez vite au fur et à mesure de l’amplitude horaire de la prédiction.

B.Avec le modèle des forêts aléatoires.

Les histogrammes des degrés d’utilisation des variables

Pour la direction du vent:

1 jour, une heure
1 jour, 12 heures
1 jour, 23 heures

On voit que les forets aléatoires utilisent plus de variables pour affuter la prédiction. La variable la plus utilisée est la direction du vent. Plus la variable est éloignée en heures de la prévision et moins elle sera utilisée, et les autres en revanche sont de plus en plus sollicitées.

On passe à la force du vent:

1 jour une heure
1 jour 12 heures
1 jour, 23 heures

ça reste assez similaire à ce qu’on a pu voir avec la direction du vent.

Et pour la température:

1 jour, une heure
1 jour, 12 heures
1 jour, 23 heures

Pas de changement drastique en avançant dans le futur des prédictions avec la température.

Les scores (1 jour pour chaque échantillons).

Voilà les scores en gardant toutes les variables:

1h2h3h8h16h23h
Force du vent71%69%70%70%71%72%
Direction du vent76%75%75%76%76%78%
Température96%96%96%95%95%95%
pourcentage de prédictions réussies

Contrairement à l’arbre de décision ce qu’on remarque de suite c’est l’absence de baisse dans l’efficacité de la prédiction quand on avance dans le temps ce qui est étonnant. Les résultats sont meilleurs avec ce modèle (ça grimpe de 10% pour la force et la direction du vent). Par contre la non baisse dans le temps ça colle pas avec nos hypothèses…

Et maintenant en gardant juste la variable prédominante:

1h12h23h
force du vent67%42%37%
direction du vent72%41%31%
température95%89%85%
pourcentage de prédictions réussies

comme avec le modèle de l’arbre de décision, au début c’est similaire bien que moins bon et ça dégringole ensuite; pas de stabilisation cette fois.

Mais revenons aux scores qui ne baissent pas avec le temps pour les forets aléatoires; en creusant un peu le score ne baisse pas, mais c’est la certitude dans la prévision qui diminue semblerait-il. En utilisant l’attribut predict_proba du modèle (donne pour chaque classe sa probabilité de réalisation par échantillon, la probabilité la plus élevée est la prévision retenue), on remarque que la moyenne des probas les plus élevées diminuent dans le temps si la prévision va plus loin dans le futur:

1h2h3h12h23h
direction68%65%63%56%54%
force63%60%58%53%53%
température95%94%93%91%90%
moyenne des probas max(certitude)

Pour conclure sur le dataset des bouées

En testant plusieurs configurations des données, il semble que la meilleures configuration c’est 3 jours par échantillons en intégrant toutes les variables. On obtient ceci:

vue:6h12h
force du vent72%71%
direction du vent78%76%
température95%95%
scores pour 3 jours par échantillon

Ce qui donne des scores un peu au-dessus d’un dataset avec 1 jour par échantillon.

Pour finir…Ou plutôt poursuivre

Revenons au premier dataset provenant de MeteoNet. En calculant la certitude (via predict_proba) de la prévision pour la direction (3 jours par échantillon donc une forme (180000, 508)) on obtient ça:

vue :1h2h3h6h12h
score67.967.967.867.667.6
certitude54.754.654.454.454.5
scores et certitue en % pour un dataset de 3 jours par échantillon.

En comparant avec le dataset des bouées on voit que la certitude ne baisse quasiment pas, pareil pour le score… Peut-être parce que ce dataset est bien plus volumineux ?

Et maintenant avec un jour par échantillon:

vue :1h3h6h12h
score67.266.166.464.8
certitude57.953.751.246
scores et certitude en % pour un dataset de 1 jour par échantillon.

Ici on va avoir un dataset de forme (400000, 172). On voit mieux la décroissance de la certitude c’est marrant. Par rapport au tableau précédent on dirait que c’est le nombre de dimensions qui semble jouer là-dessus.

Bref, en comparant ces 2 datasets (nous appellerons le premier issus de MeteoNet Ben et le second issus des bouées Nutz) on remarque que:

  • les scores globaux de Ben sont un peu moins bon que Nutz. Je pense à cause de la pluralité des lieux présent dans MeteoNet, chacuns avec ses effets de site propres.

  • La direction du vent/température est mieux prédite par Nutz, ça peut s’expliquer par les effets de site sur terre, non présents sur l’eau, et aussi par la pluralité des lieux différents compris dans Ben, alors que Nutz ne comprend que deux lieux différents. Merde je me répète là je viens de le dire au-dessus.

  • La force du vent est légèrement mieux prédite par Ben, peut-être à cause des pets de mouette non présents à terre et …Non j’ai pas d’idées, les frottements plus présents à terre peut-être ?

Il y a des améliorations possibles:

  • Trouver un dataset sur la luminosité à l’extérieur pour ‘traduire’ la couverture nuageuse via une diode photosensible. MeteoNet intègre un jeu de données sur les types de nuages qui couvrent la zone par heure, cependant il faudrait faire le lien entre ‘type de nuages’ et ‘luminosité’ en lumen ou autre afin de pouvoir exploiter ça. Je pense que ça pourrait améliorer les modèles prédictifs surtout pour des zones comme le Sud-Est de la France plus sensible aux effets de sites et thermiques. Les nuages permettent de bien affuter une prédiction et malheureusement ils sont absents de nos datasets.
  • Tenir compte des données aberrantes, ce que je n’ai pas fait. C’est encore plus important si on va faire du deep learning.
  • Pour prédire la pluie, utiliser la variable point de rosée et humidité/pression plutôt.
  • Pour ceux qui ont un bon pc, améliorer les modules en traitant les données manquantes en utilisant les stations météo de proche en proche. De cette façon on récoltera plus d’échantillons, avec un risque de corruption mais limité si on gère bien les distances limite (pas plus de quelques kilomètres entre les stations utilisées).
  • Utiliser enfin Keras et tensorflow, notamment pour l’usage des réseaux RNR (réseau de neurones récurrents, à ‘mémoire’) car ces architectures sont bien adaptées (parait-il, je n’ai jamais essayé) aux séries temporelles. Peut-être auront-nous de meilleurs résultats ? Eventuellement essayer aussi les réseaux convolutifs.
  • Si mon pc n’est pas assez puissant ou si j’en ai marre, passer directement à l’assemblage de la station meteo car c’est quand même l’objectif de base.
  • Utiliser comme modèle le boosting d’arbres de décision. C’est souvent plus efficace que les forêts aléatoires, mais là avec la taille des données mon pc est pas assez puissant.

Allez vas-y, soit pas timide ! Bin allez quoi, dis le que cet article est bouleversant et extraordinaire, que...Comment ça c'est de la merde ?

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.