Prédiction et Analyse de la Valeur de l'Énergie dans les Réseaux Électriques Intelligents
I. Objectifs et Exigences de l'Expérience
- Maîtriser les méthodes de base de traitement de données avec la bibliothèque pandas.
- Comprendre les techniques préliminaires de prétraitement des séries temporelles.
- Acquérir les compétences de visualisaiton de données avec matplotlib et pandas.
II. Contenu de l'Expérience
- Utilisation de bibliothèques Python comme pandas pour lire et prétraiter les données.
- Réalisation de visualisations de données avec matplotlib.
- Construction d'un modèle d'arbre de décision en utilisant les coefficients de corrélation de Sklearn, entraînement du modèle, tests sur un jeu de données et évaluation des performances.
III. Étapes de l'Expérience
- Prétraitement des données. Lecture du fichier de données, vérification de l'intégrité de la série temporelle, détection de valeurs manquantes ou dupliquées.
(1) Importation des bibloithèques nécessaires
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdate
from datetime import datetime, timedelta
from matplotlib.dates import DateFormatter, WeekdayLocator, DayLocator, MONDAY, YEARLY
import dateutil.relativedelta
import time
from matplotlib.pyplot import MultipleLocator
import warnings
from sklearn import tree
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from scipy.stats import pearsonr
from sklearn.tree import DecisionTreeRegressor
# Configuration de la police
plt.rcParams['font.sans-serif']=['SimHei']
(2) Lecture du fichier
chemin_fichier = '/data/bigfiles/donnees_energie.csv'
donnees_brutes = pd.read_csv(chemin_fichier)
(3) Conslutation des informations statistiques de base
donnees_brutes.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 87648 entries, 0 to 87647 Data columns (total 8 columns): Date 87648 non-null object Heure 87648 non-null float64 Tempéré_sèche 87648 non-null float64 Tempéré_rosée 87648 non-null float64 Tempéré_humide 87648 non-null float64 Humidité 87648 non-null float64 Prix_électricité 87648 non-null float64 Charge_électrique 87648 non-null float64 dtypes: float64(7), object(1) memory usage: 5.3+ MB
(4) Vérification de l'intégrité des données
# Calcul de la période attendue
periode_std = pd.date_range(start='2006/1/1', end='2011/1/1', freq='D')
longueur_attendue = len(periode_std)
print(f"Nombre de jours attendus: {longueur_attendue}")
1827
(5) Calcul des données journalières moyennes et ajout du type de jour
# Conversion de l'humidité en type flottant
donnees_brutes['Humidité'] = donnees_brutes['Humidité'].map(lambda x: float(x))
# Initialisation des colonnes journalières
donnees_brutes['Humidité_max_jour'] = donnees_brutes["Humidité"]
donnees_brutes['Humidité_min_jour'] = donnees_brutes["Humidité"]
donnees_brutes['Charge_moyenne_jour'] = donnees_brutes['Charge_électrique']
donnees_brutes['Charge_max_jour'] = donnees_brutes['Charge_électrique']
donnees_brutes['Charge_min_jour'] = donnees_brutes['Charge_électrique']
# Définir la date comme index
donnees_brutes = donnees_brutes.set_index(['Date'])
# Conversion de l'index en format datetime
donnees_brutes.index = donnees_brutes.index.map(lambda x: datetime.strptime(x, '%Y/%m/%d'))
donnees_brutes['Jour_semaine'] = donnees_brutes.index
# Ajout du numéro du jour de la semaine
jours_semaine = [1, 2, 3, 4, 5, 6, 7]
donnees_brutes['Jour_semaine'] = donnees_brutes['Jour_semaine'].map(lambda x: jours_semaine[pd.to_datetime(x).weekday()])
# Agrégation des données par jour
donnees_agregees = donnees_brutes.groupby('Date').agg({
"Tempéré_sèche": "mean",
"Tempéré_rosée": "mean",
"Tempéré_humide": "mean",
"Humidité": "mean",
"Humidité_max_jour": "max",
"Humidité_min_jour": "min",
"Prix_électricité": "mean",
"Charge_max_jour": "max",
"Charge_min_jour": "min",
"Charge_moyenne_jour": "mean",
"Jour_semaine": "mean"
})
# Remplissage des valeurs manquantes
donnees_agregees.head(30)
(6) Sauvegarde des données prétraitées
donnees_agregees.to_csv('/data/bigfiles/donnees_pretraitees.csv')
- Visualisation des données.
(1) Lecture des données prétraitées
donnees_agregees = pd.read_csv('/data/bigfiles/donnees_pretraitees.csv', index_col=0)
(2) Tracé des courbes temporelles des informations météorologiques
# Sélection d'une période pour la visualisation
periode_visu = donnees_agregees["2006-01-01":"2010-02-01"]
periode_visu.index = periode_visu.index.map(lambda x: str(x)[:10])
# Configuration de la taille de figure
plt.figure(figsize=(15.6, 7.2))
# Tracé de l'humidité
plt.plot(periode_visu.index, periode_visu['Humidité'], 'r-', label='Humidité')
plt.legend()
plt.title("Évolution de l'humidité")
plt.show()
# Tracé de l'humidité maximale
plt.figure(figsize=(15.6, 7.2))
plt.plot(periode_visu.index, periode_visu['Humidité_max_jour'], 'b--', label='Humidité maximale')
plt.legend()
plt.title("Évolution de l'humidité maximale")
plt.show()
# Tracé de l'humidité minimale
plt.figure(figsize=(15.6, 7.2))
plt.plot(periode_visu.index, periode_visu['Humidité_min_jour'], 'g-', label='Humidité minimale')
plt.legend()
plt.title("Évolution de l'humidité minimale")
plt.show()
(3) Tracé des courbes temporelles des prix et de la charge électrique
# Configuration de la période de visualisation
periode_prix = donnees_agregees["2006-01-01":"2010-02-01"]
periode_prix.index = periode_prix.index.map(lambda x: str(x)[:10])
# Tracé de la charge électrique moyenne
plt.figure(figsize=(15.6, 7.2))
plt.plot(periode_prix.index, periode_prix['Charge_moyenne_jour'], 'r-', label='Charge moyenne')
plt.legend()
plt.title("Évolution de la charge électrique moyenne")
plt.show()
# Tracé de la charge électrique maximale
plt.figure(figsize=(15.6, 7.2))
plt.plot(periode_prix.index, periode_prix['Charge_max_jour'], 'b--', label='Charge maximale')
plt.legend()
plt.title("Évolution de la charge électrique maximale")
plt.show()
# Tracé de la charge électrique minimale
plt.figure(figsize=(15.6, 7.2))
plt.plot(periode_prix.index, periode_prix['Charge_min_jour'], 'g-', label='Charge minimale')
plt.legend()
plt.title("Évolution de la charge électrique minimale")
plt.show()
# Tracé du prix de l'électricité
plt.figure(figsize=(15.6, 7.2))
plt.plot(periode_prix.index, periode_prix['Prix_électricité'], 'y-', label='Prix de l\'électricité')
plt.legend()
plt.title("Évolution du prix de l'électricité")
plt.show()
(4) Fonction de filtrage médian pour éliminer le bruit évident
def filtre_median(donnees, taille_fenetre):
"""
Applique un filtre médian pour réduire le bruit dans les données.
Paramètres:
donnees (array): Tableau de données à filtrer
taille_fenetre (int): Taille de la fenêtre de filtrage
Retourne:
array: Données filtrées
"""
donnees_filtrees = np.zeros_like(donnees)
moitie_fenetre = taille_fenetre // 2
for i in range(moitie_fenetre, len(donnees) - moitie_fenetre):
fenetre = donnees[i - moitie_fenetre:i + moitie_fenetre + 1]
donnees_filtrees[i] = np.median(fenetre)
return donnees_filtrees
# Application du filtre médian
periode_prix['Tempéré_sèche'] = filtre_median(periode_prix['Tempéré_sèche'], 5)
periode_prix['Charge_moyenne_jour'] = filtre_median(periode_prix['Charge_moyenne_jour'], 5)
periode_prix['Charge_max_jour'] = filtre_median(periode_prix['Charge_max_jour'], 5)
periode_prix['Charge_min_jour'] = filtre_median(periode_prix['Charge_min_jour'], 5)
periode_prix['Tempéré_rosée'] = filtre_median(periode_prix['Tempéré_rosée'], 5)
(5) Tracé des courbes temporelles filtrées
# Tracé de la charge moyenne filtrée
plt.figure(figsize=(15.6, 7.2))
plt.plot(periode_prix.index, periode_prix['Charge_moyenne_jour'], 'r-', label='Charge moyenne filtrée')
plt.legend()
plt.title("Charge électrique moyenne après filtrage")
plt.show()
# Tracé de la charge maximale filtrée
plt.figure(figsize=(15.6, 7.2))
plt.plot(periode_prix.index, periode_prix['Charge_max_jour'], 'b--', label='Charge maximale filtrée')
plt.legend()
plt.title("Charge électrique maximale après filtrage")
plt.show()
# Tracé de la charge minimale filtrée
plt.figure(figsize=(15.6, 7.2))
plt.plot(periode_prix.index, periode_prix['Charge_min_jour'], 'g-', label='Charge minimale filtrée')
plt.legend()
plt.title("Charge électrique minimale après filtrage")
plt.show()
- Analyse de corrélation. Calcul des coefficients de corrélation de Pearson entre chaque variable et la charge électrique, sélection des 3 variables avec les coefficients de corrélation absolus les plus élevés comme caractéristiques pour l'entraînement du modèle.
# Exemple de calcul de corrélation entre deux séries
x_exemple = np.array([1, 3, 5, 7, 9])
y_exemple = np.array([2, 5, 4, 8, 10])
coef_corr, p_value = pearsonr(x_exemple, y_exemple)
print(f"Coefficient de corrélation: {coef_corr:.4f}")
print("Niveau de signification:", p_value)
# Calcul des corrélations avec la charge électrique
variables = ['Humidité', 'Tempéré_sèche', 'Tempéré_humide', 'Tempéré_rosée', 'Prix_électricité',
'Charge_max_jour', 'Charge_min_jour']
for var in variables:
coef_corr, p_value = pearsonr(periode_prix[var], periode_prix['Charge_moyenne_jour'])
print(f"\n{var}:")
print(f"Coefficient de corrélation: {coef_corr:.4f}")
print("Niveau de signification:", p_value)
- Analyse de données. Utilisation des 3 caractéristiques sélectionnées comme entrées, la charge électrique comme sortie, division appropriée entre ensemble d'entraînement et de test, sélection des paramètres adaptés, construction d'un modèle d'arbre de décision avec Sklearn et tests du modèle.
(1) Construction du modèle d'arbre de décision
# Préparation des caractéristiques et de la variable cible
X = pd.concat([periode_prix['Tempéré_humide'], periode_prix['Tempéré_sèche'], periode_prix['Prix_électricité']], axis=1)
Y = periode_prix['Charge_moyenne_jour']
# Division des données en ensembles d'entraînement et de test
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.1, random_state=42)
# Définition des paramètres à optimiser
parametres_arbre = {
'criterion': ['mse', 'friedman_mse', 'mae'],
'max_depth': list(range(5, 15)),
'min_samples_split': [2, 5, 10]
}
# Optimisation des hyperparamètres avec recherche sur grille
modele_arbre = DecisionTreeRegressor()
recherche_grille = GridSearchCV(modele_arbre, parametres_arbre, cv=3)
recherche_grille.fit(X_train, Y_train)
# Meilleurs paramètres et score
print("Meilleurs paramètres:", recherche_grille.best_params_)
print("Meilleur score:", recherche_grille.best_score_)
# Entraînement du modèle avec les meilleurs paramètres
modele_final = DecisionTreeRegressor(**recherche_grille.best_params_)
modele_final.fit(X_train, Y_train)
# Prédictions sur l'ensemble de test
predictions = modele_final.predict(X_test)
(2) Visualisation des résultats de prédiction
# Création du graphique de comparaison
plt.figure(figsize=(15.6, 7.2))
plt.scatter(range(len(predictions)), predictions, color='red', label='Prédictions', alpha=0.6)
plt.scatter(range(len(Y_test)), Y_test, color='blue', label='Valeurs réelles', alpha=0.6)
plt.legend()
plt.title("Comparaison entre prédictions et valeurs réelles")
plt.xlabel("Index des échantillons")
plt.ylabel("Charge électrique")
plt.show()