LSTM時系列予測の予測間隔


13

LSTM(または他のリカレント)ニューラルネットワークからの時系列予測の周りの予測間隔(確率分布)を計算する方法はありますか?

たとえば、最後の10個の観測されたサンプル(t-9からt)に基づいて、未来(t + 1からt + 10)までの10個のサンプルを予測しているとすると、t + 1での予測はより大きくなると予想します。 t + 10での予測よりも正確です。通常、予測の周りにエラーバーを描画して、間隔を示します。ARIMAモデル(正規分布エラーを想定)を使用すると、各予測値の周囲の予測間隔(95%など)を計算できます。LSTMモデルから同じもの(または予測間隔に関連するもの)を計算できますか?

私はより多くの例以下、Keras / PythonでLSTMsで作業されていmachinelearningmastery.com私のサンプルコードは、(下記)に基づいているから、。私は問題を離散的なビンへの分類として再構成することを検討しています。それはクラスごとの信頼を生み出しますが、それは不十分な解決策のようです。

同様のトピックがいくつかありますが(以下など)、LSTM(または実際に他の)ニューラルネットワークからの予測間隔の問題に直接対処するものはないようです。

/stats/25055/how-to-calculate-the-confidence-interval-for-time-series-prediction

ARIMAと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)

回答:


9

直接、これは不可能です。ただし、別の方法でモデル化すると、信頼区間を取得できます。通常の回帰の代わりに、連続確率分布を推定することでアプローチできます。すべてのステップでこれを行うと、分布をプロットできます。これを行う方法は、カーネル混合ネットワーク(https://janvdvegt.github.io/2017/06/07/Kernel-Mixture-Networks.html、開示、私のブログ)または密度混合ネットワーク(http://www.cedar)です。 .buffalo.edu /〜srihari / CSE574 / Chap5 / Chap5.7-MixDensityNetworks.pdf)、最初はカーネルをベースとして使用し、これらのカーネルの混合を推定し、2番目はそれぞれのパラメーターを含む分布の混合を推定します分布。モデルのトレーニングには対数尤度を使用します。

不確実性をモデル化するための別のオプションは、トレーニング中にドロップアウトを使用し、次に推論中にも使用することです。あなたはこれを複数回行い、毎回あなたの後方からサンプルを得る。ディストリビューションを取得するのではなく、サンプルのみを取得しますが、実装が最も簡単で、非常にうまく機能します。

あなたの場合、t + 2からt + 10までを生成する方法について考える必要があります。現在の設定によっては、前のタイムステップからサンプリングして、次のタイムステップに供給する必要がある場合があります。これは、最初のアプローチでも、2番目のアプローチでもうまく機能しません。タイムステップごとに10個の出力がある場合(t + 1からt + 10まで)、これらのアプローチはすべてよりクリーンですが、直感的にはやや劣ります。


1
混合ネットワークの使用は興味深いので、それを実装してみます。ここにドロップアウトの使用に関する確かな調査があります:arxiv.org/abs/1709.01907およびarxiv.org/abs/1506.02142
4Oh4

ドロップアウトに関するメモ、モンテカルロドロップアウトの予測の分散を実際に計算し、それを不確実性の定量化として使用できます
Charles Chow

それは本当の@CharlesChowですが、これはこのコンテキストで信頼区間を構築するための悪い方法です。分布が非常に歪んでいる可能性があるため、値を並べ替えて変位値を使用する方が適切です。
Jan van der Vegt

@JanvanderVegtに同意しますが、出力分布を仮定せずにMCドロップアウトの統計を推定できます。つまり、パーセンタイルまたはブートストラップを使用して、MCドロップアウトのCIを構築することもできます
Charles Chow

2

流行語としてのコンフォーマル予測は、多くの条件下で機能するため、興味深いかもしれません。特に、通常の分散エラーを必要とせず、ほとんどすべての機械学習モデルで機能します。

Scott LocklinHenrik Linussonの 2つの素晴らしい紹介文があり ます。


1

少し発散して、計算の信頼区間は実際には実際には価値のあることではないと主張します。その理由は、常にあなたがしなければならない仮定の全体がたくさんあるからです。最も単純な線形回帰であっても、

  • 線形関係。
  • 多変量正規性。
  • 多重共線性がないか、ほとんどない。
  • 自己相関はありません。
  • ホモセダスティシティ。

より実用的なアプローチは、モンテカルロシミュレーションを行うことです。入力変数の分布についてすでに知っているか、または仮定する意思がある場合は、大量のサンプルを取り、それをLSTMに送ります。これで、「信頼区間」を経験的に計算できます。


1

はい、できます。変更する必要があるのは、損失関数だけです。分位回帰で使用される損失関数を実装し、それを統合します。また、これらの間隔をどのように評価するかを確認する必要があります。そのために、ICP、MIL、およびRMILメトリックを使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.