Maschinelles Lernen für Zeitreihen - Exam.pdf

Maschinelles Lernen für Zeitreihen - Exam
Maschinelles Lernen für Zeitreihen - Exam Aufgabe 1) Gegeben sei eine Zeitreihe bestehend aus den monatlichen Durchschnittstemperaturen in einer Stadt über einen Zeitraum von 10 Jahren. Du sollst ein Modell erstellen, um die Temperaturen für die nächsten Monate vorherzusagen. Nutze dazu ein ARIMA-Modell. Es sei bekannt, dass die Daten nicht stationär sind und sowohl autoregressive als auch gleiten...

© StudySmarter 2024, all rights reserved.

Maschinelles Lernen für Zeitreihen - Exam

Aufgabe 1)

Gegeben sei eine Zeitreihe bestehend aus den monatlichen Durchschnittstemperaturen in einer Stadt über einen Zeitraum von 10 Jahren. Du sollst ein Modell erstellen, um die Temperaturen für die nächsten Monate vorherzusagen. Nutze dazu ein ARIMA-Modell. Es sei bekannt, dass die Daten nicht stationär sind und sowohl autoregressive als auch gleitende Durchschnittsanteile enthalten.

a)

Überprüfe zuerst, ob die gegebene Zeitreihe stationär ist oder nicht. Erkläre, welche Methode Du anwendest und wie Du zum Ergebnis kommst. Bestimme, falls notwendig, den Differenzierungsgrad (d), um die Daten stationär zu machen.

Lösung:

Um zu überprüfen, ob eine gegebene Zeitreihe stationär ist, verwenden wir in der Regel die Dickey-Fuller-Test (ADF-Test), der ein statistischer Test ist, der auf das Vorliegen einer Einheitwurzel in einer Zeitreihe hinweist. Eine stationäre Zeitreihe hat keine Einheitwurzel.

  • ADF-Test: Der Augmented Dickey-Fuller-Test wird verwendet, um zu überprüfen, ob eine Zeitreihe eine Einheitwurzel hat. Die Nullhypothese (H0) des Tests lautet, dass die Zeitreihe eine Einheitwurzel besitzt (d.h., die Zeitreihe ist nicht stationär).
Die Schritte zur Überprüfung der Stationarität sind wie folgt:
  • Visuelle Überprüfung: Plotte die Zeitreihe und überprüfe, ob es offensichtliche Trends oder saisonale Muster gibt.
  • ADF-Test durchführen: Erhalte den p-Wert aus dem ADF-Test. Wenn der p-Wert klein genug (typischerweise < 0,05) ist, können wir die Nullhypothese ablehnen und schließen, dass die Zeitreihe stationär ist.

Falls die Zeitreihe nicht stationär ist, müssen wir sie stationär machen. Dies geschieht typischerweise durch Differenzierung. Der Differenzierungsgrad (d) ist die Anzahl der Male, die die Zeitreihe differenziert werden muss, um stationär zu werden.

  • Erste Differenzierung: Ziehe den vorherigen Wert von jedem Wert in der Zeitreihe ab.
  • Führe erneut den ADF-Test durch, um zu überprüfen, ob die differenzierte Zeitreihe stationär ist.
  • Wiederhole den Vorgang, bis die Zeitreihe stationär wird.

Hier ist ein Beispiel, wie du dies in Python mit der Bibliothek statsmodels umsetzen kannst:

 import pandas as pd from statsmodels.tsa.stattools import adfuller  # Lade die Zeitreihe (als Beispiel verwendet CSV-Datei) df = pd.read_csv('temperaturen.csv', parse_dates=['Datum'], index_col='Datum')  # Visuelle Überprüfung der Zeitreihe df['Temperatur'].plot(title='Monatliche Durchschnittstemperaturen')  # ADF-Test adf_result = adfuller(df['Temperatur']) print('ADF Statistic:', adf_result[0]) print('p-Wert:', adf_result[1])  if adf_result[1] > 0.05:     print('Zeitreihe ist nicht stationär, Differenzierung erforderlich')     # Differenzieren df['Differenziert'] = df['Temperatur'].diff().dropna()     # ADF-Test auf differenzierte Zeitreihe adf_result_diff = adfuller(df['Differenziert'].dropna())     print('ADF Statistic nach Differenzierung:', adf_result_diff[0])     print('p-Wert nach Differenzierung:', adf_result_diff[1]) else:     print('Zeitreihe ist stationär, Differenzierung nicht erforderlich') 

Diese Schritte sollten Dir helfen, die Stationarität der Zeitreihe zu überprüfen und den notwendigen Differenzierungsgrad zu bestimmen, um die Daten für die Modellierung mit einem ARIMA-Modell vorzubereiten.

b)

Ermittle anhand der stationär gemachten Zeitreihe die Parameter p und q. Beschreibe den Prozess zur Auswahl dieser Parameter und zeige, welche Werte Du letztendlich gewählt hast.

Lösung:

Um ein ARIMA-Modell zu erstellen, müssen wir die Parameter p und q bestimmen. Diese stehen für den autoregressiven Anteil (AR) und den gleitenden Durchschnittsanteil (MA) der Zeitreihe. Der Prozess zur Auswahl dieser Parameter kann mit Hilfe der Autokorrelationsfunktion (ACF) und der partiellen Autokorrelationsfunktion (PACF) durchgeführt werden.

  • Autokorrelationsfunktion (ACF): Diese zeigt den Zusammenhang zwischen einer Beobachtung und mehreren verzögerten Werten dieser Beobachtung. Sie hilft bei der Identifizierung des MA-Anteils.
  • Partielle Autokorrelationsfunktion (PACF): Diese zeigt den linearen Zusammenhang zwischen einer Beobachtung und mehreren verzögerten Werten dieser Beobachtung, wobei der Einfluss der dazwischen liegenden Beobachtungen entfernt wird. Sie hilft bei der Identifizierung des AR-Anteils.

Die Schritte zur Bestimmung der Parameter p und q sind wie folgt:

  • Plotten der ACF und PACF: Analysiere die ACF und PACF Plots der stationär gemachten Zeitreihe.
  • Identifizieren der signifikanten Abschöpfungen: Prüfe die Stellen, an denen die ACF und PACF Werte die Konfidenzintervalle überschreiten. Diese Stellen geben Hinweise auf die möglichen Werte für p und q.

Hier ist ein Beispiel, wie du dies in Python mit der Bibliothek statsmodels umsetzen kannst:

 import pandas as pd from statsmodels.graphics.tsaplots import plot_acf, plot_pacf import matplotlib.pyplot as plt  # Lade die stationär gemachte Zeitreihe (dies setzt voraus, dass die Differenzierung bereits durchgeführt wurde) df = pd.read_csv('differenzierte_temperaturen.csv', parse_dates=['Datum'], index_col='Datum')  # Plotten der ACF und PACF plot_acf(df['Differenziert'].dropna(), lags=40) plot_pacf(df['Differenziert'].dropna(), lags=40) plt.show() 

Nach dem Plotten der ACF und PACF können wir die Abschöpfungen analysieren.

  • Parameter p: Werte der PACF, die über die Konfidenzintervallgrenze hinausgehen, geben Aufschluss über die Anzahl der autoregressiven Lag-Terms.
  • Parameter q: Werte der ACF, die über die Konfidenzintervallgrenze hinausgehen, geben Aufschluss über die Anzahl der gleitenden Durchschnitts-Lag-Terms.

Angenommen, die PACF zeigt signifikante Abschöpfungen bei den Lags 1 und 2, und die ACF zeigt signifikante Abschöpfungen bei den Lags 1, dann wählen wir p = 2 und q = 1.

Zusammengefasst, hier ist die Auswahl der Parameter in deinem Fall:

  • p: 2 (basierend auf den signifikanten Abschöpfungen der PACF)
  • q: 1 (basierend auf den signifikanten Abschöpfungen der ACF)

Diese Werte können dann zur Erstellung des ARIMA-Modells verwendet werden.

c)

Schreibe die Gleichung des ARIMA-Modells für die gegebenen monatlichen Durchschnittstemperaturen. Nutze die ermittelten Werte für p, d, und q. Implementiere das Modell in Python und zeige eine Vorhersage für die nächsten 12 Monate.

Lösung:

Für die gegebenen monatlichen Durchschnittstemperaturen über einen Zeitraum von 10 Jahren haben wir ein ARIMA-Modell ermittelt, bei dem die Parameter p, d und q wie folgt festgelegt wurden:

  • p: 2 (Autoregressiver Anteil)
  • d: 1 (Differenzierungsgrad)
  • q: 1 (Gleitender Durchschnittsanteil)

Die Gleichung für das ARIMA(2, 1, 1)-Modell lautet:

Sei \(Y_t\) die monatliche Durchschnittstemperatur zum Zeitpunkt \(t\). Da \(d = 1\), differenzieren wir die Zeitreihe einmal, um sie stationär zu machen, sodass \(\Delta Y_t = Y_t - Y_{t-1}\). Die ARIMA-Gleichung wird dann:

\(\Delta Y_t = c + \theta_1 \Delta Y_{t-1} + \theta_2 \Delta Y_{t-2} + \beta_1 \epsilon_{t-1} + \epsilon_t\)

  • \(\Delta Y_t\): Differenzierte Zeitreihe
  • \(\theta_1\), \(\theta_2\): Koeffizienten des autoregressiven Teils
  • \(\beta_1\): Koeffizient des gleitenden Durchschnittsteils
  • \(\epsilon_t\): Fehlerterm zum Zeitpunkt \(t\)
  • \(c\): Konstante

Die Implementierung des ARIMA(2, 1, 1)-Modells in Python kann wie folgt durchgeführt werden:

 import pandas as pd from statsmodels.tsa.arima.model import ARIMA import matplotlib.pyplot as plt  # Daten laden (Beispiel: CSV-Datei) df = pd.read_csv('temperaturen.csv', parse_dates=['Datum'], index_col='Datum')  # ARIMA-Modell erstellen und anpassen model = ARIMA(df['Temperatur'], order=(2, 1, 1)) model_fit = model.fit()  # Modellergebnisse zusammenfassen print(model_fit.summary())  # Vorhersage für die nächsten 12 Monate forecast = model_fit.forecast(steps=12)  # Plotten der Originalzeitreihe und der Vorhersage plt.figure(figsize=(12, 6)) plt.plot(df['Temperatur'], label='Original Zeitreihe') plt.plot(forecast, label='Vorhersage', color='red') plt.title('ARIMA Vorhersage der monatlichen Durchschnittstemperaturen') plt.xlabel('Datum') plt.ylabel('Temperatur') plt.legend() plt.show() 

In diesem Code werden die folgenden Schritte ausgeführt:

  • Daten aus einer CSV-Datei laden.
  • Ein ARIMA-Modell mit den Parametern (2, 1, 1) erstellen.
  • Das Modell an die Zeitreihe anpassen.
  • Eine Zusammenfassung der Modellergebnisse anzeigen.
  • Vorhersagen für die nächsten 12 Monate erstellen.
  • Die Originalzeitreihe und die Vorhersagedaten plotten.

Aufgabe 2)

In dieser Aufgabe wirst Du ein Long Short-Term Memory (LSTM) Netz implementieren und seine Funktionsweise anhand eines Beispiels erläutern. LSTMs sind eine Art rekurrenter neuronaler Netze (RNNs), die entwickelt wurden, um das vanishing gradient Problem zu beheben. Sie bestehen aus Speicherzellen, die Informationen über viele Zeitschritte hinweg beibehalten können. Jede Speicherzelle besitzt drei Tore: das Eingangs-, das Ausgangs- und das Vergangenheitswert-Tor (input, output, forget gate).

Die Zustandsaktualisierung in einer LSTM-Speicherzelle erfolgt nach folgenden Gleichungen:

  • Vergangenheitswert-Tor: \( f_t = \text{sigmoid}(W_f \times [h_{t-1}, x_t] + b_f) \)
  • Eingabe-Tor: \( i_t = \text{sigmoid}(W_i \times [h_{t-1}, x_t] + b_i) \)
  • Neue Zellzustandsvorschläge: \( \tilde{C}_t = \text{tanh}(W_C \times [h_{t-1}, x_t] + b_C) \)
  • Zellzustand: \( C_t = f_t \times C_{t-1} + i_t \times \tilde{C}_t \)
  • Ausgabe-Gate: \( o_t = \text{sigmoid}(W_o \times [h_{t-1}, x_t] + b_o) \)
  • Aktueller Zellwert: \( h_t = o_t \times \text{tanh}(C_t) \)

a)

(a) Zeige, dass das Vergangenheitswert-Tor (forget gate) Informationen über viele Zeitschritte hinweg beibehalten kann, indem Du die Gleichung \( C_t = f_t \times C_{t-1} + i_t \times \tilde{C}_t \) für einen Zeitschritt \( t \) mehrfach anwendest. Erläutere, wie sich das Vergangenheitswert-Tor auf den Zellzustand \( C_t \) auswirkt.

Lösung:

Um zu zeigen, dass das Vergangenheitswert-Tor (forget gate) Informationen über viele Zeitschritte hinweg beibehalten kann, betrachten wir die Gleichung:

  • Zellzustand: \(\displaystyle C_t = f_t \times C_{t-1} + i_t \times \tilde{C}_t \)

Wir können diese Beziehung rekursiv für frühere Zeitschritte ausdrücken und die Information durch mehrere Zeitschritte zurückverfolgen:

    Für Zeitschritt t-1:

    • \[\displaystyle C_{t-1} = f_{t-1} \times C_{t-2} + i_{t-1} \times \tilde{C}_{t-1} \]

    Setzen wir \(C_{t-1}\) in \(C_t\) ein:

    • \[\displaystyle C_t = f_t \times (f_{t-1} \times C_{t-2} + i_{t-1} \times \tilde{C}_{t-1}) + i_t \times \tilde{C}_t \]

    Das ergibt:

    • \[\displaystyle C_t = f_t \times f_{t-1} \times C_{t-2} + f_t \times i_{t-1} \times \tilde{C}_{t-1} + i_t \times \tilde{C}_t \]

    Für einen früheren Zeitschritt t-2:

    • \[\displaystyle C_{t-2} = f_{t-2} \times C_{t-3} + i_{t-2} \times \tilde{C}_{t-2} \]

    Setzen wir \(C_{t-2}\) ein, erhält man:

    • \[\displaystyle C_t = f_t \times f_{t-1} \times (f_{t-2} \times C_{t-3} + i_{t-2} \times \tilde{C}_{t-2}) + f_t \times i_{t-1} \times \tilde{C}_{t-1} + i_t \times \tilde{C}_t \]

    Das ergibt:

    • \[\displaystyle C_t = f_t \times f_{t-1} \times f_{t-2} \times C_{t-3} + f_t \times f_{t-1} \times i_{t-2} \times \tilde{C}_{t-2} + f_t \times i_{t-1} \times \tilde{C}_{t-1} + i_t \times \tilde{C}_t \]

Dies kann über viele Zeitschritte fortgeführt werden. Allgemein resultiert:

  • \[\displaystyle C_t = \prod_{k=1}^{t} f_{t-k+1} \times C_0 + \sum_{k=1}^{t} \left( \prod_{j=1}^{k-1} f_{t-j+1} \times i_{t-k+1} \times \tilde{C}_{t-k+1} \right) \]

Diese Gleichung zeigt, dass der Zellzustand \(C_t\) Informationen aus dem frühen Zellzustand \(C_0\) über viele Zwischenstufen hinweg behalten kann. Da das Vergangenheitswert-Tor \(f_t\) für jede vergangene Zeitstufe einbezogen wird, steuert es effektiv die Menge der Informationen, die aus früheren Zeitschritten durch das Netz fließen:

  • Wenn \(f_t\) nahe bei 1 liegt, wird der Zustand fast vollständig in den nächsten Zeitschritt übertragen. Dies bedeutet, dass frühere Informationen weitgehend erhalten bleiben.
  • Wenn \(f_t\) nahe bei 0 liegt, werden frühere Informationen stark reduziert, und der Zellzustand wird durch neuere Informationen dominiert.

Somit ist das Vergangenheitswert-Tor (forget gate) entscheidend für die langfristige Speicherung und den Transfer von Informationen in LSTM-Zellen. Es ermöglicht der LSTM-Zelle, Informationen über eine lange Zeitspanne hinweg aufrechtzuerhalten, was effektiv dazu beiträgt, das Vanishing Gradient Problem zu lösen.

b)

(b) Implementiere ein einfaches LSTM in Python, das die oben beschriebenen Gleichungen verwendet. Schreibe eine Funktion lstm_cell, die die Zustände und Ausgaben für einen gegebenen Zeitschritt berechnet. Verwende dabei zufällig initialisierte Gewichte und Biases.

'import numpy as np def sigmoid(x):\t return 1 / (1 + np.exp(-x)) def tanh(x):\t return np.tanh(x) def lstm_cell(x_t, h_prev, C_prev, W_f, W_i, W_C, W_o, b_f, b_i, b_C, b_o):\t f_t = sigmoid(np.dot(W_f, np.concatenate((h_prev, x_t))) + b_f)\t i_t = sigmoid(np.dot(W_i, np.concatenate((h_prev, x_t))) + b_i)\t C_tilde_t = tanh(np.dot(W_C, np.concatenate((h_prev, x_t))) + b_C)\t C_t = f_t * C_prev + i_t * C_tilde_t\t o_t = sigmoid(np.dot(W_o, np.concatenate((h_prev, x_t))) + b_o)\t h_t = o_t * tanh(C_t)\t return h_t, C_t'

Lösung:

Um ein einfaches LSTM in Python zu implementieren, welches die beschriebenen Gleichungen verwendet, können wir die Funktion lstm_cell schreiben. Diese Funktion berechnet die Zustände und Ausgaben für einen gegebenen Zeitschritt unter Verwendung zufällig initialisierter Gewichte und Biases. Hier ist der vollständige Code:

import numpy as npdef sigmoid(x):    return 1 / (1 + np.exp(-x))def tanh(x):    return np.tanh(x)def lstm_cell(x_t, h_prev, C_prev, W_f, W_i, W_C, W_o, b_f, b_i, b_C, b_o):    # Berechnung des Vergangenheitswert-Tores (forget gate)    f_t = sigmoid(np.dot(W_f, np.concatenate((h_prev, x_t))) + b_f)        # Berechnung des Eingabe-Tores (input gate)    i_t = sigmoid(np.dot(W_i, np.concatenate((h_prev, x_t))) + b_i)        # Berechnung der neuen Zellzustandsvorschläge    C_tilde_t = tanh(np.dot(W_C, np.concatenate((h_prev, x_t))) + b_C)        # Berechnung des Zellzustandes    C_t = f_t * C_prev + i_t * C_tilde_t        # Berechnung des Ausgabe-Tores (output gate)    o_t = sigmoid(np.dot(W_o, np.concatenate((h_prev, x_t))) + b_o)        # Berechnung des aktuellen Zellwertes    h_t = o_t * tanh(C_t)        return h_t, C_t# Beispiel einer initialisierten LSTM-Zelleinput_size = 3hidden_size = 5# Zufällig initialisierte Gewichte und BiasesW_f = np.random.randn(hidden_size, hidden_size + input_size)W_i = np.random.randn(hidden_size, hidden_size + input_size)W_C = np.random.randn(hidden_size, hidden_size + input_size)W_o = np.random.randn(hidden_size, hidden_size + input_size)b_f = np.random.randn(hidden_size)b_i = np.random.randn(hidden_size)b_C = np.random.randn(hidden_size)b_o = np.random.randn(hidden_size)# Beispiel-Eingabenx_t = np.random.randn(input_size)h_prev = np.random.randn(hidden_size)C_prev = np.random.randn(hidden_size)# Berechnung des nächsten Zustandes und Ausgabeh_t, C_t = lstm_cell(x_t, h_prev, C_prev, W_f, W_i, W_C, W_o, b_f, b_i, b_C, b_o)print('h_t:', h_t)print('C_t:', C_t)

Erklärung der Komponenten:

  • sigmoid und tanh-Funktionen: Aktivierungsfunktionen, die innerhalb der LSTM-Zelle verwendet werden.
  • lstm_cell-Funktion: Berechnet die Zustände und Ausgaben für einen gegebenen Zeitschritt.
  • Zufällig initialisierte Gewichte und Biases: Mathematische Parameter, die die LSTM-Zelle definieren.
  • Beispiel-Eingaben: Zufällig generierte Daten für den Zeitschritt \(x_t\), den vorherigen Zustand \(h_{prev}\) und den vorherigen Zellzustand \(C_{prev}\).

Mit dieser Implementierung werden die Zustände und Ausgaben einer LSTM-Zelle für einen einzelnen Zeitschritt berechnet.

c)

(c) Betrachte die Auswirkungen der Wahl von Gewichten und Biases auf das Verhalten des LSTM. Führe ein kleines Experiment durch, bei dem Du die Gewichte \( W_f, W_i, W_o \) und die Biases \( b_f, b_i, b_o \) der einzelnen Tore variierst, und beobachte die Änderungen im Zellzustand \( C_t \) und den Zell-Ausgaben \( h_t \). Analysiere die Ergebnisse und erläutere, wie die anfänglichen Parameter die Funktionsweise des LSTMs beeinflussen.

Lösung:

Um die Auswirkungen der Wahl von Gewichten und Biases auf das Verhalten des LSTM zu betrachten, führen wir ein kleines Experiment durch. Wir werden die Gewichte \( W_f, W_i, W_o \) und die Biases \( b_f, b_i, b_o \) der einzelnen Tore variieren und beobachten, wie sich der Zellzustand \( C_t \) und die Zell-Ausgaben \( h_t \) ändern. Anschließend analysieren wir die Ergebnisse und erläutern, wie die anfänglichen Parameter die Funktionsweise des LSTMs beeinflussen.

Hier ist ein Beispielcode, der diese Variation durchführt:

import numpy as npdef sigmoid(x):    return 1 / (1 + np.exp(-x))def tanh(x):    return np.tanh(x)def lstm_cell(x_t, h_prev, C_prev, W_f, W_i, W_C, W_o, b_f, b_i, b_C, b_o):    # Berechnung des Vergangenheitswert-Tores (forget gate)    f_t = sigmoid(np.dot(W_f, np.concatenate((h_prev, x_t))) + b_f)    # Berechnung des Eingabe-Tores (input gate)    i_t = sigmoid(np.dot(W_i, np.concatenate((h_prev, x_t))) + b_i)    # Berechnung der neuen Zellzustandsvorschläge    C_tilde_t = tanh(np.dot(W_C, np.concatenate((h_prev, x_t))) + b_C)    # Berechnung des Zellzustandes    C_t = f_t * C_prev + i_t * C_tilde_t    # Berechnung des Ausgabe-Tores (output gate)    o_t = sigmoid(np.dot(W_o, np.concatenate((h_prev, x_t))) + b_o)    # Berechnung des aktuellen Zellwertes    h_t = o_t * tanh(C_t)    return h_t, C_t# Funktion zur Initialisierung der Gewichte und Biasesdef initialize_parameters(input_size, hidden_size):    W_f = np.random.randn(hidden_size, hidden_size + input_size)    W_i = np.random.randn(hidden_size, hidden_size + input_size)    W_C = np.random.randn(hidden_size, hidden_size + input_size)    W_o = np.random.randn(hidden_size, hidden_size + input_size)    b_f = np.random.randn(hidden_size)    b_i = np.random.randn(hidden_size)    b_C = np.random.randn(hidden_size)    b_o = np.random.randn(hidden_size)    return W_f, W_i, W_C, W_o, b_f, b_i, b_C, b_o# Beispiel-Eingabenx_t = np.random.randn(input_size)h_prev = np.random.randn(hidden_size)C_prev = np.random.randn(hidden_size)# Initialisieren der Parameterinput_size = 3hidden_size = 5W_f, W_i, W_C, W_o, b_f, b_i, b_C, b_o = initialize_parameters(input_size, hidden_size)# Experiment 1: Standardparameterh_t1, C_t1 = lstm_cell(x_t, h_prev, C_prev, W_f, W_i, W_C, W_o, b_f, b_i, b_C, b_o)# Experiment 2: Erhöhte Biases für die Vergangenheitswert-Tor (forget gate)b_f_exp = np.random.randn(hidden_size) + 2h_t2, C_t2 = lstm_cell(x_t, h_prev, C_prev, W_f, W_i, W_C, W_o, b_f_exp, b_i, b_C, b_o)# Experiment 3: Niedrigere Biases für das Eingabe-Tor (input gate)b_i_exp = np.random.randn(hidden_size) - 2h_t3, C_t3 = lstm_cell(x_t, h_prev, C_prev, W_f, W_i, W_C, W_o, b_f, b_i_exp, b_C, b_o)# Ergebnisse ausgebenprint('Experiment 1 - Standardparameter')print('h_t1:', h_t1)print('C_t1:', C_t1)print('Experiment 2 - Erhöhte Biases für das Vergangenheitswert-Tor (forget gate)')print('h_t2:', h_t2)print('C_t2:', C_t2)print('Experiment 3 - Niedrigere Biases für das Eingabe-Tor (input gate)')print('h_t3:', h_t3)print('C_t3:', C_t3)

Dieser Code führt drei verschiedene Experimente durch:

  • Experiment 1: Standardmäßig zufällig initialisierte Parameter für Gewichte und Biases.
  • Experiment 2: Erhöhte Biases für das Vergangenheitswert-Tor (forget gate).
  • Experiment 3: Niedrigere Biases für das Eingabe-Tor (input gate).

Die Ergebnisse der Experimente zeigen den Zellzustand \( C_t \) und die Zell-Ausgabe \( h_t \) für jedes Experiment. Wir können sehen, wie die Variationen der Biases die Funktionsweise der LSTM-Zelle beeinflussen:

  • Erhöhte Biases für das Vergangenheitswert-Tor (Experiment 2): Dies führt dazu, dass das Forget Gate häufiger aktiviert ist und daher weniger Informationen aus den vergangenen Zuständen gelöscht werden. Dadurch kann der Zellzustand \( C_t \) stärker von den vorherigen Zuständen beeinflusst werden.
  • Niedrigere Biases für das Eingabe-Tor (Experiment 3): In diesem Fall ist das Input Gate weniger häufig aktiviert, und daher werden weniger neue Informationen in den Zellzustand \( C_t \) aufgenommen. Dies kann dazu führen, dass der Zellzustand weniger stark von den neuen Zellzustandsvorschlägen beeinflusst wird.

Die anfänglichen Parameter, insbesondere die Wahl der Biases, haben einen signifikanten Einfluss auf die Funktionsweise des LSTMs, da sie bestimmen, wie die verschiedenen Tore der LSTM-Zelle aktiviert werden und wie der Informationsfluss durch die Zelle gesteuert wird.

Aufgabe 3)

Du bist ein Data Scientist in einem Unternehmen, das maschinelles Lernen auf Zeitreihendaten anwendet. Dein Ziel ist es, Support Vector Machines (SVMs) zu nutzen, um aus diesen Zeitreihendaten nützliche Klassifikations- und Regressionsmodelle zu erstellen. Du hast Zeitreihendaten, die in Vektoren mittels der Zeitfenstertechnik (Sliding Window) umgewandelt wurden. Die Daten sind jedoch nicht linear trennbar und benötigen daher den Kernel-Trick. Um die Modelle zu optimieren, nutzt du Lagrange-Multiplikatoren und wählst Parameter wie C und \(\gamma\) zur Feinabstimmung aus.

a)

Erkläre, wie Du den Kernel-Trick in einem SVM-Modell auf nichtlinear trennbare Zeitreihendaten anwendest. Erläutere die theoretische Grundlage des Kernel-Tricks mit der entsprechenden mathematischen Formulierung.

Lösung:

Anwendung des Kernel-Tricks in einem SVM-Modell auf nichtlinear trennbare Zeitreihendaten

Als Data Scientist bist Du verantwortlich für die Erstellung von Klassifikations- und Regressionsmodellen aus Zeitreihendaten mithilfe von Support Vector Machines (SVMs). Wenn die Zeitreihendaten mittels der Zeitfenstertechnik (Sliding Window) in Vektoren umgewandelt wurden und nicht linear trennbar sind, kommt der Kernel-Trick ins Spiel.

Theoretische Grundlage des Kernel-Tricks

Der Kernel-Trick ermöglicht es, die Daten aus dem ursprünglichen Merkmalsraum in einen höherdimensionalen Raum abzubilden, ohne die tatsächlichen Transformationen der Daten berechnen zu müssen. Dies geschieht durch die Verwendung von Kernel-Funktionen, die das innere Produkt von Datenpunkten in diesem höherdimensionalen Raum darstellen.

Die mathematische Formulierung des Kernel-Tricks kann in mehreren Schritten erklärt werden:

  • Erster Schritt: Definition des Kernels: Sei \(\textbf{x}_i\) und \(\textbf{x}_j\) zwei Datenpunkte im ursprünglichen Merkmalsraum. Ein Kernel \(k(\textbf{x}_i, \textbf{x}_j)\) berechnet das innere Produkt dieser Punkte im höherdimensionalen Raum:
k(\textbf{x}_i, \textbf{x}_j) = \phi(\textbf{x}_i) \cdot \phi(\textbf{x}_j)
  • Zweiter Schritt: Wahl des geeigneten Kernels: Je nach Art des Problems können verschiedene Kernel-Funktionen verwendet werden, darunter:
    • Lineare Kernel:
k(\textbf{x}_i, \textbf{x}_j) = \textbf{x}_i \cdot \textbf{x}_j
  • Polynomiale Kernel:
k(\textbf{x}_i, \textbf{x}_j) = (\textbf{x}_i \cdot \textbf{x}_j + c)^d
  • RBF (Radial Basis Function) Kernel:
k(\textbf{x}_i, \textbf{x}_j) = \exp(-\gamma \|\textbf{x}_i - \textbf{x}_j\|^2)
  • Sigmoid Kernel:
k(\textbf{x}_i, \textbf{x}_j) = \tanh(\alpha \textbf{x}_i \cdot \textbf{x}_j + c)
  • Dritter Schritt: Anpassen der Parameter: Die Parameter C (Regularisierungsparameter) und \(\gamma\) (im Falle des RBF-Kernels) müssen so gewählt werden, dass das Modell gut generalisiert. Dies erfolgt typischerweise durch Cross-Validation:
Cross-Validation: Ein Verfahren zur Beurteilung der Modellleistung, indem die Daten in Trainings- und Testsets aufgeteilt werden.
  • Optimierung mit Lagrange-Multiplikatoren: Ein weiterer wesentlicher Aspekt bei der Anwendung des Kernel-Tricks in SVM-Modellen ist die Optimierung mit Lagrange-Multiplikatoren, um die optimalen Hyperparameter zu finden.
  • Durch die Anwendung des Kernel-Tricks können die komplexen, nichtlinear trennbaren Zeitreihendaten effektiv mit einem SVM-Modell klassifiziert werden. Der Einsatz von Kernel-Funktionen ermöglicht es, verborgene Muster in den Daten zu erkennen, die im ursprünglichen Merkmalsraum nicht sichtbar wären.

b)

Implementiere ein SVM-Modell mit einer geeigneten Python-Bibliothek wie 'scikit-learn', das auf Zeitreihendaten anwendbar ist. Achte dabei auf die Auswahl und Optimierung der Parameter C und \(\gamma\). Verwende die Zeitfenstertechnik (Sliding Window), um die Zeitreihen in Vektoren zu konvertieren. Führe eine Hyperparameter-Optimierung durch und interpretiere die Ergebnisse.

Lösung:

Implementation eines SVM-Modells mit scikit-learn auf Zeitreihendaten

In dieser Aufgabe zeige ich Dir, wie Du ein SVM-Modell mit der Python-Bibliothek 'scikit-learn' implementierst, um es auf Zeitreihendaten anzuwenden. Dabei verwenden wir die Zeitfenstertechnik (Sliding Window), um die Zeitreihen in Vektoren zu konvertieren und optimieren die Parameter C und \( \gamma \).

Schritt 1: Installiere die notwendigen Bibliotheken

pip install numpy pandas scikit-learn

Schritt 2: Datenvorbereitung und Zeitfenstertechnik

Ein Beispiel mit pandas und numpy, um Zeitreihendaten mit der Sliding Window Technik in Vektoren zu konvertieren:

import numpy as npimport pandas as pdfrom sklearn.model_selection import train_test_split, GridSearchCVfrom sklearn.svm import SVCfrom sklearn.metrics import classification_report# Beispiel-Zeitreihendatendata = np.sin(np.linspace(0, 100, 500))window_size = 5# Sliding Window Funktiondef create_sliding_windows(data, window_size):    X, y = [], []    for i in range(len(data) - window_size):        X.append(data[i:i + window_size])        y.append(data[i + window_size])    return np.array(X), np.array(y)X, y = create_sliding_windows(data, window_size)# Aufteilung in Trainings- und TestdatenX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Schritt 3: SVM-Modell implementieren und Hyperparameter-Optimierung

# Parameterbereich für die Optimierungparam_grid = {    'C': [0.1, 1, 10, 100],    'gamma': [1, 0.1, 0.01, 0.001],    'kernel': ['rbf']}# SVM-Modellsvm = SVC()# GridSearchCV zur Hyperparameter-Optimierunggrid_search = GridSearchCV(svm, param_grid, refit=True, verbose=2, cv=5)# Training des Modellsgrid_search.fit(X_train, y_train)# Beste Parameterprint(f'Beste Parameter: {grid_search.best_params_}')# Vorhersageny_pred = grid_search.predict(X_test)# Ergebnisinterpretationprint(classification_report(y_test, y_pred))

Schritt 4: Ergebnisse interpretieren

Die Ausgabe von GridSearchCV zeigt die besten Parameter C und \( \gamma \). Anhand des classification_report kannst Du die Leistungsfähigkeit des Modells hinsichtlich Metriken wie Präzision, Recall und F1-Score bewerten.

Aufgabe 4)

Du hast eine Zeitreihe, die monatliche Durchschnittstemperaturen über mehrere Jahre hinweg darstellt. Um diese Zeitreihe für ein maschinelles Lernmodell vorzubereiten, entscheidest Du Dich, Lag-Features und differenzielle Features zu erstellen.

a)

Erzeuge Lag-Features bis zu einem Lag von 3 Monaten für die gegebene Zeitreihe. Beschreibe die resultierende Transformationsmatrix und erkläre, wie diese Lag-Features dem Modell helfen können, Zeitabhängigkeiten zu erkennen.

Lösung:

  • Erzeugen von Lag-Features:
Um Lag-Features bis zu einem Lag von 3 Monaten für die gegebene Zeitreihe zu erzeugen, fügen wir die Durchschnittstemperaturen der vorherigen Monate (bis zu 3 Monaten zurück) als neue Spalten in unsere Datenmatrix hinzu. Dies bedeutet, dass für jeden Monat in der Zeitreihe zusätzliche Datenpunkte zu früheren Monaten existieren werden.
import pandas as pddef create_lag_features(df, lag_num):    for lag in range(1, lag_num + 1):        df[f'Temperature_lag_{lag}'] = df['Temperature'].shift(lag)    return df# Angenommen df ist unser DataFrame, der die Zeitreihe mit einer Spalte 'Temperature' enthält# Angenommen df enthält auch eine Datetime-Index-Spalte für das Datumdf = create_lag_features(df, 3)print(df.head())
  • Resultierende Transformationsmatrix:
    • Die resultierende Transformationsmatrix enthält vier Spalten: 'Temperature', 'Temperature_lag_1', 'Temperature_lag_2' und 'Temperature_lag_3'.
    • Die Zeilen am Anfang (für die ersten drei Monate) haben fehlende Werte (NaNs) in den Lag-Features, da keine vorherigen Werte vorhanden sind, auf die verwiesen werden kann.
    Beispiel:
| Datum     | Temperature | Temperature_lag_1 | Temperature_lag_2 | Temperature_lag_3 ||-----------|-------------|-------------------|-------------------|-------------------|| 2021-01-01| 5.0         | NaN               | NaN               | NaN               || 2021-02-01| 6.0         | 5.0               | NaN               | NaN               || 2021-03-01| 7.0         | 6.0               | 5.0               | NaN               || 2021-04-01| 8.0         | 7.0               | 6.0               | 5.0               |
  • Wie Lag-Features dem Modell helfen können:
    • Erkennen von Mustern: Lag-Features helfen dem Modell, Muster und Trends in den Daten zu erkennen. Beispielsweise könnte das Modell lernen, dass die Temperatur in einem bestimmten Monat tendenziell höher oder niedriger ist, wenn die Temperatur in den vorhergehenden Monaten einen bestimmten Verlauf hatte.
    • Erkennung von Saisonalitäten: Indem frühere Werte in das Modell einbezogen werden, kann das Modell saisonale Schwankungen erkennen. Dies ist besonders wichtig bei Zeitreihen, die typischerweise saisonalen Einflüssen unterliegen, wie zum Beispiel monatliche Durchschnittstemperaturen.
    • Verbesserte Vorhersagegenauigkeit: Zeitempfindliche Muster, die aus den Lag-Features erkannt werden, können die Vorhersagegenauigkeit des Modells verbessern. Das Modell kann beispielsweise lernen, dass ein Anstieg der Temperatur in den letzten Monaten zu einem Anstieg in den kommenden Monaten führen könnte.

b)

Erstelle differenzielle Features für die gleiche Zeitreihe mit einer Differenzierung von 1 Monat und 12 Monaten ( um saisonale Muster zu erfassen). Zeige die entsprechenden Berechnungsformeln für die Differenzen. Beschreibe, wie diese Features dazu beitragen können, Trends und Saisonabhängigkeiten in der Zeitreihe zu mildern und die Stationarität der Daten zu unterstützen.

Lösung:

  • Erstellen von differenziellen Features:
Um differenzielle Features für die gegebene Zeitreihe zu erstellen, berechnen wir die Differenz der Durchschnittstemperaturen zwischen aufeinanderfolgenden Monaten (1-Monats-Differenz) und zwischen demselben Monat in aufeinanderfolgenden Jahren (12-Monats-Differenz). Diese Differenzen helfen dabei, Trends und saisonale Muster zu identifizieren.
import pandas as pddef create_differential_features(df):    df['1_month_diff'] = df['Temperature'].diff(1)    df['12_months_diff'] = df['Temperature'].diff(12)    return df# Angenommen df ist unser DataFrame, der die Zeitreihe mit einer Spalte 'Temperature' enthält und eine Datetime-Index-Spaltedf = create_differential_features(df)print(df.head(15))
  • Berechnungsformeln:
Die entsprechenden Berechnungsformeln zur Berechnung der Differenzen lauten:
  • 1-Monats-Differenz:

    Die Differenz der Temperatur zwischen dem aktuellen Monat und dem vorhergehenden Monat kann als\( \text{1-Monats-Differenz} = T_t - T_{t-1} \) berechnet werden, wobei \(T_t\) die Temperatur zum Zeitpunkt \( t \) ist.

  • 12-Monats-Differenz:
    • Die Differenz der Temperatur zwischen dem aktuellen Monat und demselben Monat im vorhergehenden Jahr kann als \( \text{12-Monats-Differenz} = T_t - T_{t-12} \) berechnet werden, wobei \(T_t\) die Temperatur zum Zeitpunkt \( t \) ist.

    • Beschreibung der transformierten Matrix:
      • Die resultierende Transformationsmatrix enthält drei Spalten: 'Temperature', '1_month_diff' und '12_month_diff'.
      Beispiel:
| Datum     | Temperature | 1_month_diff | 12_month_diff ||-----------|-------------|--------------|---------------|| 2021-01-01| 5.0         | NaN          | NaN           || 2021-02-01| 6.0         | 1.0          | NaN           || 2021-03-01| 7.0         | 1.0          | NaN           || 2021-04-01| 8.0         | 1.0          | NaN           || 2022-01-01| 5.5         | -2.5         | 0.5           || 2022-02-01| 6.5         | 1.0          | 0.5           || 2022-03-01| 7.5         | 1.0          | 0.5           || 2022-04-01| 8.5         | 1.0          | 0.5           |
  • Wie differenzielle Features dem Modell helfen können:
  • Trends und Saisonabhängigkeiten mildern: Durch die Betrachtung der Differenzen der Temperaturdaten über verschiedene Zeiträume können differenzielle Features langfristige Trends und saisonale Muster mildern. Dies hilft dem Maschinellen Lernmodell, besser auf kurzfristige Schwankungen zu reagieren, ohne von langfristigen Trends oder Saisonalitäten beeinflusst zu werden.
  • Stationarität der Daten: Differenzielle Features tragen zur Stationarität der Daten bei, indem sie z. B. saisonale Effekte entfernen. Stationäre Zeitreihen sind oft leichter zu modellieren, da ihre statistischen Eigenschaften über die Zeit hinweg konstant bleiben. Differenzieren kann insbesondere nützlich sein, wenn das Modell Annahmen benötigt, dass die Eingabedaten stationär sind.
  • Bessere Vorhersagequalität: Durch das Erfassen von Veränderungen in den Zeitreihendaten anstelle der Rohwerte können differenzielle Features dabei helfen, genaue und zeitlich sensiblere Vorhersagen zu treffen. Dies ist besonders nützlich bei Zeitreihen, die saisonale Schwankungen oder Trends aufweisen.
Sign Up

Melde dich kostenlos an, um Zugriff auf das vollständige Dokument zu erhalten

Mit unserer kostenlosen Lernplattform erhältst du Zugang zu Millionen von Dokumenten, Karteikarten und Unterlagen.

Kostenloses Konto erstellen

Du hast bereits ein Konto? Anmelden