Gibt es eine Methode zur Berechnung des Vorhersageintervalls (Wahrscheinlichkeitsverteilung) um eine Zeitreihenprognose aus einem LSTM-Netzwerk (oder einem anderen wiederkehrenden neuronalen Netzwerk)?
Angenommen, ich prognostiziere 10 Stichproben für die Zukunft (t + 1 bis t + 10), basierend auf den letzten 10 beobachteten Stichproben (t-9 bis t), würde ich erwarten, dass die Vorhersage bei t + 1 höher ist genauer als die Vorhersage bei t + 10. Normalerweise kann man Fehlerbalken um die Vorhersage ziehen, um das Intervall anzuzeigen. Mit einem ARIMA-Modell (unter der Annahme normalverteilter Fehler) kann ich ein Vorhersageintervall (z. B. 95%) um jeden vorhergesagten Wert berechnen. Kann ich dasselbe (oder etwas, das sich auf das Vorhersageintervall bezieht) aus einem LSTM-Modell berechnen?
Ich habe mit LSTMs in Keras / Python gearbeitet und dabei viele Beispiele von machinelearningmastery.com befolgt , auf denen mein Beispielcode (unten) basiert. Ich denke darüber nach, das Problem als Klassifizierung in diskrete Klassen umzuformulieren, da dies ein Vertrauen pro Klasse erzeugt, aber das scheint eine schlechte Lösung zu sein.
Es gibt einige ähnliche Themen (wie das folgende), aber nichts scheint das Problem der Vorhersageintervalle von LSTM (oder anderen) neuronalen Netzen direkt anzusprechen:
/stats/25055/how-to-calculate-the-confidence-interval-for-time-series-prediction
Zeitreihenvorhersage mit ARIMA vs LSTM
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from math import sin
from matplotlib import pyplot
import numpy as np
# Build an LSTM network and train
def fit_lstm(X, y, batch_size, nb_epoch, neurons):
X = X.reshape(X.shape[0], 1, X.shape[1]) # add in another dimension to the X data
y = y.reshape(y.shape[0], y.shape[1]) # but don't add it to the y, as Dense has to be 1d?
model = Sequential()
model.add(LSTM(neurons, batch_input_shape=(batch_size, X.shape[1], X.shape[2]), stateful=True))
model.add(Dense(y.shape[1]))
model.compile(loss='mean_squared_error', optimizer='adam')
for i in range(nb_epoch):
model.fit(X, y, epochs=1, batch_size=batch_size, verbose=1, shuffle=False)
model.reset_states()
return model
# Configuration
n = 5000 # total size of dataset
SLIDING_WINDOW_LENGTH = 30
SLIDING_WINDOW_STEP_SIZE = 1
batch_size = 10
test_size = 0.1 # fraction of dataset to hold back for testing
nb_epochs = 100 # for training
neurons = 8 # LSTM layer complexity
# create dataset
#raw_values = [sin(i/2) for i in range(n)] # simple sine wave
raw_values = [sin(i/2)+sin(i/6)+sin(i/36)+np.random.uniform(-1,1) for i in range(n)] # double sine with noise
#raw_values = [(i%4) for i in range(n)] # saw tooth
all_data = np.array(raw_values).reshape(-1,1) # make into array, add anothe dimension for sci-kit compatibility
# data is segmented using a sliding window mechanism
all_data_windowed = [np.transpose(all_data[idx:idx+SLIDING_WINDOW_LENGTH]) for idx in np.arange(0,len(all_data)-SLIDING_WINDOW_LENGTH, SLIDING_WINDOW_STEP_SIZE)]
all_data_windowed = np.concatenate(all_data_windowed, axis=0).astype(np.float32)
# split data into train and test-sets
# round datasets down to a multiple of the batch size
test_length = int(round((len(all_data_windowed) * test_size) / batch_size) * batch_size)
train, test = all_data_windowed[:-test_length,:], all_data_windowed[-test_length:,:]
train_length = int(np.floor(train.shape[0] / batch_size)*batch_size)
train = train[:train_length,...]
half_size = int(SLIDING_WINDOW_LENGTH/2) # split the examples half-half, to forecast the second half
X_train, y_train = train[:,:half_size], train[:,half_size:]
X_test, y_test = test[:,:half_size], test[:,half_size:]
# fit the model
lstm_model = fit_lstm(X_train, y_train, batch_size=batch_size, nb_epoch=nb_epochs, neurons=neurons)
# forecast the entire training dataset to build up state for forecasting
X_train_reshaped = X_train.reshape(X_train.shape[0], 1, X_train.shape[1])
lstm_model.predict(X_train_reshaped, batch_size=batch_size)
# predict from test dataset
X_test_reshaped = X_test.reshape(X_test.shape[0], 1, X_test.shape[1])
yhat = lstm_model.predict(X_test_reshaped, batch_size=batch_size)
#%% Plot prediction vs actual
x_axis_input = range(half_size)
x_axis_output = [x_axis_input[-1]] + list(half_size+np.array(range(half_size)))
fig = pyplot.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x_axis_input,np.zeros_like(x_axis_input), 'r-')
line2, = ax.plot(x_axis_output,np.zeros_like(x_axis_output), 'o-')
line3, = ax.plot(x_axis_output,np.zeros_like(x_axis_output), 'g-')
ax.set_xlim(np.min(x_axis_input),np.max(x_axis_output))
ax.set_ylim(-4,4)
pyplot.legend(('Input','Actual','Predicted'),loc='upper left')
pyplot.show()
# update plot in a loop
for idx in range(y_test.shape[0]):
sample_input = X_test[idx]
sample_truth = [sample_input[-1]] + list(y_test[idx]) # join lists
sample_predicted = [sample_input[-1]] + list(yhat[idx])
line1.set_ydata(sample_input)
line2.set_ydata(sample_truth)
line3.set_ydata(sample_predicted)
fig.canvas.draw()
fig.canvas.flush_events()
pyplot.pause(.25)
Konforme Vorhersage als Modewort könnte für Sie interessant sein, da sie unter vielen Bedingungen funktioniert - insbesondere benötigt sie keinen normalverteilten Fehler und funktioniert für fast jedes Modell des maschinellen Lernens.
Zwei nette Einführungen geben Scott Locklin und Henrik Linusson .
quelle
Ich werde ein wenig auseinander gehen und argumentieren, dass das Berechnungskonfidenzintervall in der Praxis normalerweise keine wertvolle Sache ist. Der Grund ist, dass Sie immer eine ganze Reihe von Annahmen treffen müssen. Selbst für die einfachste lineare Regression müssen Sie haben
Ein viel pragmatischerer Ansatz ist die Durchführung einer Monte-Carlo-Simulation. Wenn Sie bereits wissen oder bereit sind, Annahmen über die Verteilung Ihrer Eingabevariablen zu treffen, nehmen Sie eine ganze Reihe von Stichproben und geben Sie sie an LSTM weiter. Jetzt können Sie Ihr "Konfidenzintervall" empirisch berechnen.
quelle
Ja, du kannst. Das einzige, was Sie ändern müssen, ist die Verlustfunktion. Implementieren Sie die in der Quantilregression verwendete Verlustfunktion und integrieren Sie sie. Außerdem möchten Sie einen Blick darauf werfen, wie Sie diese Intervalle bewerten. Dafür würde ich ICP-, MIL- und RMIL-Metriken verwenden.
quelle