Website-Suche

Ein Leitfaden zur Zeitreihenprognose mit ARIMA in Python 3


Einführung

Zeitreihen bieten die Möglichkeit, zukünftige Werte vorherzusagen. Basierend auf vorherigen Werten können Zeitreihen genutzt werden, um Trends in der Wirtschaft, im Wetter und in der Kapazitätsplanung vorherzusagen, um nur einige zu nennen. Die spezifischen Eigenschaften von Zeitreihedaten bedeuten, dass normalerweise spezialisierte statistische Methoden erforderlich sind.

In diesem Tutorial werden wir zuverlässige Vorhersagen von Zeitreihen erstellen. Wir werden damit beginnen, die Konzepte der Autokorrelation, Stationarität und Saisonalität vorzustellen und zu diskutieren, und anschließend eines der am häufigsten verwendeten Verfahren zur Vorhersage von Zeitreihen anwenden, das als ARIMA bekannt ist.

Eine der Methoden, die in Python verfügbar sind, um zukünftige Punkte einer Zeitreihe zu modellieren und vorherzusagen, ist als SARIMAX bekannt, was für saisonale autoregressive integrierte gleitende Durchschnitte mit exogenen Regressoren steht. Hier werden wir uns hauptsächlich auf die ARIMA-Komponente konzentrieren, die verwendet wird, um Zeitreihendaten anzupassen, um zukünftige Punkte in der Zeitreihe besser zu verstehen und vorherzusagen.

Voraussetzungen

Dieser Leitfaden behandelt, wie man Zeitreihenanalysen entweder auf einem lokalen Desktop oder auf einem entfernten Server durchführt. Die Arbeit mit großen Datensätzen kann speicherintensiv sein, daher benötigt der Computer in beiden Fällen mindestens 2 GB Speicher, um einige der Berechnungen in diesem Leitfaden durchzuführen.

Um das Beste aus diesem Tutorial herauszuholen, kann es hilfreich sein, sich mit Zeitreihen und Statistik auszukennen.

Für dieses Tutorial werden wir Jupyter Notebook verwenden, um mit den Daten zu arbeiten. Wenn Sie es noch nicht haben, sollten Sie unserem Tutorial folgen, um Jupyter Notebook für Python 3 zu installieren und einzurichten.

Schritt 1 — Pakete installieren

Um unsere Umgebung für die Zeitreihenprognose einzurichten, lassen Sie uns zunächst in unsere lokale Programmierumgebung oder serverbasierte Programmierumgebung wechseln:

  1. cd environments
  1. . my_env/bin/activate

Von hier aus erstellen wir ein neues Verzeichnis für unser Projekt. Wir werden es ARIMA nennen und dann in das Verzeichnis wechseln. Wenn Sie dem Projekt einen anderen Namen geben, stellen Sie sicher, dass Sie Ihren Namen überall im Leitfaden anstelle von ARIMA einsetzen.

  1. mkdir ARIMA
  2. cd ARIMA

Dieses Tutorial benötigt die Bibliotheken warnings, itertools, pandas, numpy, matplotlib und statsmodels. Die Bibliotheken warnings und itertools sind im Standard-Bibliothekspaket von Python enthalten, sodass Sie sie nicht installieren müssen.

Wie bei anderen Python-Paketen können wir diese Anforderungen mit pip installieren. Wir können jetzt pandas, statsmodels und das Datenvisualisierungspaket matplotlib installieren. Ihre Abhängigkeiten werden ebenfalls installiert:

  1. pip install pandas numpy statsmodels matplotlib

An diesem Punkt sind wir nun bereit, mit den installierten Paketen zu arbeiten.

Schritt 2 — Pakete importieren und Daten laden

Um mit unseren Daten zu arbeiten, werden wir Jupyter Notebook starten:

  1. jupyter notebook

Um eine neue Notizbuchdatei zu erstellen, wählen Sie Neu > Python 3 aus dem Dropdown-Menü oben rechts:

Das öffnet ein Notizbuch.

Wie es Best Practice ist, beginnen Sie damit, die Bibliotheken, die Sie benötigen, an den Anfang Ihres Notebooks zu importieren:

import warnings
import itertools
import pandas as pd
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')

Wir haben auch einen matplotlib Stil von fivethirtyeight für unsere Diagramme definiert.

Wir werden mit einem Datensatz namens „Atmosphärisches CO2 aus kontinuierlichen Luftproben am Mauna Loa Observatorium, Hawaii, USA“ arbeiten, der CO2-Proben von März 1958 bis Dezember 2001 gesammelt hat. Wir können diese Daten wie folgt einbringen:

data = sm.datasets.co2.load_pandas()
y = data.data

Lass uns unsere Daten ein wenig vorverarbeiten, bevor wir fortfahren. Wöchentliche Daten können schwierig zu bearbeiten sein, da es sich um einen kürzeren Zeitraum handelt, also lass uns stattdessen monatliche Durchschnitte verwenden. Wir werden die Umwandlung mit der resample Funktion durchführen. Zur Vereinfachung können wir auch die fillna() Funktion verwenden, um sicherzustellen, dass wir keine fehlenden Werte in unserer Zeitreihe haben.

The 'MS' string groups the data in buckets by start of the month
y = y['co2'].resample('MS').mean()

The term bfill means that we use the value before filling in missing values
y = y.fillna(y.bfill())

print(y)
co2
1958-03-01  316.100000
1958-04-01  317.200000
1958-05-01  317.433333
...
2001-11-01  369.375000
2001-12-01  371.020000

Lass uns diese Zeitreihe e als Datenvisualisierung erkunden:

y.plot(figsize=(15, 6))
plt.show()

Einige unterscheidbare Muster erscheinen, wenn wir die Daten darstellen. Die Zeitreihe weist ein offensichtliches Saisonalitätsmuster sowie einen insgesamt steigenden Trend auf.

Um mehr über die Vorverarbeitung von Zeitreihen zu erfahren, bitte beziehen Sie sich auf "Ein Leitfaden zur Visualisierung von Zeitreihen mit Python 3", in dem die oben genannten Schritte ausführlicher beschrieben werden.

Jetzt, da wir unsere Daten konvertiert und erkundet haben, lassen Sie uns mit der Zeitreihenprognose mit ARIMA fortfahren.

Schritt 3 — Das ARIMA-Zeitreihenmodell

Eine der häufigsten Methoden, die in der Zeitreihenprognose verwendet wird, ist das ARIMA-Modell, das für Autoregressives Integriertes Moving Average steht. ARIMA ist ein Modell, das an Zeitreihendaten angepasst werden kann, um zukünftige Punkte in der Serie besser zu verstehen oder vorherzusagen.

Es gibt drei verschiedene ganze Zahlen (p, d, q), die zur Parametrisierung von ARIMA-Modellen verwendet werden. Daher werden ARIMA-Modelle mit der Notation ARIMA(p, d, q) bezeichnet. Zusammen erfassen diese drei Parameter Saisonalität, Trend und Rauschen in Datensätzen:

  • p ist der auto-regressive Teil des Modells. Es ermöglicht uns, den Einfluss vergangener Werte in unser Modell einzubeziehen. Intuitiv wäre dies ähnlich wie zu sagen, dass es wahrscheinlich morgen warm sein wird, wenn es in den letzten 3 Tagen warm war.
  • d ist der integrierte Teil des Modells. Dazu gehören Begriffe im Modell, die die Menge der Differenzierung (d.h. die Anzahl der zurückliegenden Zeitpunkte, die vom aktuellen Wert subtrahiert werden sollen) für die Zeitreihe einbeziehen. Intuitiv würde dies einem Hinweis ähneln, dass es wahrscheinlich morgen die gleiche Temperatur sein wird, wenn der Temperaturunterschied in den letzten drei Tagen sehr gering war.
  • q ist der gleitende Durchschnitt Teil des Modells. Dies ermöglicht es uns, den Fehler unseres Modells als lineare Kombination der Fehlerwerte, die zu früheren Zeitpunkten in der Vergangenheit beobachtet wurden, festzulegen.

Wenn wir mit saisonalen Effekten umgehen, nutzen wir das saisonale ARIMA, das als ARIMA(p,d,q)(P,D,Q)s bezeichnet wird. Hierbei sind (p, d, q) die nicht-saisonalen Parameter, die oben beschrieben wurden, während (P, D, Q) dieselbe Definition haben, jedoch auf die saisonale Komponente der Zeitreihe angewendet werden. Der Begriff s ist die Periodizität der Zeitreihe (4 für vierteljährliche Perioden, 12 für jährliche Perioden usw.).

Die saisonale ARIMA-Methode kann einschüchternd erscheinen, da es mehrere Tuning-Parameter gibt. Im nächsten Abschnitt werden wir beschreiben, wie der Prozess zur Identifizierung des optimalen Satzes von Parametern für das saisonale ARIMA-Zeitreihenmodell automatisiert werden kann.

Schritt 4 — Auswahl der Parameter für das ARIMA-Zeitreihenmodell

Bei der Anpassung von Zeitreihendaten an ein saisonales ARIMA-Modell ist unser erstes Ziel, die Werte von ARIMA(p,d,q)(P,D,Q)s zu finden, die eine interessante Kennzahl optimieren. Es gibt viele Richtlinien und bewährte Verfahren, um dieses Ziel zu erreichen, doch die richtige Parametrierung von ARIMA-Modellen kann ein mühsamer manueller Prozess sein, der Fachwissen und Zeit erfordert. Andere statistische Programmiersprachen wie R bieten automatisierte Möglichkeiten zur Lösung dieses Problems, aber diese wurden noch nicht auf Python portiert. In diesem Abschnitt werden wir dieses Problem lösen, indem wir Python-Code schreiben, um programmgesteuert die optimalen Parameterwerte für unser ARIMA(p,d,q)(P,D,Q)s Zeitreihenmodell auszuwählen.

Wir werden eine "Gitter-Suche" verwenden, um iterativ verschiedene Kombinationen von Parametern zu erkunden. Für jede Kombination von Parametern passen wir ein neues saisonales ARIMA-Modell mit der SARIMAX()-Funktion aus dem statsmodels-Modul an und beurteilen seine Gesamtqualität. Sobald wir die gesamte Landschaft der Parameter erkundet haben, wird unser optimales Set von Parametern dasjenige sein, das die beste Leistung für unsere Interessenskriterien liefert. Lassen Sie uns beginnen, die verschiedenen Kombinationen von Parametern zu generieren, die wir bewerten möchten:

Define the p, d and q parameters to take any value between 0 and 2
p = d = q = range(0, 2)

Generate all different combinations of p, q and q triplets
pdq = list(itertools.product(p, d, q))

Generate all different combinations of seasonal p, q and q triplets
seasonal_pdq = [(x[0], x[1], x[2], 12) for x in list(itertools.product(p, d, q))]

print('Examples of parameter combinations for Seasonal ARIMA...')
print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[1]))
print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[2]))
print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[3]))
print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[4]))
Examples of parameter combinations for Seasonal ARIMA...
SARIMAX: (0, 0, 1) x (0, 0, 1, 12)
SARIMAX: (0, 0, 1) x (0, 1, 0, 12)
SARIMAX: (0, 1, 0) x (0, 1, 1, 12)
SARIMAX: (0, 1, 0) x (1, 0, 0, 12)

Wir können nun die oben definierten Parametertriplets verwenden, um den Prozess des Trainings und der Evaluierung von ARIMA-Modellen für verschiedene Kombinationen zu automatisieren. In der Statistik und im maschinellen Lernen wird dieser Prozess als Grid-Suche (oder Hyperparameter-Optimierung) zur Modellauswahl bezeichnet.

Bei der Bewertung und dem Vergleich von statistischen Modellen, die mit unterschiedlichen Parametern angepasst wurden, kann jedes Modell anhand seiner Anpassung an die Daten oder seiner Fähigkeit, zukünftige Datenpunkte genau vorherzusagen, gegeneinander eingestuft werden. Wir werden den AIC (Akaike-Informationskriterium) Wert verwenden, der bequem mit ARIMA-Modellen zurückgegeben wird, die mit statsmodels angepasst wurden. Der AIC misst, wie gut ein Modell zu den Daten passt, wobei die Gesamtheit der Komplexität des Modells berücksichtigt wird. Ein Modell, das sehr gut zu den Daten passt und viele Merkmale verwendet, erhält einen höheren AIC-Wert als ein Modell, das weniger Merkmale nutzt, um die gleiche Anpassungsgüte zu erreichen. Daher sind wir daran interessiert, das Modell zu finden, das den niedrigsten AIC Wert liefert.

Der untenstehende Code durchläuft Kombinationen von Parametern und verwendet die SARIMAX-Funktion aus statsmodels, um das entsprechende saisonale ARIMA-Modell anzupassen. Hier gibt das Argument order die (p, d, q)-Parameter an, während das Argument seasonal_order die saisonalen Komponenten des saisonalen ARIMA-Modells (P, D, Q, S) angibt. Nach der Anpassung jedes SARIMAX()-Modells gibt der Code den jeweiligen AIC-Wert aus.

warnings.filterwarnings("ignore") # specify to ignore warning messages

for param in pdq:
    for param_seasonal in seasonal_pdq:
        try:
            mod = sm.tsa.statespace.SARIMAX(y,
                                            order=param,
                                            seasonal_order=param_seasonal,
                                            enforce_stationarity=False,
                                            enforce_invertibility=False)

            results = mod.fit()

            print('ARIMA{}x{}12 - AIC:{}'.format(param, param_seasonal, results.aic))
        except:
            continue

Da einige Parameterkombinationen zu numerischen Fehlenspezifikationen führen können, haben wir Warnmeldungen ausdrücklich deaktiviert, um eine Überlastung an Warnmeldungen zu vermeiden. Diese Fehlenspezifikationen können auch zu Fehlern führen und eine Ausnahme auslösen, daher stellen wir sicher, dass wir diese Ausnahmen abfangen und die Parameterkombinationen ignorieren, die diese Probleme verursachen.

Der obige Code sollte die folgenden Ergebnisse liefern, dies kann einige Zeit in Anspruch nehmen:

SARIMAX(0, 0, 0)x(0, 0, 1, 12) - AIC:6787.3436240402125
SARIMAX(0, 0, 0)x(0, 1, 1, 12) - AIC:1596.711172764114
SARIMAX(0, 0, 0)x(1, 0, 0, 12) - AIC:1058.9388921320026
SARIMAX(0, 0, 0)x(1, 0, 1, 12) - AIC:1056.2878315690562
SARIMAX(0, 0, 0)x(1, 1, 0, 12) - AIC:1361.6578978064144
SARIMAX(0, 0, 0)x(1, 1, 1, 12) - AIC:1044.7647912940095
...
...
...
SARIMAX(1, 1, 1)x(1, 0, 0, 12) - AIC:576.8647112294245
SARIMAX(1, 1, 1)x(1, 0, 1, 12) - AIC:327.9049123596742
SARIMAX(1, 1, 1)x(1, 1, 0, 12) - AIC:444.12436865161305
SARIMAX(1, 1, 1)x(1, 1, 1, 12) - AIC:277.7801413828764

Die Ausgabe unseres Codes deutet darauf hin, dass SARIMAX(1, 1, 1)x(1, 1, 1, 12) den niedrigsten AIC-Wert von 277,78 liefert. Wir sollten dies daher als die optimale Option aus allen von uns in Betracht gezogenen Modellen betrachten.

Schritt 5 — Anpassen eines ARIMA-Zeitreihenmodells

Durch die Verwendung von Gitter-Suche haben wir die Parameterkombination identifiziert, die das am besten passende Modell für unsere Zeitreihendaten liefert. Wir können nun dieses spezifische Modell eingehender analysieren.

Wir werden damit beginnen, die optimalen Parameterwerte in ein neues SARIMAX-Modell einzufügen:

mod = sm.tsa.statespace.SARIMAX(y,
                                order=(1, 1, 1),
                                seasonal_order=(1, 1, 1, 12),
                                enforce_stationarity=False,
                                enforce_invertibility=False)

results = mod.fit()

print(results.summary().tables[1])
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
ar.L1          0.3182      0.092      3.443      0.001       0.137       0.499
ma.L1         -0.6255      0.077     -8.165      0.000      -0.776      -0.475
ar.S.L12       0.0010      0.001      1.732      0.083      -0.000       0.002
ma.S.L12      -0.8769      0.026    -33.811      0.000      -0.928      -0.826
sigma2         0.0972      0.004     22.634      0.000       0.089       0.106
==============================================================================

Das summary-Attribut, das aus der Ausgabe von SARIMAX resultiert, liefert eine beträchtliche Menge an Informationen, aber wir werden uns auf die Tabelle der Koeffizienten konzentrieren. Die coef-Spalte zeigt das Gewicht (d.h. die Wichtigkeit) jedes Merkmals und wie jedes einzelne die Zeitreihe beeinflusst. Die P>|z|-Spalte informiert uns über die Signifikanz jedes Merkmalsgewichts. Hier hat jedes Gewicht einen p-Wert, der kleiner oder nahe bei 0.05 liegt, daher ist es sinnvoll, alle in unserem Modell beizubehalten.

Bei der Anpassung saisonaler ARIMA-Modelle (und anderen Modellen) ist es wichtig, Modell-Diagnosen durchzuführen, um sicherzustellen, dass keine der Annahmen, die das Modell getroffen hat, verletzt wurden. Das plot_diagnostics-Objekt ermöglicht es uns, schnell Modell-Diagnosen zu erstellen und nach ungewöhnlichem Verhalten zu suchen.

results.plot_diagnostics(figsize=(15, 12))
plt.show()

Unser Hauptanliegen ist es sicherzustellen, dass die Residuen unseres Modells unkorreliert und normalverteilt mit einem Mittelwert von null sind. Wenn das saisonale ARIMA-Modell diese Eigenschaften nicht erfüllt, ist das ein gutes Indiz dafür, dass es weiter verbessert werden kann.

In diesem Fall deutet unsere Modeldiagnose darauf hin, dass die Modellresiduen basierend auf Folgendem normal verteilt sind:

  • Im Diagramm oben rechts sehen wir, dass die rote KDE-Linie eng mit der N(0,1)-Linie übereinstimmt (wobei N(0,1) die standardisierte Notation für eine Normalverteilung mit einem Mittelwert von 0 und einer Standardabweichung von 1 ist). Dies ist ein gutes Zeichen dafür, dass die Residuen normalverteilt sind.

  • Das QQ-Diagramm unten links zeigt, dass die geordnete Verteilung der Residuen (blaue Punkte) dem linearen Trend der Proben aus einer Standardnormalverteilung mit N(0, 1) folgt. Dies ist erneut ein starkes Indiz dafür, dass die Residuen normalverteilt sind.

  • Die Residuen über die Zeit (obere linke Grafik) zeigen keine offensichtliche Saisonalität und erscheinen als weißes Rauschen. Dies wird durch das Autokorrelationsdiagramm (d.h. Korrelogramm) unten rechts bestätigt, das zeigt, dass die Residuen der Zeitreihe eine geringe Korrelation mit verzögerten Versionen von sich selbst haben.

Diese Beobachtungen führen uns zu dem Schluss, dass unser Modell eine zufriedenstellende Anpassung bietet, die uns helfen könnte, unsere Zeitreihendaten zu verstehen und zukünftige Werte vorherzusagen.

Obwohl wir eine zufriedenstellende Anpassung haben, könnten einige Parameter unseres saisonalen ARIMA-Modells geändert werden, um die Modellanpassung zu verbessern. Zum Beispiel berücksichtigte unsere Gitter-Suche nur eine eingeschränkte Menge an Parameterkombinationen, daher könnten wir bessere Modelle finden, wenn wir die Gitter-Suche erweitern.

Schritt 6 — Überprüfung der Prognosen

Wir haben ein Modell für unsere Zeitreihe erstellt, das nun verwendet werden kann, um Prognosen zu erstellen. Wir beginnen damit, die vorhergesagten Werte mit den realen Werten der Zeitreihe zu vergleichen, was uns helfen wird, die Genauigkeit unserer Prognosen zu verstehen. Die Attribute get_prediction() und conf_int() ermöglichen es uns, die Werte und die dazugehörigen Vertrauensintervalle für die Prognosen der Zeitreihe zu erhalten.

pred = results.get_prediction(start=pd.to_datetime('1998-01-01'), dynamic=False)
pred_ci = pred.conf_int()

Der obige Code erfordert, dass die Prognosen im Januar 1998 beginnen.

Das Argument dynamic=False stellt sicher, dass wir Vorhersagen für den nächsten Schritt erstellen, was bedeutet, dass die Vorhersagen zu jedem Zeitpunkt unter Verwendung der gesamten Geschichte bis zu diesem Zeitpunkt generiert werden.

Wir können die realen und prognostizierten Werte der CO2-Zeitreihe darstellen, um zu bewerten, wie gut wir abgeschnitten haben. Beachten Sie, wie wir am Ende der Zeitreihe hineingezoomt haben, indem wir den Datumsindex geschnitten haben.

ax = y['1990':].plot(label='observed')
pred.predicted_mean.plot(ax=ax, label='One-step ahead Forecast', alpha=.7)

ax.fill_between(pred_ci.index,
                pred_ci.iloc[:, 0],
                pred_ci.iloc[:, 1], color='k', alpha=.2)

ax.set_xlabel('Date')
ax.set_ylabel('CO2 Levels')
plt.legend()

plt.show()

Insgesamt stimmen unsere Prognosen sehr gut mit den tatsächlichen Werten überein und zeigen einen insgesamt zunehmenden Trend.

Es ist auch nützlich, die Genauigkeit unserer Vorhersagen zu quantifizieren. Wir werden den MSE (Mean Squared Error) verwenden, der den durchschnittlichen Fehler unserer Vorhersagen zusammenfasst. Für jeden vorhergesagten Wert berechnen wir seine Entfernung zum tatsächlichen Wert und quadrieren das Ergebnis. Die Ergebnisse müssen quadriert werden, damit positive/negative Unterschiede sich nicht gegenseitig aufheben, wenn wir den Gesamtdurchschnitt berechnen.

y_forecasted = pred.predicted_mean
y_truth = y['1998-01-01':]

Compute the mean square error
mse = ((y_forecasted - y_truth) ** 2).mean()
print('The Mean Squared Error of our forecasts is {}'.format(round(mse, 2)))
The Mean Squared Error of our forecasts is 0.07

Die MSE unserer ein-Schritt-vorher Prognosen ergibt einen Wert von 0,07, was sehr niedrig ist, da es nahe bei 0 liegt. Ein MSE von 0 würde bedeuten, dass der Schätzer die Beobachtungen des Parameters mit perfekter Genauigkeit vorhersagt, was ein ideales Szenario wäre, aber normalerweise nicht möglich ist.

Eine bessere Darstellung unserer tatsächlichen Vorhersagekraft kann jedoch durch dynamische Vorhersagen erreicht werden. In diesem Fall verwenden wir nur Informationen aus der Zeitreihe bis zu einem bestimmten Punkt, und danach werden Vorhersagen unter Verwendung von Werten aus vorhergesagten Zeitpunkten generiert.

Im folgenden Code-Abschnitt geben wir an, dass die dynamischen Vorhersagen und Vertrauensintervalle ab Januar 1998 berechnet werden sollen.

pred_dynamic = results.get_prediction(start=pd.to_datetime('1998-01-01'), dynamic=True, full_results=True)
pred_dynamic_ci = pred_dynamic.conf_int()

Wenn wir die beobachteten und prognostizierten Werte der Zeitreihe darstellen, sehen wir, dass die Gesamtschätzungen genau sind, selbst bei der Verwendung dynamischer Prognosen. Alle prognostizierten Werte (rote Linie) stimmen ziemlich genau mit der tatsächlichen Entwicklung (blaue Linie) überein und liegen gut innerhalb der Konfidenzintervalle unserer Prognose.

ax = y['1990':].plot(label='observed', figsize=(20, 15))
pred_dynamic.predicted_mean.plot(label='Dynamic Forecast', ax=ax)

ax.fill_between(pred_dynamic_ci.index,
                pred_dynamic_ci.iloc[:, 0],
                pred_dynamic_ci.iloc[:, 1], color='k', alpha=.25)

ax.fill_betweenx(ax.get_ylim(), pd.to_datetime('1998-01-01'), y.index[-1],
                 alpha=.1, zorder=-1)

ax.set_xlabel('Date')
ax.set_ylabel('CO2 Levels')

plt.legend()
plt.show()

Einmal mehr quantifizieren wir die prognostische Leistung unserer Vorhersagen, indem wir den MSE berechnen:

Extract the predicted and true values of our time series
y_forecasted = pred_dynamic.predicted_mean
y_truth = y['1998-01-01':]

Compute the mean square error
mse = ((y_forecasted - y_truth) ** 2).mean()
print('The Mean Squared Error of our forecasts is {}'.format(round(mse, 2)))
The Mean Squared Error of our forecasts is 1.01

Die vorhergesagten Werte aus den dynamischen Prognosen ergeben einen MSE von 1,01. Dies ist leicht höher als der ein Schritt im Voraus, was zu erwarten ist, da wir auf weniger historische Daten aus der Zeitreihe angewiesen sind.

Sowohl die einstufigen als auch die dynamischen Vorhersagen bestätigen, dass dieses Zeitreihenmodell gültig ist. Das meiste Interesse an der Zeitreihenvorhersage besteht jedoch darin, zukünftige Werte weit im Voraus vorhersagen zu können.

Schritt 7 — Produzieren und Visualisieren von Prognosen

Im letzten Schritt dieses Tutorials beschreiben wir, wie wir unser saisonales ARIMA-Zeitmodell nutzen können, um zukünftige Werte vorherzusagen. Das Attribut get_forecast() unseres Zeitobjekts kann vorhergesagte Werte für eine angegebene Anzahl an Schritten im Voraus berechnen.

Get forecast 500 steps ahead in future
pred_uc = results.get_forecast(steps=500)

Get confidence intervals of forecasts
pred_ci = pred_uc.conf_int()

Wir können die Ausgabe dieses Codes verwenden, um die Zeitreihe und die Vorhersagen ihrer zukünftigen Werte zu plotten.

ax = y.plot(label='observed', figsize=(20, 15))
pred_uc.predicted_mean.plot(ax=ax, label='Forecast')
ax.fill_between(pred_ci.index,
                pred_ci.iloc[:, 0],
                pred_ci.iloc[:, 1], color='k', alpha=.25)
ax.set_xlabel('Date')
ax.set_ylabel('CO2 Levels')

plt.legend()
plt.show()

Die von uns erstellten Prognosen und der zugehörige Vertrauensintervall können nun verwendet werden, um die Zeitreihe weiter zu verstehen und vorherzusehen, was zu erwarten ist. Unsere Prognosen zeigen, dass die Zeitreihe voraussichtlich weiterhin in einem stetigen Tempo steigen wird.

Wenn wir weiter in die Zukunft blicken, ist es natürlich, dass unser Vertrauen in unsere Werte abnimmt. Dies spiegelt sich in den Konfidenzintervallen wider, die von unserem Modell generiert werden und größer werden, je weiter wir in die Zukunft schauen.

Schlussfolgerung

In diesem Tutorial haben wir beschrieben, wie man ein saisonales ARIMA-Modell in Python implementiert. Wir haben umfangreich die pandas- und statsmodels-Bibliotheken verwendet und gezeigt, wie man Modediagnosen durchführt sowie Prognosen der CO2-Zeitreihe erstellt.

Hier sind einige andere Dinge, die Sie ausprobieren könnten:

  • Ändern Sie das Startdatum Ihrer dynamischen Prognosen, um zu sehen, wie sich dies auf die Gesamtqualität Ihrer Prognosen auswirkt.
  • Versuchen Sie mehr Kombinationen von Parametern, um zu sehen, ob Sie die Güte der Anpassung Ihres Modells verbessern können.
  • Wählen Sie eine andere Metrik, um das beste Modell auszuwählen. Zum Beispiel haben wir das AIC-Maß verwendet, um das beste Modell zu finden, aber Sie könnten stattdessen versuchen, den mittleren quadratischen Fehler außerhalb der Stichprobe zu optimieren.

Für mehr Übung könntest du auch versuchen, einen anderen Zeitreihen-Datensatz zu laden, um deine eigenen Vorhersagen zu erstellen.