วิธีการคาดการณ์ค่าในอนาคตของขอบฟ้าเวลาด้วย Keras


11

ฉันเพิ่งสร้างเครือข่ายประสาท LSTMนี้ด้วย Keras

    import numpy as np
    import pandas as pd 
    from sklearn import preprocessing
    from keras.layers.core import Dense, Dropout, Activation
    from keras.activations import linear
    from keras.layers.recurrent import LSTM
    from keras.models import Sequential
    from matplotlib import pyplot

    #read and prepare data from datafile
    data_file_name = "DailyDemand.csv"
    data_csv = pd.read_csv(data_file_name, delimiter = ';',header=None, usecols=[1,2,3,4,5])
    yt = data_csv[1:]
    data = yt
    data.columns = ['MoyenneTransactHier', 'MaxTransaction', 'MinTransaction','CountTransaction','Demand']
    # print (data.head(10))
    pd.options.display.float_format = '{:,.0f}'.format
    data = data.dropna ()
    y=data['Demand'].astype(int)
    cols=['MoyenneTransactHier', 'MaxTransaction', 'MinTransaction','CountTransaction']
    x=data[cols].astype(int)

    #scaling data
    scaler_x = preprocessing.MinMaxScaler(feature_range =(-1, 1))
    x = np.array(x).reshape ((len(x),4 ))
    x = scaler_x.fit_transform(x)
    scaler_y = preprocessing.MinMaxScaler(feature_range =(-1, 1))
    y = np.array(y).reshape ((len(y), 1))
    y = scaler_y.fit_transform(y)
    print("longeur de y",len(y))
    # Split train and test data
    train_end = 80
    x_train=x[0: train_end ,]
    x_test=x[train_end +1: ,]
    y_train=y[0: train_end]
    y_test=y[train_end +1:] 
    x_train=x_train.reshape(x_train.shape +(1,))
    x_test=x_test.reshape(x_test.shape + (1,))

    print("Data well prepared")
    print ('x_train shape ', x_train.shape)
    print ('y_train', y_train.shape)

    #Design the model - LSTM Network
    seed = 2016
    np.random.seed(seed)
    fit1 = Sequential ()
    fit1.add(LSTM(
        output_dim = 4,
        activation='tanh',
        input_shape =(4, 1)))
    fit1.add(Dense(output_dim =1))
    fit1.add(Activation(linear))
    #rmsprop or sgd
    batchsize = 1
    fit1.compile(loss="mean_squared_error",optimizer="rmsprop")
    #train the model
    fit1.fit(x_train , y_train , batch_size = batchsize, nb_epoch =20, shuffle=True)

    print(fit1.summary ())

    #Model error
    score_train = fit1.evaluate(x_train ,y_train ,batch_size =batchsize)
    score_test = fit1.evaluate(x_test , y_test ,batch_size =batchsize)
    print("in  train  MSE = ",round(score_train,4))
    print("in test  MSE = ",round(score_test ,4))

    #Make prediction
    pred1=fit1.predict(x_test)
    pred1 = scaler_y.inverse_transform(np.array(pred1).reshape ((len(pred1), 1)))
    real_test = scaler_y.inverse_transform(np.array(y_test).reshape ((len(y_test), 1))).astype(int)

    #save prediction
    testData = pd.DataFrame(real_test)
    preddData = pd.DataFrame(pred1)
    dataF = pd.concat([testData,preddData], axis=1)
    dataF.columns =['Real demand','Predicted Demand']
    dataF.to_csv('Demandprediction.csv')

    pyplot.plot(pred1, label='Forecast')
    pyplot.plot(real_test,label='Actual')
    pyplot.legend()
    pyplot.show()

จากนั้นจะสร้างผลลัพธ์นี้: การทำนายผลการทดสอบ

หลังจากสร้างและฝึกอบรมแบบจำลองที่ดีเกี่ยวกับข้อมูลในอดีตฉันไม่รู้ว่าฉันจะสร้างการทำนายค่าในอนาคตได้อย่างไร เช่นความต้องการของ 10 วันถัดไป ข้อมูลเป็นรายวัน

นี่เป็นตัวอย่างของการจัดรูปแบบข้อมูล

หมายเหตุ: นี่เป็นตัวอย่างของรูปทรงของข้อมูลสีเขียวคือฉลากและสีเหลืองเป็นคุณสมบัติ
หลังจากdropna()(ลบค่า Null) ยังคงอยู่ 100 แถวข้อมูลฉันใช้ 80 ในการฝึกอบรมและ 20 ในการทดสอบ


เมื่อคุณทำลายอนุกรมเวลาของคุณคุณมีกี่ครั้ง?
JahKnows

ขอโทษครับผมไม่มีคุณช่วยอธิบายเพิ่มเติมหน่อยได้ไหม? ขอบคุณ
Nbenz

หลังจากปรับโครงสร้างข้อมูลของคุณสำหรับปัญหาการพยากรณ์แล้วคุณมีตัวอย่างกี่บรรทัด
JahKnows

คุณช่วยบอกลำดับของคะแนนในคราวเดียวให้ฉันได้ไหมและฉันจะแสดงวิธีการพยากรณ์กับพวกเขา
JahKnows

คุณสามารถตรวจสอบคำถามที่ฉันแก้ไขอีกครั้งโดยเพิ่มตัวอย่างของรูปแบบข้อมูลและรูปร่าง ขอบคุณ
Nbenz

คำตอบ:


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

เนื่องจากคุณใช้คำว่าขอบฟ้าฉันจะถือว่าคุณหมายความว่าคุณต้องการคาดการณ์ 10 วันในอนาคตในช่วงเวลาที่กำหนด มีสองสามวิธีในการทำเช่นนี้ ด้วยปัญหาอนุกรมเวลาแบบนี้มันเป็นเรื่องธรรมดาที่จะทำการสันนิษฐานว่ามีเพียงประวัติศาสตร์ที่แน่นอนเท่านั้นที่จะมีอิทธิพลต่อขั้นตอนต่อไปในไม่กี่ขั้นตอนถัดไป

ตัวอย่างในคำพูด:

ดังนั้นในกรณีของคุณคุณอาจใช้เช่น 60 วันก่อนหน้านี้และทำนาย 10 ถัดไปการใช้ข้อมูล 100 แถวของคุณเป็นตัวอย่างซึ่งหมายความว่าคุณสามารถ(100 - 60 - 9) = 31คาดการณ์ได้จริงแต่ละการคาดการณ์ล่วงหน้า 10 ขั้นตอนล่วงหน้า 31 predictive_blocks ในภายหลัง) จาก 100 แถวเราเสีย 60 แรกเพื่อให้พอดีกับรุ่นแรก จากข้อมูล 40 แถวที่เหลือเราสามารถคาดการณ์ล่วงหน้า 10 ขั้นตอน (แถวที่ 61-70) จากนั้นเราเลื่อนทั้งแถวไปอีกหนึ่งแถวแล้วทำซ้ำ การทำนายสุดท้ายของ 10 คะแนนในอนาคตจะเป็นแถวที่ 91-100 หลังจากนั้นเราไม่สามารถทำนายได้ 10 ขั้นตอนอีกต่อไปดังนั้นเราจึงหยุด - และนี่คือสาเหตุที่เราต้องลบส่วนที่เกินออกไป 9 [มีวิธีการทำนายอย่างต่อเนื่องเพื่อใช้ข้อมูลทั้งหมด]

ตัวอย่างที่มีคำพันคำ:

ขอผมวาดภาพหน่อย เพื่อช่วยอธิบายแนวคิดของการคาดคะเนหน้าต่างแบบขยับ

สำหรับชุดรถไฟแต่ละชุด (เช่นจากt=0ถึงเป็นชุดt=5สีแดง - รถไฟ 1) คุณต้องการทำนายขั้นตอนเวลา H ต่อไปนี้ (ตรงกับ t = 6 ในชุดทดสอบสีส้ม 1) H=1ในการนี้ขอบฟ้าของคุณเป็นเพียงหนึ่งคือ

ร่างพื้นฐานของการคาดการณ์ที่ไม่อยู่ในกรอบ

จากสิ่งที่ฉันเข้าใจคุณต้องการที่จะคาดการณ์ 10 H=10วันถัดไปซึ่งหมายความว่าคุณต้อง

เพื่อลองกับตัวอย่างของคุณฉันคิดว่าคุณจะต้องทำการเปลี่ยนแปลงสองครั้ง

เปลี่ยน # 1

รูปร่างของชุดรถไฟและชุดทดสอบของคุณจะต้องตรงกับขอบฟ้าใหม่ แต่ละตัวอย่างของแบบจำลองอินพุตของคุณ ( x_trainและx_testสามารถอยู่เหมือนเดิมได้อย่างไรก็ตามแต่ละตัวอย่างในชุดทดสอบของคุณจะต้องมีH=10ค่าถัดไปของฉลากไม่ใช่เพียงค่าเดียว

นี่เป็นตัวอย่างคร่าวๆว่าคุณจะทำสิ่งนี้อย่างไร:

# Define our horizon
H = 10

# Create data split, using values from my example above
window_size = 60
num_pred_blocks = 31    # as computed above

# Loop over the train and test samples to create the sliding window sets
x_train = []
y_train = []
for i in range(num_pred_blocks):
    x_train_block = x_train[i:(i + window_size)]    # 31 blocks of 60 * num-columns
    x_train.append(x_train_block)
    y_train_block = y_train[(i + window_size):(i + window_size + H)]    # 31 blocks of 10 * 1
    y_train.append(y_train_block)

เนื่องจากคุณทำการทดสอบนอกตัวอย่างการคาดการณ์ของคุณจึงน่าสนใจที่จะวิเคราะห์ เมื่อทำงานแล้วคุณสามารถสร้างชุดข้อมูลการทดสอบที่เทียบเท่ากับข้อมูลใหม่ที่คุณกล่าวถึง

โดยไม่ทราบว่าข้อมูลของคุณดีเกินไปฉันไม่รู้ว่าคุณควรทำนายค่า y ของแถวเดียวกันกับอินพุตหรือแถวต่อไปนี้หรือไม่ นอกจากนี้ขึ้นอยู่กับข้อมูลของคุณคุณอาจรวมถึงค่าที่ผ่านมาของyในแต่ละx_trainช่วงตึก ในกรณีนี้คุณเพียงแค่ต้องการสลับxสำหรับตารางทั้งหมดเช่นที่data[cols]new_cols = ['Demand'] + cols

เปลี่ยน # 2

คุณจะต้องทำให้แบบจำลองสะท้อนเส้นขอบฟ้านี้โดยบังคับให้เป็นHค่าที่ส่งออก

นี่คือตัวอย่างของวิธีการระบุรุ่น:

# Define our horizon
H = 10

# Create the model using the parameterised horizon
fit1 = Sequential ()
fit1.add(LSTM(output_dim = 4, activation='tanh', input_shape =(4, 1)))
fit1.add(Dense(output_dim=30, activation='sigmoid')
fit1.add(Dense(output_dim=H))    # our horizon is produced!

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

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

หากคุณไม่เพียงแค่ทำสิ่งนี้เพื่อเรียนรู้เกี่ยวกับ LSTM ฯลฯ แนวทางการปฏิบัติอื่น ๆ อาจดูเป็นแบบอนุกรมเวลาที่ง่ายกว่าเช่นแบบจำลองARIMA (ไม่ต้องถูกข่มขู่ด้วยชื่อที่ซับซ้อน - มันง่ายกว่า LSTM มาก) . รุ่นดังกล่าวสามารถสร้างได้ง่ายมากกับงูหลามใช้แพคเกจ statsmodelsซึ่งมีการดำเนินงานที่ดี

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