ช่วงเวลาการทำนายรอบการคาดการณ์อนุกรมเวลา LSTM


14

มีวิธีการคำนวณช่วงเวลาการทำนาย (การแจกแจงความน่าจะเป็น) รอบการพยากรณ์อนุกรมเวลาจากเครือข่ายประสาท LSTM (หรือการเกิดขึ้นอีกครั้ง) หรือไม่?

ตัวอย่างเช่นฉันคาดการณ์ 10 ตัวอย่างในอนาคต (t + 1 ถึง t + 10) ตามตัวอย่างที่สังเกตได้ 10 รายการล่าสุด (t-9 ถึง t) ฉันคาดว่าการทำนายที่ t + 1 จะมากกว่านี้ แม่นยำกว่าการทำนายที่ t + 10 โดยปกติแล้วหนึ่งอาจวาดแถบข้อผิดพลาดรอบการทำนายเพื่อแสดงช่วงเวลา ด้วยโมเดล ARIMA (ภายใต้สมมติฐานของข้อผิดพลาดแบบกระจายทั่วไป) ฉันสามารถคำนวณช่วงการทำนาย (เช่น 95%) รอบค่าที่ทำนายแต่ละค่า ฉันสามารถคำนวณแบบเดียวกัน (หรือบางอย่างที่เกี่ยวข้องกับช่วงเวลาการทำนาย) จากแบบจำลอง LSTM ได้หรือไม่

ฉันทำงานกับ LSTM ใน Keras / Python ตามตัวอย่างจำนวนมากจากmachinelearningmastery.comซึ่งเป็นตัวอย่างโค้ดของฉัน (ด้านล่าง) ฉันกำลังพิจารณา reframing ปัญหาเป็นการจัดหมวดหมู่เป็นถังขยะแบบแยกเนื่องจากความเชื่อมั่นต่อชั้นเรียน แต่ดูเหมือนจะเป็นวิธีที่ไม่ดี

มีหัวข้อที่คล้ายกันสองสามข้อ (เช่นด้านล่าง) แต่ดูเหมือนว่าจะไม่มีอะไรแก้ไขปัญหาการทำนายช่วงเวลาจาก 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)

คำตอบ:


10

ตรงนี้เป็นไปไม่ได้ อย่างไรก็ตามหากคุณสร้างแบบจำลองในวิธีที่แตกต่างคุณจะได้รับช่วงความมั่นใจ คุณสามารถใช้วิธีการถดถอยแบบปกติแทนการประเมินการแจกแจงความน่าจะเป็นแบบต่อเนื่อง ด้วยการทำเช่นนี้ในทุกขั้นตอนคุณสามารถวางแผนการกระจายของคุณได้ วิธีในการทำเช่นนี้คือ Kernel Mixture Networks ( https://janvdvegt.github.io/2017/06/07/Kernel-Mixture-Networks.htmlการเปิดเผยบล็อกของฉัน) หรือ Density Mixture Networks ( http: //www.cedar .buffalo.edu / ~ srihari / CSE574 / Chap5 / Chap5.7-MixDensityNetworks.pdf ) ครั้งแรกที่ใช้เมล็ดเป็นฐานและประมาณการส่วนผสมเหนือเมล็ดเหล่านี้และอันที่สองประเมินการกระจายตัวของพารามิเตอร์รวมถึงพารามิเตอร์ของแต่ละส่วน การแจกแจง คุณใช้โอกาสในการบันทึกสำหรับฝึกอบรมโมเดล

ตัวเลือกอื่นสำหรับการสร้างแบบจำลองความไม่แน่นอนคือการใช้งานกลางคันระหว่างการฝึกอบรมและจากนั้นในระหว่างการอนุมาน คุณทำสิ่งนี้หลายครั้งและทุกครั้งที่คุณได้รับตัวอย่างจากด้านหลังของคุณ คุณไม่ได้รับการแจกแจงเพียงตัวอย่าง แต่มันเป็นวิธีที่ง่ายที่สุดในการติดตั้งและใช้งานได้ดีมาก

ในกรณีของคุณคุณต้องคิดเกี่ยวกับวิธีที่คุณสร้าง t + 2 ถึง t + 10 ขึ้นอยู่กับการตั้งค่าปัจจุบันของคุณคุณอาจต้องสุ่มตัวอย่างจากขั้นตอนก่อนหน้าและป้อนฟีดสำหรับขั้นตอนถัดไป นั่นไม่ได้ผลดีกับวิธีแรกหรือครั้งที่สอง หากคุณมี 10 เอาต์พุตต่อขั้นตอน (t + 1 ถึง t + 10) วิธีการเหล่านี้ทั้งหมดจะสะอาดกว่า แต่ใช้งานง่ายกว่าเล็กน้อย


2
การใช้เครือข่ายแบบผสมนั้นน่าสนใจฉันจะพยายามใช้มัน มีการวิจัยที่เป็นของแข็งเกี่ยวกับการใช้งานกลางคันได้ที่นี่: arxiv.org/abs/1709.01907และarxiv.org/abs/1506.02142
4Oh4

หมายเหตุสำหรับการออกกลางคันคุณสามารถคำนวณความแปรปรวนของการคาดการณ์ของการออกกลางคัน monte carlo และใช้เป็นปริมาณของความไม่แน่นอน
Charles Chow

นั่นเป็นความจริง @CharlesChow แต่นั่นเป็นวิธีที่ไม่ดีในการสร้างช่วงความมั่นใจในบริบทนี้ มันจะเป็นการดีกว่าถ้าจะเรียงลำดับค่าและใช้ปริมาณเนื่องจากการแจกแจงแบบเบ้ที่อาจเบ้มาก
Jan van der Vegt

เห็นด้วย @JanvanderVegt แต่คุณยังสามารถประมาณสถิติของการออกกลางคันของ MC ได้โดยไม่ต้องสมมติว่ามีการแจกแจงเอาท์พุทฉันหมายความว่าคุณสามารถใช้เปอร์เซ็นไทล์หรือ bootstrapping เพื่อสร้าง CI ของ MC dropout
Charles Chow

2

การคาดเดาแบบ Conformalเป็นคำที่น่าสนใจสำหรับคุณเพราะมันทำงานภายใต้เงื่อนไขหลายประการ - โดยเฉพาะอย่างยิ่งมันไม่จำเป็นต้องมีข้อผิดพลาดการกระจายแบบปกติและใช้ได้กับเกือบทุกรูปแบบการเรียนรู้ของเครื่อง

สองแนะนำที่ดีจะได้รับจาก สกอตต์ Locklinและเฮนริก Linusson


1

ฉันจะแยกความแตกต่างเล็กน้อยและยืนยันว่าช่วงความมั่นใจในการคำนวณในทางปฏิบัติมักจะไม่ใช่สิ่งที่มีค่าที่ต้องทำ เหตุผลก็คือมีข้อสมมติฐานมากมายที่คุณต้องทำเสมอ แม้กระทั่งการถดถอยเชิงเส้นที่ง่ายที่สุดคุณต้องมี

  • ความสัมพันธ์เชิงเส้น
  • กฎเกณฑ์หลายตัวแปร
  • ไม่มีความสัมพันธ์หลายระดับหรือน้อย
  • ไม่มีความสัมพันธ์อัตโนมัติ
  • Homoscedasticity

วิธีการปฏิบัติอื่น ๆ อีกมากมายคือการจำลองมอนติคาร์โล หากคุณรู้หรือเต็มใจที่จะตั้งสมมติฐานเกี่ยวกับการกระจายตัวของตัวแปรป้อนเข้าให้ลองสุ่มตัวอย่างทั้งหมดแล้วป้อนให้คุณ LSTM ตอนนี้คุณสามารถคำนวณ "ช่วงความมั่นใจ" ของคุณเชิงประจักษ์ได้แล้ว


1

ใช่คุณสามารถ. สิ่งเดียวที่คุณต้องเปลี่ยนคือฟังก์ชั่นการสูญเสีย ใช้ฟังก์ชั่นการสูญเสียที่ใช้ในการถดถอยเชิงปริมาณและรวมเข้าด้วยกัน นอกจากนี้คุณต้องการดูว่าคุณประเมินช่วงเวลาเหล่านั้นอย่างไร สำหรับสิ่งนั้นฉันจะใช้การวัด ICP, MIL และ RMIL

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.