LSTM (또는 다른 반복적) 신경망으로부터 시계열 예측에 대한 예측 간격 (확률 분포)을 계산하는 방법이 있습니까?
예를 들어, 마지막 10 개의 관측 된 샘플 (t-9 ~ t)을 기반으로 미래에 10 개의 샘플 (t + 1 ~ t + 10)을 예측한다고 가정하면, t + 1에서의 예측은 더 많을 것으로 예상됩니다 t + 10의 예측보다 정확합니다. 일반적으로 예측 주위에 오차 막대를 그려 간격을 표시 할 수 있습니다. ARIMA 모델 (정규 분포 오차 가정)을 사용하여 각 예측 값 주변의 예측 간격 (예 : 95 %)을 계산할 수 있습니다. LSTM 모델에서 동일하거나 예측 간격과 관련된 것을 계산할 수 있습니까?
나는 Keras / Python에서 LSTM과 함께 일하고 있으며, machinelearningmastery.com의 많은 예제를 따르며 , 여기에서 내 예제 코드 (아래)가 기반으로합니다. 클래스별로 신뢰를 생성하지만 솔루션이 좋지 않은 것처럼 분리 된 빈으로 분류하는 것으로 문제를 재구성하는 것을 고려하고 있습니다.
몇 가지 유사한 주제가 있지만 (아래와 같이) LSTM (또는 실제로 다른) 신경망의 예측 간격 문제를 직접 해결하는 것은 없습니다.
/stats/25055/how-to-calculate-the-confidence-interval-for-time-series-prediction
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)