基于Keras的LSTM多变量时间序列预测-免费源代码


1.概述

长短期记忆(英语:Long Short-Term Memory,LSTM)是一种时间递归神经网络(RNN),论文首次发表于1997年。由于独特的设计结构,LSTM适合于处理和预测时间序列中间隔和延迟非常长的重要事件。

目前关于LSTM多因素时间序列预测的文章很多,但我们发现完整通用的文章并不多,因此进化学习团队将在已有文章的基础上进一步提供更通用化的分析与研究,与已有研究形成互补,并提供源代码(下载),供大家交流学习。

2.已有相关分析

下面列出已有相关分析:

3.通用LSTM模型预测分析——以预测上海市二手住宅价格指数为例

3.1背景介绍

住宅价格是房地产市场健康稳定发展的重要指标,住宅价格同时也是整个社会所重点关注的话题。掌握住宅价格走势,对于房地产市场就有着清晰的认识和分析。因此,无论是购房者、房地产开发商,还是政府管理部口对于住宅价格的走势,各方一直都保持着髙度的关注。住宅价格的有效预测,不仅可以帮助政府部门更好对于房地产市场进行精确调控,保持房地产市场的平稳有序,严格控制炒房等现象的发生;也可以帮助广大的房地产开发商提前投资决策,对于未来市场走向进行研判,从而先行一步,预先布局,决定时间和空间上的布置,在什么时候加大买入土地开发,在哪些城市减少开盘,这些都和住宅价格的预期息息相关。此外,购房者投资很大程度上取决于对于未来住宅价格的预测,未来预测越精准,购房者则会更加理性地配置当期及未来投资组合。

影响住宅价格的因素众多,通常包括土地价格、当地经济发展状况、城镇就业人口与工资水平、房地产开发投入、利率等金融政策、房地产税费政策、政府限购政策等。各种因素不仅来源复杂多样,而且关系复杂,导致住宅价格表现为一种复杂非线性变化的价格。本文通过选取多个影响因素,进而构建一个多因素的LSTM回归系统,用于未来住宅价格的预测,并以上海市为例进行实验测试。

3.2数据说明

我们以上海市为例进行实验测试。选取月度数据,从2011年1月至2018年7月,总计91组数据。原始数据特征名称及来源如下表:

3.3算法实现

3.3.1导入基本算法模块

首先明确代码运行的环境。我们的代码的环境是Anaconda(python3.5+)+TensorFlow1.6+(做后端计算)+Keras2.0+(网络搭建)。然后导入预测系统所需的基本模块,如下:

1
2
3
4
5
6
7
8
9
10
11
12
import time
import math
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime
from keras.models import Sequential
from keras.layers import LSTM, Dense
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from keras import backend as K  # Keras解决OOM超内存问题

3.3.2LSTM算法

1)lstm类。首先构建lstm总体框架,这个综合的框架包含:初始化,数据集分割,网络创建与训练,网络评估和结果可视化。初始化主要是将基本的参数和数据导入进将要创建的实例;数据集分割是将导入数据转换成适合模型训练与测试的格式;网络创建与训练是基于传导进来的参数创建网络,并进行拟合训练;网络评估是对网络测试效果进行量化评估的过程;结果可视化为从图形角度展示测试效果的步骤。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class lstm():
    # Initialization/初始化
    def __init__(self, dataset, hyper_params):

    # Split into train and test sets/分割训练集与测试集
    def split_dataset(self):

    # Create and fit the LSTM network/创建并拟合LSTM网络
    def lstm(self):

    # Evaluate network performance/评估网络效果
    def mape(self, scaler, trainPredict, testPredict):

    # Visualization results/可视化结果
    def plot(self, scaler, trainPredict, testPredict):

2)lstm类初始化。网络的初始化主要包括数据集和相关超参数的初始化。数据集初始化包含对数据整体数据和训练数据与测试数据的初始化。其他的网络设定参数包括隐藏层数,各隐藏层神经元个数,窗口长度,训练次数,批数,数据集分割比例,特征选择等。

1
2
3
4
5
6
7
8
9
10
11
12
13
def __init__(self, dataset, hyper_params):
    self.dataset = dataset  # Initialize data sets/数据集初始化
    self.num_neur = hyper_params[0]  # Initialize number of layer and number of neurons in each layer/初始化隐层数和各层神经元个数
    self.look_back = hyper_params[1]  # Initialize length of windows/初始化窗口长度
    self.epochs = hyper_params[2]  # Initialize training times/初始化训练次数
    self.batch_size = hyper_params[3]  # Initialize batch size/初始化批数
    self.selected_feature = hyper_params[4]  # Initialize the selected features/初始化选择特征
    self.train_ratio = hyper_params[5]  # Initialize the splitted ratio of training/初始化训练集分割比例
    self.feature_num = hyper_params[6]  # Initialize the number of features/初始化特征数量
    self.x_train = []  # Initialize training features of training data set/初始化训练集x部分-训练特征
    self.y_train = []  # Initialize supervisory signals of training data set/初始化训练集y部分-监督信号
    self.x_test = []  # Initialize test features of training data set/初始化测试集x部分-测试特征
    self.y_test = []  # Initialize supervisory signals of training data set/初始化测试集y部分-监督信号

3)数据集分割。导入数据集被按比例分割为训练集和测试集,分别用于LSTM网络的训练和模型效果的测试。该模块中的重点是将数据转换为时序预测所需的格式。下面我们说明一下数据转换过程。我们假定下表为导入源数据,A为监督信号,也为特征之一,B,C,D,E均为特征。

我们选择A,B,D,E四个特征加入模型(假定C不适合加入模型),窗口长度设定为2,那么就可以产生如下数据作为时序训练测试的数据。通过左侧t-2,t-1时期特征数据,预测对应右侧t时期的监督指标。


数据集分割模块代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def split_dataset(self):
    # Feature selection/特征选择
    def feature_selection(selected_feature):
        selected_list = []
        for index, item in enumerate(selected_feature):
            if item == 1:
                selected_list.append(index)
            else:
                if index == 1:
                    selected_list.append(index)
        return selected_list

    # Convert an array of values into a dataset matrix/转换数据结构,准备训练集与测试集
    def create_dataset(dataset, look_back):
        dataX, dataY = [], []
        for i in range(len(dataset) - look_back):
            a = dataset[i:(i + look_back), 0:dataset.shape[1]]
            dataX.append(a)
            dataY.append(dataset[i + look_back, 0])
        return np.array(dataX), np.array(dataY)

    selected_list = feature_selection(self.selected_feature)  # Index list of selected feature/选择特征列表索引
    train_size = int(len(self.dataset) * self.train_ratio)  # Size of training data set/训练集大小
    train_data = self.dataset[0:train_size, selected_list]  # Training data set/训练集
    test_data = self.dataset[train_size - self.look_back - 1:len(self.dataset), selected_list]  # Test data set/测试集
    self.feature_num = len(selected_list)  # Update the number of selected feature/更新特征数量

    # Data set detail/具体分割后数据集
    x_train, self.y_train = create_dataset(train_data, self.look_back)
    x_test, self.y_test = create_dataset(test_data, self.look_back)

    # Reshape input to be [samples, feature_num, features]/整理特征数据的格式
    self.x_train = np.reshape(x_train, (x_train.shape[0], self.feature_num, x_train.shape[1]))
    self.x_test = np.reshape(x_test, (x_test.shape[0], self.feature_num, x_test.shape[1]))

4)lstm网络创建与训练。网络创建与训练基于导入参数的信息,如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def lstm(self):
    start_cr_a_fit_net = time.time()  # Record time/记录网络创建与训练时间
    self.split_dataset()  # Split the data set/数据分割

    # Create and fit the LSTM network/创建并拟合LSTM网络
    LSTM_model = Sequential()
    for i in range(len(self.num_neur)):  # 构建多层网络
        if len(self.num_neur) == 1:
            LSTM_model.add(LSTM(self.num_neur[i], input_shape=(None, self.look_back)))
        else:
            if i < len(self.num_neur) - 1:
                LSTM_model.add(LSTM(self.num_neur[i], input_shape=(None, self.look_back), return_sequences=True))
            else:
                LSTM_model.add(LSTM(self.num_neur[i], input_shape=(None, self.look_back)))

    LSTM_model.add(Dense(1))
    LSTM_model.summary()  # Summary the structure of neural network/网络结构总结
    LSTM_model.compile(loss='mean_squared_error', optimizer='adam')  # Compile the neural network/编译网络
    LSTM_model.fit(self.x_train, self.y_train, epochs=self.epochs, batch_size=self.batch_size
                   , verbose=0)  # Fit the LSTM network/拟合LSTM网络
    end_cr_a_fit_net = time.time() - start_cr_a_fit_net
    print('Running time of creating and fitting the LSTM network: %.2f Seconds' % (end_cr_a_fit_net))

    # LSTM prediction/LSTM进行预测
    trainPredict = LSTM_model.predict(self.x_train)  # Predict by training data set/训练集预测
    testPredict = LSTM_model.predict(self.x_test)  # Predict by test data set/测试集预测
    return trainPredict, testPredict, self.y_train, self.y_test

5)lstm网络评估。由于训练与测试的结果仍为标准化后的数值,因此效果评估首先要将结果还原为标准化前的数据。之后,计算训练集和测试集的MAPE(平均绝对百分误差)和RMSE(均方根误差)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def mape(self, scaler, trainPredict, testPredict):
    # Invert predictions start / 将预测值转换为正常数值
    # Create empty table like the dataset/创建一个空的数组, 结构同dataset
    trainPredict_dataset_like = np.zeros(shape=(len(trainPredict), self.dataset.shape[1]))
    # Put the predicted values in the right field/将预测值填充进新建数组
    trainPredict_dataset_like[:, 0] = trainPredict[:, 0]
    # Inverse transform and then select the right field/数据转换
    trainPredict = scaler.inverse_transform(trainPredict_dataset_like)[:, 0]

    y_train_dataset_like = np.zeros(shape=(len(self.y_train), self.dataset.shape[1]))
    y_train_dataset_like[:, 0] = self.y_train
    self.y_train = scaler.inverse_transform(y_train_dataset_like)[:, 0]

    testPredict_dataset_like = np.zeros(shape=(len(testPredict), self.dataset.shape[1]))
    testPredict_dataset_like[:, 0] = testPredict[:, 0]
    testPredict = scaler.inverse_transform(testPredict_dataset_like)[:, 0]

    y_test_dataset_like = np.zeros(shape=(len(self.y_test), self.dataset.shape[1]))
    y_test_dataset_like[:, 0] = self.y_test
    self.y_test = scaler.inverse_transform(y_test_dataset_like)[:, 0]
    # Invert predictions end/数据转换结束

    # Calculate root mean squared error and MAPE/计算RMSE和误差率MAPE
    train_RMSE = math.sqrt(mean_squared_error(self.y_train, trainPredict))
    test_RMSE = math.sqrt(mean_squared_error(self.y_test, testPredict))
    trainMAPE = np.mean(np.abs(self.y_train - trainPredict) / self.y_train)
    testMAPE = np.mean(np.abs(self.y_test - testPredict) / self.y_test)

    print(str(round(train_RMSE, 2)) + ' ' + str(round(trainMAPE * 100, 2)) + ' ' +
          str(round(test_RMSE, 2)) + ' ' + str(round(testMAPE * 100, 2)))
    return trainMAPE, testMAPE, trainPredict, testPredict

6)结果可视化。首先要将结果还原为标准化前的数据。之后,将价格指数真实值,训练集预测值和测试集预测值图形展示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def plot(self, scaler, trainPredict, testPredict):
    # Shift training predictions for plotting/转换数据结构用于作图-训练预测结果
    sub_traindataset = [[data] for data in self.dataset[:, 0]]
    trainPredictPlot = np.empty_like(sub_traindataset)
    trainPredictPlot[:, 0] = np.nan
    trainPredictPlot[self.look_back:len(trainPredict) + self.look_back, 0] = trainPredict

    # Shift test predictions for plotting/转换数据结构用于作图-测试预测结果
    sub_testdataset = [[data] for data in self.dataset[:, 0]]
    testPredictPlot = np.empty_like(sub_testdataset)
    testPredictPlot[:] = np.nan
    testPredictPlot[len(trainPredict) + self.look_back - 1:len(self.dataset), 0] = testPredict

    # plot baseline and predictions/作图
    datasety_like = np.zeros(shape=(self.dataset.shape[0], self.dataset.shape[1]))
    datasety_like[:, 0] = self.dataset[:, 0]
    y = scaler.inverse_transform(datasety_like)[:, 0]

    dates = pd.date_range('2010-12', periods=len(y), freq='M')
    xs = [datetime.strptime(str(d)[0:7], '%Y-%m').date() for d in dates]
    # 配置横坐标
    plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
    plt.gca().xaxis.set_major_locator(mdates.MonthLocator(bymonth=[1, 7]))

    A, = plt.plot(xs, y[0:len(y)], linewidth='2', color='r')  # 真实值
    B, = plt.plot(xs, trainPredictPlot, linewidth='1.5', color='g')  # LSTM训练集结果
    C, = plt.plot(xs, testPredictPlot, linewidth='4', color='g')  # LSTM测试集结果

    # plt.plot(NpredYPlot,linewidth = '3',color='k')
    plt.axvline(xs[76], linewidth='2', color='black')  # 画直线区分训练部分与测试部分
    plt.legend((A, B, C), ('real_value', 'LSTM_train', 'LSTM_test'), loc='best')
    plt.gcf().autofmt_xdate()  # 自动旋转日期标记

    plt.xlabel('Date', family='Times New Roman', fontsize=16)  # X轴
    plt.ylabel('Housing price Index', family='Times New Roman', fontsize=16)  # Y轴

    plt.title('LSTM', family='Times New Roman', fontsize=16)  # 添加标题

    plt.savefig('C:\Users\10321\Desktop\result.png', dpi=600)  # 保存图片

    plt.show()

3.3.3参数导入与实验

在完成LSTM方法架构之后,我们将数据与参数导入,进行实验测试。num_neur=[15, 12]表示这个LSTM网络有两个隐藏层,第一层的神经元个数为15,第二层的神经元个数为10;select_feature = [1, 1, 1, 0, 0, 0, 1, 0]表示数据集中第1,2,3,7项特征被加入到模型中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
if __name__ == "__main__":
    # Load the dataset/导入数据集
    file = r'C:\Users\10321\Desktop\data.xlsx'
    dataframe = pd.read_excel(file, sheet_name=0, header=0, index_col=None)
    dataset = dataframe.iloc[:, [1, 2, 3, 4, 5, 6, 7, 8]].values
    dataset = dataset.astype('float32')

    # Normalize the dataset/标准化数据集
    scaler = MinMaxScaler(feature_range=(0, 1))
    dataset = scaler.fit_transform(dataset)

    # Set hyper-parameters/设定超参数
    num_neur = [15, 10]  # Number of layer and number of neurons in each layer/隐藏层数和各层神经元个数
    look_back = 1  # Length of windows/窗口长度
    epochs = 100  # Training times/训练次数
    batch_size = 10 # Batch size/批数大小
    select_feature = [1, 1, 1, 0, 0, 0, 1, 0]  # Selected features list/被选择特征列表
    train_ratio = 0.85  # Splitted ratio of training data set/训练集分割比例
    feature_num = dataset.shape[1]  # Feature number+y/特征数量+1,也将预测项作为特征
    # Hyper-parameter list/超参数列表
    hyper_params = [num_neur, look_back, epochs, batch_size, select_feature, train_ratio, feature_num]

    # Start an LSTM model/开始一个LSTM网络
    model = lstm(dataset, hyper_params)  # Create instance of LSTM/实例化模型
    trainPredict, testPredict, y_train, y_test = model.lstm()  # Create and fit the LSTM network/创建并拟合LSTM网络
    trainMAPE, testMAPE, trainPredict, testPredict = model.mape(scaler, trainPredict
                                                                , testPredict)  # Evaluate network performance/评估网络效果
    model.plot(scaler, trainPredict, testPredict)  # Visualization results/可视化结果
    K.clear_session()  # 关掉内存中神经网络

从最终结果来看,拟合效果不错,见下图。

3.4总结

1.创建了一个通用的时间序列预测模型。模型可以快捷的调节相关超参数,比如网络层数,各层神经元个数,训练集分割比例,窗口长度,特征选择等,达到快速调节模型的效果。
2.以一个实例展示了模型的有效性。

点击进行完整源代码下载
完整代码详解及注释将会根据网友意见和建议持续修改、维护与更新。
转载请注明出处!

参考文献

[1]Hochreiter S, Schmidhuber J. Long Short-term memory[J]. Neural Computation, 1997,9(8):1735-1780.

[2]Understanding LSTM network http://colah.github.io/posts/2015-08-Understanding-LSTMs/

赞赏

微信赞赏支付宝赞赏

Have any Question or Comment?

45 comments on “基于Keras的LSTM多变量时间序列预测-免费源代码

Sean

您好,我依您程式測試,出現如下訊息,無法繪圖出來?

AttributeError Traceback (most recent call last)
in
25 trainPredict, testPredict, y_train, y_test = model.lstm() # Create and fit the LSTM network/创建并拟合LSTM网络
26 trainMAPE, testMAPE, trainPredict, testPredict = model.mape(scaler, trainPredict, testPredict) # Evaluate network performance/评估网络效果
---> 27 model.plot(scaler, trainPredict, testPredict) # Visualization results/可视化结果
28 K.clear_session() # 关掉内存中神经网络

AttributeError: 'lstm' object has no attribute 'plot'

Reply

你再试试,这里面的程序我这里可以跑通。https://www.evolutionarylearn.com/download/lstm_ts_predict-keras-python/

Reply
Sean

有了,感謝。

Reply
Sean

請問,如果我數據是以日為單位,要如何改呢?

Reply

需要你配置下面的参数,我用的是月度数据,你看我下面的结构都是月

dates = pd.date_range('2010-12', periods=len(y), freq='M') #从2010年12开始,freq='M'指按月
xs = [datetime.strptime(str(d)[0:7], '%Y-%m').date() for d in dates] #'%Y-%m'这个也是‘年-月’格式
# 配置横坐标
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
plt.gca().xaxis.set_major_locator(mdates.MonthLocator(bymonth=[1, 7]))

Reply
Sean

請問,我改成
dates = pd.date_range('2010-12-01', periods=len(y), freq='d')
xs = [datetime.strptime(str(d), '%Y-%m-%d').date() for d in dates]
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.gca().xaxis.set_major_locator(mdates.DateLocator())

但出現ValueError: unconverted data remains: 00:00:00 ??
請問還有哪些需要調整的嗎?

Reply

应该是语句xs = [datetime.strptime(str(d), '%Y-%m-%d').date() for d in dates]的问题,由于d是yyyy-mm-rr 00:00:00 的格式,需要限定str(d)[0:10]
我试了下面这个,是可以的

dates = pd.date_range('2010-12-31', periods=len(y), freq='d')
xs = [datetime.strptime(str(d)[0:10], '%Y-%m-%d').date() for d in dates]
# 配置横坐标
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator(bymonthday=range(1,32), interval=5))

Reply
Sean

謝謝您,再請教我修改如下,出現錯誤…
dates = pd.date_range('2010-12-01', periods=len(y), freq='d')
xs = [datetime.strptime(str(d), '%Y-%m-%d').date() for d in dates]
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.gca().xaxis.set_major_locator(mdates.DateLocator())

--------------------------------------------------
ValueError: unconverted data remains: 00:00:00

Reply

应该是语句xs = [datetime.strptime(str(d), '%Y-%m-%d').date() for d in dates]的问题,由于d是yyyy-mm-rr 00:00:00 的格式,需要限定str(d)[0:10]
我试了下面这个,是可以的

dates = pd.date_range('2010-12-31', periods=len(y), freq='d')
xs = [datetime.strptime(str(d)[0:10], '%Y-%m-%d').date() for d in dates]
# 配置横坐标
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator(bymonthday=range(1,32), interval=5))

Reply
Tony Li

输入的格式不应该是[samples,timesteps,features]吗?请问为什么是 # Reshape input to be [samples, feature_num, features]/整理特征数据的格式。如何理解?谢谢。

Reply

是的,注释有误,不过应该是[samples, feature_num, timesteps]

Reply
Tony Li

谢谢答复,但是Keras文档中的要求不是按照[samples,timesteps,features]的格式input吗?另外这里的timesteps和后面的input_shape中的(None,self.loop_back)中的self.loop_back如何关联?理论上self.loop_back就是keras文档中规定的input_shape中的timesteps。谢谢。

Reply

这个我是这样理解的,格式[samples,timesteps,features]是对应model.add中input_shape的。如果[samples,timesteps,features],后面input_shape要用[timesteps,features];如果[samples,features,timesteps],你可以用[features,timesteps],或者我程序中的(None,self.loop_back)。另外,我里面的self.loop_back确实是时间窗口timesteps

Reply
Tony Li

谢谢解答

Sean

請問,我將數據導入後RMSE數值很大(達5千多),但實際和預測的圖卻很接近,為何?

Reply

这个我没有看到具体测试,你可以再试试,可能是数据的情况

Reply
Sean

請問我是調整 底下這些參數來使rsme和mape值降低嗎? 我把num_neur提高到=[120,45],look_back =10, epochs = 800,batch_size = 10。它的train rmse和mape會降低,但test rmse和mape就不會降低。造成圖在train上是吻合,但在test上就差異較大。可否指導一下了?
num_neur = [15, 10]
look_back = 1
epochs = 100
batch_size = 10

Reply

我建议做这种时序预测不要设置太大的层数、神经元个数和时间窗口(look _back),训练效果不一定好,也容易过拟合

Reply
SEAN

感謝,另請問若过拟合,加上dropout是否可行? 又該如何使用呢?

Asuka

作者,您好。请问如果我想进行多目标预测,即y_train的维度大于1,我需要修改那些代码呢?

Reply

这个需要调整的就比较多了,凡是涉及到y的都要调整,而且我也还没做过多目标预测的测试,是个挺好的题目啊,有兴趣深入研究的朋友可以多交流下,我的微信 bubian092674,哈哈。

Reply
lilu

作者您好,想麻烦问下为什么选取两层隐藏层,并且第一层为15,第二层为10 呢?

Reply

这个你可以自己设定,也可以多选几层,每层神经元个数也可以设定为其他数值,这里只是做个展示。如果需要设定较优的超参数,可以调一下参数,或者利用优化技术对参数寻优

Reply
czq

作者您好,想请问一下您使用的python和各种库的版本是哪个版本?我这里报错:“TypeError: Expected int32, got list containing Tensors of type '_Message' instead.”,定位到“LSTM_model.add(LSTM(self.num_neur[i], input_shape=(None, self.look_back), return_sequences=True))”这一行。是需要怎么解决呢?

Reply

代码的环境是Anaconda(python3.5+)+TensorFlow1.6+(做后端计算)+Keras2.0+(网络搭建)

Reply

您好,看到文章里面有这样的说明
--># Feature number+y/特征数量+1,也将预测项作为特征
x是[0,1,2,6],y是[0],输入同时作为输出,可以提高模型准确率,但是如果有种情况只有x[1,2,6],即y[0]未知的,只作为输出去“预测”,我试了一下只用[1,2,6]去拟合[0],趋势是一致的,但是具体数值偏差较大了,想解决这个问题应该怎么调整算法呢,盼回复。

Reply
smy

# Feature number+y/特征数量+1,也将预测项作为特征

您好,看到文章里说将预测项作为特征了,那如果预测项是未知的呢,输入就少了权重最大的那一个,我试了只用其他三个维度拟合,整体趋势一致,预测值差了不少,请问下要怎么调整算法呢,盼回复。

Reply

你好,确实可能会有这种效果。之前我考虑的是目标变量的部分信息也会存在于目标变量历史数据中,所以把这个也加入,也确实提高了效果。加入目标变量,我就把时间窗口lookback缩小到了1,因为时间窗口越短,历史目标变量中包含的信息越多。如果你要不用目标变量y,你可以试试调整lookback

Reply
smy

了解了,感谢。

Reply
ZB

您好,请问创建多层网络的时候,为什么要设置if条件判断呢?

Reply

判断层数,多层网络第一层和后面的层语句不一样

Reply
ZB

谢谢,我明白了。
我看到这段代码中的测试集划分用的是test_data = self.dataset[train_size - self.look_back - 1:len(self.dataset), selected_list],
为什么不是test_data = self.dataset[train_size :len(self.dataset), selected_list]呢?

Reply

这个是为了保证测试集中有更多样本,后面一种会由于存在窗口损失掉一部分数据,那个减一应该是为了作图时连接训练部分和测试部分

Reply
ZB

如果是这样的话,测试集和训练集岂不是有重合?这样不会影响最后的效果吗?

嗯,最多那个交接点出有一个是重合的

ZB

还有一个问题是,plt.show()后面有一行del trainPredictPlot, testPredictPlot,添加这一行的目的是什么呢?

删掉一些过程中的数据,也可以保留的,没有特别目的

Liu erjia

我也有想做一个多目标预测的想法,可是找不到相关的代码,想问下您最后有做出来结果吗?

Reply

多目标预测的我这还没做出来😂

Reply
汪瑞

你好,非常感谢你的帮助,我成功的运行出了结果,下一步我想预测未来几个月的房价应该怎么操作呢?

Reply

可以啊,两种,一种可以直接挪动目标变量,可以直接预测未来第二个月,第三个月;另一种就是先将特征变量预测加长,就可以预测更久的了

Reply
汪瑞

你好,谢谢你的解答,我在看代码时遇到了两个疑问,希望您有空可以帮我看看:
1.for index, item in enumerate(selected_feature):
if item == 1:
selected_list.append(index)
else:
if index == 1:
selected_list.append(index)
return selected_list
这里的条件判断好像总是会把index=1的那个特征给选进去,为什么会这样呢?

2.# Reshape input to be [samples, feature_num, features]/整理特征数据的格式
self.x_train = np.reshape(x_train, (x_train.shape[0], self.feature_num, x_train.shape[1]))
这里的reshape为什么能够执行,x_train原来是二维的,现在要reshape成三维的,除非self.feature为1,不然应该执行不了啊。

Reply

第一个是我把目标变量的历史数据也作为特征变量输入;第二个,没看到self.feature这个参数,reshape成三维,它的长宽高都可以不是1啊,

Reply
汪瑞

你好,非常感谢你的帮助,我成功的运行出了结果,请问一下如果要预测未来的房价该怎么做呢?是把当前所有的数据都当成训练集输入吗?

Reply

[…] 基于Keras的LSTM多变量时间序列预测-免费源代码 […]

发表评论

电子邮件地址不会被公开。 必填项已用*标注

分类目录

博客统计

  • 14,394 点击次数