1) Météo et machine learning

L’objectif final (actuel, ça changera peut-être au cours du temps on verra) de cette nouvelle suite d’articles sera de fabriquer une station météo embarquée fonctionnant en machine learning ou deep learning, bref capable de prédire avec le plus de précision possible le temps qu’il fera ensuite, un peu comme une miss météo de canal mais en moins sexy, et en moins lourdingue également.

Partie 1: machine/deep learning

Ce concept date en fait de plusieurs décennies; à l’époque on se creusait déjà le ciboulot pour rédiger des algorithmes capables de se modifier en comparant leur résultat au données réelles, bref capables « d’apprendre » pour petit à petit fournir des réponses de plus en plus efficaces. Même si on parle beaucoup de l’intelligence artificielle actuellement, le pitch ne date pas d’hier; c’est la puissance de calcul et de traitement de données de nos ordinateurs contemporains qui permettent d’exploiter pleinement le potentiel du bidule. Cette idée de « machine apprenante » est très utile dans des domaines comme la reconnaissance d’images ou de formes, voix, détecter des tumeurs, classer des objets, traduire des textes…

Pour tenter de résumer de façon extrêmement succinte ce concept (et en racontant le moins de conneries possibles)…

a) Le machine learning

Il regroupe tout un ensemble de techniques basées sur des statistiques, de calcul pour pouvoir écrire des programmes ; on peut les regrouper en 3 principales catégories comme:

  • L’apprentissage supervisé où on va entraîner le programme à devenir de plus en plus performant en comparant ses données calculées et le résultat attendu. Cette forme d’apprentissage est utilisée beaucoup dans les programmes de classement ou de prévision, et c’est la forme de machine learning la plus couramment rencontrée.
  • L’apprentissage non supervisé où là le programme va repérer des points communs entre les objets étudiés, pour ensuite faire émerger des catégories (les frimeurs parlent de « clustering »). Ces algos sont très utilisés pour les logiciels de proposition de vente sur internet selon le profil de l’utilisateur (son âge, ses goûts, son style de vie etc..) par exemple (mais si, les fenêtres qui s’affichent pour acheter du viagra quand vous ouvrez une page web et qui font bien chier souvenez vous).
  • L’apprentissage par renforcement où le programme va apprendre et s’améliorer un peu avec une logique « essai/erreur » ; il donne une bonne réponse il gagne un susucre, une mauvaise a pas de susucre (en gros). Bref plus il se gave de susucres, plus il est bon, sans les aléas du choléstérol, c’est fou.

Si l’on travaille sur des données qualitatives comme par exemple classer un objet dans une catégorie (problème de classement) ou alors quantitatives comme calculer un salaire moyen selon plusieurs critères (problème de régression), les techniques utilisées vont différer. Voici en gros quelques techniques répandues:

  • Les K plus proches voisins: technique la plus simple à comprendre. Le programme compare les caractéristiques d’un objet avec celles des objets enregistrés dans sa banque de données, puis classe l’objet dans la classe de l’objet (ou majorité de groupe d’objets) le plus proche. En gros plus la banque de données est conséquente, plus ça va fonctionner. Par contre le temps de calcul prédictif est de plus en plus long. Fonctionne pour les problèmes de classement et de régression.
  • Les Bayésien naifs: cette technique classe les objets selon leurs caractéristiques mais considère qu’il n’y a pas de corrélations entre ces caractéristiques (traite indépendamment les variables à la fois). Du coup rapide en calcul mais pas toujours précis en résultat. par rapport à d’autres modèles.
  • Les arbres de décision: ça fonctionne un peu comme un livre dont vous êtes le héro; on part d’une racine, puis à chaque étape un test du style « si/sinon »sépare le chemin de données en 2. l’arbre se termine par des « feuilles » correspondant à la classe de l’objet ou le nombre à trouver. Fonctionne pour les régressions et les classements.
  • La régression linéaire: la plus simple. On utilise une fonction linéaire pour prédire des données, pour cela on rédige une fonction linéaire qui ressemble à une fonction affine dont les paramètre sont les poids et les biais; ces paramètres vont nous permettre de rédiger une fonction calculant l’erreur (différence entre ce que l’on calcule et la réponse attendue,c’est la fonction de coût) que l’on va minimiser un maximum par rapport aux poids, généralement avec la technique de descente de gradient. Comme son nom l’indique, utilisé pour les régressions.
  • Régressions Ridge/lasso: c’est un modèle linéaire pour la régression mais cette fois il va chercher à minimiser les coefficients d’erreur (de pondération) pour limiter le surapprentissage pour le mode ridge. En configuration lasso certains coefficients tombent même à zéro donc c’est parfois utile pour simplifier un modèle ou repérer les caractéristiques qui comptent vraiment pour nos calculs.

Chaque modèle va avoir ses qualités et ses défauts selon l’usage. Le choix de l’un des ces modèles va dépendre de plusieurs facteurs comme le nombre de dimensions traitées dans notre tableau de données, le nombre de caractéristiques par rapport au nombre d’échantillons, le nombre de corrélations entre nos caractéristiques, si notre problème est un classement ou une régression, notre capacité de calcul, l’étendue de notre jeu de données, votre groupe sanguin ainsi que votre signe astral et si vous êtes plutôt slip ou caleçon.

b) Le deep learning

Cette fois on va mobiliser des réseaux de neurones « virtuels » (des fonctions telles que des sommes pondérées et des fonctions non linéaires la plupart du temps comme la fonction RELU par exemple) pour classer, prédire, faire le café…Actuellement ce type de modèle est l’un des plus efficace, mais son efficacité se fait au détriment d’une simplicité de configuration et d’un temps d’entrainement parfois long. On va chercher à minimiser une fonction de coût (l’erreur) par rétropropagation de l’information.

Partie 2: Le projet en plus détaillé

Pour le moment, l’idée finale va être d’utiliser une carte raspberry pi pour fabriquer une station météo embarquée. Cette station va capter la pression atmosphérique, la température et l’hygrométrie via un BME 280 (capteur électronique), la vitesse et la direction du vent via un anémo. En navigation, ce qui nous intéresse le plus c’est la force et la direction du vent, donc notre bidule devra prédire au moins ces 2 paramètres. Pour entraîner notre programme, on va se servir des données en open source de météo France. Voilà grosso merdo le projet actuellement. On se concentrera sur le nord ouest de la France pour le moment. Notre problème est donc ici clairement un problème de régression. Bon honnêtement ce serait bien prétentieux d’envisager des résultats conséquents sachant qu’il n’y a pas plus complexe et chaotique que la météo comme système, mais comme disait Jean-Louis Socrate (ou Bernard Platon je sais plus):

« En négo, si tu veux avoir un sandwich jambon fromage, vise l’américain

steak/oignons/salade/oeufs/poulet/cornichons !!! »

Si je peux décrocher un cornichon dans mon jambon fromage ce sera déjà pas si mal !

a) Les données de météo France

Accessibles via leur site ou sur kaggle (banque de données en ligne gratuite pour data scientists ou bidouilleurs) ces données comprennent les enregistrements sur 2016,2017 et 2018 de 262 stations dans le nord ouest de la France (donc pour nous la Manche, l’Atlantique) et aussi des stations dans le sud est (Mediterranée). Ces données intègrent : le numéro des stations, la date, la localisation (latitude/longitude) , la pression atmosphérique, l’altitude de la mesure, la température, le point de rosée, l’humidité, la vitesse du vent, la direction du vent, la quantité de précipitations. Les données sont enregistrées pour toutes les stations toutes les 6 minutes, ça fait donc un gros paquet d’infos !

b) Raspberry pi

C’est un peu comme un mini ordinateur avec un processeur ARM (moins puissant mais aussi plus économe et facilitant donc son utilisation en embarqué). On va s’en servir comme cerveau pour notre projet. Ici on va utiliser le modèle raspberry pi zero puis 3 b+.

Raspberry pi zero

Raspberry pi 3 b+

c) Ressources pour guider un bidouilleur complètement paumé

Pour pouvoir mener à bien ce projet je me suis servi des 30 vidéos de la chaine « machine learnia » sur youtube, qui propose un cour gratuit de machine learning/python très clair et très bien expliqué sur le sujet, le bouquin de Yann le Cun « quand la machine apprend », le bouquin d’Emmanuel Jakobowicz « Python pour le data scientist » (particulièrement bien pour apprendre pandas, numpy, matplotlib et comment bien préparer nos données avant usage), et aussi le livre « le machine learning avec python » de C Muller et S Guido (plutôt bon pour vulgariser et expliquer les différents modèles de machine/deep learning et comment les utiliser avec sklearn).

d) Ressources autres

Pour pouvoir programmer en python j’ai téléchargé anaconda. J’utilise principalement l’environnement de programmation spyder. Les packages (équivalents aux bibliothèques arduino par exemple) que l’on va manipuler pour bosser:

  • Numpy: permet de créer/manipuler des tableaux, des matrices de données (ndarray).
  • Pandas: permet de créer/manipuler des « dataframes »,structures de données un peu comme des dictionnaires de listes, ou encore des sortes de tableaux indexés.
  • Matplotlib: permet de faire de joli petits graphiques tout beaux tout mignons avec plein de couleurs, des chiffres…Et aussi d’identifier, visualiser les liens entre nos données (ou pas).
  • Seaborn: permet également de faire des graphiques, en se prenant moins la tête.
  • Sklearn: intègre presque tout les modèles/techniques de base en machine/deep learning. Il permet de tester et prédire nos données. Très intéressant car la méthode pour utiliser chaque modèle est quasiment la même à chaque fois, seul les hyperparamètres et leurs réglages diffèrent la plupart du temps.

e) Pourquoi ce projet, et surtout comment être à peu près sûr que ça devrait marcher (un peu).

La zone couverte par notre fichier comprend la Manche et également une bonne partie du Golfe de Gascogne; ces 2 zones ont une météo globale qui diffère c’est vrai mais en gros cet endroit est soumis au passage des dépressions, et on peut prédire à partir de variables notre position approximative dans le système en jeu. Par exemple Un vent qui tourne Nord Ouest avec une hausse rapide de pression et une baisse de l’humidité ainsi qu’une baisse de température augure généralement un passage de front froid, ou encore une montée de l’humidité, une baisse de pression et un passage du vent à l’ouest l’arrivée d’une dépression…

Evidemment notre système sera bien loin d’être aussi précis qu’une prévision normale bénéficiant d’une vue d’ensemble de toutes les balises météo en temps réel sur toute la zone avec une puissance de calcul conséquente, mais ça devrait peut-être rendre un truc intéressant. En tout cas pour l’étude de nos données on devrait pouvoir faire apparaître des liens entre nos variables:

  • Les stations ayant une altitude élevée devraient moins subir les forces de frottements, donc avoir une direction de vent ainsi qu’une force de vent enregistrées un peu différentes. En effet il ne faut pas oublier que le vent synoptique (vent à 10 mètres d’altitude) ne fait que 2/3 du vent géostrophique (plus haut, sans les frottements).
  • Les stations ayant une latitude plus élevée devraient être plus soumises à la force de Coriolis, donc avoir une direction de vent un peu différente pour les mêmes variables annexes en jeu, et un vent moins fort pour un même changement de pression. En effet sur les cartes isobariques de surface, plus on est bas en latitude et plus cet écart indique un vent géostrophique fort.
  • Plus les stations sont hautes en altitude, plus la pression atmosphérique va descendre pour un même relevé.
  • Comme indiqué précédemment, un changement de direction de vent couplé à un changement de pression, température, humidité est souvent un signe de passage de front chaud ou froid, donc utile pour prévoir ce qui va se passer.
  • L’équation d’état bien connue reliant la pression, le volume et la température : P*V=R*T (R constante).

Bref, va y avoir du boulot…

Partie 3: organiser les données et utiliser la bonne technique sur un pc portable (processeur basique x86 de 32 bits).

Pour le moment on va utiliser le pc portable; on verra ensuite avec notre raspberry. Les contraintes au niveau puissance de calcul, consommation d’énergie, architecture du processeur qui peut empêcher l’usage de certains packages, ce sera pour plus tard, comme on dit une emmerde à la fois (si possible).

a) Importer les données meteo-France

Comme les fichiers csv des données de 2016, 2017 et 2018 sont conséquents il n’est pas possible de directement les lire et les stocker dans un dataframe (ce serait trop simple…) donc il va falloir bidouiller. Au départ j’ai essayé d’utiliser le package « dask » pour pouvoir traiter les données comme dans pandas (dask permet au lieu de stocker l’info dans un dataframe, de la stocker dans plein de petits dataframes englobés dans un grand dataframe, donc de paralléliser le traitement des données). Dask regroupe quasiment toutes les fonctionnalités de pandas mais pas tout, et du coup c’était laborieux pour un novice innocent vierge de toute les vicissitudes amères de la vie comme moi…

Donc pour faire tenir tout dans un seul dataframe, j’ai lu, traité via une fonction (j’ai écrit le module « fon_changer » qui contient la fonction « changer ») et importé le csv par morceaux dans une liste que j’ai ensuite concaténé. La fonction « changer » agit comme un filtre qui en gros supprime les colonnes « point de rosée » et « précipitations » (inutiles pour nous), ne garde que les données toutes les quatre heures, et ne garde que les stations qui remplissent tout les champs de données (49 au final sur 262). Certaines données sont également converties pour être plus pertinentes ou prendre moins de mémoire (float en int).

Voici le module « fon_changer » avec la fonction « changer »:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from datetime import datetime

def changer(data_1):
    
     data_1=data_1.sort_values(by=['number_sta','date'],ascending=True) #met les données dans l'ordre de chacune station, puis dans l'ordre temporel.

     data_1=data_1.drop(['precip','td'],axis=1) #on se débarrasse des colonnes inutiles pour nous.

     data_1=data_1.set_index('date') #on indexe notre dataframe sur le temps.

     data_1=data_1.fillna(data_1.rolling(window=1).mean()) #remplit les nan par la valeur moyenne de la journée pour chaque station.

     data_1=data_1.dropna(axis=0) #on se débarrasse des stations dont un champ de données n'est pas renseigné du tout.

     data_1.index=pd.to_datetime(data_1.index) #on convertit les index en objets datetime pour mieux les manipuler.

     heure_1=data_1[(data_1.index.hour==0) & (data_1.index.minute==0) & (data_1.index.second==0)] #on conserve juste les données toutes les quatre heures pour chaque station.
     heure_2=data_1[(data_1.index.hour==4) & (data_1.index.minute==0) & (data_1.index.second==0)]
     heure_3=data_1[(data_1.index.hour==8) & (data_1.index.minute==0) & (data_1.index.second==0)]
     heure_4=data_1[(data_1.index.hour==12) & (data_1.index.minute==0) & (data_1.index.second==0)]
     heure_5=data_1[(data_1.index.hour==16) & (data_1.index.minute==0) & (data_1.index.second==0)]
     heure_6=data_1[(data_1.index.hour==20) & (data_1.index.minute==0) & (data_1.index.second==0)]

     liste2=[heure_1,heure_2,heure_3,heure_4,heure_5,heure_6]
     data_one=pd.concat(liste2,axis=0)
     data_one=data_one.sort_values(by=['number_sta','date'],ascending=True)

     data_one['t']=data_one['t'].map(lambda x:int(x-273.15)) #convertit les Kelvin en degrés celsius.
     data_one['psl']=data_one['psl'].map(lambda x:int(x/100)) #convertit les pascals en hectopascals.
     data_one['hu']=data_one['hu'].map(lambda x:int(x)) #change en entier
     data_one['dd']=data_one['dd'].map(lambda x:int(x)) #pareil
     data_one['height_sta']=data_one['height_sta'].map(lambda x:int(x)) #encore pareil
     data_one['ff']=data_one['ff'].map(lambda x:int(x*3600/1852)) #change la vitesse du vent en noeuds.
     
     return data_one # renvoie les données "filtrées"

« nan » signifie « not a number », en général il faut combler ces trous soit en virant complètement l’échantillon, soit en estimant la donnée manquante via différentes méthodes(moyennes, nombres quelconques,nombres précédents…).

Et maintenant le petit programme pour filtrer nos données pour chaque année (ici c’est 2016 dans notre exemple):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from fon_changer import changer

chunksize=100000 # on définit la taille de chaque tronçon de données que l'on va passer à la moulinette.
chunks=[] # Cette liste va recueillir les tronçons filtrés.

for chunk in pd.read_csv("C:/Users/Psychopathe/Documents/cours tech/machine learning/meteonet-master/NW_Ground_Stations/Meteo_NW_2016.csv",chunksize=chunksize):
    filtered=changer(chunk) # on filtre le tronçon.
    chunks.append(filtered) # on remplit notre liste au fur et à mesure.
data_meteo_2016=pd.concat(chunks,axis=0) # on compile les données filtrées dans un seul dataframe.
data_meteo_2016.to_csv('data_meteo_2016.csv',sep='\t') # on stocke tout ça dans un fichier csv.

Une fois que l’on a fait tout ça pour les 3 années, il suffit d’importer les 3 fichiers csv puis les concaténer dans une liste afin d’obtenir un dataframe global pour les 3 ans du Nord-Ouest de la France, purgé des données inutiles pour nous.

b) Analyse des données traitées

Les pairplots

En utilisant seaborn, on peut faire un premier coup d’oeil rapide sur nos données du nord_ouest filtrées en faisant un « pairplot ». Ce tableau de graphiques met en corrélation des variables sélectionnées au préalable sur notre jeu de données; sur la diagonale ce sont les distributions de toutes les variables. J’ai fait deux pairplots sur les données; un où l’on visualise avec la couleur les variables selon la hauteur de l’observation, et un autre avec la latitude de l’observation. Ca donne ça:

Ce premier pairplot utilise la couleur pour voir les variables aussi selon la hauteur des stations météo (en mètres).

Ce second pairplot avec les couleurs indique nos variables selon la latitude d’observation.

Pour nos variables:

dd=direction du vent en degrés.

ff=force du vent en noeuds.

hu=humidité en pourcentage.

t=tétine en tétinou-octets. Meuh nan c’est la température !

psl=pression atmosphérique en hectopascals.

Premières observations :

  • La direction du vent est le plus souvent d’ouest, ensuite plutôt nord en moyenne (distplot dd).
  • La force du vent dépasse rarement les 25 noeuds en moyenne. La courbe des forces enregistrées décroit très vite (distplot ff).
  • L’humidité est le plus souvent élevée, autour de 80% environ (distplot hu).
  • La température est généralement autour de 10 °C (distplot t).
  • La pression tourne autour de 1015 hectopascals en moyenne (distplot psl).

Secondes observations:

  • Les stations ayant une latitude plus faible ont un pourcentage d’humidité global plus bas.
  • Il semblerait que plus l’humidité augmente, plus la force du vent peut potentiellement augmenter jusqu’à une sorte de seuil. Par exemple d’après nos données, une humidité de moins de 50% n’indique pas de vent au-dessus de 40 noeuds normalement.
  • Il semble que plus la température se rapproche de 10°C, plus elle peut potentiellement induire des vents forts.
  • C’est léger, mais il semble que plus la direction du vent se rapproche du Nord ouest, plus le vent peut potentiellement être fort.
  • Au-delà d’une pression de 1010 hectopascals environ, la force de vent potentielle maximale décroit progressivement.
  • Concernant la direction du vent il est bien plus délicat de trouver des corrélations avec les autres variables à priori.

Bon, pour le moment on est pas très avancé…

Maintenant que nous avons pu récupérer les données dans un dataframe, on va pouvoir les exploiter. Dans le prochain article on va voir comment les mettre en forme pour ensuite pouvoir soumettre nos données à un modèle prédictif comme les K voisins et les régressions linéaires, ridge et lasso. Dans un premier temps on va je pense orienter le projet sur une station météo « statique » (ça tombe bien, ma maison est assez bien exposée au vent sans trop subir d’effets de sites) avant de passer à l’embarqué.

Pour finir voilà en gros la distribution géographique des stations restantes:

Plus le rond est gros plus l’altitude de la station est élevée. On devine assez bien le Nord-Ouest de la France, ou alors un schtroumpf tuberculeux qui éternue.

Laisser un commentaire

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