Prédire l'Avenir Énergétique : Votre Guide LSTM pour la Prochaine Semaine
Un tutoriel détaillé avec code Python pour prévoir les valeurs de puissance futures en utilisant les réseaux LSTM sur vos données normalisées.
Les réseaux de neurones récurrents de type Long Short-Term Memory (LSTM) sont exceptionnellement bien adaptés à l'analyse et à la prédiction de séries temporelles, comme vos données de puissance. Leur capacité à mémoriser des informations sur de longues périodes les rend idéaux pour capturer les dépendances temporelles complexes souvent présentes dans la consommation ou la production d'énergie. Ce guide vous accompagnera pas à pas dans la construction et l'utilisation d'un modèle LSTM pour prévoir les valeurs de puissance pour la semaine suivant le '2023-10-31 23:59:31'.
Points Clés à Retenir
- Préparation des Séquences : L'étape cruciale pour les LSTM est de transformer votre série temporelle linéaire en séquences d'entrée (fenêtres temporelles ou 'lookback') et de cibles correspondantes.
- Prédiction Itérative : Pour prévoir plusieurs pas dans le futur (une semaine), nous utiliserons une approche itérative : prédire un pas, ajouter cette prédiction à l'entrée, et répéter le processus.
- Importance de la Fréquence : Déterminer le nombre exact de pas de temps (
n_prediction_steps) à prédire pour couvrir une semaine dépend directement de la fréquence d'échantillonnage de vos données (horaire, minute, etc.).
Étape 1 : Préparation Essentielle des Données
Transformer votre série temporelle en séquences pour LSTM
Même si vos données sont déjà normalisées et dans le bon format (437796, 1), les modèles LSTM requièrent une structuration spécifique des données en séquences. Chaque prédiction se basera sur une séquence des points de données précédents. Cette séquence est définie par un paramètre appelé lookback.
Création des Séquences d'Entrée/Sortie
Nous allons définir une fonction pour découper votre série temporelle en fenêtres glissantes (X) et les valeurs cibles correspondantes (y).
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from tensorflow.keras.callbacks import EarlyStopping
import matplotlib.pyplot as plt
# --- Chargement de vos données ---
# Supposons que vos données normalisées sont dans un tableau NumPy nommé 'data_normalized'
# Assurez-vous qu'il a la forme (437796, 1)
# Exemple: Si vos données sont dans un fichier CSV sans en-tête
# data_normalized = pd.read_csv('votre_fichier_de_donnees.csv', header=None).values
# Ou si vous avez déjà un DataFrame pandas 'df' avec une colonne 'puissance':
# data_normalized = df[['puissance']].values
# <b>* ASSUREZ-VOUS QUE 'data_normalized' CONTIENT VOS DONNÉES ICI </b>*
# Exemple avec des données aléatoires pour l'exécution (REMPLACEZ PAR VOS DONNÉES)
data_normalized = np.random.rand(437796, 1)
print(f"Forme initiale des données: {data_normalized.shape}")
def create_sequences(data, lookback):
"""
Crée des séquences d'entrée et des valeurs de sortie pour un modèle LSTM.
Args:
data (np.ndarray): Le tableau NumPy de la série temporelle. Forme (n_samples, 1).
lookback (int): Le nombre de pas de temps précédents à utiliser comme entrée.
Returns:
tuple: Tuple contenant (X, y) où X sont les séquences d'entrée
et y sont les valeurs de sortie correspondantes.
"""
X, y = [], []
if len(data) <= lookback:
print("Erreur: Pas assez de données pour créer une séquence avec le lookback spécifié.")
return np.array(X), np.array(y)
for i in range(len(data) - lookback):
seq_x = data[i:(i + lookback), 0] # Séquence d'entrée
seq_y = data[i + lookback, 0] # Valeur suivante comme sortie
X.append(seq_x)
y.append(seq_y)
return np.array(X), np.array(y)
# Définir la taille de la fenêtre temporelle (lookback)
# Un hyperparamètre crucial. Exemple: 60 pas précédents.
# Adaptez cette valeur en fonction de la périodicité attendue dans vos données.
lookback = 60
# Créer les séquences
X, y = create_sequences(data_normalized, lookback)
# Vérifier si des séquences ont été créées
if X.shape[0] == 0:
print("Aucune séquence n'a été créée. Vérifiez la taille des données et le lookback.")
else:
print(f"Forme de X avant reshape: {X.shape}") # (samples, lookback)
print(f"Forme de y avant reshape: {y.shape}") # (samples,)
# Remodeler X pour l'entrée LSTM : [échantillons, pas de temps, caractéristiques]
# Dans notre cas, nous avons 1 caractéristique (la valeur de puissance).
X = X.reshape((X.shape[0], X.shape[1], 1))
print(f"Forme de X après reshape (pour LSTM): {X.shape}")
print(f"Forme de y: {y.shape}")
# Diviser les données pour l'entraînement et la validation (séquentiellement)
# Il est crucial de ne pas mélanger les données chronologiques.
# Nous gardons les 10% les plus récents pour la validation.
split_index = int(len(X) * 0.9)
X_train, X_val = X[:split_index], X[split_index:]
y_train, y_val = y[:split_index], y[split_index:]
print(f"\nDivision des données:")
print(f"Forme de X_train : {X_train.shape}")
print(f"Forme de y_train : {y_train.shape}")
print(f"Forme de X_val : {X_val.shape}")
print(f"Forme de y_val : {y_val.shape}")
Étape 2 : Construction de l'Architecture LSTM
Définir votre réseau de neurones pour la prédiction
Nous allons construire un modèle LSTM séquentiel simple mais efficace en utilisant Keras. Il comprendra une couche LSTM pour traiter les séquences temporelles, une couche Dropout pour réduire le risque de surapprentissage, et une couche Dense pour produire la prédiction finale (la valeur de puissance au pas de temps suivant).
# Définir l'architecture du modèle LSTM
model = Sequential()
# Ajout de la couche LSTM
# units=50 : Nombre d'unités (neurones) dans la couche LSTM. Hyperparamètre à ajuster.
# activation='relu' : Fonction d'activation. 'tanh' est aussi couramment utilisé pour LSTM.
# input_shape=(lookback, 1) : Forme des données d'entrée pour une séquence. (pas de temps, caractéristiques)
# return_sequences=False : Car c'est la dernière couche LSTM avant la couche Dense.
# Mettre à True si vous empilez plusieurs couches LSTM.
model.add(LSTM(units=50, activation='relu', input_shape=(lookback, 1), return_sequences=False))
# Ajout d'une couche Dropout pour la régularisation
# 20% des connexions seront mises à zéro aléatoirement pendant l'entraînement.
model.add(Dropout(0.2))
# Ajout de la couche de sortie Dense
# units=1 : Une seule sortie, car nous prédisons une seule valeur à la fois.
model.add(Dense(units=1))
# Compiler le modèle
# optimizer='adam' : Un optimiseur efficace et populaire.
# loss='mse' : Mean Squared Error (Erreur Quadratique Moyenne), courante pour les problèmes de régression.
model.compile(optimizer='adam', loss='mean_squared_error')
# Afficher le résumé du modèle
model.summary()
Étape 3 : Entraînement du Modèle
Apprendre les motifs à partir de vos données historiques
L'entraînement consiste à ajuster les poids du réseau neuronal pour minimiser l'erreur de prédiction sur les données d'entraînement. Nous utiliserons les données de validation pour surveiller la performance du modèle sur des données qu'il n'a pas vues pendant l'entraînement et pour arrêter l'entraînement prématurément (EarlyStopping) si la performance sur la validation cesse de s'améliorer, évitant ainsi le surapprentissage.
# Définir le callback EarlyStopping
# monitor='val_loss' : Surveille la perte sur l'ensemble de validation.
# patience=10 : Nombre d'époques sans amélioration avant d'arrêter l'entraînement.
# restore_best_weights=True : Restaure les poids du modèle de la meilleure époque.
early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
# Entraîner le modèle
# epochs=50 : Nombre maximal d'époques. EarlyStopping peut l'arrêter avant.
# batch_size=32 : Nombre d'échantillons par mise à jour des poids.
# validation_data=(X_val, y_val) : Données pour évaluer la performance à chaque époque.
# callbacks=[early_stopping] : Appliquer le callback défini.
history = model.fit(X_train, y_train,
epochs=50,
batch_size=32,
validation_data=(X_val, y_val),
callbacks=[early_stopping],
verbose=1) # verbose=1 pour afficher la progression
# Optionnel : Visualiser l'historique de la perte
plt.figure(figsize=(10, 5))
plt.plot(history.history['loss'], label='Perte d\'entraînement')
plt.plot(history.history['val_loss'], label='Perte de validation')
plt.title('Courbes d\'Apprentissage (Perte)')
plt.ylabel('Perte (MSE)')
plt.xlabel('Époque')
plt.legend()
plt.grid(True)
plt.show()
# Sauvegarder le modèle entraîné (optionnel)
# model.save('modele_lstm_puissance_final.h5')
Étape 4 : Prédiction de la Semaine Future
Générer les valeurs de puissance pour les 7 prochains jours
Maintenant, la partie cruciale : prédire la semaine suivant votre dernière mesure ('2023-10-31 23:59:31'). Nous utiliserons une approche itérative. Le modèle prédit la valeur pour le pas de temps suivant, puis cette prédiction est ajoutée à la fin de la séquence d'entrée (et le point le plus ancien est retiré) pour prédire le pas suivant, et ainsi de suite.
Calculer le Nombre de Pas de Temps (n_prediction_steps)
C'est l'étape la plus critique pour obtenir une prédiction d'exactement une semaine. Vous devez connaître la fréquence de vos données :
- Si vos données sont par minute : 7 jours * 24 heures/jour * 60 minutes/heure = 10080 pas.
- Si vos données sont horaires : 7 jours * 24 heures/jour = 168 pas.
- Si vos données sont toutes les 5 minutes : 7 * 24 * (60/5) = 2016 pas.
- Si vos données sont toutes les 15 minutes : 7 * 24 * (60/15) = 672 pas.
Vous DEVEZ ajuster n_prediction_steps ci-dessous en fonction de VOTRE fréquence de données ! L'exemple utilise 10080 (supposant des données par minute).
# --- PARAMÈTRE CRUCIAL À AJUSTER ---
# Définissez le nombre total de pas de temps à prédire pour couvrir 7 jours.
# Exemple pour des données par minute :
n_prediction_steps = 10080
# Exemple pour des données horaires :
# n_prediction_steps = 168
# *** MODIFIEZ CETTE VALEUR SELON LA FRÉQUENCE DE VOS DONNÉES ***
# Récupérer la dernière séquence 'lookback' des données normalisées ORIGINALES
# C'est la séquence juste avant la période que nous voulons prédire.
last_sequence_from_data = data_normalized[-lookback:]
# Vérifier si la séquence a la bonne longueur
if len(last_sequence_from_data) < lookback:
print(f"Erreur: Pas assez de données historiques ({len(last_sequence_from_data)}) pour former la séquence initiale de longueur {lookback}.")
else:
# Remodeler pour correspondre à l'entrée du modèle [1, lookback, 1]
current_batch = last_sequence_from_data.reshape((1, lookback, 1))
# Liste pour stocker les prédictions futures
future_predictions = []
print(f"\nDébut de la prédiction itérative pour {n_prediction_steps} pas...")
for i in range(n_prediction_steps): # Boucle pour le nombre de pas à prédire
# Obtenir la prédiction pour le pas suivant
current_pred = model.predict(current_batch)[0, 0] # Prend la valeur prédite
# Stocker la prédiction
future_predictions.append(current_pred)
# Préparer la prochaine séquence d'entrée :
# 1. Retirer la valeur la plus ancienne de 'current_batch'
# 2. Ajouter la 'current_pred' à la fin
# 3. Assurer que la forme reste (1, lookback, 1)
# Créer le nouveau pas de temps (la prédiction) avec la bonne forme
new_step = np.array([[current_pred]] ).reshape((1, 1, 1)) # Forme (1, 1, 1)
# Concaténer le nouveau pas et retirer le plus ancien
current_batch = np.concatenate((current_batch[:, 1:, :], new_step), axis=1)
# Afficher la progression (optionnel)
if (i + 1) % 100 == 0:
print(f"Prédit {i + 1}/{n_prediction_steps} pas...")
print("Prédiction terminée.")
# Convertir la liste des prédictions en tableau NumPy
future_predictions = np.array(future_predictions)
print(f"Forme des prédictions futures : {future_predictions.shape}") # Doit être (n_prediction_steps,)
# Les 'future_predictions' sont dans l'échelle normalisée.
# Si vous aviez utilisé un scaler (MinMaxScaler), vous devriez utiliser
# scaler.inverse_transform(future_predictions.reshape(-1, 1)) pour les dénormaliser.
# Comme vos données sont déjà fournies normalisées, nous les gardons telles quelles pour la visualisation.
Étape 5 : Visualisation des Résultats
Observer les prédictions par rapport aux données historiques
Visualiser les prédictions futures à côté des données historiques récentes aide à évaluer qualitativement la performance du modèle. Nous allons tracer les dernières données utilisées pour la validation (ou une partie des données historiques) et les prédictions générées.
# Créer un index temporel pour les prédictions
# La prédiction commence juste après la dernière date connue : '2023-10-31 23:59:31'
# Nous devons déterminer la fréquence ('freq') à partir de vos données.
# Exemples : 'T' ou 'min' pour minute, 'H' pour heure, '5min', '15min', etc.
# *** AJUSTEZ 'freq' SELON VOTRE FRÉQUENCE DE DONNÉES ***
assumed_frequency = 'min' # EXEMPLE: suppose une fréquence minute
last_timestamp = pd.to_datetime('2023-10-31 23:59:31')
prediction_index = pd.date_range(start=last_timestamp + pd.Timedelta(seconds=1 if assumed_frequency=='S' else minutes=1 if assumed_frequency in ['T','min'] else hours=1 if assumed_frequency=='H' else 0), # Ajuster le démarrage selon la fréquence
periods=n_prediction_steps,
freq=assumed_frequency)
# Créer un DataFrame pour les prédictions
predictions_df = pd.DataFrame({'Prediction': future_predictions}, index=prediction_index)
# Visualisation
plt.figure(figsize=(15, 7))
# Tracer une partie des données historiques récentes (par exemple, les dernières 2*n_prediction_steps)
# Ajustez la quantité d'historique à afficher si nécessaire
history_to_plot = data_normalized[-(2*n_prediction_steps + lookback):-n_prediction_steps] # Exemple
# Créer un index pour l'historique à tracer (remonte depuis la dernière date connue)
history_index = pd.date_range(end=last_timestamp, periods=len(history_to_plot), freq=assumed_frequency) # Approximation
if len(history_index) == len(history_to_plot):
plt.plot(history_index, history_to_plot, label='Données Historiques Récentes (Normalisées)', color='blue')
else:
# Tracer sans index temporel si la création d'index échoue
print("Avertissement: Impossible de créer un index temporel précis pour l'historique.")
plt.plot(history_to_plot, label='Données Historiques Récentes (Normalisées)', color='blue')
# Tracer les prédictions
plt.plot(predictions_df.index, predictions_df['Prediction'], label='Prédictions Futures (Normalisées)', color='red', linestyle='--')
plt.title(f'Prédiction de Puissance sur 7 Jours avec LSTM (Lookback={lookback})')
plt.xlabel('Date et Heure')
plt.ylabel('Valeur de Puissance (Normalisée)')
plt.legend()
plt.grid(True)
plt.xticks(rotation=45)
plt.tight_layout() # Ajuste la mise en page pour éviter les superpositions
plt.show()
Exemple illustratif de prédiction de puissance photovoltaïque utilisant des modèles LSTM. Source: ScienceDirect (adapté).
Exploration des Approches LSTM : Diagramme Radar
Comparer différentes architectures LSTM
Le modèle présenté est un LSTM simple. Il existe des variantes comme les LSTM empilés (Stacked) ou Bidirectionnels qui peuvent offrir des performances différentes selon le problème. Ce diagramme radar compare subjectivement ces approches sur plusieurs critères clés.
Ce diagramme suggère que si les LSTM Bidirectionnels peuvent potentiellement offrir une meilleure précision en considérant le contexte passé et futur (utile si le modèle est entraîné pour cela, moins direct pour la prédiction future pure), ils sont aussi plus complexes et gourmands en ressources. Le LSTM simple offre un bon compromis pour commencer.
Le Processus de Prévision en un Coup d'Œil : Mindmap
Visualiser les étapes clés de la modélisation LSTM
Cette carte mentale résume le flux de travail que nous avons suivi pour passer de vos données brutes normalisées à une prédiction de puissance pour la semaine à venir.
Comprendre les Hyperparamètres Clés
Ajuster le modèle pour de meilleures performances
Plusieurs paramètres influencent le comportement et la performance de votre modèle LSTM. Comprendre leur rôle est essentiel pour l'optimisation.
| Hyperparamètre | Description | Rôle / Impact | Exemple de Valeur |
|---|---|---|---|
lookback (Fenêtre Temporelle) |
Nombre de pas de temps passés utilisés comme entrée pour prédire le pas suivant. | Capture les dépendances temporelles. Un lookback plus grand voit plus loin dans le passé mais augmente la complexité. Doit être adapté à la saisonnalité/périodicité des données. | 60 (pour données minutes), 24 (pour données heures), 168 (pour hebdomadaire si horaire) |
units (Unités LSTM) |
Nombre de neurones dans la couche LSTM. Détermine la capacité d'apprentissage de la couche. | Trop peu d'unités peuvent limiter l'apprentissage (sous-apprentissage), trop peuvent mener au surapprentissage et augmenter le temps de calcul. | 32, 50, 64, 100, 128... |
Dropout rate (Taux de Dropout) |
Fraction des neurones désactivés aléatoirement pendant l'entraînement pour prévenir le surapprentissage. | Aide à la régularisation. Une valeur trop élevée peut entraver l'apprentissage. | 0.1, 0.2, 0.3, 0.5 |
batch_size (Taille du Lot) |
Nombre d'échantillons traités avant une mise à jour des poids du modèle. | Influence la vitesse et la stabilité de l'entraînement. Des lots plus petits peuvent introduire du bruit mais aider à la généralisation ; des lots plus grands sont plus rapides mais peuvent converger vers des minima locaux moins bons. | 16, 32, 64, 128... |
epochs (Époques) |
Nombre de fois que l'ensemble de l'entraînement est présenté au modèle. | Détermine la durée de l'entraînement. Trop peu d'époques = sous-apprentissage. Trop = surapprentissage (mais EarlyStopping aide à contrer cela). | Contrôlé par EarlyStopping (ex: max 50 ou 100) |
optimizer (Optimiseur) |
Algorithme utilisé pour mettre à jour les poids du réseau (ex: Adam, RMSprop, SGD). | Influence la vitesse et la qualité de la convergence. Adam est souvent un bon choix par défaut. | 'adam', 'rmsprop' |
L'ajustement de ces hyperparamètres, souvent par expérimentation ou des techniques comme Grid Search ou Random Search, est une partie importante du développement d'un modèle performant.
Tutoriel Vidéo : Prévision de Séries Temporelles avec LSTM et TensorFlow
Approfondir vos connaissances avec un guide visuel
Cette vidéo (en anglais) fournit une excellente introduction visuelle à l'utilisation des LSTM pour la prévision de séries temporelles avec TensorFlow et Keras, couvrant des concepts similaires à ceux de ce guide. Elle explique comment structurer les données, construire le modèle LSTM et l'entraîner pour faire des prédictions, renforçant ainsi votre compréhension du processus.
Questions Fréquemment Posées (FAQ)
Réponses aux interrogations courantes sur la prédiction LSTM
Comment déterminer la bonne fréquence ('freq') et le `n_prediction_steps` pour mes données ?
La première étape est d'inspecter vos données sources ou les timestamps (si disponibles). Quelle est la différence de temps entre deux mesures consécutives ? Est-ce constant (ex: 1 minute, 1 heure) ?
Si vous avez un index datetime dans Pandas, vous pouvez essayer `pd.infer_freq(votre_dataframe.index)` pour obtenir une estimation. Une fois la fréquence connue (par exemple, 'H' pour horaire, 'T' pour minute), calculez le nombre total de pas pour 7 jours comme montré dans l'Étape 4. C'est crucial : une erreur ici signifie que vous ne prédirez pas pour la bonne durée.
Comment choisir la meilleure valeur pour `lookback` ?
Le choix du `lookback` dépend des dépendances temporelles que vous pensez exister dans vos données.
- Y a-t-il des cycles journaliers ? Un `lookback` couvrant au moins 24 heures (en nombre de pas) pourrait être utile.
- Des cycles hebdomadaires ? Un `lookback` couvrant 7 jours pourrait être pertinent, mais devient très long.
- Commencez par une valeur raisonnable basée sur la fréquence (ex: 60 pour minutes, 24 pour heures) et expérimentez.
- Analysez les fonctions d'autocorrélation (ACF) et d'autocorrélation partielle (PACF) de vos données pour identifier les décalages temporels significatifs.
- Testez différentes valeurs de `lookback` et évaluez leur impact sur la performance du modèle sur l'ensemble de validation.
Mon modèle semble surapprendre (overfitting). Que faire ?
Le surapprentissage se produit lorsque le modèle apprend trop bien les données d'entraînement, y compris le bruit, et perd sa capacité à généraliser sur de nouvelles données. Signes : la perte d'entraînement diminue mais la perte de validation stagne ou augmente.
Stratégies pour réduire le surapprentissage :
- Augmenter le taux de Dropout : Essayez des valeurs plus élevées (ex: 0.3, 0.4).
- Utiliser EarlyStopping : C'est déjà implémenté dans le code, assurez-vous qu'il fonctionne correctement. Réduire la `patience` peut aider.
- Réduire la complexité du modèle : Diminuez le nombre d'unités (`units`) dans les couches LSTM ou supprimez des couches si vous en avez empilé plusieurs.
- Ajouter de la régularisation L1/L2 : Moins courant pour LSTM mais possible via les arguments `kernel_regularizer` / `recurrent_regularizer` des couches Keras.
- Obtenir plus de données : Si possible, augmenter la taille de l'ensemble d'entraînement aide souvent.
- Réduire le `lookback` : Un `lookback` trop long peut parfois contribuer au surapprentissage.
Dois-je dénormaliser les prédictions ?
Puisque vos données d'entrée étaient *déjà normalisées*, les prédictions du modèle seront également dans cette échelle normalisée (généralement entre 0 et 1 ou -1 et 1).
Pour interpréter les valeurs de puissance réelles (par exemple, en kW ou MW), vous *devez* appliquer l'opération de dénormalisation inverse. Cependant, pour faire cela, vous avez besoin de connaître la méthode de normalisation exacte utilisée initialement (ex: MinMaxScaler) et les paramètres de cette normalisation (valeur minimale et maximale des données *originales* avant normalisation).
Si vous ne disposez pas de ces informations (le 'scaler' original), vous ne pourrez pas revenir à l'échelle d'origine. La visualisation et l'analyse devront se faire sur les valeurs normalisées.
Comment puis-je améliorer encore les prédictions ?
Au-delà de l'ajustement des hyperparamètres mentionnés :
- Architecture du Modèle : Essayez des architectures plus complexes comme les LSTM empilés (Stacked LSTM) ou les LSTM bidirectionnels (Bidirectional LSTM).
- Caractéristiques Exogènes : Si disponibles, ajoutez d'autres séries temporelles pertinentes comme variables d'entrée (ex: température, jour de la semaine, heure du jour, statut férié). Cela transforme le problème en prévision multivariée.
- Traitement des Données : Explorez différentes méthodes de normalisation si vous repartez des données brutes. La décomposition de la série (tendance, saisonnalité, résidu) peut parfois aider.
- Modèles Hybrides : Combinez LSTM avec d'autres modèles (ex: CNN pour extraire des caractéristiques locales, ou des modèles statistiques comme ARIMA pour les résidus).
- Fenêtre Glissante d'Entraînement : Pour les très longues séries, réentraîner périodiquement le modèle sur les données les plus récentes peut améliorer l'adaptation aux changements de motifs.
- Optimisation Poussée : Utilisez des techniques d'optimisation d'hyperparamètres plus avancées (ex: Keras Tuner, Optuna, Hyperopt).
Références
Ressources utiles pour approfondir
- How to Develop LSTM Models for Time Series Forecasting - Machine Learning Mastery
- Time Series Prediction with LSTM Recurrent Neural Networks in Python with Keras - Machine Learning Mastery
- How to Develop LSTM Models for Multi-Step Time Series Forecasting of Household Power Consumption - Machine Learning Mastery
- Forecasting the Future Power Consumption of Germany using LSTM, RNN and DNN - Towards Data Science
- How to Build LSTM Models for Time Series Prediction in Python - Statology
- Time series forecasting - TensorFlow Core
Recherches Recommandées
Explorer des sujets connexes
Last updated April 24, 2025