2) Meteo et machine learning

Bon, cette fois c’est parti ! Pour commencer et s’échauffer pénardo sans se claquer un tendon ou une rustine, on va d’abord réduire notre jeu de données (conséquent, j’ai planté mon pc plusieurs fois) en une seule station, et voir ce que ça donne ensuite. Va-t-on pouvoir prévoir des trucs ? Est-ce que déféquer du marbre brut à apprendre python aura été utile ? Est-ce que ça vaut le coup de perdre du temps à lire mon article plutôt que courir nu dans un champ de blé en jouant de la lyre et en riant tel un farfadet facétieux ? Nous allons tenter ensemble de répondre à ces questions existentielles hô combien cruciales.

Précédemment on avait dit qu’on commencerait par une station météo fixe « à la maison » avant de voir pour la mettre sur un bateau. Dans tout ce bordel contenu par les 3 fichiers csv de météo France, il va donc falloir dénicher les données d’une station proche de chez moi, ayant aussi des données exploitables…Car ce jeu de données est parfois un gros gruyère. Des stations n’indiquent pas la pression atmosphérique, d’autres n’indiquent des infos que une fois par jour…Moi j’ai besoin d’une station météo qui me donne pour 2016,2017 et 2018 la pression, la direction du vent, la température et le pourcentage d’humidité sans trop de trous, car plus il manque de l’info, plus on va perdre de l’efficacité sur notre modèle prédictif ! Va falloir chercher un gouda plutôt qu’un gruyère…

I.Traiter les données avant usage.

Au départ on a environ 250 stations, mais seules 49 valent vraiment le détour à première vue, pour sélectionner ces 49 stations on va utiliser un peu la même trame que la fonction fon_changer précédente.

Bien, maintenant il va falloir rendre notre jeu de données présentable pour le soumettre aux différents modèles de machine learning de sklearn… Je vous cache pas que c’est le gros du boulot avec son lot de sueur, de sang, de larmes et de pointes de côté pour un novice informatico-geek prépubère…Mais merde pourquoi j’ai pas choisit des loisirs comme ping pong ou pelote basque…Enfin…En gros voilà comment on va procéder pour commencer:

  1. Se débarrasser du superflu.
  2. arranger nos données, les indexer selon le temps avec le package « datetime »pour faciliter les manips.
  3. gérer les données manquantes en interpolant.
  4. Modifier des variables pour les adapter à notre projet.

L’objectif final sera d’avoir un dataframe de 60 colonnes ou variables et de 1096 lignes ou échantillons. Pourquoi 1096 lignes ? parce que notre jeu de donnée dure trois ans, avec une année bissextile (2016) donc ça fait 366+365+365=1096 jours. Donc une ligne=un jour. Pourquoi 60 colonnes ? En fait on va garder seulement les données toutes les 2 heures, soit 12 fois 5 variables (pression,direction,température,humidité,force) et pis 12X5 bin ça fait 60. C’est ce dataframe qu’on va faire passer à la moulinette façon sklearn! En fait on va prendre le parti pris qu’une journée de données permet de prédire ce qui se passera dans les heures suivantes. Bon faut bien commencer quelque part de toute façon…

Voilà le programme pour traiter nos données et partir des fichiers météo France pour arriver aux données de Deauville en un dataframe de 1096 sur 60 :

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


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

     data_1['date']=pd.to_datetime(data_1['date']) # change la colonne date en objet datetime.

     data_1=data_1.set_index('date') #on indexe notre dataframe sur le temps.
     
     data_1=data_1.drop(['precip','td','lon','height_sta','lat'],axis=1) #on se débarrasse des colonnes inutiles pour nous.

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

     data_1=data_1.dropna(axis=0) # on vire les données de stations pour dégraisser.
     
     

     
     heure_1=data_1[(data_1.index.hour==0) & (data_1.index.minute==0)]#on conserve juste les données toutes les deux heures.
     heure_2=data_1[(data_1.index.hour==2) & (data_1.index.minute==0)]
     heure_3=data_1[(data_1.index.hour==4) & (data_1.index.minute==0)]
     heure_4=data_1[(data_1.index.hour==6) & (data_1.index.minute==0)]
     heure_5=data_1[(data_1.index.hour==8) & (data_1.index.minute==0)]
     heure_6=data_1[(data_1.index.hour==10) & (data_1.index.minute==0)]
     heure_7=data_1[(data_1.index.hour==12) & (data_1.index.minute==0)]
     heure_8=data_1[(data_1.index.hour==14) & (data_1.index.minute==0)]
     heure_9=data_1[(data_1.index.hour==16) & (data_1.index.minute==0)]
     heure_10=data_1[(data_1.index.hour==18) & (data_1.index.minute==0)]
     heure_11=data_1[(data_1.index.hour==20) & (data_1.index.minute==0)]
     heure_12=data_1[(data_1.index.hour==22) & (data_1.index.minute==0)]
    
     
     heures=[heure_1,heure_2,heure_3,heure_4,heure_5,heure_6,heure_7,heure_8,heure_9,heure_10,heure_11,heure_12]
     
     data_one=pd.concat(heures,axis=0) # on remet les données en un seul dataframe
     
     
     
     
     
     
     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['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"
 


chunksize=100000 # taille du morceau de données filtré à la fois.

chunks=[] # liste qui va prendre les morceaux filtrés de 2016.


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)
        chunks.append(filtered)
    
    
Deauville_2016=pd.concat(chunks,axis=0)
Deauville_2016=Deauville_2016[Deauville_2016['number_sta']==14578001] # on garde les valeurs de Deauville seulement.
Deauville_2016=Deauville_2016.drop(['number_sta'],axis=1) #on vire cette colonne qui ne nous sert plus
Deauville_2016=Deauville_2016.resample('2H').ffill() #on comble les heures manquantes avec les données de l'heure précédente.


chunks2=[]

for chunk2 in pd.read_csv('C:/Users/Psychopathe/Documents/cours tech/machine learning/meteonet-master/NW_Ground_Stations/Meteo_NW_2017.csv',chunksize=chunksize):
    filtered2=changer(chunk2)
    chunks2.append(filtered2)
    
Deauville_2017=pd.concat(chunks2,axis=0)
Deauville_2017=Deauville_2017[Deauville_2017['number_sta']==14578001]
Deauville_2017=Deauville_2017.drop(['number_sta'],axis=1)
Deauville_2017=Deauville_2017.resample('2H').ffill()


chunks3=[]

for chunk3 in pd.read_csv('C:/Users/Psychopathe/Documents/cours tech/machine learning/meteonet-master/NW_Ground_Stations/Meteo_NW_2018.csv',chunksize=chunksize):
    filtered3=changer(chunk3)
    chunks3.append(filtered3)
    
Deauville_2018=pd.concat(chunks3,axis=0)
Deauville_2018=Deauville_2018[Deauville_2018['number_sta']==14578001]
Deauville_2018=Deauville_2018.drop(['number_sta'],axis=1)
Deauville_2018=Deauville_2018.resample('2H').ffill()


Deauville=[Deauville_2016,Deauville_2017,Deauville_2018]
Deauville=pd.concat(Deauville,axis=0)



liste_heures=[Deauville[Deauville.index.hour==0+2*i] for i in range(12)] # permet de mettre les données de façon à avoir un jour égal une ligne.
Deauville=np.concatenate(liste_heures,axis=1)
Deauville=pd.DataFrame(Deauville)


Deauville.to_csv('Deauville_2H.csv',sep='\t') # crée le fichier avec nos données exploitables.



    
    
    
    
    
    
    
    

Maintenant, on a notre dataframe noté dans le fichier csv « Deauville_2H ». Ouéééé champagne !!!

II. SKLEARN

Sklearn est un package pour faire du machine learning, il contient donc tout un lot de modules pour ça.. Des modules se destinent à l’usage de modèles particuliers (arbres, régression, SVM…) et d’autres au prétraitement et à l’analyse des données, car beaucoup de modèles ont besoin d’un traitement statistique des variables avant, sinon c’est pas terrible niveau résultat, d’autres n’en n’ont pas besoin comme les forêts aléatoires par exemple, enfin comme j’ai lu dans les bouquins à voir. Sklearn permet aussi de résoudre des problèmes de classement, de régression, d’apprentissage non-supervisé et supervisé… Bon pour notre cas c’est de l’apprentissage supervisé pour un problème de régression.

  1. Les problèmes de régression

C’est simplement quand le résultat recherché est un nombre, une donnée « continue » comme un prix ou encore une dimension, une taille, etc…Les autres problèmes sont appelés des problèmes de classement, donc là on va chercher un résultat « discret » comme oui ou non, blanc ou noir, Tom ou Jerry, Riri, Fifi ou Loulou, Joe, averell, Jack ou William…Bref vous voyez le truc quoi.

2. L’apprentissage supervisé

On va séparer nos données en 2 jeux de données distincts; un jeu pour « l’entrainement » du modèle, et un autre pour vérifier si ça marche bien. En général le ratio entre données d’entrainement et données de test est de 70 % / 30 % environ;pour notre jeu de Deauville on prendra un ratio 80%/20%. Ne jamais utiliser des données d’entrainement pour évaluer un modèle, sinon on dit que les données sont « corrompues », et alors on va accoucher d’un modèle qui va tout péter à l’éval test car il aura déjà vu les données mais sur le terrain ça va ramer. Pour faire tout ça on va utiliser la fonction « train_test_split ».

En fait, l’apprentissage supervisé consiste à entrainer un modèle à fournir un résultat proche de ce qui est attendu, le modèle a les variables et le résultat qu’on attend de lui, et avec ça il se modifie via généralement une fonction de coût pour coller au mieux à tout ça.

3. Le prétraitement

Pour presque tout les modèles il est nécessaire de modifier les variables au préalable de façon statistique pour faciliter l’entrainement et l’efficacité des modèles. Pour cela on va majoritairement utiliser le module « preprocessing » de sklearn, ainsi que « make_pipeline » et la fonction « greadsearchcv ».

a) Preprocessing

Pour notre cas, déjà on va pas être emmerdé par des soucis d’encodage (changer des noms en nombres, car un processeur ne sait pas calculer avec des mots) car toutes nos variables sont des nombres. On va utiliser et comparer les résultats de 3 fonctions:

MinMaxScaler

Décale et recalibre les données pour que toutes les caractéristiques soient comprises entre 0 et 1.

RobustScaler

Un peu comme StandardScaler, mais utilise la médiane et les quartiles au lieu de la moyenne et la variance. Son avantage est de gommer les données aberrantes (outliers pour les frimeurs).

StandardScaler

Pour chaque caractéristique, rend la moyenne nulle et la variance égale à 1 (permet à toutes les caractéristiques d’avoir la même amplitude).

b) Les pipelines

Ce sont des structures qui associent un transformateur (l’une des fonctions précédente) et un estimateur (un modèle de machine learning). Ca permet d’économiser des lignes de codes, donc de rendre le code plus clair avec moins de chances de se planter, et aussi d’éviter de corrompre les données. La fonction « make_pipeline » permet de rédiger un pipeline.

c) gridsearcv

Permet de faire de la validation croisée. Cette fonction découpe nos données en sections de taille identiques (dans notre cas, j’ai découpé en 5 parties), puis teste les données selon toutes les configurations de découpage des données (un coup une section est une section test, un autre coup c’est une section entrainement…) et aussi les différents paramètres. Bon désolé c’est pas clair mais j’ai pas trouvé mieux pour expliquer, ou alors j’ai pas compris.

4. Les modèles qu’on va utiliser

Ce sont des modèles adaptés pour l’apprentissage supervisé et la régression. Notre jeu de données comprend pas mal de variables (60), mais bon il y a pire. En effet certains modèles déconnent quand on augmente le nombre de variables, enfin il paraît. Pour tout les modèles les tableaux de résultats concernent une prévision à 12 heures, et l’évolution des scores selon l’étendue de la prédiction se base sur la moyenne des différents scores par traitement.

Les plus proches voisins

Comme on l’a vu rapidement dans le précédent article, cette technique compare notre échantillon avec tout ceux stockés en mémoire. Il détecte le ou les échantillons dont les variables sont les plus similaires, regarde leur « target » ou donnée test correspondante puis attribue cette donnée ou la majorité de ces données si on prend plusieurs voisins pour l’attribuer à notre échantillon. Le plus simple, mais également le moins efficace. Voilà le petit programme pour étudier notre dataframe de Deauville (pour une prévision à 12 heures):

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

Deauville=pd.read_csv('C:/Users/Psychopathe/Documents/Python Scripts/meteo/station maison/mercredi28octobre/Deauville_2H.csv',sep='\t')

Deauville=Deauville.drop(['Unnamed: 0'],axis=1) # on vire la colonne inutile



variables=Deauville.iloc[:-1,:] # pour l'entrainement on garde tout sauf la dernière ligne.

résultat_dd=Deauville.iloc[1:,30] # pour la direction du vent, on vire la première ligne.
résultat_ff=Deauville.iloc[1:,31] # pour la force du vent, on vire aussi la première ligne.
résultat_hu=Deauville.iloc[1:,32] # pour l'humidité.
résultat_te=Deauville.iloc[1:,33] # pour la température.
résultat_pr=Deauville.iloc[1:,34] # pour la pression.



from sklearn.neighbors import KNeighborsRegressor # technique des plus proches voisins en regression.

from sklearn.model_selection import train_test_split # partage nos données en données test et entrainement (ratio réglé ici via test_size à 20%/80%)
from sklearn.model_selection import GridSearchCV # permet de trouver plus facilement les meilleurs paramètres de réglage du modèle.
from sklearn.model_selection import learning_curve # estime la limite de performance d'un modèle.

from sklearn.pipeline import make_pipeline # assemble un ou des transfomateurs de données et un estimateur, évite les fuites de données et réduit le code, donc évite les erreurs aussi.

from sklearn.preprocessing import MinMaxScaler # traitement de données, normalisation où nos variables deviennent comprises entre 0 et 1.
from sklearn.preprocessing import RobustScaler # traitement de données moins sujet aux outliers (échantillons aberrantes).
from sklearn.preprocessing import StandardScaler # traitement de donnée, rend la moyenne nulle et l'écart-type égal à un.

''' on sépare données entrainement et test pour toutes nos variables que l'on veut tester '''

X_train_direction,X_test_direction,y_train_direction,y_test_direction=train_test_split(variables,résultat_dd,test_size=0.2,random_state=0)
X_train_force,X_test_force,y_train_force,y_test_force=train_test_split(variables,résultat_ff,test_size=0.2,random_state=0)
X_train_humidite,X_test_humidite,y_train_humidite,y_test_humidite=train_test_split(variables,résultat_hu,test_size=0.2,random_state=0)
X_train_temperature,X_test_temperature,y_train_temperature,y_test_temperature=train_test_split(variables,résultat_te,test_size=0.2,random_state=0)
X_train_pression,X_test_pression,y_train_pression,y_test_pression=train_test_split(variables,résultat_pr,test_size=0.2,random_state=0)

traitement_1=make_pipeline(MinMaxScaler(),KNeighborsRegressor()) # création de l'objet pipeline1.
traitement_2=make_pipeline(RobustScaler(),KNeighborsRegressor()) # création du pipeline2.
traitement_3=make_pipeline(StandardScaler(),KNeighborsRegressor()) # création du pipeline3.

meilleurs_parametres=[]
score=[]

''' premier essai sans prétraitement, à poil , direction du vent   '''

param_grid={
    'n_neighbors':np.arange(1,20),
    'metric':['euclidean','manhattan']
    }

grid_1_direction=GridSearchCV(KNeighborsRegressor(),param_grid,cv=5)
grid_1_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_1_direction.best_params_)
model_1_direction=grid_1_direction.best_estimator_
score.append(model_1_direction.score(X_test_direction,y_test_direction))

''' à poil, force du vent '''

grid_1_force=GridSearchCV(KNeighborsRegressor(),param_grid,cv=5)
grid_1_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_1_force.best_params_)
model_1_force=grid_1_force.best_estimator_
score.append(model_1_force.score(X_test_force,y_test_force))

'''à poil, humidite  '''

grid_1_humidite=GridSearchCV(KNeighborsRegressor(),param_grid,cv=5)
grid_1_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_1_humidite.best_params_)
model_1_humidite=grid_1_humidite.best_estimator_
score.append(model_1_humidite.score(X_test_humidite,y_test_humidite))

''' à poil, temperature '''
grid_1_temperature=GridSearchCV(KNeighborsRegressor(),param_grid,cv=5)
grid_1_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_1_temperature.best_params_)
model_1_temperature=grid_1_temperature.best_estimator_
score.append(model_1_temperature.score(X_test_temperature,y_test_temperature))

''' à poil, pression'''

grid_1_pression=GridSearchCV(KNeighborsRegressor(),param_grid,cv=5)
grid_1_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_1_pression.best_params_)
model_1_pression=grid_1_pression.best_estimator_
score.append(model_1_pression.score(X_test_pression,y_test_pression))


''' avec le pipeline1, direction'''

param_grid2={
    'kneighborsregressor__n_neighbors':np.arange(1,20),
    'kneighborsregressor__metric':['manhattan','euclidean']
    }

grid_2_direction=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_2_direction.best_params_)
model_2_direction=grid_2_direction.best_estimator_
score.append(model_2_direction.score(X_test_direction,y_test_direction))

''' avec le pipeline1, force '''

grid_2_force=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_2_force.best_params_)
model_2_force=grid_2_force.best_estimator_
score.append(model_2_force.score(X_test_force,y_test_force))

''' avec le pipeline1, humidite  '''

grid_2_humidite=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_2_humidite.best_params_)
model_2_humidite=grid_2_humidite.best_estimator_
score.append(model_2_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline1, temperature'''

grid_2_temperature=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_2_temperature.best_params_)
model_2_temperature=grid_2_temperature.best_estimator_
score.append(model_2_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline1, pression'''

grid_2_pression=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_2_pression.best_params_)
model_2_pression=grid_2_pression.best_estimator_
score.append(model_2_pression.score(X_test_pression,y_test_pression))



'''avec le pipeline2, direction'''

grid_3_direction=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_3_direction.best_params_)
model_3_direction=grid_3_direction.best_estimator_
score.append(model_3_direction.score(X_test_direction,y_test_direction))

'''avec le pipeline2, force'''

grid_3_force=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_3_force.best_params_)
model_3_force=grid_3_force.best_estimator_
score.append(model_3_force.score(X_test_force,y_test_force))

'''avec le pipeline2, humidite'''

grid_3_humidite=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_3_humidite.best_params_)
model_3_humidite=grid_3_humidite.best_estimator_
score.append(model_3_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline2,temperature'''

grid_3_temperature=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_3_temperature.best_params_)
model_3_temperature=grid_3_temperature.best_estimator_
score.append(model_3_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline2,pression'''

grid_3_pression=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_3_pression.best_params_)
model_3_pression=grid_3_pression.best_estimator_
score.append(model_3_pression.score(X_test_pression,y_test_pression))

'''avec le pipeline3,direction'''

grid_4_direction=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_4_direction.best_params_)
model_4_direction=grid_4_direction.best_estimator_
score.append(model_4_direction.score(X_test_direction,y_test_direction))

'''avec le pipeline3,force'''

grid_4_force=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_4_force.best_params_)
model_4_force=grid_4_force.best_estimator_
score.append(model_4_force.score(X_test_force,y_test_force))

'''avec le pipeline3,humidite'''

grid_4_humidite=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_4_humidite.best_params_)
model_4_humidite=grid_4_humidite.best_estimator_
score.append(model_4_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline3,temperature'''

grid_4_temperature=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_4_temperature.best_params_)
model_4_temperature=grid_4_temperature.best_estimator_
score.append(model_4_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline3, pression'''

grid_4_pression=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_4_pression.best_params_)
model_4_pression=grid_4_pression.best_estimator_
score.append(model_4_pression.score(X_test_pression,y_test_pression))


tableau_data=pd.DataFrame([score])
tableau_data.to_csv('score_12H.csv',sep='\t')
print(score)
print(meilleurs_parametres)


N_direction,train_score_direction,val_score_direction=learning_curve(KNeighborsRegressor(),X_train_direction,y_train_direction,train_sizes=np.linspace(0.1,1,10),cv=5)
N_force,train_score_force,val_score_force=learning_curve(KNeighborsRegressor(),X_train_force,y_train_force,train_sizes=np.linspace(0.1,1,10),cv=5)
N_pression,train_score_pression,val_score_pression=learning_curve(KNeighborsRegressor(),X_train_pression,y_train_pression,train_sizes=np.linspace(0.1,1,10),cv=5)
N_humidite,train_score_humidite,val_score_humidite=learning_curve(KNeighborsRegressor(),X_train_humidite,y_train_humidite,train_sizes=np.linspace(0.1,1,10),cv=5)
N_temperature,train_score_temperature,val_score_temperature=learning_curve(KNeighborsRegressor(),X_train_temperature,y_train_temperature,train_sizes=np.linspace(0.1,1,10),cv=5)

plt.figure(figsize=[12,12])
plt.subplot(5,1,1)
plt.title("direction")
plt.plot(N_direction,train_score_direction.mean(axis=1),label='train')
plt.plot(N_direction,val_score_direction.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,2)
plt.title("force")
plt.plot(N_force,train_score_force.mean(axis=1),label='train')
plt.plot(N_force,val_score_force.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,3)
plt.title('pression')
plt.plot(N_pression,train_score_pression.mean(axis=1),label='train')
plt.plot(N_pression,val_score_pression.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,4)
plt.title('humidite')
plt.plot(N_humidite,train_score_humidite.mean(axis=1),label='train')
plt.plot(N_humidite,val_score_humidite.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,5)
plt.title('temperature')
plt.plot(N_temperature,train_score_temperature.mean(axis=1),label='train')
plt.plot(N_temperature,train_score_temperature.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()

Et voilà comment évoluent les moyennes des scores selon l’étendue de notre prévision (2 heures après, 4 heures après…on change à chaque fois l’indexation des colonnes pour les résultats attendus, de 5 en 5) :

En abscisse nous avons les heures des prédictions et en ordonnée les pourcentages de réussite sur les prédictions (par exemple 0.22 correspond à 22%). A première vue on distingue une certaine linéarité pour la force, l’humidité, la pression. Le reste c’est assez irrégulier mais pour la température ça peut s’expliquer car la variation est relativement faible pour chaque score. C’est assez rassurant on voit un lien entre les variables et le résultat attendu à priori, en tout cas pour celles où c’est à peu prêt linéaire.

Et maintenant la courbe d’apprentissage :

Un peu étrange….Les courbes ne se rejoignent pas, peut être parce que l’algo des k voisins « n’apprend pas » mais compare juste les données…A voir.

quand on regarde les paramètres ils changent beaucoup d’une variable à l’autre; les scores varient autour de 20% pour la direction,15% pour la force, 20% pour l’humidité, 80% pour la température et 60% pour la pression. Pas terrible…Aussi efficace qu’une prédiction de Paco Rabanne pour le moment. Voilà les scores en détail:

directionforcehumiditétempératurepression
sans traitement
25%17%17%59%48%
pipeline1
(MinMaxScaler)
19%13%23%84%63%
pipeline2
(RobustScaler)
18%9%25%82%67%
pipeline3
(StandardScaler)
18%8%25%84%67%

La régression linéaire

Pour bien comprendre comment ça marche allez sur youtube et regardez les vidéos consacrées à la régression linéaire sur la chaîne machine learnia, comme celle sur la descente de gradient. Voilà le programme :

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

Deauville=pd.read_csv('C:/Users/Psychopathe/Documents/Python Scripts/meteo/station maison/samedi24octobre/Deauville_le_retour.csv',sep='\t')

Deauville=Deauville.drop(['Unnamed: 0'],axis=1) # on vire la colonne inutile



variables=Deauville.iloc[:-1,:] # pour l'entrainement on garde tout sauf la dernière ligne.

résultat_dd=Deauville.iloc[1:,30] # pour la direction du vent, on vire la première ligne.
résultat_ff=Deauville.iloc[1:,31] # pour la force du vent, on vire aussi la première ligne.
résultat_hu=Deauville.iloc[1:,32] # pour l'humidité.
résultat_te=Deauville.iloc[1:,33] # pour la température.
résultat_pr=Deauville.iloc[1:,34] # pour la pression.



from sklearn.linear_model import LinearRegression# technique  regression simple.

from sklearn.model_selection import train_test_split # partage nos données en données test et entrainement (ratio réglé ici via test_size à 20%/80%)
from sklearn.model_selection import GridSearchCV # permet de trouver plus facilement les meilleurs paramètres de réglage du modèle.
from sklearn.model_selection import learning_curve # estime la limite de performance d'un modèle.

from sklearn.pipeline import make_pipeline # assemble un ou des transfomateurs de données et un estimateur, évite les fuites de données et réduit le code, donc évite les erreurs aussi.

from sklearn.preprocessing import MinMaxScaler # traitement de données, normalisation où nos variables deviennent comprises entre 0 et 1.
from sklearn.preprocessing import RobustScaler # traitement de données moins sujet aux outliers (échantillons aberrantes).
from sklearn.preprocessing import StandardScaler # traitement de donnée, rend la moyenne nulle et l'écart-type égal à un.

''' on sépare données entrainement et test pour toutes nos variables que l'on veut tester '''

X_train_direction,X_test_direction,y_train_direction,y_test_direction=train_test_split(variables,résultat_dd,test_size=0.2,random_state=0)
X_train_force,X_test_force,y_train_force,y_test_force=train_test_split(variables,résultat_ff,test_size=0.2,random_state=0)
X_train_humidite,X_test_humidite,y_train_humidite,y_test_humidite=train_test_split(variables,résultat_hu,test_size=0.2,random_state=0)
X_train_temperature,X_test_temperature,y_train_temperature,y_test_temperature=train_test_split(variables,résultat_te,test_size=0.2,random_state=0)
X_train_pression,X_test_pression,y_train_pression,y_test_pression=train_test_split(variables,résultat_pr,test_size=0.2,random_state=0)

traitement_1=make_pipeline(MinMaxScaler(),LinearRegression()) # création de l'objet pipeline1.
traitement_2=make_pipeline(RobustScaler(),LinearRegression()) # création du pipeline2.
traitement_3=make_pipeline(StandardScaler(),LinearRegression()) # création du pipeline3.

meilleurs_parametres=[]
score=[]

''' premier essai sans prétraitement, à poil , direction du vent   '''

param_grid={
    
    }

grid_1_direction=GridSearchCV(LinearRegression(),param_grid,cv=5)
grid_1_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_1_direction.best_params_)
model_1_direction=grid_1_direction.best_estimator_
score.append(model_1_direction.score(X_test_direction,y_test_direction))

''' à poil, force du vent '''

grid_1_force=GridSearchCV(LinearRegression(),param_grid,cv=5)
grid_1_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_1_force.best_params_)
model_1_force=grid_1_force.best_estimator_
score.append(model_1_force.score(X_test_force,y_test_force))

'''à poil, humidite  '''

grid_1_humidite=GridSearchCV(LinearRegression(),param_grid,cv=5)
grid_1_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_1_humidite.best_params_)
model_1_humidite=grid_1_humidite.best_estimator_
score.append(model_1_humidite.score(X_test_humidite,y_test_humidite))

''' à poil, temperature '''
grid_1_temperature=GridSearchCV(LinearRegression(),param_grid,cv=5)
grid_1_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_1_temperature.best_params_)
model_1_temperature=grid_1_temperature.best_estimator_
score.append(model_1_temperature.score(X_test_temperature,y_test_temperature))

''' à poil, pression'''

grid_1_pression=GridSearchCV(LinearRegression(),param_grid,cv=5)
grid_1_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_1_pression.best_params_)
model_1_pression=grid_1_pression.best_estimator_
score.append(model_1_pression.score(X_test_pression,y_test_pression))



''' avec le pipeline1, direction'''

param_grid2={
    
    }

grid_2_direction=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_2_direction.best_params_)
model_2_direction=grid_2_direction.best_estimator_
score.append(model_2_direction.score(X_test_direction,y_test_direction))

''' avec le pipeline1, force '''

grid_2_force=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_2_force.best_params_)
model_2_force=grid_2_force.best_estimator_
score.append(model_2_force.score(X_test_force,y_test_force))

''' avec le pipeline1, humidite  '''

grid_2_humidite=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_2_humidite.best_params_)
model_2_humidite=grid_2_humidite.best_estimator_
score.append(model_2_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline1, temperature'''

grid_2_temperature=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_2_temperature.best_params_)
model_2_temperature=grid_2_temperature.best_estimator_
score.append(model_2_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline1, pression'''

grid_2_pression=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_2_pression.best_params_)
model_2_pression=grid_2_pression.best_estimator_
score.append(model_2_pression.score(X_test_pression,y_test_pression))


'''avec le pipeline2, direction'''

grid_3_direction=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_3_direction.best_params_)
model_3_direction=grid_3_direction.best_estimator_
score.append(model_3_direction.score(X_test_direction,y_test_direction))

'''avec le pipeline2, force'''

grid_3_force=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_3_force.best_params_)
model_3_force=grid_3_force.best_estimator_
score.append(model_3_force.score(X_test_force,y_test_force))

'''avec le pipeline2, humidite'''

grid_3_humidite=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_3_humidite.best_params_)
model_3_humidite=grid_3_humidite.best_estimator_
score.append(model_3_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline2,temperature'''

grid_3_temperature=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_3_temperature.best_params_)
model_3_temperature=grid_3_temperature.best_estimator_
score.append(model_3_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline2,pression'''

grid_3_pression=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_3_pression.best_params_)
model_3_pression=grid_3_pression.best_estimator_
score.append(model_3_pression.score(X_test_pression,y_test_pression))

'''avec le pipeline3,direction'''

grid_4_direction=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_4_direction.best_params_)
model_4_direction=grid_4_direction.best_estimator_
score.append(model_4_direction.score(X_test_direction,y_test_direction))

'''avec le pipeline3,force'''

grid_4_force=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_4_force.best_params_)
model_4_force=grid_4_force.best_estimator_
score.append(model_4_force.score(X_test_force,y_test_force))

'''avec le pipeline3,humidite'''

grid_4_humidite=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_4_humidite.best_params_)
model_4_humidite=grid_4_humidite.best_estimator_
score.append(model_4_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline3,temperature'''

grid_4_temperature=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_4_temperature.best_params_)
model_4_temperature=grid_4_temperature.best_estimator_
score.append(model_4_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline3, pression'''

grid_4_pression=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_4_pression.best_params_)
model_4_pression=grid_4_pression.best_estimator_
score.append(model_4_pression.score(X_test_pression,y_test_pression))


tableau_data=pd.DataFrame([score])
tableau_data.to_csv('score_12H.csv',sep='\t')
print(score)
print(meilleurs_parametres)


N_direction,train_score_direction,val_score_direction=learning_curve(LinearRegression(),X_train_direction,y_train_direction,train_sizes=np.linspace(0.1,1,10),cv=5)
N_force,train_score_force,val_score_force=learning_curve(LinearRegression(),X_train_force,y_train_force,train_sizes=np.linspace(0.1,1,10),cv=5)
N_pression,train_score_pression,val_score_pression=learning_curve(LinearRegression(),X_train_pression,y_train_pression,train_sizes=np.linspace(0.1,1,10),cv=5)
N_humidite,train_score_humidite,val_score_humidite=learning_curve(LinearRegression(),X_train_humidite,y_train_humidite,train_sizes=np.linspace(0.1,1,10),cv=5)
N_temperature,train_score_temperature,val_score_temperature=learning_curve(LinearRegression(),X_train_temperature,y_train_temperature,train_sizes=np.linspace(0.1,1,10),cv=5)

plt.figure(figsize=[12,12])
plt.subplot(5,1,1)
plt.title("direction")
plt.plot(N_direction,train_score_direction.mean(axis=1),label='train')
plt.plot(N_direction,val_score_direction.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,2)
plt.title("force")
plt.plot(N_force,train_score_force.mean(axis=1),label='train')
plt.plot(N_force,val_score_force.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,3)
plt.title('pression')
plt.plot(N_pression,train_score_pression.mean(axis=1),label='train')
plt.plot(N_pression,val_score_pression.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,4)
plt.title('humidite')
plt.plot(N_humidite,train_score_humidite.mean(axis=1),label='train')
plt.plot(N_humidite,val_score_humidite.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,5)
plt.title('temperature')
plt.plot(N_temperature,train_score_temperature.mean(axis=1),label='train')
plt.plot(N_temperature,train_score_temperature.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()

Comme vous pouvez le constater, les grilles des paramètres sont vides car il n’y a pas (à ma connaissance) de paramètres à ajuster pour la régression linéaire simple.

Et maintenant les résultats selon l’étendue de la prévision:

A première vue le constat est à peu prêt identique par rapport aux proches voisins, par contre la température semble plus linéaire.

Et maintenant voilà les courbes d’apprentissage pour la régression:

Pour les 4 premières variables on remarque une montée rapide de la validation jusqu’à environ 130 échantillons, ensuite ça devient bien plus lent. Pour la température c’est l’inverse jusqu’à 130 échantillons ça descend progressivement, ensuite ça met plus de temps à baisser.

Quand on observe nos résultats, ils ne varient quasiment pas entre nos données non traitées et nos données traitées, à chaque fois on a ça:

variablesdirectionforcehumiditétemperaturepression
scores en %20%19%18%86%85%

Bon ça reste aussi prédictif qu’un retard SNCF pour le moment.

La régression Ridge

Ce type de régression fonctionne comme celle d’avant sauf que le système va chercher à minimiser les poids au maximum. C’est une méthode particulièrement intéressante pour éviter le surapprentissage des modèles. Pour le programme c’est presque comme la régression sauf que là on peut jouer avec le paramètre alpha, présent cette fois dans les paramètres de grille:

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

Deauville=pd.read_csv('C:/Users/Psychopathe/Documents/Python Scripts/meteo/station maison/samedi24octobre/Deauville_le_retour.csv',sep='\t')

Deauville=Deauville.drop(['Unnamed: 0'],axis=1) # on vire la colonne inutile



variables=Deauville.iloc[:-1,:] # pour l'entrainement on garde tout sauf la dernière ligne.

résultat_dd=Deauville.iloc[1:,30] # pour la direction du vent, on vire la première ligne.
résultat_ff=Deauville.iloc[1:,31] # pour la force du vent, on vire aussi la première ligne.
résultat_hu=Deauville.iloc[1:,32] # pour l'humidité.
résultat_te=Deauville.iloc[1:,33] # pour la température.
résultat_pr=Deauville.iloc[1:,34] # pour la pression.



from sklearn.linear_model import Ridge# technique  regression ridge.

from sklearn.model_selection import train_test_split # partage nos données en données test et entrainement (ratio réglé ici via test_size à 20%/80%)
from sklearn.model_selection import GridSearchCV # permet de trouver plus facilement les meilleurs paramètres de réglage du modèle.
from sklearn.model_selection import learning_curve # estime la limite de performance d'un modèle.

from sklearn.pipeline import make_pipeline # assemble un ou des transfomateurs de données et un estimateur, évite les fuites de données et réduit le code, donc évite les erreurs aussi.

from sklearn.preprocessing import MinMaxScaler # traitement de données, normalisation où nos variables deviennent comprises entre 0 et 1.
from sklearn.preprocessing import RobustScaler # traitement de données moins sujet aux outliers (échantillons aberrantes).
from sklearn.preprocessing import StandardScaler # traitement de donnée, rend la moyenne nulle et l'écart-type égal à un.

''' on sépare données entrainement et test pour toutes nos variables que l'on veut tester '''

X_train_direction,X_test_direction,y_train_direction,y_test_direction=train_test_split(variables,résultat_dd,test_size=0.2,random_state=0)
X_train_force,X_test_force,y_train_force,y_test_force=train_test_split(variables,résultat_ff,test_size=0.2,random_state=0)
X_train_humidite,X_test_humidite,y_train_humidite,y_test_humidite=train_test_split(variables,résultat_hu,test_size=0.2,random_state=0)
X_train_temperature,X_test_temperature,y_train_temperature,y_test_temperature=train_test_split(variables,résultat_te,test_size=0.2,random_state=0)
X_train_pression,X_test_pression,y_train_pression,y_test_pression=train_test_split(variables,résultat_pr,test_size=0.2,random_state=0)

traitement_1=make_pipeline(MinMaxScaler(),Ridge()) # création de l'objet pipeline1.
traitement_2=make_pipeline(RobustScaler(),Ridge()) # création du pipeline2.
traitement_3=make_pipeline(StandardScaler(),Ridge()) # création du pipeline3.

meilleurs_parametres=[]
score=[]

''' premier essai sans prétraitement, à poil , direction du vent   '''

param_grid={
    'alpha':[10,1,0.1,0.01,0.001]
    }

grid_1_direction=GridSearchCV(Ridge(),param_grid,cv=5)
grid_1_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_1_direction.best_params_)
model_1_direction=grid_1_direction.best_estimator_
score.append(model_1_direction.score(X_test_direction,y_test_direction))

''' à poil, force du vent '''

grid_1_force=GridSearchCV(Ridge(),param_grid,cv=5)
grid_1_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_1_force.best_params_)
model_1_force=grid_1_force.best_estimator_
score.append(model_1_force.score(X_test_force,y_test_force))

'''à poil, humidite  '''

grid_1_humidite=GridSearchCV(Ridge(),param_grid,cv=5)
grid_1_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_1_humidite.best_params_)
model_1_humidite=grid_1_humidite.best_estimator_
score.append(model_1_humidite.score(X_test_humidite,y_test_humidite))

''' à poil, temperature '''
grid_1_temperature=GridSearchCV(Ridge(),param_grid,cv=5)
grid_1_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_1_temperature.best_params_)
model_1_temperature=grid_1_temperature.best_estimator_
score.append(model_1_temperature.score(X_test_temperature,y_test_temperature))

''' à poil, pression'''

grid_1_pression=GridSearchCV(Ridge(),param_grid,cv=5)
grid_1_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_1_pression.best_params_)
model_1_pression=grid_1_pression.best_estimator_
score.append(model_1_pression.score(X_test_pression,y_test_pression))



''' avec le pipeline1, direction'''

param_grid2={
    'ridge__alpha':[10,1,0.1,0.01,0.001]
    }

grid_2_direction=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_2_direction.best_params_)
model_2_direction=grid_2_direction.best_estimator_
score.append(model_2_direction.score(X_test_direction,y_test_direction))

''' avec le pipeline1, force '''

grid_2_force=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_2_force.best_params_)
model_2_force=grid_2_force.best_estimator_
score.append(model_2_force.score(X_test_force,y_test_force))

''' avec le pipeline1, humidite  '''

grid_2_humidite=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_2_humidite.best_params_)
model_2_humidite=grid_2_humidite.best_estimator_
score.append(model_2_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline1, temperature'''

grid_2_temperature=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_2_temperature.best_params_)
model_2_temperature=grid_2_temperature.best_estimator_
score.append(model_2_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline1, pression'''

grid_2_pression=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_2_pression.best_params_)
model_2_pression=grid_2_pression.best_estimator_
score.append(model_2_pression.score(X_test_pression,y_test_pression))


'''avec le pipeline2, direction'''

grid_3_direction=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_3_direction.best_params_)
model_3_direction=grid_3_direction.best_estimator_
score.append(model_3_direction.score(X_test_direction,y_test_direction))

'''avec le pipeline2, force'''

grid_3_force=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_3_force.best_params_)
model_3_force=grid_3_force.best_estimator_
score.append(model_3_force.score(X_test_force,y_test_force))

'''avec le pipeline2, humidite'''

grid_3_humidite=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_3_humidite.best_params_)
model_3_humidite=grid_3_humidite.best_estimator_
score.append(model_3_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline2,temperature'''

grid_3_temperature=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_3_temperature.best_params_)
model_3_temperature=grid_3_temperature.best_estimator_
score.append(model_3_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline2,pression'''

grid_3_pression=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_3_pression.best_params_)
model_3_pression=grid_3_pression.best_estimator_
score.append(model_3_pression.score(X_test_pression,y_test_pression))

'''avec le pipeline3,direction'''

grid_4_direction=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_4_direction.best_params_)
model_4_direction=grid_4_direction.best_estimator_
score.append(model_4_direction.score(X_test_direction,y_test_direction))

'''avec le pipeline3,force'''

grid_4_force=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_4_force.best_params_)
model_4_force=grid_4_force.best_estimator_
score.append(model_4_force.score(X_test_force,y_test_force))

'''avec le pipeline3,humidite'''

grid_4_humidite=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_4_humidite.best_params_)
model_4_humidite=grid_4_humidite.best_estimator_
score.append(model_4_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline3,temperature'''

grid_4_temperature=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_4_temperature.best_params_)
model_4_temperature=grid_4_temperature.best_estimator_
score.append(model_4_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline3, pression'''

grid_4_pression=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_4_pression.best_params_)
model_4_pression=grid_4_pression.best_estimator_
score.append(model_4_pression.score(X_test_pression,y_test_pression))


tableau_data=pd.DataFrame([score])
tableau_data.to_csv('scoreridge_12H.csv',sep='\t')
print(score)
print(meilleurs_parametres)

"""
N_direction,train_score_direction,val_score_direction=learning_curve(Ridge(),X_train_direction,y_train_direction,train_sizes=np.linspace(0.1,1,10),cv=5)
N_force,train_score_force,val_score_force=learning_curve(Ridge(),X_train_force,y_train_force,train_sizes=np.linspace(0.1,1,10),cv=5)
N_pression,train_score_pression,val_score_pression=learning_curve(Ridge(),X_train_pression,y_train_pression,train_sizes=np.linspace(0.1,1,10),cv=5)
N_humidite,train_score_humidite,val_score_humidite=learning_curve(Ridge(),X_train_humidite,y_train_humidite,train_sizes=np.linspace(0.1,1,10),cv=5)
N_temperature,train_score_temperature,val_score_temperature=learning_curve(Ridge(),X_train_temperature,y_train_temperature,train_sizes=np.linspace(0.1,1,10),cv=5)

plt.figure(figsize=[12,12])
plt.subplot(5,1,1)
plt.title("direction")
plt.plot(N_direction,train_score_direction.mean(axis=1),label='train')
plt.plot(N_direction,val_score_direction.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,2)
plt.title("force")
plt.plot(N_force,train_score_force.mean(axis=1),label='train')
plt.plot(N_force,val_score_force.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,3)
plt.title('pression')
plt.plot(N_pression,train_score_pression.mean(axis=1),label='train')
plt.plot(N_pression,val_score_pression.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,4)
plt.title('humidite')
plt.plot(N_humidite,train_score_humidite.mean(axis=1),label='train')
plt.plot(N_humidite,val_score_humidite.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,5)
plt.title('temperature')
plt.plot(N_temperature,train_score_temperature.mean(axis=1),label='train')
plt.plot(N_temperature,train_score_temperature.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()

Et maintenant les courbes des scores selon les heures de prédiction:

On voit bien la linéarité pour nos variables, pour la direction ça reste un peu les montagnes russes par contre. Ensuite on va pouvoir voir les courbes d’apprentissage du modèle Ridge:

A première vue ça ressemble assez à la régression linéaire simple, avec peut-être une progression un peu moins tranchée aux alentour des 130 écahntillons. Les résultats des scores à 12 heures selon les traitements maintenant:

directionforcehumiditétempératurepression
sans traitement20%19%19%86%85%
MinMaxScaler25%17%21%86%85%
RobustScaler23%20%20%86%85%
StandardScaler22%20%20%86%85%

Pour les meilleurs paramètres on a alpha à 10 très souvent, un peu à 1 et une fois à 0.01.

La régression Lasso

Ce modèle va cette fois descendre à 0 les poids « inutiles ». Pratique pour identifier les variables qui sont vraiment utiles des variables inutiles pour nos prédictions…Programme:

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

Deauville=pd.read_csv('C:/Users/Psychopathe/Documents/Python Scripts/meteo/station maison/samedi24octobre/Deauville_le_retour.csv',sep='\t')

Deauville=Deauville.drop(['Unnamed: 0'],axis=1) # on vire la colonne inutile



variables=Deauville.iloc[:-1,:] # pour l'entrainement on garde tout sauf la dernière ligne.

résultat_dd=Deauville.iloc[1:,30] # pour la direction du vent, on vire la première ligne.
résultat_ff=Deauville.iloc[1:,31] # pour la force du vent, on vire aussi la première ligne.
résultat_hu=Deauville.iloc[1:,32] # pour l'humidité.
résultat_te=Deauville.iloc[1:,33] # pour la température.
résultat_pr=Deauville.iloc[1:,34] # pour la pression.



from sklearn.linear_model import Lasso# technique  regression lasso.

from sklearn.model_selection import train_test_split # partage nos données en données test et entrainement (ratio réglé ici via test_size à 20%/80%)
from sklearn.model_selection import GridSearchCV # permet de trouver plus facilement les meilleurs paramètres de réglage du modèle.
from sklearn.model_selection import learning_curve # estime la limite de performance d'un modèle.

from sklearn.pipeline import make_pipeline # assemble un ou des transfomateurs de données et un estimateur, évite les fuites de données et réduit le code, donc évite les erreurs aussi.

from sklearn.preprocessing import MinMaxScaler # traitement de données, normalisation où nos variables deviennent comprises entre 0 et 1.
from sklearn.preprocessing import RobustScaler # traitement de données moins sujet aux outliers (échantillons aberrantes).
from sklearn.preprocessing import StandardScaler # traitement de donnée, rend la moyenne nulle et l'écart-type égal à un.

''' on sépare données entrainement et test pour toutes nos variables que l'on veut tester '''

X_train_direction,X_test_direction,y_train_direction,y_test_direction=train_test_split(variables,résultat_dd,test_size=0.2,random_state=0)
X_train_force,X_test_force,y_train_force,y_test_force=train_test_split(variables,résultat_ff,test_size=0.2,random_state=0)
X_train_humidite,X_test_humidite,y_train_humidite,y_test_humidite=train_test_split(variables,résultat_hu,test_size=0.2,random_state=0)
X_train_temperature,X_test_temperature,y_train_temperature,y_test_temperature=train_test_split(variables,résultat_te,test_size=0.2,random_state=0)
X_train_pression,X_test_pression,y_train_pression,y_test_pression=train_test_split(variables,résultat_pr,test_size=0.2,random_state=0)

traitement_1=make_pipeline(MinMaxScaler(),Lasso()) # création de l'objet pipeline1.
traitement_2=make_pipeline(RobustScaler(),Lasso()) # création du pipeline2.
traitement_3=make_pipeline(StandardScaler(),Lasso()) # création du pipeline3.

meilleurs_parametres=[]
score=[]
v_u=[]

''' premier essai sans prétraitement, à poil , direction du vent   '''

param_grid={
    'alpha':[10,1,0.1,0.01,0.001],
    'max_iter':[100000]
    }

grid_1_direction=GridSearchCV(Lasso(),param_grid,cv=5)
grid_1_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_1_direction.best_params_)
model_1_direction=grid_1_direction.best_estimator_
score.append(model_1_direction.score(X_test_direction,y_test_direction))
v_u.append(np.sum(model_1_direction.coef_!=0))

''' à poil, force du vent '''

grid_1_force=GridSearchCV(Lasso(),param_grid,cv=5)
grid_1_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_1_force.best_params_)
model_1_force=grid_1_force.best_estimator_
score.append(model_1_force.score(X_test_force,y_test_force))
v_u.append(np.sum(model_1_force.coef_!=0))

'''à poil, humidite  '''

grid_1_humidite=GridSearchCV(Lasso(),param_grid,cv=5)
grid_1_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_1_humidite.best_params_)
model_1_humidite=grid_1_humidite.best_estimator_
score.append(model_1_humidite.score(X_test_humidite,y_test_humidite))
v_u.append(np.sum(model_1_humidite.coef_!=0))

''' à poil, temperature '''
grid_1_temperature=GridSearchCV(Lasso(),param_grid,cv=5)
grid_1_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_1_temperature.best_params_)
model_1_temperature=grid_1_temperature.best_estimator_
score.append(model_1_temperature.score(X_test_temperature,y_test_temperature))
v_u.append(np.sum(model_1_temperature.coef_!=0))

''' à poil, pression'''

grid_1_pression=GridSearchCV(Lasso(),param_grid,cv=5)
grid_1_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_1_pression.best_params_)
model_1_pression=grid_1_pression.best_estimator_
score.append(model_1_pression.score(X_test_pression,y_test_pression))
v_u.append(np.sum(model_1_pression.coef_!=0))

print(score)
print(meilleurs_parametres)
print(v_u)
print(model_1_direction.coef_)
print(model_1_force.coef_)
print(model_1_humidite.coef_)
print(model_1_temperature.coef_)
print(model_1_pression.coef_)


''' avec le pipeline1, direction'''

param_grid2={
    'lasso__alpha':[10,1,0.1,0.01,0.001],
    'lasso__max_iter':[100000]
    }

grid_2_direction=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_2_direction.best_params_)
model_2_direction=grid_2_direction.best_estimator_
score.append(model_2_direction.score(X_test_direction,y_test_direction))


''' avec le pipeline1, force '''

grid_2_force=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_2_force.best_params_)
model_2_force=grid_2_force.best_estimator_
score.append(model_2_force.score(X_test_force,y_test_force))

''' avec le pipeline1, humidite  '''

grid_2_humidite=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_2_humidite.best_params_)
model_2_humidite=grid_2_humidite.best_estimator_
score.append(model_2_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline1, temperature'''

grid_2_temperature=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_2_temperature.best_params_)
model_2_temperature=grid_2_temperature.best_estimator_
score.append(model_2_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline1, pression'''

grid_2_pression=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_2_pression.best_params_)
model_2_pression=grid_2_pression.best_estimator_
score.append(model_2_pression.score(X_test_pression,y_test_pression))


'''avec le pipeline2, direction'''

grid_3_direction=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_3_direction.best_params_)
model_3_direction=grid_3_direction.best_estimator_
score.append(model_3_direction.score(X_test_direction,y_test_direction))

'''avec le pipeline2, force'''

grid_3_force=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_3_force.best_params_)
model_3_force=grid_3_force.best_estimator_
score.append(model_3_force.score(X_test_force,y_test_force))

'''avec le pipeline2, humidite'''

grid_3_humidite=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_3_humidite.best_params_)
model_3_humidite=grid_3_humidite.best_estimator_
score.append(model_3_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline2,temperature'''

grid_3_temperature=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_3_temperature.best_params_)
model_3_temperature=grid_3_temperature.best_estimator_
score.append(model_3_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline2,pression'''

grid_3_pression=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_3_pression.best_params_)
model_3_pression=grid_3_pression.best_estimator_
score.append(model_3_pression.score(X_test_pression,y_test_pression))

'''avec le pipeline3,direction'''

grid_4_direction=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_direction.fit(X_train_direction,y_train_direction)
meilleurs_parametres.append(grid_4_direction.best_params_)
model_4_direction=grid_4_direction.best_estimator_
score.append(model_4_direction.score(X_test_direction,y_test_direction))

'''avec le pipeline3,force'''

grid_4_force=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_force.fit(X_train_force,y_train_force)
meilleurs_parametres.append(grid_4_force.best_params_)
model_4_force=grid_4_force.best_estimator_
score.append(model_4_force.score(X_test_force,y_test_force))


'''avec le pipeline3,humidite'''

grid_4_humidite=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_humidite.fit(X_train_humidite,y_train_humidite)
meilleurs_parametres.append(grid_4_humidite.best_params_)
model_4_humidite=grid_4_humidite.best_estimator_
score.append(model_4_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline3,temperature'''

grid_4_temperature=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_temperature.fit(X_train_temperature,y_train_temperature)
meilleurs_parametres.append(grid_4_temperature.best_params_)
model_4_temperature=grid_4_temperature.best_estimator_
score.append(model_4_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline3, pression'''

grid_4_pression=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_pression.fit(X_train_pression,y_train_pression)
meilleurs_parametres.append(grid_4_pression.best_params_)
model_4_pression=grid_4_pression.best_estimator_
score.append(model_4_pression.score(X_test_pression,y_test_pression))


tableau_data=pd.DataFrame([score])
tableau_data.to_csv('scorelasso_12H.csv',sep='\t')
print(score)
print(meilleurs_parametres)
print(v_u)

N_direction,train_score_direction,val_score_direction=learning_curve(Lasso(),X_train_direction,y_train_direction,train_sizes=np.linspace(0.1,1,10),cv=5)
N_force,train_score_force,val_score_force=learning_curve(Lasso(),X_train_force,y_train_force,train_sizes=np.linspace(0.1,1,10),cv=5)
N_pression,train_score_pression,val_score_pression=learning_curve(Lasso(),X_train_pression,y_train_pression,train_sizes=np.linspace(0.1,1,10),cv=5)
N_humidite,train_score_humidite,val_score_humidite=learning_curve(Lasso(),X_train_humidite,y_train_humidite,train_sizes=np.linspace(0.1,1,10),cv=5)
N_temperature,train_score_temperature,val_score_temperature=learning_curve(Lasso(),X_train_temperature,y_train_temperature,train_sizes=np.linspace(0.1,1,10),cv=5)

plt.figure(figsize=[12,12])
plt.subplot(5,1,1)
plt.title("direction")
plt.plot(N_direction,train_score_direction.mean(axis=1),label='train')
plt.plot(N_direction,val_score_direction.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,2)
plt.title("force")
plt.plot(N_force,train_score_force.mean(axis=1),label='train')
plt.plot(N_force,val_score_force.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,3)
plt.title('pression')
plt.plot(N_pression,train_score_pression.mean(axis=1),label='train')
plt.plot(N_pression,val_score_pression.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,4)
plt.title('humidite')
plt.plot(N_humidite,train_score_humidite.mean(axis=1),label='train')
plt.plot(N_humidite,val_score_humidite.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,5)
plt.title('temperature')
plt.plot(N_temperature,train_score_temperature.mean(axis=1),label='train')
plt.plot(N_temperature,train_score_temperature.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()

Les courbes scores sont presque pareilles, donc passons aux courbes d’apprentissage:

La courbe de validation se fait de façon encore plus progressive.

Voici les résultats trouvé pour une prédiction à 12 heures selon les divers traitements:

directionforcehumiditétempératurepression
sans traitement24%21%21%86%85%
MinMaxScaler25%18%24%86%85%
RobustScaler25%20%23%81%86%
StandardScaler24%20%22%86%85%

Et maintenant comme on a vu avant, avec le mode lasso on peut savoir quelles variables comptent pour nous, on a alors ça:

directionforcehumiditétempératurepression
nombre de variables utilisées pour la prédiction2541294050

J’ai fait le test pour des heures de prédiction plus proches et moins proches, ça varie mais ça reste aux alentours des mêmes valeurs grosso modo. La direction du vent utilise moins de variables. En exécutant le code on voit les variables « jetées » dans les arrays. Il faudra que je regarde tout ça plus en détail pour la suite.

Les forêts aléatoires

Pour avoir une bonne explication du bidule , allez sur wikipépé ou d’autres liens parce que je crois que je vais dire des conneries…Bon temps pis je me lance: on sélectionne un nombre d’arbres de décision pour notre forêt, pour chaque arbre on pioche au hasard des échantillon dans nos données. Du coup chaque arbre va être un peu différend des autres lors de leur construction à l’entrainement. Ensuite pour la prédiction on fait la moyenne (ou la majorité je ne sais plus) des résultats trouvés par nos arbres. Le prog ça donne ça:

from sklearn.ensemble import RandomForestRegressor # technique des forêts aléatoires pour les regressions.

from sklearn.model_selection import train_test_split # partage nos données en données test et entrainement (ratio réglé ici via test_size à 20%/80%)
from sklearn.model_selection import GridSearchCV # permet de trouver plus facilement les meilleurs paramètres de réglage du modèle.
from sklearn.model_selection import learning_curve # estime la limite de performance d'un modèle.

from sklearn.pipeline import make_pipeline # assemble un ou des transfomateurs de données et un estimateur, évite les fuites de données et réduit le code, donc évite les erreurs aussi.

from sklearn.preprocessing import MinMaxScaler # traitement de données, normalisation où nos variables deviennent comprises entre 0 et 1.
from sklearn.preprocessing import RobustScaler # traitement de données moins sujet aux outliers (échantillons aberrantes).
from sklearn.preprocessing import StandardScaler # traitement de donnée, rend la moyenne nulle et l'écart-type égal à un.


import numpy as np # permet de manipuler les array.
import pandas as pd # permet de manipuler les dataframes.

import matplotlib.pyplot as plt

deauville3=pd.read_csv('C:/Users/Psychopathe/Documents/Python Scripts/meteo/station maison/samedi24octobre/Deauville_le_retour.csv',sep='\t') # on importe les données.

deauville3=deauville3.drop(['Unnamed: 0'],axis=1) # on vire la colonne inutile pour pas pourrir l'entrainement du modèle.

Vars_training=deauville3.iloc[:-1,:] # les données d'entrainements sont reprises sauf la dernière ligne pour ajuster le nombre de lignes entre les données et les variables cibles.
direction_train=deauville3.iloc[1:,30] # données cibles. Ici c'est la direction du vent 6 heures après.
force_train=deauville3.iloc[1:,31] # données cibles. Ici c'est la force du vent 6 heures après.
humidite_train=deauville3.iloc[1:,32] # données cibles, ici pourcentage d'humidité 6 heures après.
temperature_train=deauville3.iloc[1:,33] # données cibles, ici la température 6 heures après.
pression_train=deauville3.iloc[1:,34] # données cibles, ici la pression atmosphérique 6 heures après.

''' on sépare données entrainement et test pour toutes nos variables que l'on veut tester '''

X_train_direction,X_test_direction,y_train_direction,y_test_direction=train_test_split(Vars_training,direction_train,test_size=0.2,random_state=0)
X_train_force,X_test_force,y_train_force,y_test_force=train_test_split(Vars_training,force_train,test_size=0.2,random_state=0)
X_train_humidite,X_test_humidite,y_train_humidite,y_test_humidite=train_test_split(Vars_training,humidite_train,test_size=0.2,random_state=0)
X_train_temperature,X_test_temperature,y_train_temperature,y_test_temperature=train_test_split(Vars_training,temperature_train,test_size=0.2,random_state=0)
X_train_pression,X_test_pression,y_train_pression,y_test_pression=train_test_split(Vars_training,pression_train,test_size=0.2,random_state=0)

traitement_1=make_pipeline(MinMaxScaler(),RandomForestRegressor()) # création de l'objet pipeline1.
traitement_2=make_pipeline(RobustScaler(),RandomForestRegressor()) # création du pipeline2.
traitement_3=make_pipeline(StandardScaler(),RandomForestRegressor()) # création du pipeline3.

''' premier essai sans prétraitement, à poil , direction du vent   '''

param_grid={
    'n_estimators':[5,10,50,100,150,200],
    
    
    }

grid_1_direction=GridSearchCV(RandomForestRegressor(),param_grid,cv=5)
grid_1_direction.fit(X_train_direction,y_train_direction)
print(grid_1_direction.best_params_)
model_1_direction=grid_1_direction.best_estimator_
print(model_1_direction.score(X_test_direction,y_test_direction))

''' à poil, force du vent '''

grid_1_force=GridSearchCV(RandomForestRegressor(),param_grid,cv=5)
grid_1_force.fit(X_train_force,y_train_force)
print(grid_1_force.best_params_)
model_1_force=grid_1_force.best_estimator_
print(model_1_force.score(X_test_force,y_test_force))

'''à poil, humidite  '''

grid_1_humidite=GridSearchCV(RandomForestRegressor(),param_grid,cv=5)
grid_1_humidite.fit(X_train_humidite,y_train_humidite)
print(grid_1_humidite.best_params_)
model_1_humidite=grid_1_humidite.best_estimator_
print(model_1_humidite.score(X_test_humidite,y_test_humidite))

''' à poil, temperature '''
grid_1_temperature=GridSearchCV(RandomForestRegressor(),param_grid,cv=5)
grid_1_temperature.fit(X_train_temperature,y_train_temperature)
print(grid_1_temperature.best_params_)
model_1_temperature=grid_1_temperature.best_estimator_
print(model_1_temperature.score(X_test_temperature,y_test_temperature))

''' à poil, pression'''

grid_1_pression=GridSearchCV(RandomForestRegressor(),param_grid,cv=5)
grid_1_pression.fit(X_train_pression,y_train_pression)
print(grid_1_pression.best_params_)
model_1_pression=grid_1_pression.best_estimator_
print(model_1_pression.score(X_test_pression,y_test_pression))


''' avec le pipeline1, direction'''

param_grid2={
    'randomforestregressor__n_estimators':[5,10,50,100,150,200]
    }

grid_2_direction=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_direction.fit(X_train_direction,y_train_direction)
print(grid_2_direction.best_params_)
model_2_direction=grid_2_direction.best_estimator_
print(model_2_direction.score(X_test_direction,y_test_direction))

''' avec le pipeline1, force '''

grid_2_force=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_force.fit(X_train_force,y_train_force)
print(grid_2_force.best_params_)
model_2_force=grid_2_force.best_estimator_
print(model_2_force.score(X_test_force,y_test_force))

''' avec le pipeline1, humidite  '''

grid_2_humidite=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_humidite.fit(X_train_humidite,y_train_humidite)
print(grid_2_humidite.best_params_)
model_2_humidite=grid_2_humidite.best_estimator_
print(model_2_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline1, temperature'''

grid_2_temperature=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_temperature.fit(X_train_temperature,y_train_temperature)
print(grid_2_temperature.best_params_)
model_2_temperature=grid_2_temperature.best_estimator_
print(model_2_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline1, pression'''

grid_2_pression=GridSearchCV(traitement_1,param_grid2,cv=5)
grid_2_pression.fit(X_train_pression,y_train_pression)
print(grid_2_pression.best_params_)
model_2_pression=grid_2_pression.best_estimator_
print(model_2_pression.score(X_test_pression,y_test_pression))

'''avec le pipeline2, direction'''

grid_3_direction=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_direction.fit(X_train_direction,y_train_direction)
print(grid_3_direction.best_params_)
model_3_direction=grid_3_direction.best_estimator_
print(model_3_direction.score(X_test_direction,y_test_direction))

'''avec le pipeline2, force'''

grid_3_force=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_force.fit(X_train_force,y_train_force)
print(grid_3_force.best_params_)
model_3_force=grid_3_force.best_estimator_
print(model_3_force.score(X_test_force,y_test_force))

'''avec le pipeline2, humidite'''

grid_3_humidite=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_humidite.fit(X_train_humidite,y_train_humidite)
print(grid_3_humidite.best_params_)
model_3_humidite=grid_3_humidite.best_estimator_
print(model_3_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline2,temperature'''

grid_3_temperature=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_temperature.fit(X_train_temperature,y_train_temperature)
print(grid_3_temperature.best_params_)
model_3_temperature=grid_3_temperature.best_estimator_
print(model_3_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline2,pression'''

grid_3_pression=GridSearchCV(traitement_2,param_grid2,cv=5)
grid_3_pression.fit(X_train_pression,y_train_pression)
print(grid_3_pression.best_params_)
model_3_pression=grid_3_pression.best_estimator_
print(model_3_pression.score(X_test_pression,y_test_pression))

'''avec le pipeline3,direction'''

grid_4_direction=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_direction.fit(X_train_direction,y_train_direction)
print(grid_4_direction.best_params_)
model_4_direction=grid_4_direction.best_estimator_
print(model_4_direction.score(X_test_direction,y_test_direction))

'''avec le pipeline3,force'''

grid_4_force=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_force.fit(X_train_force,y_train_force)
print(grid_4_force.best_params_)
model_4_force=grid_4_force.best_estimator_
print(model_4_force.score(X_test_force,y_test_force))

'''avec le pipeline3,humidite'''

grid_4_humidite=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_humidite.fit(X_train_humidite,y_train_humidite)
print(grid_4_humidite.best_params_)
model_4_humidite=grid_4_humidite.best_estimator_
print(model_4_humidite.score(X_test_humidite,y_test_humidite))

'''avec le pipeline3,temperature'''

grid_4_temperature=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_temperature.fit(X_train_temperature,y_train_temperature)
print(grid_4_temperature.best_params_)
model_4_temperature=grid_4_temperature.best_estimator_
print(model_4_temperature.score(X_test_temperature,y_test_temperature))

'''avec le pipeline3, pression'''

grid_4_pression=GridSearchCV(traitement_3,param_grid2,cv=5)
grid_4_pression.fit(X_train_pression,y_train_pression)
print(grid_4_pression.best_params_)
model_4_pression=grid_4_pression.best_estimator_
print(model_4_pression.score(X_test_pression,y_test_pression))




N_direction,train_score_direction,val_score_direction=learning_curve(traitement_1,X_train_direction,y_train_direction,train_sizes=np.linspace(0.1,1,10),cv=5)
N_force,train_score_force,val_score_force=learning_curve(traitement_1,X_train_force,y_train_force,train_sizes=np.linspace(0.1,1,10),cv=5)
N_pression,train_score_pression,val_score_pression=learning_curve(traitement_1,X_train_pression,y_train_pression,train_sizes=np.linspace(0.1,1,10),cv=5)
N_humidite,train_score_humidite,val_score_humidite=learning_curve(traitement_1,X_train_humidite,y_train_humidite,train_sizes=np.linspace(0.1,1,10),cv=5)
N_temperature,train_score_temperature,val_score_temperature=learning_curve(traitement_1,X_train_temperature,y_train_temperature,train_sizes=np.linspace(0.1,1,10),cv=5)

plt.figure(figsize=[12,12])
plt.subplot(5,1,1)
plt.title("direction")
plt.plot(N_direction,train_score_direction.mean(axis=1),label='train')
plt.plot(N_direction,val_score_direction.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,2)
plt.title("force")
plt.plot(N_force,train_score_force.mean(axis=1),label='train')
plt.plot(N_force,val_score_force.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,3)
plt.title('pression')
plt.plot(N_pression,train_score_pression.mean(axis=1),label='train')
plt.plot(N_pression,val_score_pression.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,4)
plt.title('humidite')
plt.plot(N_humidite,train_score_humidite.mean(axis=1),label='train')
plt.plot(N_humidite,val_score_humidite.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()
plt.subplot(5,1,5)
plt.title('temperature')
plt.plot(N_temperature,train_score_temperature.mean(axis=1),label='train')
plt.plot(N_temperature,train_score_temperature.mean(axis=1),label='validation')
plt.xlabel('train_sizes')
plt.legend()

la courbe d’apprentissage:

Ca rappelle un peu les voisins…Va falloir trouver une explication à ces courbes que je n’ai pas pour le moment. En général les paramètres les plus efficaces tournent à au moins 150 arbres. Si vous faites juste un potager avec 2 radis ça marchera pas trop.

Et maintenant les résultats selon le pré traitement, comme prévu ça ne varie pas beaucoup:

directionforcehumiditétempératurepression
sans traitement22%15%28%87%83%
MinMAxScaler23%15%29%87%84%
robustScaler24%14%31%89%83%
StandardScaler25%15%27%89%83%

BILAN

Au final, pour une précision à 12 heures il semblerait que notre jeu de données est un peu faiblard, particulièrement pour la direction du vent (au mieux un score de 25%), sa force (21% au mieux) et l’humidité (31%). La différence d’efficacité entre chaque modèle n’est pas vraiment tranchée pour le moment, tout comme les traitements différends. Ce qui est rassurant c’est de voir que toutes nos variables décroissent en score avec une prévision plus avancée, donc à priori si on rajoute des échantillons on va peut-être avoir une chance d’améliorer nos scores.

Donc pour la suite il va falloir:

  • Tester nos données en deep learning avec un réseau de neurones virtuels, pour commencer via un perceptron multicouches (MLP), le plus simple .
  • Tester nos données « densifiées » pour voir ce que ça donne via un dataframe de toujours 1096 lignes pour cette fois 120 colonnes (variables toutes les heures).
  • Evidemment, agrandir notre jeu, en prenant cette fois au moins 40 stations météo (ça fera donc un dataframe de 43840 échantillons pour 60 ou 120 colonnes ou autre à voir). On prendra si possible les stations plus gouda que gruyère, même si j’aime le gruyère dans les pâtes.
  • Creuser plus les fonctionnalités du mode Lasso pour bien voir quelles sont les variables utiles, ça va peut-être nous servir.
  • Eventuellement veiller à reconfigurer nos données ou leur mise en forme dans notre dataframe pour plus d’efficacité. En effet, nos variables sont de nature très différentes: on a des degrés, des degrés celsius, des vitesses, des pourcentages et des pressions.

Avec tout ça on devrait pas trop s’emmerder en somme.

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.

les dépressions

Les dépressions des régions tempérées proviennent en grande partie des changements du jet Stream polaire, ce dernier confronte le déplacement de la masse d’air froid de la cellule polaire et de la masse d’air plus chaud de la cellule de Ferrel.

dépression

Les cellules convectives fonctionnent un peu comme des engrenages, l’air chaud prend de l’altitude, en montant il refroidit, en refroidissant il devient plus dense, s’alourdit et redescend. Si la terre était plus petite il y aurait moins de cellules convectives.

 

 

dépression2

Le jet Stream polaire est plus fort et plus bas en altitude par rapport au jet Stream subtropical. Les jet Stream suivent une trajectoire circulaire ondulée autour du globe, formant de forts vents d’ouest à cet endroit.

 

 

Le jet Stream polaire ne souffle pas à vitesse constante, n’avance pas de façon rectiligne et n’est donc pas régulier. Il change de vitesse selon ses virages ou ses méandres comme une rivière, provoquant l’entassement ou la dispersion d’air selon les endroits. Quand il y a entassement on parle de convergence(tendance à faire descendre de l’air à la surface), et dispersion on parle de divergence(créer des appels d’air depuis la surface). Ces deux cas de figure sont à l’origine des fronts froids et chauds rencontrés dans une dépression.

Les dépressions sont évolutives et migratrices, dans l’hémisphère Nord elles se forment la plupart du temps près des côtes Américaines dans l’Atlantique Ouest, évoluent sur l’océan et finissent leur vie en Europe du Nord ou à l’Est de la Méditerranée.

1)Les ingrédients d’une dépression

D’après la loi de Buys-Ballot, on sait que le vent tourne dans le sens inverse des aiguilles d’une montre autour des dépressions dans l’hémisphère Nord(inversement dans le Sud).

dépression3En altitude le vent suit les lignes isobares(lignes d’égale pression atmosphérique)et en surface avec les frottements, le vent rentre dans la dépression en formant environ un angle de 20° avec les lignes isobares. Avec un frottement plus important(sur terre)cet angle va augmenter.

 

vue d’une dépression en coupe:

depression4

 

La divergence du jet Stream provoque un appel d’air en surface.

 

 

Ce qui caractérise aussi une dépression, c’est la présence des fronts à l’intérieur. Il y a deux types de fronts, le front chaud et le front froid, et deux zones appelées le secteur froid et le secteur chaud(car une dépression n’est autre que la rencontre d’un courant d’air froid et d’un courant d’air chaud sous influence de Coriolis). Pour les dépressions plus « matures » on trouve en plus un front occlus et un point triple.

depression5

Sur les cartes météo isobares les fronts chauds sont en rouge et les fronts froids en bleu(j’ai plus de stylo bleu du coup…), mais ils sont symbolisés de la même façon. Le point triple est le point de rencontre des fronts.

 

 

 

Quand une dépression se forme, au début il n’y a pas de front occlus et les fronts chaud et froid sont très écartés. En vieillissant, le front froid plus rapide rattrape le front chaud créant le front occlus qui augmente au fur et à mesure que le secteur chaud est rattrapé, et le point triple se décale de plus en plus par rapport au centre de la dépression. Plus la dépression prend de l’âge et plus les fronts vont tourner dans la dépression dans le même sens que le vent.

Front occlus: quand la masse d’air froid a rattrapé la masse d’air chaud, l’air chaud plus léger a été expulsé en altitude. Ces fronts sont généralement caractérisés par une forte couverture nuageuse et de la pluie, moins de vent.

Front froid: quand l’air froid chasse l’air chaud en altitude, cela amène des conditions instables de vent et de visibilité. C’est généralement l’endroit où il y a le plus de vent avec la présence de grains dans une dépression.

Front chaud: Ici l’air chaud monte doucement sur l’air froid, amenant une augmentation progressive de la couverture nuageuse.

2)Les nuages rencontrés

On rencontre différents types de nuages dans une dépression selon l’endroit où l’on est, de plus le baromètre est aussi un outil précieux pour se situer par rapport à ce centre d’action.

depression6

1. Arrivée du front chaud: on observe tout d’abord les cirrus précurseurs(nuages d’altitude en forme de cheveux, filaments)avec une baisse de la pression atmosphérique. Plus les cirrus sont « courbés » plus il y a de chances de voir la situation se dégrader rapidement. Pour l’instant le temps reste clair avec une bonne visibilité. Ensuite viennent les cirrostratus(aussi en altitude), nuages formés de particules de glace ressemblant à des veines blanches, les  seuls capables de produire un halo autour du soleil ou de la lune. Si le halo diminue, c’est signe de pluie, d’arrivée du secteur chaud. A ce stade la pression diminue encore et la visibilité à son tour diminue.

2. Secteur chaud: la couverture nuageuse descend et se couvre encore plus, la pression continue de diminuer. Juste avant le front chaud on voit des altostratus(voile grisâtre à travers lequel le soleil ou la lune peut apparaître comme un disque flou)le ciel s’obscurcit. Le front chaud amène une stabilisation de la pression atmosphérique et une couverture nuageuse basse et sombre avec de la pluie(stratus, nimbostratus). Dans le secteur chaud on trouve les stratus qui sont les nuages les plus bas, formant un voile uniforme; la pression est toujours stable et la visibilité est faible. En général dans le secteur chaud les vents viennent d’Ouest ou Sud-Ouest(hémisphère Nord).

3. Front froid: l’arrivée du front froid amène une petite baisse suivie d’une remontée de la pression atmosphérique. La couverture nuageuse encore épaisse se découvre un peu, les grains arrivent. Au front froid on note la présence des cumulonimbus(nuages très étendus verticalement, source de vent fort et de rafales), une remontée rapide de la pression et une augmentation de la visibilité qui se réduit à nouveau sous les grains. Au front froid on note aussi la plupart du temps une bascule du vent au Nord-Ouest.

3)Vie d’une dépression

Jeunesse: les fronts se mettent en place, la pression diminue et l’angle entre les fronts est très ouvert. Le centre de la dépression est superposé avec le point triple, des précipitations apparaissent au niveau des fronts.

Maturité: la dépression se déplace plus vite(entre 15 et 40 nœuds environ), le front froid commence à rattraper le front chaud créant le front occlus, et le point triple se sépare du centre de la dépression. Le vent devient plus fort au front froid, et montre une bascule significative.

Vieillissement: Occlusion importante avec l’approche près de la côte, le centre de la dépression ralentit ou s’arrête. Les pluies augmentent à l’occlusion et le vent est moins marqué dans la dépression, la bascule de vent au front froid est moins significative.

Fin: les fronts ne sont plus différenciés, la dépression ne bouge plus et les fronts ou ce qu’il en reste continuent de tourner dans la dépression tête en bas.

4)La règle des vents croisés

Cette règle bien pratique et assez efficace est un petit plus pour se positionner dans une dépression, et donc pouvoir anticiper la météo à venir(ici, pour l’hémisphère Nord).

On se place face au vent de surface. Avec les vents d’altitude(indiqué par les nuages d’altitude, les cirrus par exemple), on peut avoir des indices sur le déplacement de la dépression:

.Si les vents d’altitude arrivent de la droite, le front chaud approche.

.Si ils arrivent de la gauche, la dépression s’éloigne.

.Si vent surface/altitude sont parallèles, à quelque degrés près bien sûr, et de même sens on est dans le secteur chaud(mais bon en général dans le secteur chaud on ne voit pas les nuages d’altitude, on sait que l’on y est avec la pression stable et la couverture nuageuse dense, basse et pourrie…).

.Si parallèles et de sens contraire, ou est dans le secteur froid, le Nord de la dépression.

Remarque: une houle résiduelle marquée d’Ouest peut aussi être un indice supplémentaire pour l’arrivée d’une dépression.

Il y a plein de bouquins qui expliquent très bien le fonctionnement des dépressions comme « météo et stratégie, croisière et course au large » de Jean-Yves Bernot, le bloc marine est pas mal aussi.

depression-meteorologique-par-satellite-islande-dossier-cyclone_121-63213

 

 

 

 

 

 

 

 

 

Les cyclones

On les retrouve surtout à l’Ouest des océans dans leur région intertropicale. Ils se manifestent surtout à la fin de l’été(septembre dans l’hémisphère Nord et février/mars dans le Sud). Dans l’Atlantique Nord la saison des cyclones se déroule de juillet à novembre; le nombre de cyclones varie beaucoup d’une année à l’autre. On leur donne toujours un prénom féminin…

cyclone_vu_de_l_espace_1426

1)Formation

Le premier stade est la dépression tropicale, elle nécessite plusieurs facteurs pour se mettre en place. La température de la mer doit faire plus de 26°C sur une épaisseur de 50 mètres au moins, il doit y avoir une faible zone dépressionnaire en surface. une zone faiblement anticyclonique en altitude doit être là, et la variation de vent entre la surface et l’altitude doit être faible. Le cyclone fonctionne un peu comme une cheminée qui aspire l’air en surface et le rejette en altitude, cette cheminée ne doit pas être « coupée » par des vents trop forts sur sa longueur. La force de Coriolis doit être suffisamment forte(en-dessous de 5° de latitude il y a beaucoup moins de chances de rencontrer un cyclone).

2)Fonctionnement

L’air en périphérie est aspiré vers le centre de la dépression tropicale et bouge en spirale avec Coriolis(dans l’hémisphère Nord en sens inverse des aiguilles d’une montre). Près du centre les vents viennent dans toutes les directions et montent, cette région c’est le mur de l’œil du cyclone là où c’est le plus violent(au centre même l’air est calme). Les cyclones, même si ils rappellent la forme de nos dépressions des régions tempérées sont différents. Ils sont moins grands(500 à 1000km de diamètre)et ils se déplacent assez lentement(5 à 15 nœuds environ). Le diamètre de l’œil fait environ une cinquantaine de kilomètres. Ce phénomène ne peut pas se manifester sur terre ou sur des mers froides.

3)Quelques trucs

La zone dangereuse lors de la saison des cyclones est la zone de rayon correspondant à 24 heures de déplacement du cyclone. On peut aussi diviser le cyclone en deux parties(demi-cercle dangereux où la vitesse du vent s’ajoute à celle du cyclone, et l’autre demi-cercle):

cyclone

Les cyclones sont classés selon l’échelle de Saffir-Simpson en 5 classes, l’intensité du cyclone peut aller de 64 nœuds(seulement!)en classe 1 à plus de 136 nœuds(les gars sortez la bible et serrez les fesses!)en classe 5.

 

 

Le baromètre

Il permet d’anticiper les phénomènes météorologiques en partie, et de se placer par rapport aux centres d’action(anticyclones, dépressions). Pour avoir une analyse complète de la vue d’ensemble il faut combiner cet outil avec l’état du ciel(types de nuages, visibilité), la direction du vent synoptique et l’état de la mer, on peut aussi y intégrer les changements de température ou d’humidité. Mais même seul, c’est un outil précieux indispensable pour prévoir l’évolution du temps et pour la sécurité.

1)La pression atmosphérique

Le baromètre nous indique la pression atmosphérique en hectopascals. Cette pression induite par le poids de l’air sur un point donné a été découverte par un élève de Galilée, Evangelista Torricelli, grâce à son invention du baromètre à mercure et inspiré par Benedetto Castelli, autre disciple de Galilée spécialisé en hydrologie. En gros Torricelli s’est aperçu que le poids de l’atmosphère créait une pression quasi constante sur la surface de la terre, et que cette pression était du coup quantifiable avec des fluides, déformables sous la contrainte d’une force.

On retrouve un peu le même principe en plongé où la pression augmente d’une atmosphère terrestre tout les 10 mètres environ(à la surface de la mer la pression est de 1 bar, soit environ 1013 hpa, et à 20 mètres de profondeur elle est de 3 bar, soit environ 3040 hpa) plus l’on va en profondeur et plus le poids de la colonne d’eau au-dessus de notre tête est conséquent. Heureusement que le poids de l’air l’est beaucoup moins!

Sachant qu’une masse d’air chaud est moins dense donc plus légère par rapport à une masse d’air froid, plus dense donc plus « lourde », on comprend vite l’utilité du baromètre pour anticiper les arrivées des centres d’action(masse d’air chaude apparentée aux dépressions, air froid aux anticyclones). En fait si on voit le baromètre baisser il va en général indiquer l’arrivée d’une dépression, si il grimpe il va indiquer la venue de conditions anticycloniques.

La pression atmosphérique peut s’illustrer avec l’équation des gaz parfaits:

Pression(pascals)*Volume(en m3)=Masse(en Kg)*R*Température(en Kelvin)

R est la constante du gaz, la valeur de R pour de l’air sec est de 288 et de la vapeur d’eau 460 environ. 0 Kelvin=-273,15°C.

2)Types de baromètres

Il existe des baromètres à mercure, à eau, à gaz(utilise la déformation d’un fluide sous la pression pour établir leur mesure). Sur les bateau on trouve surtout soit les baromètres classiques en laiton dit « anéroÏdes » et les instruments électroniques qui fonctionnent avec la déformation d’une capsule à vide.

Les baromètres anéroïdes utilisent une enceinte métallique hermétiquement close, vide d’air. Une membrane montée sur cette enceinte se déforme avec la pression et un mécanisme retranscrit l’information obtenue sur un cadran avec une aiguille.

3)Utilisation en navigation

Pour étalonner correctement son baromètre, on peut prendre une mesure de la pression atmosphérique à la capitainerie la plus proche par exemple, et rajouter la correction suivante:

Correction(hpa)=0,12*différence d’altitude(en mètres)

La différence d’altitude est celle entre notre baromètre et celui de référence pris pour l’étalonner. Si le baromètre est plus bas que le baromètre de référence on additionne la correction.

La variation de pression plus ou moins rapide indiquée est très importante, à chaque ligne écrite dans le livre de bord il faut noter les changements du baromètre. Plus la pression change rapidement, plus le vent risque de monter(cela est valable autant pour une baisse que pour une augmentation de la pression, l’important c’est la vitesse de variation).

Sous nos latitudes moyennes(environ 45° de latitude), on peut dire à peu prêt que:

.Un changement de 5 hpa en 1 heure annonce au moins 50 nœuds(bon là il vaut mieux plier les gaules et rentrer…).

.Un changement de 3 hpa en 1 heure annonce environ 40 nœuds.

.Un changement de 3 hpa en 3 heures annonce environ 25 nœuds.

Si nous sommes plus bas en latitude, pour une même vitesse de changement de pression, il y aura encore plus de vent; si nous sommes plus haut en latitude, pour une même variation il y aura moins de vent. Cela est je pense dût à la force de Coriolis moins importante au fur et à mesure que l’on s’approche de l’équateur.

 

Quelques effets locaux

1)La brise thermique

Elle a pour origine une différence de température entre l’air au-dessus de la mer et l’air au-dessus de la terre. Cet écart provoque un mouvement de circulation de l’air sous forme d’une petite cellule convective; l’air chaud de terre plus léger va s’élever, créant un appel d’air du large pour combler le trou.

effets locaux

L’eau met plus de temps que la surface terrestre pour se réchauffer au fur et à mesure de la journée. La brise commence à s’établir généralement en début d’après-midi quand la terre a eu du temps pour chauffer suffisamment. La brise thermique choisit toujours le chemin le plus court pour s’établir, au début souvent perpendiculaire à la côte, elle tourne à droite en cours de journée en mollissant(environ 5/10° par heure)pour finir parallèle et s’arrête en début de soirée la plupart du temps. Cette brise se caractérise par la présence de cumulus(nuages en forme de bouts de coton à basse altitude) sur la côte et pas sur l’eau, quand ces nuages sont très développé c’est signe que la brise va bientôt cesser.

Ce phénomène nécessite plusieurs facteurs combinés pour exister: il faut une différence significative de température entre terre et mer, un vent synoptique inférieur à 15 nœuds, de l’ensoleillement prolongé, un horizon clair au large, une côte basse et l’orientation du vent synoptique doit en gros venir de la côte pour ne pas casser le courant de pente(règle des quadrans).

2)Les grains

Ces nuages modifient la force et l’orientation du vent synoptique sur leur passage, on distingue deux types de grains:

.Les grains non-pluvieux

effets locaux2Ils fonctionnent un peu comme un aspirateur qui pompe l’air de surface en altitude, créant un vent local. Parfois en mer quand on croise un grain orageux, on a même l’impression que le grain se déplace en sens inverse du vent ressenti. En fait le vent ressenti est celui qui est pompé vers le grain.

En mouvement

effets locaux3

Ce vent local additionné au vent synoptique crée le vent en vecteur vert. Le vent est plus fort en haut du grain et plus faible en bas sur le schéma. Dans l’hémisphère Nord les grains se déplacent de droite à gauche quand on est face au vent synoptique(à cause des forces de frottement moindres en altitude).

.Les grains pluvieux

effets locaux4

Contrairement aux grains sans pluie, cette fois on va trouver plus de vent en bas du grain et moins en haut(cf schéma).

3)Les effets de site

Le relief côtier comme on l’a vu au début modifie parfois le vent synoptique avec sa température, mais sa forme influe aussi.

.Pour les côtes basses(exemple Bretagne Sud)

effets locaux5

Avec les forces de frottement plus importantes le vent prend de la gauche en se rapprochant de la côte.

.côtes moyennement élevées

effets locaux6

Quand le vent est perpendiculaire à la côte et vient du large il crée une zone sans vent appelé « coussin » à proximité de la côte. Si il vient de terre il induit aussi une zone sans vent, le « dévent »; plus la côte est élevée et plus cette zone sera grande.

Pour les côtes élevées comme la Corse par exemple, les différences d’altitude changent la nature des masses d’air.

4)Effet de pointe et effet Venturi

effets locaux7

L’effet de pointe se sens au niveau des cap, l’effet Venturi se rencontre aux embouchures(exemple golfe du Morbihan, détroit de Gibraltar). Ces phénomènes ayant pour cause la forme du relief côtier augmentent la force du vent synoptique.

La force de Coriolis

Le vent ne se déplace jamais directement des hautes pressions vers les basses pressions, il est dévié à cause du mouvement de rotation de la terre. La force de Coriolis résulte de ce mouvement.

1)Dans un cadre à 2 dimensions

Le mouvement est une notion relative, il dépend du lieu d’observation de ce dernier. On va prendre l’exemple du tourniquet.

coriolis

Quand Bernard lance la balle à Jacky(veuillez pardonner mon manque d’inspiration pour les prénoms mais bon…), un observateur situé en dehors du tourniquet verra la balle avec une trajectoire rectiligne.

En revanche pour ces derniers, la trajectoire de la balle sera déviée vers la droite(donc pour un observateur placé dans le référentiel tourniquet).

Sur terre c’est presque la même chose, le tourniquet symbolise la terre en rotation et le chemin de la balle représente le déplacement du vent(ou du courant). Pour l’hémisphère sud il suffit de reprendre le même schéma en inversant le sens de rotation du tourniquet, la balle(le vent)sera alors dévié vers la gauche.

2)Dans un cadre à trois dimensions

La force de Coriolis dépend de trois paramètres: la masse du corps en mouvement, sa vitesse et sa latitude. Elle peut s’écrire sous la forme d’équation:

Fc=2*m*(vecteur vitesse*vecteur vitesse angulaire)

La vitesse angulaire est celle de la terre(environ 15 degrés par heure). On remarque que l’équation comporte une multiplication de vecteurs, pour trouver la norme du vecteur obtenu le calcul est:

||vecteur vitesse||*||vecteur vitesse angulaire||*sin(L)

L est la latitude du corps en mouvement.

coriolis 2Remarque: comme la fonction sinus est symétrique par rapport au point 0( dans un repère cartésien)alors on peut déduire que plus l’objet est proche de la latitude 0, plus la force de Coriolis diminue jusqu’à s’annuler à l’équateur. Au contraire, la force de Coriolis est plus importante près des pôles.

 

 

Il y a une bonne illustration du phénomène Coriolis avec le pendule de Foucault(la première expérience a eu lieu au panthéon, il y en a un à Paris qui fonctionne en permanence je crois…). Je ferai un petit truc dessus plus tard c’est assez marrant(on peut notamment savoir sa latitude suivant la vitesse de rotation du pendule).

 

 

 

 

En gros…

L’atmosphère terrestre se divise en différentes couches, pour les phénomènes météo l’une d’entre elles va nous concerner particulièrement: la Troposphère. Elle s’étend en altitude jusqu’à une quinzaine de kilomètres à l’équateur à son maximum, et elle constitue le terrain de jeu des centres d’action en météo. La limite de la troposphère s’appelle la tropopause.

1)Le vent

L’air étant un très mauvais conducteur thermique, le réchauffement de l’atmosphère inégal à la surface du globe va générer des sortes de courants d’air chaud et des courants d’air froid. Ces courants vont se déplacer et agir sur la météo d’une façon différente. Les courants chauds, moins denses donc plus légers, vont avoir tendance à « monter » contrairement aux courants froids, plus denses donc plus lourds. Les limites entres ces courants vont créer ce qu’on appelle des fronts. Le vent est le résultat d’un échange entre ces masses d’air.

2)Les principaux systèmes

Sous nos latitudes tempérées moyennes la météo s’organise autours de deux systèmes principaux: les anticyclones et les dépressions. Les anticyclones correspondent à des masses d’air denses, sèches et froides, relativement stationnaire, et les dépressions des masses d’air chaudes et plutôt humides, relativement mobiles. Quelque soit l’hémisphère, l’air circule toujours des hautes pressions(donc les anticyclones)vers les basses pressions(les dépressions).

3)Lois fondamentales

.Loi de Buys-Ballot: Dans l’hémisphère nord quand on se place face au vent, on a les basses pressions à sa droite. Dans l’hémisphère sud c’est l’inverse. Pour résumer dans l’hémisphère nord le vent tourne dans le sens inverse des aiguilles d’une montre autour des dépressions, et dans le sens horaire autour des anticyclones(c’est le contraire pour l’hémisphère sud).

.Force de Coriolis: Elle est engendrée par le mouvement de rotation de la terre. Elle dévie vers la droite les mouvements de grandes masses(vents et courants marins)dans l’hémisphère nord et vers la gauche dans l’hémisphère sud.