当前位置:   article > 正文

【Python时序预测系列】基于LSTM实现多变量时间序列预测(案例+源码)_lstm多变量时序预测

lstm多变量时序预测

这是我的第229篇原创文章。

一、问题

       单站点多变量单步预测问题----基于LSTM实现多变量时间序列预测股票价格。

二、实现过程

2.1 读取数据集

  1. df=pd.read_csv("train.csv", parse_dates=["Date"], index_col=[0])
  2. print(df.shape)
  3. print(df.head())

data:

图片

2.2 划分数据集

  1. # 拆分数据集为训练集和测试集
  2. test_split=round(len(df)*0.20)
  3. df_for_training=df[:-test_split]
  4. df_for_testing=df[-test_split:]
  5. # 绘制训练集和测试集的折线图
  6. plt.figure(figsize=(10, 6))
  7. plt.plot(train_data, label='Training Data')
  8. plt.plot(test_data, label='Testing Data')
  9. plt.xlabel('Year')
  10. plt.ylabel('Passenger Count')
  11. plt.title('International Airline Passengers - Training and Testing Data')
  12. plt.legend()
  13. plt.show()

共5203条数据,8:2划分:训练集4162,测试集1041。

训练集和测试集:

图片

2.3 归一化

  1. # 将数据归一化到 0~1 范围
  2. scaler = MinMaxScaler(feature_range=(0,1))
  3. df_for_training_scaled = scaler.fit_transform(df_for_training)
  4. df_for_testing_scaled=scaler.transform(df_for_testing)

2.4 构造LSTM数据集(时序-->监督学习)

  1. def createXY(dataset,n_past):
  2. pass
  3. window_size = 30
  4. trainX,trainY=createXY(df_for_training_scaled,window_size)
  5. testX,testY=createXY(df_for_testing_scaled,window_size)
  6. print(trainY[0])
  7. print(trainY[0])
  8. # 将数据集转换为 LSTM 模型所需的形状(样本数,时间步长,特征数)
  9. trainX = np.reshape(trainX, (trainX.shape[0], window_size, 5))
  10. testX = np.reshape(testX, (testX.shape[0], window_size, 5))
  11. print("trainX Shape-- ",trainX.shape)
  12. print("trainY Shape-- ",trainY.shape)
  13. print("testX Shape-- ",testX.shape)
  14. print("testY Shape-- ",testY.shape)

滑动窗口30:

图片

前30天的数据,即30行5列(特征列),预测第31天的第1列(目标列)

trainX[0]是前30天的数据,一个30行5列的数组

图片

trainY[0]是第31天的第一列的值

图片

训练集:经过滑动窗口构造的数据集,新的训练集数据数量(4132)比原始训练集(4162)少一个滑动窗口数量(30)。因此,实际训练值只有4132条,是训练的31-4162的部分。

    【1-30】5列-----【31】第一列

    【2-31】5列-----【32】第一列

        ...

    【4131-4160】5列-----【4161】第一列

    【4132-4161】5列-----【4162】第一列

    X_train:(4132,30,5)

    Y_train:(4132,1)

测试集:经过滑动窗口构造的数据集,新的测试集数据数量(1011)比原始训测试集(1041)少一个滑动窗口数量(30)。因此,实际预测值只有1011个,是预测的4193-5203的部分,如果想预测4163-4192的部分,可以取训练集的最后30个数进行预测。

    【4163-4192】5列-----【4193】第一列

    【4164-4163】5列-----【4194】第一列

        ...

    【5172-5201】5列-----【5202】第一列

    【5173-5202】5列-----【5203】第一列

    X_test:(1011,30,5)

    Y_test:(1011,1)

2.5 建立模拟合模型

  1. from keras.wrappers.scikit_learn import KerasRegressor
  2. from sklearn.model_selection import GridSearchCV
  3. def build_model(optimizer):
  4. grid_model = Sequential()
  5. grid_model.add(LSTM(50,return_sequences=True,input_shape=(30,5)))
  6. grid_model.add(LSTM(50))
  7. grid_model.add(Dropout(0.2))
  8. grid_model.add(Dense(1))
  9. grid_model.compile(loss = 'mse',optimizer = optimizer)
  10. return grid_model
  11. grid_model = KerasRegressor(build_fn=build_model,verbose=1,validation_data=(testX,testY))
  12. parameters = {'batch_size' : [16,20],
  13. 'epochs' : [8,10],
  14. 'optimizer' : ['adam','Adadelta'] }
  15. grid_search = GridSearchCV(estimator = grid_model,
  16. param_grid = parameters,
  17. cv = 2)
  18. grid_search = grid_search.fit(trainX,trainY)
  19. print(grid_search.best_params_)
  20. my_model=grid_search.best_estimator_.model

2.6 进行预测

  1. prediction=my_model.predict(testX)
  2. print("prediction\n", prediction)
  3. print("\nPrediction Shape-",prediction.shape)

prediction:

图片

2.7 预测效果展示

  1. prediction_copies_array = np.repeat(prediction,5, axis=-1)
  2. print(prediction_copies_array.shape)
  3. pred=scaler.inverse_transform(np.reshape(prediction_copies_array,(len(prediction),5)))[:,0]
  4. original_copies_array = np.repeat(testY,5, axis=-1)
  5. print(original_copies_array.shape)
  6. original=scaler.inverse_transform(np.reshape(original_copies_array,(len(testY),5)))[:,0]
  7. print("Pred Values-- ",pred)
  8. print("\nOriginal Values-- ",original)
  9. import matplotlib.pyplot as plt
  10. plt.plot(original, color = 'red', label = 'Real Stock Price')
  11. plt.plot(pred, color = 'blue', label = 'Predicted Stock Price')
  12. plt.title(' Stock Price Prediction')
  13. plt.xlabel('Time')
  14. plt.ylabel(' Stock Price')
  15. plt.legend()
  16. plt.show()

测试集真实值与预测值:

图片

图片

三、新测试集上预测

代码:

  1. df_30_days_past=df.iloc[-30:,:]
  2. df_30_days_future=pd.read_csv("test.csv",parse_dates=["Date"],index_col=[0])
  3. print(df_30_days_future.shape)
  4. df_30_days_future["Open"]=0
  5. df_30_days_future=df_30_days_future[["Open","High","Low","Close","Adj Close"]]
  6. old_scaled_array=scaler.transform(df_30_days_past)
  7. new_scaled_array=scaler.transform(df_30_days_future)
  8. new_scaled_df=pd.DataFrame(new_scaled_array)
  9. new_scaled_df.iloc[:,0]=np.nan
  10. full_df=pd.concat([pd.DataFrame(old_scaled_array),new_scaled_df]).reset_index().drop(["index"],axis=1)
  11. full_df_scaled_array=full_df.values
  12. all_data=[]
  13. time_step=30
  14. for i in range(time_step,len(full_df_scaled_array)):
  15. data_x=[]
  16. data_x.append(full_df_scaled_array[i-time_step:i,0:full_df_scaled_array.shape[1]])
  17. data_x=np.array(data_x)
  18. prediction=my_model.predict(data_x)
  19. all_data.append(prediction)
  20. full_df.iloc[i,0]=prediction
  21. new_array=np.array(all_data)
  22. new_array=new_array.reshape(-1,1)
  23. prediction_copies_array = np.repeat(new_array,5, axis=-1)
  24. y_pred_future_30_days = scaler.inverse_transform(np.reshape(prediction_copies_array,(len(new_array),5)))[:,0]
  25. print(y_pred_future_30_days)

数据:30行4列

图片

结果:

图片

作者简介:

读研期间发表6篇SCI数据挖掘相关论文,现在某研究院从事数据算法相关科研工作,结合自身科研实践经历不定期分享关于Python、机器学习、深度学习、人工智能系列基础知识与应用案例。致力于只做原创,以最简单的方式理解和学习,关注我一起交流成长。需要数据集和源码的小伙伴可以关注底部公众号添加作者微信。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/612988
推荐阅读
相关标签
  

闽ICP备14008679号