|
2 weeks ago | |
---|---|---|
.. | ||
solution | 3 weeks ago | |
working | 3 weeks ago | |
README.md | 2 weeks ago | |
assignment.md | 3 weeks ago |
README.md
Zeitreihenprognose mit ARIMA
In der vorherigen Lektion haben Sie etwas über Zeitreihenprognosen gelernt und einen Datensatz geladen, der die Schwankungen der elektrischen Last über einen bestimmten Zeitraum zeigt.
🎥 Klicken Sie auf das Bild oben, um ein Video anzusehen: Eine kurze Einführung in ARIMA-Modelle. Das Beispiel wird in R durchgeführt, aber die Konzepte sind universell.
Quiz vor der Lektion
Einführung
In dieser Lektion lernen Sie eine spezifische Methode kennen, um Modelle mit ARIMA: AutoRegressive Integrated Moving Average zu erstellen. ARIMA-Modelle eignen sich besonders gut für Daten, die Nicht-Stationarität aufweisen.
Allgemeine Konzepte
Um mit ARIMA arbeiten zu können, müssen Sie einige grundlegende Konzepte kennen:
-
🎓 Stationarität. Im statistischen Kontext bezieht sich Stationarität auf Daten, deren Verteilung sich nicht ändert, wenn sie in der Zeit verschoben werden. Nicht-stationäre Daten zeigen hingegen Schwankungen aufgrund von Trends, die transformiert werden müssen, um analysiert werden zu können. Saisonalität kann beispielsweise Schwankungen in den Daten verursachen, die durch einen Prozess des „saisonalen Differenzierens“ eliminiert werden können.
-
🎓 Differenzieren. Das Differenzieren von Daten bezieht sich auf den Prozess, nicht-stationäre Daten zu transformieren, um sie stationär zu machen, indem der nicht-konstante Trend entfernt wird. „Differenzieren entfernt die Änderungen im Niveau einer Zeitreihe, eliminiert Trends und Saisonalität und stabilisiert dadurch den Mittelwert der Zeitreihe.“ Paper von Shixiong et al
ARIMA im Kontext von Zeitreihen
Lassen Sie uns die Bestandteile von ARIMA genauer betrachten, um besser zu verstehen, wie es uns hilft, Zeitreihen zu modellieren und Vorhersagen zu treffen.
-
AR - für AutoRegressiv. Autoregressive Modelle analysieren, wie der Name schon sagt, frühere Werte in Ihren Daten, um Annahmen über sie zu treffen. Diese früheren Werte werden als „Lags“ bezeichnet. Ein Beispiel wären Daten, die monatliche Verkaufszahlen von Bleistiften zeigen. Die Verkaufszahlen jedes Monats würden als „entwickelnde Variable“ im Datensatz betrachtet. Dieses Modell wird erstellt, indem „die interessierende Variable auf ihre eigenen verzögerten (d. h. vorherigen) Werte regressiert wird.“ Wikipedia
-
I - für Integriert. Im Gegensatz zu den ähnlichen 'ARMA'-Modellen bezieht sich das 'I' in ARIMA auf den integrierten Aspekt. Die Daten werden „integriert“, wenn Differenzierungsschritte angewendet werden, um Nicht-Stationarität zu eliminieren.
-
MA - für Gleitender Durchschnitt. Der gleitende Durchschnitt in diesem Modell bezieht sich auf die Ausgangsvariable, die durch die Beobachtung der aktuellen und vergangenen Werte der Lags bestimmt wird.
Fazit: ARIMA wird verwendet, um ein Modell so genau wie möglich an die spezielle Form von Zeitreihendaten anzupassen.
Übung - Ein ARIMA-Modell erstellen
Öffnen Sie den /working-Ordner in dieser Lektion und suchen Sie die Datei notebook.ipynb.
-
Führen Sie das Notebook aus, um die Python-Bibliothek
statsmodels
zu laden; diese benötigen Sie für ARIMA-Modelle. -
Laden Sie die notwendigen Bibliotheken.
-
Laden Sie nun weitere Bibliotheken, die für die Datenvisualisierung nützlich sind:
import os import warnings import matplotlib.pyplot as plt import numpy as np import pandas as pd import datetime as dt import math from pandas.plotting import autocorrelation_plot from statsmodels.tsa.statespace.sarimax import SARIMAX from sklearn.preprocessing import MinMaxScaler from common.utils import load_data, mape from IPython.display import Image %matplotlib inline pd.options.display.float_format = '{:,.2f}'.format np.set_printoptions(precision=2) warnings.filterwarnings("ignore") # specify to ignore warning messages
-
Laden Sie die Daten aus der Datei
/data/energy.csv
in ein Pandas-DataFrame und werfen Sie einen Blick darauf:energy = load_data('./data')[['load']] energy.head(10)
-
Visualisieren Sie alle verfügbaren Energiedaten von Januar 2012 bis Dezember 2014. Es sollte keine Überraschungen geben, da wir diese Daten in der letzten Lektion gesehen haben:
energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12) plt.xlabel('timestamp', fontsize=12) plt.ylabel('load', fontsize=12) plt.show()
Jetzt erstellen wir ein Modell!
Erstellen von Trainings- und Testdatensätzen
Nachdem Ihre Daten geladen sind, können Sie sie in Trainings- und Testdatensätze aufteilen. Sie trainieren Ihr Modell mit dem Trainingsdatensatz. Wie üblich bewerten Sie nach Abschluss des Trainings die Genauigkeit des Modells mit dem Testdatensatz. Sie müssen sicherstellen, dass der Testdatensatz einen späteren Zeitraum als der Trainingsdatensatz abdeckt, um sicherzustellen, dass das Modell keine Informationen aus zukünftigen Zeiträumen erhält.
-
Weisen Sie dem Trainingsdatensatz einen Zeitraum von zwei Monaten vom 1. September bis zum 31. Oktober 2014 zu. Der Testdatensatz umfasst den Zeitraum vom 1. November bis zum 31. Dezember 2014:
train_start_dt = '2014-11-01 00:00:00' test_start_dt = '2014-12-30 00:00:00'
Da diese Daten den täglichen Energieverbrauch widerspiegeln, gibt es ein starkes saisonales Muster, aber der Verbrauch ähnelt am meisten dem Verbrauch in den letzten Tagen.
-
Visualisieren Sie die Unterschiede:
energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)][['load']].rename(columns={'load':'train'}) \ .join(energy[test_start_dt:][['load']].rename(columns={'load':'test'}), how='outer') \ .plot(y=['train', 'test'], figsize=(15, 8), fontsize=12) plt.xlabel('timestamp', fontsize=12) plt.ylabel('load', fontsize=12) plt.show()
Daher sollte ein relativ kleines Zeitfenster für das Training der Daten ausreichen.
Hinweis: Da die Funktion, die wir zum Anpassen des ARIMA-Modells verwenden, während des Anpassens eine Validierung innerhalb des Datensatzes durchführt, werden wir auf Validierungsdaten verzichten.
Daten für das Training vorbereiten
Nun müssen Sie die Daten für das Training vorbereiten, indem Sie die Daten filtern und skalieren. Filtern Sie Ihren Datensatz, um nur die benötigten Zeiträume und Spalten einzuschließen, und skalieren Sie die Daten, um sicherzustellen, dass sie im Intervall 0,1 projiziert werden.
-
Filtern Sie den ursprünglichen Datensatz, um nur die oben genannten Zeiträume pro Datensatz und nur die benötigte Spalte 'load' sowie das Datum einzuschließen:
train = energy.copy()[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']] test = energy.copy()[energy.index >= test_start_dt][['load']] print('Training data shape: ', train.shape) print('Test data shape: ', test.shape)
Sie können die Form der Daten sehen:
Training data shape: (1416, 1) Test data shape: (48, 1)
-
Skalieren Sie die Daten, um sie in den Bereich (0, 1) zu bringen.
scaler = MinMaxScaler() train['load'] = scaler.fit_transform(train) train.head(10)
-
Visualisieren Sie die ursprünglichen vs. skalierten Daten:
energy[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']].rename(columns={'load':'original load'}).plot.hist(bins=100, fontsize=12) train.rename(columns={'load':'scaled load'}).plot.hist(bins=100, fontsize=12) plt.show()
Die ursprünglichen Daten
Die skalierten Daten
-
Nachdem Sie die skalierten Daten kalibriert haben, können Sie die Testdaten skalieren:
test['load'] = scaler.transform(test) test.head()
ARIMA implementieren
Es ist Zeit, ARIMA zu implementieren! Sie verwenden jetzt die zuvor installierte statsmodels
-Bibliothek.
Nun müssen Sie mehrere Schritte ausführen:
- Definieren Sie das Modell, indem Sie
SARIMAX()
aufrufen und die Modellparameter p, d und q sowie P, D und Q übergeben. - Bereiten Sie das Modell für die Trainingsdaten vor, indem Sie die Funktion
fit()
aufrufen. - Treffen Sie Vorhersagen, indem Sie die Funktion
forecast()
aufrufen und die Anzahl der Schritte (denHorizont
) angeben, die vorhergesagt werden sollen.
🎓 Wofür stehen all diese Parameter? In einem ARIMA-Modell gibt es 3 Parameter, die verwendet werden, um die Hauptaspekte einer Zeitreihe zu modellieren: Saisonalität, Trend und Rauschen. Diese Parameter sind:
p
: Der Parameter, der mit dem autoregressiven Aspekt des Modells verbunden ist und vergangene Werte einbezieht.
d
: Der Parameter, der mit dem integrierten Teil des Modells verbunden ist und die Menge an Differenzierung (🎓 erinnern Sie sich an Differenzierung 👆?) beeinflusst, die auf eine Zeitreihe angewendet wird.
q
: Der Parameter, der mit dem gleitenden Durchschnitt des Modells verbunden ist.
Hinweis: Wenn Ihre Daten einen saisonalen Aspekt haben – was hier der Fall ist –, verwenden wir ein saisonales ARIMA-Modell (SARIMA). In diesem Fall müssen Sie ein weiteres Set von Parametern verwenden:
P
,D
undQ
, die dieselben Assoziationen wiep
,d
undq
beschreiben, aber den saisonalen Komponenten des Modells entsprechen.
-
Beginnen Sie mit der Festlegung Ihres bevorzugten Horizontwerts. Versuchen wir es mit 3 Stunden:
# Specify the number of steps to forecast ahead HORIZON = 3 print('Forecasting horizon:', HORIZON, 'hours')
Die Auswahl der besten Werte für die Parameter eines ARIMA-Modells kann herausfordernd sein, da sie subjektiv und zeitaufwändig ist. Sie könnten die Funktion
auto_arima()
aus derpyramid
-Bibliothek in Betracht ziehen. -
Versuchen Sie vorerst einige manuelle Auswahlmöglichkeiten, um ein gutes Modell zu finden.
order = (4, 1, 0) seasonal_order = (1, 1, 0, 24) model = SARIMAX(endog=train, order=order, seasonal_order=seasonal_order) results = model.fit() print(results.summary())
Eine Ergebnistabelle wird ausgegeben.
Sie haben Ihr erstes Modell erstellt! Nun müssen wir eine Möglichkeit finden, es zu bewerten.
Modell bewerten
Um Ihr Modell zu bewerten, können Sie die sogenannte walk forward
-Validierung durchführen. In der Praxis werden Zeitreihenmodelle jedes Mal neu trainiert, wenn neue Daten verfügbar werden. Dies ermöglicht es dem Modell, die beste Vorhersage zu jedem Zeitpunkt zu treffen.
Beginnen Sie am Anfang der Zeitreihe mit dieser Technik, trainieren Sie das Modell mit dem Trainingsdatensatz. Treffen Sie dann eine Vorhersage für den nächsten Zeitpunkt. Die Vorhersage wird mit dem bekannten Wert verglichen. Der Trainingsdatensatz wird dann erweitert, um den bekannten Wert einzuschließen, und der Prozess wird wiederholt.
Hinweis: Sie sollten das Fenster des Trainingsdatensatzes fixieren, um effizienter zu trainieren, sodass jedes Mal, wenn Sie eine neue Beobachtung zum Trainingsdatensatz hinzufügen, die Beobachtung vom Anfang des Datensatzes entfernt wird.
Dieser Prozess bietet eine robustere Schätzung, wie das Modell in der Praxis abschneiden wird. Allerdings entstehen dadurch höhere Rechenkosten, da so viele Modelle erstellt werden. Dies ist akzeptabel, wenn die Daten klein oder das Modell einfach ist, könnte jedoch bei größeren Datenmengen problematisch sein.
Die Walk-Forward-Validierung ist der Goldstandard für die Bewertung von Zeitreihenmodellen und wird für Ihre eigenen Projekte empfohlen.
-
Erstellen Sie zunächst einen Testdatenpunkt für jeden HORIZON-Schritt.
test_shifted = test.copy() for t in range(1, HORIZON+1): test_shifted['load+'+str(t)] = test_shifted['load'].shift(-t, freq='H') test_shifted = test_shifted.dropna(how='any') test_shifted.head(5)
load load+1 load+2 2014-12-30 00:00:00 0.33 0.29 0.27 2014-12-30 01:00:00 0.29 0.27 0.27 2014-12-30 02:00:00 0.27 0.27 0.30 2014-12-30 03:00:00 0.27 0.30 0.41 2014-12-30 04:00:00 0.30 0.41 0.57 Die Daten werden horizontal entsprechend ihrem Horizontpunkt verschoben.
-
Treffen Sie Vorhersagen für Ihre Testdaten mit diesem gleitenden Fensteransatz in einer Schleife, die der Länge der Testdaten entspricht:
%%time training_window = 720 # dedicate 30 days (720 hours) for training train_ts = train['load'] test_ts = test_shifted history = [x for x in train_ts] history = history[(-training_window):] predictions = list() order = (2, 1, 0) seasonal_order = (1, 1, 0, 24) for t in range(test_ts.shape[0]): model = SARIMAX(endog=history, order=order, seasonal_order=seasonal_order) model_fit = model.fit() yhat = model_fit.forecast(steps = HORIZON) predictions.append(yhat) obs = list(test_ts.iloc[t]) # move the training window history.append(obs[0]) history.pop(0) print(test_ts.index[t]) print(t+1, ': predicted =', yhat, 'expected =', obs)
Sie können das Training beobachten:
2014-12-30 00:00:00 1 : predicted = [0.32 0.29 0.28] expected = [0.32945389435989236, 0.2900626678603402, 0.2739480752014323] 2014-12-30 01:00:00 2 : predicted = [0.3 0.29 0.3 ] expected = [0.2900626678603402, 0.2739480752014323, 0.26812891674127126] 2014-12-30 02:00:00 3 : predicted = [0.27 0.28 0.32] expected = [0.2739480752014323, 0.26812891674127126, 0.3025962399283795]
-
Vergleichen Sie die Vorhersagen mit der tatsächlichen Last:
eval_df = pd.DataFrame(predictions, columns=['t+'+str(t) for t in range(1, HORIZON+1)]) eval_df['timestamp'] = test.index[0:len(test.index)-HORIZON+1] eval_df = pd.melt(eval_df, id_vars='timestamp', value_name='prediction', var_name='h') eval_df['actual'] = np.array(np.transpose(test_ts)).ravel() eval_df[['prediction', 'actual']] = scaler.inverse_transform(eval_df[['prediction', 'actual']]) eval_df.head()
Ausgabe
timestamp h prediction actual 0 2014-12-30 00:00:00 t+1 3,008.74 3,023.00 1 2014-12-30 01:00:00 t+1 2,955.53 2,935.00 2 2014-12-30 02:00:00 t+1 2,900.17 2,899.00 3 2014-12-30 03:00:00 t+1 2,917.69 2,886.00 4 2014-12-30 04:00:00 t+1 2,946.99 2,963.00 Beobachten Sie die stündlichen Vorhersagen im Vergleich zur tatsächlichen Last. Wie genau ist das?
Modellgenauigkeit überprüfen
Überprüfen Sie die Genauigkeit Ihres Modells, indem Sie den mittleren absoluten prozentualen Fehler (MAPE) über alle Vorhersagen testen.
🧮 Zeig mir die Mathematik
MAPE wird verwendet, um die Vorhersagegenauigkeit als Verhältnis darzustellen, das durch die obige Formel definiert ist. Die Differenz zwischen tatsächlichem und vorhergesagtem Wert wird durch den tatsächlichen Wert geteilt. "Der Absolutwert dieser Berechnung wird für jeden prognostizierten Zeitpunkt summiert und durch die Anzahl der angepassten Punkte n geteilt." wikipedia
-
Ausdruck der Gleichung im Code:
if(HORIZON > 1): eval_df['APE'] = (eval_df['prediction'] - eval_df['actual']).abs() / eval_df['actual'] print(eval_df.groupby('h')['APE'].mean())
-
Berechnung des MAPE für einen Schritt:
print('One step forecast MAPE: ', (mape(eval_df[eval_df['h'] == 't+1']['prediction'], eval_df[eval_df['h'] == 't+1']['actual']))*100, '%')
MAPE der Ein-Schritt-Vorhersage: 0.5570581332313952 %
-
Ausgabe des MAPE für die Mehrschritt-Vorhersage:
print('Multi-step forecast MAPE: ', mape(eval_df['prediction'], eval_df['actual'])*100, '%')
Multi-step forecast MAPE: 1.1460048657704118 %
Eine niedrige Zahl ist am besten: Beachten Sie, dass eine Vorhersage mit einem MAPE von 10 um 10 % abweicht.
-
Aber wie immer ist es einfacher, diese Art von Genauigkeitsmessung visuell zu sehen. Lassen Sie uns das plotten:
if(HORIZON == 1): ## Plotting single step forecast eval_df.plot(x='timestamp', y=['actual', 'prediction'], style=['r', 'b'], figsize=(15, 8)) else: ## Plotting multi step forecast plot_df = eval_df[(eval_df.h=='t+1')][['timestamp', 'actual']] for t in range(1, HORIZON+1): plot_df['t+'+str(t)] = eval_df[(eval_df.h=='t+'+str(t))]['prediction'].values fig = plt.figure(figsize=(15, 8)) ax = plt.plot(plot_df['timestamp'], plot_df['actual'], color='red', linewidth=4.0) ax = fig.add_subplot(111) for t in range(1, HORIZON+1): x = plot_df['timestamp'][(t-1):] y = plot_df['t+'+str(t)][0:len(x)] ax.plot(x, y, color='blue', linewidth=4*math.pow(.9,t), alpha=math.pow(0.8,t)) ax.legend(loc='best') plt.xlabel('timestamp', fontsize=12) plt.ylabel('load', fontsize=12) plt.show()
🏆 Ein sehr schöner Plot, der ein Modell mit guter Genauigkeit zeigt. Gut gemacht!
🚀Herausforderung
Tauchen Sie in die verschiedenen Möglichkeiten ein, die Genauigkeit eines Zeitreihenmodells zu testen. In dieser Lektion sprechen wir über MAPE, aber gibt es andere Methoden, die Sie verwenden könnten? Recherchieren Sie diese und kommentieren Sie sie. Ein hilfreiches Dokument finden Sie hier.
Quiz nach der Vorlesung
Rückblick & Selbststudium
Diese Lektion behandelt nur die Grundlagen der Zeitreihenprognose mit ARIMA. Nehmen Sie sich Zeit, Ihr Wissen zu vertiefen, indem Sie dieses Repository und seine verschiedenen Modelltypen durchstöbern, um andere Möglichkeiten zur Erstellung von Zeitreihenmodellen zu lernen.
Aufgabe
Haftungsausschluss:
Dieses Dokument wurde mit dem KI-Übersetzungsdienst Co-op Translator übersetzt. Obwohl wir uns um Genauigkeit bemühen, weisen wir darauf hin, dass automatisierte Übersetzungen Fehler oder Ungenauigkeiten enthalten können. Das Originaldokument in seiner ursprünglichen Sprache sollte als maßgebliche Quelle betrachtet werden. Für kritische Informationen wird eine professionelle menschliche Übersetzung empfohlen. Wir übernehmen keine Haftung für Missverständnisse oder Fehlinterpretationen, die sich aus der Nutzung dieser Übersetzung ergeben.