Ein Finish-to-Finish-empirischer Austausch der mehrstufigen Quantilprognose mit Tensorflow, NeuralForecast und Zero-shot LLMs.

Bild vom Autor
  1. Kurze Einleitung
  2. Daten
  3. Erstellen Sie eine Spielzeugversion von Quantile Recurrent Forecaster
  4. Quantilprognose mit modernsten Modellen
  5. Zero-Shot-Quantilprognose mit LLMs
  6. Abschluss

Die Quantilprognose ist eine statistische Technik, mit der verschiedene Quantile (z. B. der Median oder das 90. Perzentil) der Verteilung einer Antwortvariable vorhergesagt werden. Dadurch erhalten Sie einen umfassenderen Überblick über mögliche zukünftige Ergebnisse. Im Gegensatz zur traditionellen Mittelwertprognose, bei der nur der Durchschnitt geschätzt wird, können wir mit der Quantilprognose die Spanne und Wahrscheinlichkeit verschiedener möglicher Ergebnisse verstehen.

Quantilprognosen sind für die Entscheidungsfindung in Kontexten mit asymmetrischen Verlustfunktionen oder unterschiedlichen Risikopräferenzen von entscheidender Bedeutung. Im Provide Chain Administration beispielsweise stellt die Vorhersage des 90. Perzentils der Nachfrage ausreichende Lagerbestände sicher, um Engpässe zu vermeiden, während die Vorhersage des 10. Perzentils dazu beiträgt, Überbestände und damit verbundene Kosten zu minimieren. Diese Methode ist besonders in Sektoren wie Finanzen, Meteorologie und Energie von Vorteil, in denen das Verständnis von Verteilungsextremen ebenso wichtig ist wie das Verständnis des Mittelwerts.

Sowohl die Quantilprognose als auch die konforme Vorhersage berücksichtigen Unsicherheiten, ihre Methoden unterscheiden sich jedoch erheblich. Die Quantilprognose modelliert direkt bestimmte Quantile der Antwortvariablen und bietet detaillierte Einblicke in ihre Verteilung. Im Gegensatz dazu ist die konforme Vorhersage eine modellunabhängige Technik, die Prognoseintervalle um Prognosen herum konstruiert und garantiert, dass der wahre Wert mit einer bestimmten Wahrscheinlichkeit innerhalb des Intervalls liegt. Die Quantilprognose liefert präzise Quantilschätzungen, während die konforme Vorhersage breitere Intervallsicherheit bietet.

Die Implementierung von Quantilprognosen kann die Entscheidungsfindung deutlich verbessern, indem sie ein fundiertes Verständnis zukünftiger Unsicherheiten vermittelt. Mit diesem Ansatz können Unternehmen Strategien an unterschiedliche Risikostufen anpassen, die Ressourcenzuweisung optimieren und die Betriebseffizienz verbessern. Durch die Erfassung einer umfassenden Bandbreite potenzieller Ergebnisse ermöglicht die Quantilprognose Unternehmen, fundierte, datengesteuerte Entscheidungen zu treffen, wodurch Risiken gemindert und die Gesamtleistung verbessert werden.

Um die Arbeit zu demonstrieren, habe ich die Daten des M4-Wettbewerbs als Beispiel gewählt. Die Daten sind unter CC0: Gemeinfrei Lizenz, auf die zugegriffen werden kann Hier. Die Daten können auch über das Paket datasetsforecast geladen werden:

# Set up the bundle
pip set up datasetsforecast
# Load Information
df, *_ = M4.load('./knowledge', group='Weekly')
# Randomly choose three objects
df = df(df('unique_id').isin(('W96', 'W100', 'W99')))
# Outline the beginning date (for instance, "1970-01-04")
start_date = pd.to_datetime("1970-01-04")
# Convert 'ds' to precise week dates
df('ds') = start_date + pd.to_timedelta(df('ds') - 1, unit='W')
# Show the DataFrame
df.head()
Bild vom Autor

Die Originaldaten enthalten über 300 einzigartige Zeitreihen. Zur Veranschaulichung habe ich zufällig drei Zeitreihen ausgewählt: W96, W99 und W100, da sie alle dieselbe historische Länge haben. Der ursprüngliche Zeitstempel ist als Ganzzahl maskiert (d. h. 1–2296), ich habe ihn manuell wieder in das normale Datumsformat konvertiert, wobei das erste Datum der 4. Januar 1970 ist. Die folgende Abbildung ist eine Vorschau von W99:

Bild vom Autor

Lassen Sie uns zunächst einen Quantil-Prognostiker von Grund auf neu erstellen, um zu verstehen, wie die Zieldaten durch die Pipeline fließen und wie die Prognosen generiert werden. Ich habe die Idee aus dem Papier übernommen Ein wiederkehrender Multi-Horizon-Quantil-Prognostiker von Wen et al. Die Autoren schlugen ein Multi-Horizon Quantile Recurrent Neural Community (MQ-RNN)-Framework vor, das Sequence-to-Sequence Neural Networks, Quantile Regression und Direct Multi-Horizon Forecasting für eine genaue und robuste mehrstufige Zeitreihenprognose kombiniert. Durch die Nutzung der Ausdruckskraft neuronaler Netzwerke, der nichtparametrischen Natur der Quantile Regression und eines neuartigen Trainingsschemas namens Forking-Sequences kann das Modell mit wechselnder Saisonalität, bekannten zukünftigen Ereignissen und Kaltstartsituationen in groß angelegten Prognoseanwendungen effektiv umgehen.

Wir können in diesem kurzen Weblog nicht alles reproduzieren, aber wir können versuchen, einen Teil davon zu replizieren, indem wir das TensorFlow-Paket als Demo verwenden. Wenn Sie an der Implementierung des Dokuments interessiert sind, gibt es ein laufendes Projekt, das Sie nutzen können: MQRNN.

Lassen Sie uns zunächst das erforderliche Paket laden und einige globale Parameter definieren. Wir werden das LSTM-Modell als Kern verwenden und müssen die Daten vorab verarbeiten, um die gleitenden Fenster vor der Anpassung zu erhalten. Die Eingabeform ist auf (104, 1) eingestellt, was bedeutet, dass wir für jedes Trainingsfenster Daten aus zwei Jahren verwenden. In dieser exemplarischen Vorgehensweise werden wir uns nur ein 80-%-Konfidenzintervall mit dem Median als Punktprognose ansehen, was bedeutet, dass die Quantile = (0,1, 0,5, 0,9) sind. Wir werden die letzten 12 Wochen als Testdatensatz verwenden, sodass die Ausgabeschritte oder der Horizont gleich 12 sind und das Lower-off-Date „2013–10–13“ ist.

# Set up the bundle
pip set up tensorflow

# Load the bundle
from sklearn.preprocessing import StandardScaler
from datetime import datetime
from tensorflow.keras.fashions import Mannequin
from tensorflow.keras.layers import Enter, LSTM, Dense, concatenate, Layer

# Outline International Parameters
input_shape = (104, 1)
quantiles = (0.1, 0.9)
output_steps = 12
cut_off_date = '2013-10-13'
tf.random.set_seed(20240710)

Als Nächstes konvertieren wir die Daten in gleitende Fenster, was die gewünschte Eingabeform für RNN-basierte Modelle ist:

# Preprocess The Information
def preprocess_data(df, window_size = 104, forecast_horizon = 12):
# Make sure the dataframe is sorted by merchandise and date

df = df.sort_values(by=('unique_id', 'ds'))
# Listing to carry processed knowledge for every merchandise
X, y, unique_id, ds = (), (), (), ()
# Normalizer
scaler = StandardScaler()
# Iterate by every merchandise
for key, group in df.groupby('unique_id'):
demand = group('y').values.reshape(-1, 1)
scaled_demand = scaler.fit_transform(demand)
dates = group('ds').values
# Create sequences (sliding window strategy)
for i in vary(len(scaled_demand) - window_size - forecast_horizon + 1):
X.append(scaled_demand(i:i+window_size))
y.append(scaled_demand(i+window_size:i+window_size+forecast_horizon).flatten())
unique_id.append(key)
ds.append(dates(i+window_size:i+window_size+forecast_horizon))
X = np.array(X)
y = np.array(y)
return X, y, unique_id, ds, scaler

Dann teilen wir die Daten in Prepare, Val und Check auf:

# Break up Information
def split_data(X, y, unique_id, ds, cut_off_date):
cut_off_date = pd.to_datetime(cut_off_date)
val_start_date = cut_off_date - pd.Timedelta(weeks=12)
train_idx = (i for i, date in enumerate(ds) if date(0) < val_start_date)
val_idx = (i for i, date in enumerate(ds) if val_start_date <= date(0) < cut_off_date)
test_idx = (i for i, date in enumerate(ds) if date(0) >= cut_off_date)

X_train, y_train = X(train_idx), y(train_idx)
X_val, y_val = X(val_idx), y(val_idx)
X_test, y_test = X(test_idx), y(test_idx)

train_unique_id = (unique_id(i) for i in train_idx)
train_ds = (ds(i) for i in train_idx)
val_unique_id = (unique_id(i) for i in val_idx)
val_ds = (ds(i) for i in val_idx)
test_unique_id = (unique_id(i) for i in test_idx)
test_ds = (ds(i) for i in test_idx)

return X_train, y_train, X_val, y_val, X_test, y_test, train_unique_id, train_ds, val_unique_id, val_ds, test_unique_id, test_ds

Die Autoren des MQRNN nutzten sowohl den horizontspezifischen lokalen Kontext, der für die zeitliche Wahrnehmung und Saisonalitätszuordnung wesentlich ist, als auch den horizontunabhängigen globalen Kontext, um zeitunabhängige Informationen zu erfassen und so die Stabilität des Lernens und die Glätte der generierten Prognosen zu verbessern. Um ein Modell zu erstellen, das die Arbeit des MQRNN in etwa reproduziert, müssen wir eine Quantilverlustfunktion schreiben und Ebenen hinzufügen, die den lokalen und globalen Kontext erfassen. Ich habe eine Aufmerksamkeitsebene hinzugefügt, um Ihnen zu zeigen, wie der Aufmerksamkeitsmechanismus in einen solchen Prozess einbezogen werden kann:

# Consideration Layer
class Consideration(Layer):
def __init__(self, models):
tremendous(Consideration, self).__init__()
self.W1 = Dense(models)
self.W2 = Dense(models)
self.V = Dense(1)
def name(self, question, values):
hidden_with_time_axis = tf.expand_dims(question, 1)
rating = self.V(tf.nn.tanh(self.W1(values) + self.W2(hidden_with_time_axis)))
attention_weights = tf.nn.softmax(rating, axis=1)
context_vector = attention_weights * values
context_vector = tf.reduce_sum(context_vector, axis=1)
return context_vector, attention_weights

# Quantile Loss Perform
def quantile_loss(q, y_true, y_pred):
e = y_true - y_pred
return tf.reduce_mean(tf.most(q*e, (q-1)*e))

def combined_quantile_loss(quantiles, y_true, y_pred, output_steps):
losses = (quantile_loss(q, y_true, y_pred(:, i*output_steps:(i+1)*output_steps)) for i, q in enumerate(quantiles))
return tf.reduce_mean(losses)

# Mannequin structure
def create_model(input_shape, quantiles, output_steps):
inputs = Enter(form=input_shape)
lstm1 = LSTM(256, return_sequences=True)(inputs)
lstm_out, state_h, state_c = LSTM(256, return_sequences=True, return_state=True)(lstm1)
context_vector, attention_weights = Consideration(256)(state_h, lstm_out)
global_context = Dense(100, activation = 'relu')(context_vector)
forecasts = ()
for q in quantiles:
local_context = concatenate((global_context, context_vector))
forecast = Dense(output_steps, activation = 'linear')(local_context)
forecasts.append(forecast)
outputs = concatenate(forecasts, axis=1)
mannequin = Mannequin(inputs, outputs)
mannequin.compile(optimizer='adam', loss=lambda y, f: combined_quantile_loss(quantiles, y, f, output_steps))
return mannequin

Hier sind die dargestellten Prognoseergebnisse:

Wir haben außerdem den SMAPE für jeden Artikel sowie die prozentuale Abdeckung des Intervalls (wie viel tatsächlich durch das Intervall abgedeckt wurde) ausgewertet. Die Ergebnisse sind wie folgt:

Diese Spielzeugversion kann als gute Grundlage für den Einstieg in die Quantilprognose dienen. Das verteilte Coaching ist für dieses Setup nicht konfiguriert und die Modellarchitektur ist nicht für Prognosen im großen Maßstab optimiert. Daher kann es zu Geschwindigkeitsproblemen kommen. Im nächsten Abschnitt werden wir uns ein Paket ansehen, mit dem Sie Quantilprognosen mit den fortschrittlichsten Deep-Studying-Modellen erstellen können.

Der neuronale Prognose Das Paket ist eine hervorragende Python-Bibliothek, mit der Sie die meisten SOTA-Deep-Neural-Community-Modelle für Zeitreihenprognosen wie PatchTST, NBEATs, NHITS, TimeMixer usw. mit einfacher Implementierung verwenden können. In diesem Abschnitt werde ich verwenden PatchTST als Beispiel, um Ihnen zu zeigen, wie Sie eine Quantilsprognose durchführen.

Laden Sie zunächst die erforderlichen Module und definieren Sie die Parameter für PatchTST. Die Feinabstimmung des Modells erfordert einige empirische Erfahrung und ist projektabhängig. Wenn Sie an den potenziell optimalen Parametern für Ihre Daten interessiert sind, können Sie sich die Automodule von Neuralforecast ansehen. Sie ermöglichen Ihnen die Verwendung von Ray zur Feinabstimmung der Hyperparameter. Und es ist ziemlich effizient! Das Neuralforecast-Paket enthält eine große Auswahl an Modellen, die auf unterschiedlichen Sampling-Ansätzen basieren. Die Modelle mit dem Base_Window-Ansatz ermöglichen Ihnen die Verwendung von MQLoss oder HuberMQLoss, wobei Sie die gesuchten Quantilniveaus angeben können. In dieser Arbeit habe ich HuberMQLoss ausgewählt, da es gegenüber Ausreißern robuster ist.

# Set up the bundle
pip set up neuralforecast

# Load the bundle
from neuralforecast.core import NeuralForecast
from neuralforecast.fashions import PatchTST
from neuralforecast.losses.pytorch import HuberMQLoss, MQLoss

# Outline Parameters for PatchTST
PARAMS = {'input_size': 104,
'h': output_steps,
'max_steps': 6000,
'encoder_layers': 4,
'start_padding_enabled': False,
'learning_rate': 1e-4,
'patch_len': 52, # Size of every patch
'hidden_size': 256, # Dimension of the hidden layers
'n_heads': 4, # Variety of consideration heads
'res_attention': True,
'dropout': 0.1, # Dropout fee
'activation': 'gelu', # Activation perform
'dropout': 0.1,
'attn_dropout': 0.1,
'fc_dropout': 0.1,
'random_seed': 20240710,
'loss': HuberMQLoss(quantiles=(0.1, 0.5, 0.9)),
'scaler_type': 'normal',
'early_stop_patience_steps': 10}

# Get Coaching Information
train_df = df(df.ds<cut_off_date)

# Match and predict with PatchTST
fashions = (PatchTST(**PARAMS))
nf = NeuralForecast(fashions=fashions, freq='W')
nf.match(df=train_df, val_size=12)
Y_hat_df = nf.predict().reset_index()

Hier sind die aufgezeichneten Prognosen:

Hier sind die Kennzahlen:

In der Demo können Sie sehen, wie einfach sich das Modell implementieren lässt und wie sich die Leistung des Modells verbessert hat. Wenn Sie sich jedoch fragen, ob es einfachere Ansätze für diese Aufgabe gibt, lautet die Antwort JA. Im nächsten Abschnitt werden wir uns ein T5-basiertes Modell ansehen, mit dem Sie Zero-Shot-Quantilprognosen durchführen können.

Wir beobachten einen Pattern, bei dem die Weiterentwicklung der NLP auch die Grenzen der Zeitreihenprognose weiter verschieben wird, da die Vorhersage des nächsten Wortes ein synthetischer Prozess zur Vorhersage des Werts des nächsten Zeitraums ist. Angesichts der schnellen Entwicklung großer Sprachmodelle (LLMs) für generative Aufgaben haben Forscher auch damit begonnen, sich mit der Vorschulung eines großen Modells anhand von Millionen von Zeitreihen zu befassen, damit Benutzer Zero-Shot-Prognosen erstellen können.

Bevor wir jedoch ein Gleichheitszeichen zwischen den LLMs und den Zero-Shot-Time-Sequence-Aufgaben ziehen, müssen wir eine Frage beantworten: Was ist der Unterschied zwischen dem Trainieren eines Sprachmodells und dem Trainieren eines Zeitreihenmodells? Es wären „Token aus einem endlichen Wörterbuch gegenüber Werten aus einem unbegrenzten“. Amazon hat kürzlich ein Projekt namens Chronos das die Herausforderung intestine bewältigte und das große Zeitreihenmodell möglich machte. Wie die Autoren erklärten: „Chronos tokenisiert Zeitreihen in diskrete Bins durch einfache Skalierung und Quantisierung realer Werte. Auf diese Weise können wir handelsübliche Sprachmodelle auf dieser ‚Sprache der Zeitreihen‘ trainieren, ohne die Modellarchitektur zu ändern.“ Das Originalpapier finden Sie hier Hier.

Chronos ist derzeit in mehreren Versionen erhältlich. Es kann über das Autogluon-API mit nur wenigen Codezeilen.

# Get Coaching Information and Remodel
train_df = df(df.ds<cut_off_date)
train_df_chronos = TimeSeriesDataFrame(train_df.rename(columns={'ds': 'timestamp', 'unique_id': 'item_id', 'y': 'goal'}))

# Zero-shot forecast with Chronos
predictor = TimeSeriesPredictor(prediction_length=output_steps, freq='W', quantile_levels = (0.1, 0.9)).match(
train_df_chronos, presets="chronos_base",
random_seed = 20240710
)
Y_hat_df_chronos = predictor.predict(train_df_chronos).reset_index().rename(columns={'imply': 'Chronos',
'0.1': 'P10',
'0.9': 'P90',
'timestamp': 'ds',
'item_id': 'unique_id'})

Hier sind die aufgezeichneten Prognosen:

Hier sind die Kennzahlen:

Wie Sie sehen, hat Chronos im Vergleich zu PatchTST eine sehr gute Leistung gezeigt. Dies bedeutet jedoch nicht, dass es PatchTST übertroffen hat, da Chronos sehr wahrscheinlich mit M4-Daten trainiert wurde. In ihrem ursprünglichen Artikel haben die Autoren ihr Modell auch anhand der Datensätze bewertet, mit denen das Modell nicht trainiert wurde, und Chronos lieferte dennoch sehr vergleichbare Ergebnisse wie die SOTA-Modelle.

Derzeit werden viele weitere große Zeitreihenmodelle entwickelt. Eines davon heißt ZeitGPT das von NIXTLA entwickelt wurde. Die Erfindung dieser Artwork von Modell hat die Prognoseaufgabe nicht nur einfacher, zuverlässiger und konsistenter gemacht, sondern ist auch ein guter Ausgangspunkt, um vernünftige Schätzungen für Zeitreihen mit begrenzten historischen Daten anzustellen.

Von der Entwicklung einer Spielzeugversion eines rekurrierenden Quantil-Prognostikers bis hin zur Nutzung modernster Modelle und Zero-Shot-Massive-Language-Modelle hat dieser Weblog die Leistungsfähigkeit und Vielseitigkeit der Quantil-Prognose demonstriert. Durch die Einbindung von Modellen wie TensorFlows LSTM, NeuralForecasts PatchTST und Amazons Chronos können wir genaue, robuste und rechnerisch effiziente mehrstufige Zeitreihenprognosen erstellen. Quantil-Prognosen verbessern nicht nur die Entscheidungsfindung, indem sie ein differenziertes Verständnis zukünftiger Unsicherheiten bieten, sondern ermöglichen es Unternehmen auch, Strategien und Ressourcenzuweisung zu optimieren. Die Fortschritte bei neuronalen Netzwerken und Zero-Shot-Lernmodellen verschieben die Grenzen weiter und machen die Quantil-Prognose zu einem zentralen Werkzeug in modernen datengesteuerten Branchen.

Hinweis: Alle Bilder, Zahlen und Tabellen werden vom Autor selbst erstellt. Den kompletten Code finden Sie hier: Quantilprognose.

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert