Khoảng dự đoán xung quanh dự báo chuỗi thời gian LSTM


12

Có phương pháp nào để tính khoảng dự đoán (phân phối xác suất) xung quanh dự báo chuỗi thời gian từ mạng thần kinh LSTM (hoặc tái phát khác) không?

Ví dụ, tôi dự đoán 10 mẫu trong tương lai (t + 1 đến t + 10), dựa trên 10 mẫu được quan sát gần đây nhất (t-9 đến t), tôi dự đoán dự đoán ở t + 1 sẽ nhiều hơn chính xác hơn dự đoán ở t + 10. Thông thường, người ta có thể vẽ các thanh lỗi xung quanh dự đoán để hiển thị khoảng thời gian. Với mô hình ARIMA (theo giả định về các lỗi được phân phối thông thường), tôi có thể tính toán khoảng dự đoán (ví dụ 95%) xung quanh mỗi giá trị dự đoán. Tôi có thể tính toán tương tự, (hoặc một cái gì đó liên quan đến khoảng dự đoán) từ mô hình LSTM không?

Tôi đã làm việc với các LSTM trong Keras / Python, sau rất nhiều ví dụ từ machinelearningmastery.com , từ đó mã ví dụ của tôi (bên dưới) dựa trên. Tôi đang xem xét việc sắp xếp lại vấn đề như phân loại thành các thùng rời rạc, vì điều đó tạo ra sự tự tin cho mỗi lớp, nhưng đó có vẻ là một giải pháp kém.

Có một vài chủ đề tương tự (chẳng hạn như bên dưới), nhưng dường như không có gì trực tiếp giải quyết vấn đề về các khoảng dự đoán từ các mạng thần kinh LSTM (hoặc thực sự khác):

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

Dự đoán chuỗi thời gian bằng 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)

Câu trả lời:


8

Trực tiếp, điều này là không thể. Tuy nhiên, nếu bạn mô hình hóa nó theo một cách khác, bạn có thể có được khoảng tin cậy. Bạn có thể thay vì một phương pháp hồi quy thông thường như ước tính phân phối xác suất liên tục. Bằng cách làm điều này cho mỗi bước bạn có thể vẽ sơ đồ phân phối của mình. Các cách để làm điều này là Mạng hỗn hợp hạt nhân ( https://janvdvegt.github.io/2017/06/07/Kernel-Mixture-Networks.html , tiết lộ, blog của tôi) hoặc Mạng mật độ hỗn hợp ( http: //www.cedar .buffalo.edu / ~ srihari / CSE574 / Chap5 / Chap5.7-MixD mậtNetworks.pdf ), lần đầu tiên sử dụng hạt nhân làm cơ sở và ước tính hỗn hợp trên các hạt nhân này và lần thứ hai ước tính hỗn hợp các phân phối, bao gồm cả các tham số của từng phân phối các bản phân phối. Bạn sử dụng khả năng đăng nhập để đào tạo mô hình.

Một lựa chọn khác để mô hình hóa sự không chắc chắn là sử dụng bỏ học trong quá trình đào tạo và sau đó trong quá trình suy luận. Bạn làm điều này nhiều lần và mỗi lần bạn nhận được một mẫu từ hậu thế của bạn. Bạn không nhận được phân phối, chỉ các mẫu, nhưng nó dễ thực hiện nhất và nó hoạt động rất tốt.

Trong trường hợp của bạn, bạn phải suy nghĩ về cách bạn tạo t + 2 lên đến t + 10. Tùy thuộc vào thiết lập hiện tại của bạn, bạn có thể phải lấy mẫu từ bước thời gian trước đó và cung cấp cho bước tiếp theo. Điều đó không hiệu quả lắm với cách tiếp cận thứ nhất, cũng như với cách tiếp cận thứ hai. Nếu bạn có 10 đầu ra cho mỗi bước thời gian (t + 1 lên đến t + 10) thì tất cả các cách tiếp cận này sạch sẽ hơn nhưng ít trực quan hơn một chút.


1
Sử dụng mạng hỗn hợp là thú vị, tôi sẽ cố gắng thực hiện điều đó. Có một số nghiên cứu vững chắc về việc sử dụng bỏ học ở đây: arxiv.org/abs/1709.01907arxiv.org/abs/1506.02142
4Oh4

Một lưu ý cho người bỏ học, bạn thực sự có thể tính toán phương sai dự đoán của người bỏ học monte carlo và sử dụng nó như là định lượng của sự không chắc chắn
Charles Chow

Đó là sự thật @CharlesChow nhưng đó là một cách kém để xây dựng khoảng tin cậy trong bối cảnh này. Sẽ tốt hơn nếu sắp xếp các giá trị và sử dụng các lượng tử do phân phối có khả năng rất sai lệch.
Jan van der Vegt

Đồng ý @JanvanderVegt, nhưng bạn vẫn có thể ước tính số liệu thống kê MC bỏ học mà không cần giả định phân phối đầu ra, ý tôi là bạn cũng có thể sử dụng phần trăm hoặc bootstrapping để xây dựng CI của MC bỏ học
Charles Chow

2

Dự đoán phù hợp như một từ buzz có thể thú vị đối với bạn vì nó hoạt động trong nhiều điều kiện - đặc biệt là nó không cần lỗi phân phối bình thường và nó hoạt động cho hầu hết mọi mô hình học máy.

Hai lời giới thiệu hay được đưa ra bởi Scott LocklinHenrik Linusson .


1

Tôi sẽ phân kỳ một chút và lập luận rằng khoảng tin cậy tính toán trong thực tế thường không phải là một điều có giá trị để làm. Lý do là luôn có cả đống giả định bạn cần đưa ra. Ngay cả đối với hồi quy tuyến tính đơn giản nhất, bạn cần phải có

  • Mối quan hệ tuyến tính.
  • Tính đa biến.
  • Không có hoặc ít đa hình.
  • Không có tương quan tự động.
  • Tính đồng nhất.

Một cách tiếp cận thực tế hơn nhiều là thực hiện mô phỏng Monte Carlo. Nếu bạn đã biết hoặc sẵn sàng đưa ra giả định xung quanh việc phân phối các biến đầu vào của mình, hãy lấy cả đống mẫu và đưa nó cho LSTM của bạn, bây giờ bạn có thể tính toán theo "khoảng tin cậy" theo kinh nghiệm.


1

Vâng, bạn có thể. Điều duy nhất bạn cần thay đổi là chức năng mất. Thực hiện hàm mất được sử dụng trong hồi quy lượng tử và tích hợp nó. Ngoài ra, bạn muốn xem cách bạn đánh giá các khoảng đó. Vì thế, tôi sẽ sử dụng các số liệu ICP, MIL và RMIL.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.