Як передбачити майбутні значення часового горизонту за допомогою Кераса?


11

Я щойно створив цю нейронну мережу LSTM разом з Керасом

    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()(видалення нульових значень) залишається 100 рядків даних, я використовував 80 у навчанні та 20 у тесті.


Коли ви розбиваєте часовий ряд, скільки примірників у вас є?
JahKnows

Вибачте, сер, я вас не зрозумів, можете пояснити більше? дякую
Nbenz

Після реструктуризації ваших даних для проблеми прогнозування, скільки рядків прикладів у вас є?
JahKnows

Чи можете ви дати мені єдину часову послідовність балів, і я покажу вам, як робити прогнозування з ними.
JahKnows

Ви можете перевірити ще раз запитання, яке я відредагував, додавши приклад формату та форми даних. дякую
Nbenz

Відповіді:


5
Ця відповідь трохи піде в іншому напрямку, але я сподіваюся, що все-таки відповідає на ваше запитання. Він використовує ідею прогресивного прогнозу / прогнозування.

Оскільки ви використовуєте слово горизонт , я вважаю, що ви маєте на увазі, що ви хочете передбачити 10 днів у майбутньому на певному кроці часу. Є кілька способів зробити це. З такою проблемою часових рядів прийнято припускати, що лише певна історія впливатиме на наступні кілька часових кроків (нехтуючи сезонними наслідками).

Приклад словами:

Отже, у вашому випадку ви можете використовувати, наприклад, попередні 60 днів, і передбачити наступне 10. Беручи 100 прикладів для даних, це означає, що ви можете насправді робити (100 - 60 - 9) = 31прогнози, кожен прогноз на 10 кроків уперед (нам знадобляться ці 31 передбачений_блок пізніше). Зі 100 рядів ми втрачаємо перші 60, щоб підходити до першої моделі. З решти 40 рядків даних ми можемо передбачити на 10 кроків попереду (рядки 61-70), потім переносимо все це на один ряд далі і повторюємо. Останнє прогнозування 10 майбутніх очок буде для рядків 91-100. Після цього ми більше не можемо передбачити 10 кроків, тому зупиняємось - і тому нам доведеться відняти ці додаткові 9. [Звичайно, є шляхи продовження прогнозування використання всіх даних]

Приклад з тисячею слів:

Дозвольте намалювати малюнок; щоб пояснити ідею прогнозування зміщення вікон.

Для кожного набору поїзда (наприклад , від t=0до t=5червоного кольору - поїзди безліч 1), ви хочете , щоб передбачити наступні кроки часу H ( що відповідає г = 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) . Такі моделі можна легко побудувати за допомогою Python, використовуючи пакет statsmodels , який має гарну реалізацію .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.