fuelprediction / trainingscript.py
VincentGOURBIN's picture
Upload folder using huggingface_hub
985e206 verified
raw
history blame
8.83 kB
# Importation des bibliothèques nécessaires
import pandas as pd
import numpy as np
import glob
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.metrics import mean_absolute_error, mean_squared_error
from sklearn.model_selection import TimeSeriesSplit
from xgboost import XGBRegressor
import joblib
import os
# Ajustement du paramètre agg.path.chunksize pour éviter l'OverflowError
mpl.rcParams['agg.path.chunksize'] = 10000 # Vous pouvez ajuster la valeur si nécessaire
# 1. Chargement des données
print("Chargement des données...")
parquet_files = glob.glob('FuelInFranceData/*.parquet')
if not parquet_files:
raise FileNotFoundError("Aucun fichier Parquet trouvé dans le répertoire spécifié.")
df_list = []
for f in parquet_files:
print(f"Chargement du fichier {f}")
df_list.append(pd.read_parquet(f))
df = pd.concat(df_list, ignore_index=True)
del df_list # Libération de la mémoire
print(f"Nombre total d'enregistrements: {len(df)}")
# 2. Prétraitement des données
print("Prétraitement des données...")
df['rate_date'] = pd.to_datetime(df['rate_date'])
df['brent_date'] = pd.to_datetime(df['brent_date'])
df = df.sort_values('rate_date')
df = df.dropna()
# Exclure les carburants E85 et GPLc
df = df[~df['fuel_name'].isin(['E85', 'GPLc'])]
# Sélection des colonnes pertinentes (inclure 'brent_date')
cols_to_use = ['station_id', 'commune', 'marque', 'departement', 'regioncode',
'coordlatitude', 'coordlongitude', 'fuel_name', 'price',
'rate_date', 'brent_rate_eur', 'brent_date']
df = df[cols_to_use]
# Encodage des variables catégorielles
print("Encodage des variables catégorielles...")
label_encoders = {}
categorical_cols = ['station_id', 'commune', 'marque', 'departement',
'regioncode', 'fuel_name']
for col in categorical_cols:
le = LabelEncoder()
df[col] = le.fit_transform(df[col].astype(str))
label_encoders[col] = le
# 3. Nettoyage des valeurs aberrantes (outliers)
print("Nettoyage des valeurs aberrantes...")
# Suppression des outliers en utilisant l'IQR (Interquartile Range)
def remove_outliers_iqr(data, column):
Q1 = data[column].quantile(0.25)
Q3 = data[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
data_clean = data[(data[column] >= lower_bound) & (data[column] <= upper_bound)]
return data_clean
df = remove_outliers_iqr(df, 'price')
# 4. Entraînement de modèles séparés pour chaque type de carburant avec validation croisée temporelle
print("Entraînement de modèles séparés pour chaque type de carburant avec validation croisée temporelle...")
fuel_types = df['fuel_name'].unique()
models = {}
scalers = {}
results = {}
for fuel in fuel_types:
fuel_name_decoded = label_encoders['fuel_name'].inverse_transform([fuel])[0]
print(f"\nTraitement du carburant: {fuel_name_decoded}")
df_fuel = df[df['fuel_name'] == fuel].copy()
# Ingénierie des caractéristiques
df_fuel['day_of_week'] = df_fuel['rate_date'].dt.dayofweek
df_fuel['month'] = df_fuel['rate_date'].dt.month
df_fuel['year'] = df_fuel['rate_date'].dt.year
# Création des variables de décalage (lags) pour le prix du Brent
for lag in [1, 3, 7, 15, 30]:
df_fuel[f'brent_rate_eur_lag_{lag}'] = df_fuel['brent_rate_eur'].shift(lag)
df_fuel = df_fuel.dropna()
# Variables features et target
X = df_fuel.drop(['price', 'rate_date', 'brent_date'], axis=1)
y = df_fuel['price']
dates = df_fuel['rate_date']
# Normalisation des données
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# Validation croisée temporelle
tscv = TimeSeriesSplit(n_splits=5)
y_tests = []
y_preds = []
dates_list = []
for fold, (train_index, test_index) in enumerate(tscv.split(X_scaled)):
print(f" Fold {fold+1}/{tscv.get_n_splits()}")
X_train, X_test = X_scaled[train_index], X_scaled[test_index]
y_train, y_test = y.iloc[train_index], y.iloc[test_index]
dates_test = dates.iloc[test_index]
# Entraînement du modèle
model = XGBRegressor(objective='reg:squarederror', n_estimators=100, learning_rate=0.1)
model.fit(X_train, y_train)
# Prédiction sur l'ensemble de test
y_pred = model.predict(X_test)
# Stockage des résultats
y_tests.append(y_test)
y_preds.append(y_pred)
dates_list.append(dates_test)
# Concaténation des résultats
y_test_total = pd.concat(y_tests)
y_pred_total = np.concatenate(y_preds)
dates_total = pd.concat(dates_list)
# Évaluation du modèle
mae = mean_absolute_error(y_test_total, y_pred_total)
rmse = mean_squared_error(y_test_total, y_pred_total, squared=False)
print(f"Erreur Absolue Moyenne (MAE): {mae:.4f}")
print(f"Racine de l'Erreur Quadratique Moyenne (RMSE): {rmse:.4f}")
# Entraînement final sur l'ensemble des données pour la prévision future
model_final = XGBRegressor(objective='reg:squarederror', n_estimators=100, learning_rate=0.1)
model_final.fit(X_scaled, y)
# Sauvegarde du modèle final et du scaler
models[fuel] = model_final
scalers[fuel] = scaler
# Stockage des résultats pour l'analyse
results[fuel] = {
'y_test': y_test_total,
'y_pred': y_pred_total,
'dates': dates_total
}
# Sous-échantillonnage des données pour le tracé
downsample_rate = max(1, len(dates_total) // 1000) # Limiter à 1000 points
dates_sampled = dates_total.iloc[::downsample_rate]
y_test_sampled = y_test_total.iloc[::downsample_rate]
y_pred_sampled = y_pred_total[::downsample_rate]
# Tri des données pour le tracé
sorted_indices = np.argsort(dates_sampled)
dates_sampled = dates_sampled.iloc[sorted_indices]
y_test_sampled = y_test_sampled.iloc[sorted_indices]
y_pred_sampled = y_pred_sampled[sorted_indices]
# Graphique de validation (Prix prédit vs Prix réel)
plt.figure(figsize=(12, 6))
plt.plot(dates_sampled, y_test_sampled, label='Prix Réel', marker='o', linestyle='None', markersize=4)
plt.plot(dates_sampled, y_pred_sampled, label='Prix Prédit', marker='x', linestyle='None', markersize=4)
plt.xlabel('Date')
plt.ylabel('Prix (€)')
plt.title(f"Comparaison du Prix Réel et Prédit pour le Carburant {fuel_name_decoded}")
plt.legend()
plt.tight_layout()
# Enregistrer le graphique
plt.savefig(f'validation_{fuel_name_decoded}.png')
plt.close()
# 5. Prévision pour les 3, 7, 15 et 30 prochains jours pour chaque carburant
print("\nPrévision pour les prochains jours pour chaque carburant...")
for fuel in fuel_types:
fuel_name_decoded = label_encoders['fuel_name'].inverse_transform([fuel])[0]
print(f"\nPrévisions pour le carburant: {fuel_name_decoded}")
df_fuel = df[df['fuel_name'] == fuel]
last_known_data = df_fuel.iloc[-1]
model = models[fuel]
scaler = scalers[fuel]
def forecast_prices(model, last_known_data, scaler, horizons=[3, 7, 15, 30]):
forecasts = {}
for horizon in horizons:
future_date = last_known_data['rate_date'] + pd.Timedelta(days=horizon)
input_data = last_known_data.to_frame().T.copy()
input_data['rate_date'] = future_date
input_data['day_of_week'] = future_date.dayofweek
input_data['month'] = future_date.month
input_data['year'] = future_date.year
# Mise à jour des variables de décalage du Brent
for lag in [1, 3, 7, 15, 30]:
input_data[f'brent_rate_eur_lag_{lag}'] = last_known_data['brent_rate_eur']
input_data = input_data.dropna(axis=1, how='all')
# Préparation des données pour la prédiction
input_features = input_data.drop(['price', 'rate_date', 'brent_date'], axis=1)
input_features_scaled = scaler.transform(input_features)
predicted_price = model.predict(input_features_scaled)
forecasts[horizon] = predicted_price[0]
return forecasts
# Prévision des prix
forecasts = forecast_prices(model, last_known_data, scaler)
for horizon, price in forecasts.items():
print(f"Dans {horizon} jours: {price:.4f} €")
# 6. Sauvegarde des modèles et des scalers pour une utilisation future
print("\nSauvegarde des modèles et des scalers...")
for fuel in fuel_types:
fuel_name_decoded = label_encoders['fuel_name'].inverse_transform([fuel])[0]
joblib.dump(models[fuel], f'fuel_price_model_{fuel_name_decoded}.pkl')
joblib.dump(scalers[fuel], f'scaler_{fuel_name_decoded}.pkl')
print("Script terminé avec succès.")