【问题标题】:How to shape the input of a RNN with multiple features for each target?如何为每个目标塑造具有多个特征的 RNN 输入?
【发布时间】:2022-01-10 11:38:28
【问题描述】:

我正在尝试学习如何使用 RNN 进行时间序列预测,在我看到的所有示例中,他们使用一系列价格来预测以下价格。在示例中,每个目标 (Y_train[n]) 都与由最后 30 个价格/步骤 ([X_train[[n-1],[n-2]....,[n-30]) 组成的序列或矩阵相关联。

但是在现实世界中,要准确预测您需要的不仅仅是最后 30 个价格的序列,您还需要其他...我应该说功能吗?比如成交量的最后 30 个值或情绪指数的最后 30 个值。

所以我的问题是: 对于每个目标(最后 30 个价格和最后 30 个交易量值),如何使用两个序列来塑造 RNN 的输入?这是我使用的示例代码,只有 1 个序列用作参考:

import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout

# Dividing Dataset (Test and Train)
train_lim = int(len(df) * 2 / 3)
training_set = df[:train_lim][['Close']]
test_set = df[train_lim:][['Close']]

# Normalizing
sc = MinMaxScaler(feature_range=(0, 1))
training_set_scaled = sc.fit_transform(training_set)

# Shaping Input
X_train = []
y_train = []
X_test = []

for i in range(30, training_set_scaled.size):
    X_train.append(training_set_scaled[i - 30:i, 0])
    y_train.append(training_set_scaled[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)

for i in range(30, len(test_set)):
    X_test.append(test_set.iloc[i - 30:i, 0])
X_test = np.array(X_test)

# Adding extra dimension ???
X_train = np.reshape(X_train, [X_train.shape[0], X_train.shape[1], 1])
X_test = np.reshape(X_test, [X_test.shape[0], X_test.shape[1], 1])

regressor = Sequential()

# LSTM layer 1
regressor.add(LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], 1)))
regressor.add(Dropout(0.2))

# LSTM layer 2,3,4
regressor.add(LSTM(units=50, return_sequences=True))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units=50, return_sequences=True))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units=50, return_sequences=True))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units=50, return_sequences=True))
regressor.add(Dropout(0.2))

# LSTM layer 5
regressor.add(LSTM(units=50))
regressor.add(Dropout(0.2))

# Fully connected layer
regressor.add(Dense(units=1))

# Compiling the RNN
regressor.compile(optimizer='adam', loss='mean_squared_error')

# Fitting the RNN model
regressor.fit(X_train, y_train, epochs=120, batch_size=32)

我使用的数据框是带有日期时间索引的标准 OHLCV,因此它看起来像这样:

Datetime     Open         High      Low      Close     Volume
01/01/2021   102.42     103.33     100.57    101.23      1990
02/01/2021   101.23     105.22     99.45     100.11      1970
   ...         ...        ...       ...        ...        ...
 
01/12/2021   203.22     210.34     199.22    201.11      2600

【问题讨论】:

    标签: python tensorflow keras lstm recurrent-neural-network


    【解决方案1】:

    您可以遵循完全相同的过程,唯一的区别是具有输入序列的数组的最后一维的长度(X_trainX_test)将大于一(因为它将等于外部回归器的数量加一,其中加一来自目标的过去值也用作输入这一事实。

    import pandas as pd
    import numpy as np
    import yfinance as yf
    from sklearn.preprocessing import MinMaxScaler
    from keras.models import Sequential
    from keras.layers import Dense, LSTM, Dropout
    pd.options.mode.chained_assignment = None
    
    # define the target and features
    target = ['Close']
    features = ['Volume', 'High', 'Low']
    
    # download the data
    df = yf.download(tickers=['AAPL'], period='1y')
    df = df[features + target]
    
    # split the data
    split = int(df.shape[0] * 2 / 3)
    df_train = df.iloc[:split, :].copy()
    df_test = df.iloc[split:, :].copy()
    
    # scale the data
    target_scaler = MinMaxScaler().fit(df_train[target])
    df_train[target] = target_scaler.transform(df_train[target])
    df_test[target] = target_scaler.transform(df_test[target])
    
    features_scaler = MinMaxScaler().fit(df_train[features])
    df_train[features] = features_scaler.transform(df_train[features])
    df_test[features] = features_scaler.transform(df_test[features])
    
    # extract the input sequences and output values
    sequence_length = 30
    
    X_train, y_train = [], []
    
    for i in range(sequence_length, df_train.shape[0]):
        X_train.append(df_train[features + target].iloc[i - sequence_length: i])
        y_train.append(df_train[target].iloc[i])
    
    X_train, y_train = np.array(X_train), np.array(y_train)
    
    X_test, y_test = [], []
    
    for i in range(sequence_length, df_test.shape[0]):
        X_test.append(df_test[features + target].iloc[i - sequence_length: i])
        y_test.append(df_test[target].iloc[i])
    
    X_test, y_test = np.array(X_test), np.array(y_test)
    
    print(X_train.shape)
    # (138, 30, 4)
    
    print(X_test.shape)
    # (55, 30, 4)
    
    # build and train the model
    model = Sequential()
    model.add(LSTM(units=50, return_sequences=True, input_shape=X_train.shape[1:]))
    model.add(Dropout(0.2))
    model.add(LSTM(units=50, return_sequences=True))
    model.add(Dropout(0.2))
    model.add(LSTM(units=50, return_sequences=True))
    model.add(Dropout(0.2))
    model.add(LSTM(units=50, return_sequences=True))
    model.add(Dropout(0.2))
    model.add(LSTM(units=50, return_sequences=True))
    model.add(Dropout(0.2))
    model.add(LSTM(units=50))
    model.add(Dropout(0.2))
    model.add(Dense(units=1))
    
    model.compile(optimizer='adam', loss='mean_squared_error')
    
    model.fit(X_train, y_train, epochs=120, batch_size=32)
    
    model.evaluate(X_test, y_test)
    
    # generate the test set predictions
    y_pred = model.predict(X_test)
    y_pred = target_scaler.inverse_transform(y_pred)
    
    # plot the test set predictions
    df['Predicted Close'] = np.nan
    df['Predicted Close'].iloc[- y_pred.shape[0]:] = y_pred.flatten()
    df[['Close', 'Predicted Close']].plot()
    

    【讨论】:

    • 感谢您的回答,但是,我遇到以下错误“ValueError:具有形状 (171,1) 的不可广播输出操作数与广播形状 (171,2) 不匹配.我将功能更改为“ features = ['Volume', 'Close']”。
    • 如何预测 n 个未来值。例如。预测未来 30 天的收盘价?
    猜你喜欢
    • 1970-01-01
    • 2021-12-17
    • 2017-10-25
    • 1970-01-01
    • 2021-12-04
    • 2022-08-04
    • 2020-07-03
    • 2019-07-13
    • 1970-01-01
    相关资源
    最近更新 更多