精华内容
下载资源
问答
  • 多变量时间序列预测
    千次阅读
    2021-08-04 19:20:17

    深度学习时间序列预测:GRU算法构建多变量时间序列预测模型+代码实战

    注意参考:深度学习多变量时间序列预测:GRU算法构建单变量时间序列预测模型+代码实战

     GRU(Gate Recurrent Unit)是循环神经网络(Recurrent Neural Network, RNN)的一种。和LSTM(Long-Short Term Memory)一样,也是为了解决长期记忆和反向传播中的梯度等问题而提出来的。

    GRU和LSTM在很多情况下实际表现上相差无几,那么为什么我们要使用新人GRU(2014年提出)而不是相对经受了更多考验的LSTM(1997提出)呢。

    下图1-1引用论文中的一段话来说明GRU的优势所在。

    更多相关内容
  • 时间序列分析|LSTM多变量时间序列预测

    万次阅读 多人点赞 2021-03-27 20:40:42
    基于LSTM多变量时间序列预测

    从这篇博客你将学到

    (1) 何为时间序列
    (2) 多变量时间序列建模
    (3) 基于LSTM模型的时间序列预测
    (4) 如何免费加入交流群

    时间序列

    我们常说历史总是惊人的相似,时间序列预测正式依循这个道理来预测未来,时间序列英文名称为Time Series,简称TS,其假设某变量的值构成的序列依赖于时间,随着时间的变化而变化,如果时间确定了,这个变量的值也就确定了,任何一个时刻都是可以度量的,因为从现在起未来的或者过去的某一时间是可以通过现在时间演算的,同时,随着时间的变化,变量往往会呈现出某些特殊的结构特征,如上升或下降的大体趋势,季节性变动,一些循环往复的周期变动,还有一些不规则变动,而这些特质往往是可以捕捉的,所以常用时间序列模型来预测未来某一确定时间的变量的值。下图是早些年某国的航空乘客人数统计数据,单位是千人

    Figure_1  航空乘客人数统计数据

    我们用折线图将每月的航空乘客人数描绘出来

    Figure_2  航空乘客人数曲线图

    很明显可以看到航空乘客人数总体呈上升趋势,同时出现每隔一段时间上升隔一段时间下降的周期性特征,每个周期变动之间又蕴含一些细微的波动。针对不同特征的时间序列数据可以构建不同的模型,常见的时间序列模型有
    (1) AR(Autoregressive model)自回归模型
    (2) MA(Moving Average Model)移动平均模型
    (3) ARMA(Auto Regressive and Moving Average Model)自回归移动平均模型
    (4) ARIMA(Autoregressive Integrated Moving Average model)差分回归移动平均模型
    (5) SARIMA(seasonal autoregressive integrated moving average)季节性差分回归移动平均模型
    (6) SARIMAX(seasonal autoregressive integrated moving average with exogenous regressor)带外 变量的季节性差分回归移动平均模型
    (7) VAR(Vector autoregression)矢量自回归模型模型
    (6) SVAR(Structural VAR)结构自回归模型

    多变量时间序列

    平常我们构建的大多属于单变量时间序列,在构建预测模型的时候往往只有时间和变量本身可以参考,而这样的变量往往会显得很单薄,同时,时间往往是解释性因子而不是因果性因子,就以航空公司的某个常飞的航班乘客人数为例,如果说成因为是某年某月某日,所以航空乘客人数是多少多少,恐怕太牵强了,所以还需要考虑其他影响因素,比如天气,航线,节假日,旅游季等,于是就有了多变量时间序列,多变量时间序列是指除了时间依赖外,还有其他因素共同影响某一结果的发生。例如下表是某地的气象监控数据

    Figure_3  某地气象监控数据

    其中包含时间,温度,云层覆盖率,露点、湿度、风速及风向等,在这种情况下,云层覆盖率,露点、湿度、风速及风向都有可能被认为是影响温度的因果原因,而时间只是恰巧发生在此时此刻的一个表象因子。这时候建模就可以建立既包含因果原因和又包含表现原因在内的多变量时间序列模型。

    多变量时间序列建模

    假设数据如下所示

    ( x 11 x 12 ⋯ x 1 n y 1 x 21 x 22 ⋯ x 2 n y 2 ⋮ ⋮ ⋮ ⋮ x m 1 x m 2 ⋯ x m n y m ) \left( \begin{matrix} x_{11} & x_{12} & \cdots & x_{1n} & y_1 \\ x_{21} & x_{22} & \cdots & x_{2n} & y_2 \\ \vdots & \vdots & & \vdots & \vdots \\ x_{m1} & x_{m2} & \cdots & x_{mn} & y_m \\ \end{matrix} \right) x11x21xm1x12x22xm2x1nx2nxmny1y2ym

    其中 x i j ( 1 ≤ i ≤ m , 1 ≤ j ≤ n ) x_{ij}(1\leq i\leq m, 1\leq j \leq n) xij(1im,1jn) 表示第 i i i期的第 j j j个特征的值, y i ( 1 ≤ i ≤ m ) y_i(1\leq i\leq m) yi(1im)表示第 i i i期的目标值,先从最简单的开始

    (1) 一阶滞后

    为了预测第 m m m 期的 y m y_m ym值,我们可以利用第 m − 1 m-1 m1期的所有信息

    ( x m − 1 , 1 , x m − 1 , 2 , ⋯   , x m − 1 , n , y m − 1 ) (x_{m-1,1} , x_{m-1,2} , \cdots , x_{m-1,n} , y_{m-1}) (xm1,1,xm1,2,,xm1,n,ym1)

    建立第 m m m 期的目标值 y m y_m ym值与第 m − 1 m-1 m1期所有信息的线性模型
    y m = w 0 y m − 1 + w 1 x m − 1 , 1 + w 2 x m − 1 , 2 + ⋯ + w n x m − 1 , n + ϵ y_m= w_0y_{m-1}+w_1x_{m-1,1}+w_2x_{m-1,2} + \cdots + w_nx_{m-1,n}+\epsilon ym=w0ym1+w1xm1,1+w2xm1,2++wnxm1,n+ϵ

    而不是仅仅利用第 m − 1 m-1 m1期的结果 y m − 1 y_{m-1} ym1这一单一的信息, 这就是多变量时间序列的优势,再推广到p阶滞后。

    (2) p阶滞后

    我们亦可以利用第 m − p m-p mp 到第 m − 1 m-1 m1期的所有信息来进行预测

    ( x m − p , 1 x m − p , 2 ⋯ x m − p , n y m − p x m − p + 1 , 1 x m − p + 1 , 2 ⋯ x m − p + 1 , n y m − p + 1 ⋮ ⋮ ⋮ ⋮ x m − 1 , 1 x m − 1 , 2 ⋯ x m − 1 , n y m − 1 ) \left( \begin{matrix} x_{m-p,1} & x_{m-p,2} & \cdots & x_{m -p, n} & y_{m-p} \\ x_{m-p+1,1} & x_{m-p+1,2} & \cdots & x_{m-p+1,n} & y_{m-p+1} \\ \vdots & \vdots & & \vdots & \vdots \\ x_{m-1,1} & x_{m-1,2} & \cdots & x_{m-1,n} & y_{m-1} \\ \end{matrix} \right) xmp,1xmp+1,1xm1,1xmp,2xmp+1,2xm1,2xmp,nxmp+1,nxm1,nympymp+1ym1

    写成向量形式就是

    y m = W 0 Y + W m − 1 X m − 1 + W m − 2 X m − 2 + W m − 3 X m − 3 + ⋯ + W m − p X m − p + ϵ y_m = W_0Y+ W_{m-1}X_{m-1}+W_{m-2}X_{m-2}+W_{m-3}X_{m-3}+\cdots+W_{m-p}X_{m-p}+\epsilon ym=W0Y+Wm1Xm1+Wm2Xm2+Wm3Xm3++WmpXmp+ϵ

    其中, Y Y Y表示前第 m − 1 m-1 m1 到第 m − p m-p mp期的目标值
    y m − 1 , ⋯   , y m − p y_{m-1}, \cdots, y_{m-p} ym1,,ymp

    X m − i X_{m-i} Xmi表示前 i ( 1 ≤ i ≤ p ) i(1\leq i\leq p) i(1ip)期的特征向量
    ( x m − i , 1 , x m − i , 2 , ⋯   , x m − i , n ) T (x_{m-i,1}, x_{m-i,2},\cdots,x_{m-i,n})^T (xmi,1,xmi,2,,xmi,n)T

    W 0 W_0 W0表示前 i ( 1 ≤ i ≤ p ) i(1\leq i\leq p) i(1ip)期的目标值的系数
    w m − 1 , ⋯   , w m − p w_{m-1}, \cdots, w_{m-p} wm1,,wmp

    W m − i W_{m-i} Wmi表示前 i ( 1 ≤ i ≤ p ) i(1\leq i\leq p) i(1ip)期的特征向量的系数

    ( w m − i , 1 , w m − i , 2 , ⋯   , w m − i , n , w m − i ) (w_{m-i,1}, w_{m-i,2},\cdots,w_{m-i,n},w_{m-i} ) (wmi,1,wmi,2,,wmi,n,wmi)

    ϵ \epsilon ϵ服从高斯分布,这样第 m m m期的目标值就可以通过第 m − p m-p mp到第 m − 1 m-1 m1期的特征变量和目标值线性表出。与单变量时间序列不同,多变量时间序列不仅利用了纵向的时间特征还利用横向的其他特征,所以多变量时间序列不仅能够时间带来的沧桑变化也能够理解和使用多个变量之间的关系,这有助于描述数据的动态行为,并提供更好的预测结果。

    LSTM模型

    LSTM是一种时间递归神经网络,它出现的原因是为了解决RNN的一个致命的缺陷。原生的RNN会遇到一个很大的问题,叫做The vanishing gradient problem for RNNs,也就是后面时间的节点会出现老年痴呆症,也就是忘事儿,这使得RNN在很长一段时间内都没有受到关注,网络只要一深就没法训练。后来有些大牛们开始使用递归神经网络来对时间关系进行建模。而根据深度学习三大牛的阐述,针对时间序列数据,LSTM网络已被证明比传统的RNNS更加有效。

    适合多输入变量的神经网络模型一直让开发人员很头痛,但基于(LSTM)的循环神经网络能够几乎可以完美的解决多个输入变量的问题。

    基于LSTM的循环神经网络可以很好的利用在时间序列预测上,因为很多古典的线性方法难以适应多变量或多输入预测问题。下面我们通过一个案例来看看LSTM在多元时间序列预测上的表现。

    实践项目

    通过本案例实践,你将学会

    • 如何将原始数据集转换为可用于时间序列预测的数据集;
    • 如何准备数据并创建适应多变量时间序列预测问题的LSTM;
    • 如何做出预测并将结果重新调整到原始单位;

    原始pm2.5数据

    在这个案例中,我们将使用PM2.5空气质量数据集,是美国驻北京大使馆五年内收集的PM2.5污染水平及天气情况。字段包括时间、PM2.5浓度、以及一些关键天气信息,详细字段释义如下(需要这份数据的朋友可以来三行科创交流群获取)

    NO:行号。
    year:年。
    month:月。
    day:日。
    hour:小时。
    pm2.5:PM2.5浓度。
    DEWP:露点温度。
    TEMP:温度。
    PRES:压力。
    cbwd:风向。
    Iws:风速。
    ls:积雪的时间
    Ir:累积的下雨时数

    我们可以使用这些数据并构建一个预测问题,基于前一个或几个小时天气条件和PM2.5的污染,预测在下一个小时的PM2.5的污染值。

    第一步 导入用到的库

    本案例是基于keras深度学习库完成多变量时间序列模型的开发,涉及到的库比较多

    # -*- encoding: utf-8 -*-
    '''
    @Project :   LSTM多变量时间序列预测
    @Desc    :   利用LSTM模型进行多变量时间啊序列预测
    @Time    :   2021/03/21 12:16:13
    @Author  :   帅帅de三叔,zengbowengood@163.com
    '''
    
    import math
    import pandas as pd
    from datetime import datetime
    import matplotlib.pyplot as plt
    from pandas.core.algorithms import mode
    from sklearn.preprocessing import LabelEncoder, MinMaxScaler
    from tensorflow.python.keras.backend import concatenate
    from sklearn.metrics import mean_squared_error
    from tensorflow.python.keras.callbacks import History
    from series_to_supervised import series_to_supervised
    from keras.models import Sequential
    from keras.layers import Dense, Activation, Embedding, LSTM
    

    第二步 数据探索

    数据探索主要是查看原始数据的缺失情况,完整度怎么样,有没有明显的谬误等,对数据及数据之间有个感性的认真,如果能够画出原数据的图像那会更直观。

    dataset = pd.read_csv("raw.csv", index_col= "datetime", parse_dates = {"datetime":['year', 'month', 'day', 'hour']}, date_parser= lambda x:datetime.strptime(x,'%Y %m %d %H')) #读取数据并拼接时间
    dataset.drop("No", axis = 1, inplace = True) #去掉No列
    dataset.columns = ["pm25", "dew",  "temp", "press", "wnd_dir", "wnd_spd", "snow", "rain"] #重命名表头
    dataset.dropna(subset = ['pm25'], inplace = True) #去掉pm25为空的行
    values = dataset.values #数值特征变量
    groups = [0, 1, 2, 3, 5, 6, 7]
    i = 1
    plt.figure() #新建画布
    for group in groups:
        plt.subplot(len(groups), 1, i) #子图
        plt.plot(values[:, group]) #折线图
        plt.title(dataset.columns[group], y = 0.5, fontsize = 10, loc = "right") #取字段为子图标题
        i +=1
    plt.show()
    

    Figure_4 特征长什么模样

    第三步 特征工程

    将原数据处理成LSTM模型能够识别的格式,并且保持LSTM模型的输入格式要求(samples, timesteps, features),同时数据集进行划分,分为训练集和测试集,要注意这里是需要学习到时间因素,所以在训练集和测试集划分上不能破坏数据原有的序列,可以按照时间切分,比如这里用第一年数据进行训练,用剩下的4年进行评估。

    encoder = LabelEncoder() #编码
    values[:,4] = encoder.fit_transform(values[:,4]) #将第4列编码
    values = values.astype('float32') #使得所有数值类型都是float类型
    scaler = MinMaxScaler(feature_range = (0, 1)) #0-1归一化
    scaled = scaler.fit_transform(values)
    reframed = series_to_supervised(scaled, 1, 1) #调用series_to_supervised函数将数据转为监督数据变成16列
    reframed.drop(reframed.columns[[9, 10, 11, 12, 13, 14, 15]], axis= 1,inplace = True) 
    values = reframed.values
    n_train_hours = 365*24 #一年的小时数
    train = values[:n_train_hours, :] #训练集
    test = values[n_train_hours:, :] #测试集
    train_x, train_y = train[:, :-1], train[:, -1] #训练集特征和标签 
    test_x, test_y = test[:, :-1], test[:, -1] #测试集的特征和标签
    train_x = train_x.reshape((train_x.shape[0], 1, train_x.shape[1])) #转为LSTM模型的输入格式(samples, timesteps, features)
    test_x = test_x.reshape((test_x.shape[0], 1, test_x.shape[1])) #转为LSTM模型的输入格式(samples, timesteps, features)
    

    第四步 设计LSTM模型

    模型的设计是很关键的一环,一个简洁高效的模型往往能够使得训练和验证结果事半功倍,这里隐藏层有50个神经元,输出层1个神经元(回归问题),输入变量是一个时间步(t-1)的特征,损失函数采用Mean Absolute Error(MAE),优化算法采用Adam,模型采用50个epochs并且每个batch的大小为72, shuffle要设置成False,随后画出测试集的误差曲线和训练集的误差曲线。

    model = Sequential()
    model.add(LSTM(50, input_shape = (train_x.shape[0], train_x.shape[2]))) #8760*8
    model.add(Dense(1))
    model.compile(loss = "mae",optimizer= "adam")
    history =model.fit(train_x, train_y, epochs= 50, batch_size=72, validation_data=(test_x, test_y), verbose=2, shuffle=False)
    plt.figure()
    plt.plot(history.history["loss"], label = "train")
    plt.plot(history.history["val_loss"], label = "test")
    plt.legend()
    plt.show()
    

    Figure_5  训练损失与测试损失

    第五步 模型的评估

    一个模型的好坏还需要进行严格的评估工作,需要将预测结果和部分测试集数据组合然后进行比例反转(invert the scaling),同时也需要将测试集上的预期值也进行比例转换。至于在这里为什么进行比例反转,是因为我们将原始数据进行了预处理(连同输出值y),此时的误差损失计算是在处理之后的数据上进行的,为了计算在原始比例上的误差需要将数据进行转化,同时反转时的矩阵大小一定要和原来的大小(shape)完全相同,否则就会报错。通过以上处理之后,再结合RMSE(均方根误差)计算损失。

    yhat = model.predict(test_x)
    test_x = test_x.reshape((test_x.shape[0], test_x.shape[2]))
    inv_yhat = concatenate((yhat,test_x[:, 1:]), axis = 1)
    inv_yhat = scaler.inverse_transform(inv_yhat)
    inv_yhat = inv_yhat[:, 0]
    
    test_y = test_y.reshape((len(test_y), 1))
    inv_y = concatenate((test_y, test_x[:, 1:]), axis =1)
    inv_y = scaler.inverse_transform(inv_y)
    inv_y = inv_y[:, 0]
    rmse = math.sqrt(mean_squared_error(inv_y, inv_yhat))
    print("the rmse is: %.3f" %rmse)
    

    最后均方根误差值保持在26附近。

    进一步思考

    (1)在数据处理可以尝试的

    1. 加入季节特征;
    2. 时间步长大于1。
    3. 舍去一些影响不大的特征

    (2)在设计模型的时候可以尝试

    1. 隐藏层神经元个数,
    2. 优化算法
    3. 模型的epochs数,每个batch的大小

    参考资料

    1,https://www.analyticsvidhya.com/blog/2016/02/time-series-forecasting-codes-python/
    2,https://blog.csdn.net/qq_28031525/article/details/79046718
    3,https://www.analyticsvidhya.com/blog/2016/02/time-series-forecasting-codes-python/
    在这里插入图片描述

    展开全文
  • 使用 LSTM 进行多变量时间序列预测

    万次阅读 多人点赞 2022-01-11 10:13:30
    使用 LSTM 进行端到端时间序列预测的完整代码和详细解释。 在本文中我们将使用深度学习方法 (LSTM) 执行多元时间序列预测。 我们先来了解两个主题—— 什么是时间序列分析? 什么是 LSTM? 时间序列分析:时间序列...

    使用 LSTM 进行端到端时间序列预测的完整代码和详细解释。

    在本文中我们将使用深度学习方法 (LSTM) 执行多元时间序列预测。

    我们先来了解两个主题——

    • 什么是时间序列分析?
    • 什么是 LSTM?

    时间序列分析:时间序列表示基于时间顺序的一系列数据。 它可以是秒、分钟、小时、天、周、月、年。 未来的数据将取决于它以前的值。

    在现实世界的案例中,我们主要有两种类型的时间序列分析——

    • 单变量时间序列
    • 多元时间序列

    对于单变量时间序列数据,我们将使用单列进行预测。

    正如我们所见,只有一列,因此即将到来的未来值将仅取决于它之前的值。

    但是在多元时间序列数据的情况下,将有不同类型的特征值并且目标数据将依赖于这些特征。

    正如在图片中看到的,在多元变量中将有多个列来对目标值进行预测。 (上图中“count”为目标值)

    在上面的数据中,count不仅取决于它以前的值,还取决于其他特征。因此,要预测即将到来的count值,我们必须考虑包括目标列在内的所有列来对目标值进行预测。

    在执行多元时间序列分析时必须记住一件事,我们需要使用多个特征预测当前的目标,让我们通过一个例子来理解 -

    在训练时,如果我们使用 5 列 [feature1, feature2, feature3, feature4, target] 来训练模型,我们需要为即将到来的预测日提供 4 列 [feature1, feature2, feature3, feature4]。

    LSTM

    本文中不打算详细讨论LSTM。所以只提供一些简单的描述,如果你对LSTM没有太多的了解,可以参考我们以前发布的文章。

    LSTM基本上是一个循环神经网络,能够处理长期依赖关系。

    假设你在看一部电影。所以当电影中发生任何情况时,你都已经知道之前发生了什么,并且可以理解因为过去发生的事情所以才会有新的情况发生。RNN也是以同样的方式工作,它们记住过去的信息并使用它来处理当前的输入。RNN的问题是,由于渐变消失,它们不能记住长期依赖关系。因此为了避免长期依赖问题设计了lstm。

    现在我们讨论了时间序列预测和LSTM理论部分。让我们开始编码。

    让我们首先导入进行预测所需的库

    import numpy as np
    import pandas as pd
    from matplotlib import pyplot as plt
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import LSTM
    from tensorflow.keras.layers import Dense, Dropout
    from sklearn.preprocessing import MinMaxScaler
    from keras.wrappers.scikit_learn import KerasRegressor
    from sklearn.model_selection import GridSearchCV
    

    加载数据,并检查输出-

    df=pd.read_csv("train.csv",parse_dates=["Date"],index_col=[0])
    df.head()
    

    df.tail()
    

    现在让我们花点时间看看数据:csv文件中包含了谷歌从2001-01-25到2021-09-29的股票数据,数据是按照天数频率的。

    [如果您愿意,您可以将频率转换为“B”[工作日]或“D”,因为我们不会使用日期,我只是保持它的现状。]

    这里我们试图预测“Open”列的未来值,因此“Open”是这里的目标列

    让我们看一下数据的形状

    df.shape
    (5203,5)
    

    现在让我们进行训练测试拆分。这里我们不能打乱数据,因为在时间序列中必须是顺序的。

    test_split=round(len(df)*0.20)
    df_for_training=df[:-1041]
    df_for_testing=df[-1041:]
    print(df_for_training.shape)
    print(df_for_testing.shape)
    
    (4162, 5)
    (1041, 5)
    

    可以注意到数据范围非常大,并且它们没有在相同的范围内缩放,因此为了避免预测错误,让我们先使用MinMaxScaler缩放数据。(也可以使用StandardScaler)

    scaler = MinMaxScaler(feature_range=(0,1))
    df_for_training_scaled = scaler.fit_transform(df_for_training)
    df_for_testing_scaled=scaler.transform(df_for_testing)
    df_for_training_scaled
    

    将数据拆分为X和Y,这是最重要的部分,正确阅读每一个步骤。

    def createXY(dataset,n_past):
        dataX = []
        dataY = []
        for i in range(n_past, len(dataset)):
                dataX.append(dataset[i - n_past:i, 0:dataset.shape[1]])
                dataY.append(dataset[i,0])
        return np.array(dataX),np.array(dataY)
    
    trainX,trainY=createXY(df_for_training_scaled,30)
    testX,testY=createXY(df_for_testing_scaled,30)
    

    让我们看看上面的代码中做了什么:

    N_past是我们在预测下一个目标值时将在过去查看的步骤数。

    这里使用30,意味着将使用过去的30个值(包括目标列在内的所有特性)来预测第31个目标值。

    因此,在trainX中我们会有所有的特征值,而在trainY中我们只有目标值。

    让我们分解for循环的每一部分

    对于训练,dataset = df_for_training_scaled, n_past=30

    当i= 30:

    data_X.addend (df_for_training_scaled[i - n_past:i, 0:df_for_training.shape[1]])

    从n_past开始的范围是30,所以第一次数据范围将是-[30 - 30,30,0:5] 相当于 [0:30,0:5]

    因此在dataX列表中,df_for_training_scaled[0:30,0:5]数组将第一次出现。

    现在, dataY.append(df_for_training_scaled[i,0])

    i = 30,所以它将只取第30行开始的open(因为在预测中,我们只需要open列,所以列范围仅为0,表示open列)。

    第一次在dataY列表中存储df_for_training_scaled[30,0]值。

    所以包含5列的前30行存储在dataX中,只有open列的第31行存储在dataY中。然后我们将dataX和dataY列表转换为数组,它们以数组格式在LSTM中进行训练。

    我们来看看形状。

    print("trainX Shape-- ",trainX.shape)
    print("trainY Shape-- ",trainY.shape)
    
    (4132, 30, 5)
    (4132,)
    
    print("testX Shape-- ",testX.shape)
    print("testY Shape-- ",testY.shape)
    
    (1011, 30, 5)
    (1011,)
    

    4132 是 trainX 中可用的数组总数,每个数组共有 30 行和 5 列, 在每个数组的 trainY 中,我们都有下一个目标值来训练模型。

    让我们看一下包含来自 trainX 的 (30,5) 数据的数组之一 和 trainX 数组的 trainY 值

    print("trainX[0]-- \n",trainX[0])
    print("trainY[0]-- ",trainY[0])
    

    如果查看 trainX[1] 值,会发现到它与 trainX[0] 中的数据相同(第一列除外),因为我们将看到前 30 个来预测第 31 列,在第一次预测之后它会自动移动 到第 2 列并取下一个 30 值来预测下一个目标值。

    让我们用一种简单的格式来解释这一切——

    trainX — — →trainY
    
    [0 : 30,0:5] → [30,0]
    
    [1:31, 0:5] → [31,0]
    
    [2:32,0:5] →[32,0]
    

    像这样,每个数据都将保存在 trainX 和 trainY 中

    现在让我们训练模型,我使用 girdsearchCV 进行一些超参数调整以找到基础模型。

    def build_model(optimizer):
        grid_model = Sequential()
        grid_model.add(LSTM(50,return_sequences=True,input_shape=(30,5)))
        grid_model.add(LSTM(50))
        grid_model.add(Dropout(0.2))
        grid_model.add(Dense(1))
    
    grid_model.compile(loss = 'mse',optimizer = optimizer)
        return grid_modelgrid_model = KerasRegressor(build_fn=build_model,verbose=1,validation_data=(testX,testY))
    
    parameters = {'batch_size' : [16,20],
                  'epochs' : [8,10],
                  'optimizer' : ['adam','Adadelta'] }
    
    grid_search  = GridSearchCV(estimator = grid_model,
                                param_grid = parameters,
                                cv = 2)
    

    如果你想为你的模型做更多的超参数调整,也可以添加更多的层。 但是如果数据集非常大建议增加 LSTM 模型中的时期和单位。

    在第一个 LSTM 层中看到输入形状为 (30,5)。 它来自 trainX 形状。 (trainX.shape[1],trainX.shape[2]) → (30,5)

    现在让我们将模型拟合到 trainX 和 trainY 数据中。

    grid_search = grid_search.fit(trainX,trainY)
    

    由于进行了超参数搜索,所以这将需要一些时间来运行。

    你可以看到损失会像这样减少——

    现在让我们检查模型的最佳参数。

    grid_search.best_params_
    
    {‘batch_size’: 20, ‘epochs’: 10, ‘optimizer’: ‘adam’}
    

    将最佳模型保存在 my_model 变量中。

    my_model=grid_search.best_estimator_.model
    

    现在可以用测试数据集测试模型。

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

    testY 和 prediction 的长度是一样的。 现在可以将 testY 与预测进行比较。

    但是我们一开始就对数据进行了缩放,所以首先我们必须做一些逆缩放过程。

    scaler.inverse_transform(prediction)
    

    报错了,这是因为在缩放数据时,我们每行有 5 列,现在我们只有 1 列是目标列。

    所以我们必须改变形状来使用 inverse_transform

    prediction_copies_array = np.repeat(prediction,5, axis=-1)
    

    5 列值是相似的,它只是将单个预测列复制了 4 次。所以现在我们有 5 列相同的值 。

    prediction_copies_array.shape
    (1011,5)
    

    这样就可以使用 inverse_transform 函数。

    pred=scaler.inverse_transform(np.reshape(prediction_copies_array,(len(prediction),5)))[:,0]
    

    但是逆变换后的第一列是我们需要的,所以我们在最后使用了 → [:,0]。

    现在将这个 pred 值与 testY 进行比较,但是 testY 也是按比例缩放的,也需要使用与上述相同的代码进行逆变换。

    original_copies_array = np.repeat(testY,5, axis=-1)
    original=scaler.inverse_transform(np.reshape(original_copies_array,(len(testY),5)))[:,0]
    

    现在让我们看一下预测值和原始值 →

    print("Pred Values-- " ,pred)
    print("\nOriginal Values-- " ,original)
    

    最后绘制一个图来对比我们的 pred 和原始数据。

    plt.plot(original, color = 'red', label = 'Real Stock Price')
    plt.plot(pred, color = 'blue', label = 'Predicted Stock Price')
    plt.title('Stock Price Prediction')
    plt.xlabel('Time')
    plt.ylabel('Google Stock Price')
    plt.legend()
    plt.show()
    

    看样子还不错,到目前为止,我们训练了模型并用测试值检查了该模型。 现在让我们预测一些未来值。

    从主 df 数据集中获取我们在开始时加载的最后 30 个值[为什么是 30? 因为这是我们想要的过去值的数量,来预测第 31 个值]

    df_30_days_past=df.iloc[-30:,:]
    df_30_days_past.tail()
    

    可以看到有包括目标列(“Open”)在内的所有列。现在让我们预测未来的 30 个值。

    在多元时间序列预测中,需要通过使用不同的特征来预测单列,所以在进行预测时我们需要使用特征值(目标列除外)来进行即将到来的预测。

    这里我们需要“High”、“Low”、“Close”、“Adj Close”列的即将到来的 30 个值来对“Open”列进行预测。

    df_30_days_future=pd.read_csv("test.csv",parse_dates=["Date"],index_col=[0])
    df_30_days_future
    

    剔除“Open”列后,使用模型进行预测之前还需要做以下的操作:

    缩放数据,因为删除了‘Open’列,在缩放它之前,添加一个所有值都为“0”的Open列。

    缩放后,将未来数据中的“Open”列值替换为“nan”

    现在附加 30 天旧值和 30 天新值(其中最后 30 个“打开”值是 nan)

    df_30_days_future["Open"]=0
    df_30_days_future=df_30_days_future[["Open","High","Low","Close","Adj Close"]]
    old_scaled_array=scaler.transform(df_30_days_past)
    new_scaled_array=scaler.transform(df_30_days_future)
    new_scaled_df=pd.DataFrame(new_scaled_array)
    new_scaled_df.iloc[:,0]=np.nan
    full_df=pd.concat([pd.DataFrame(old_scaled_array),new_scaled_df]).reset_index().drop(["index"],axis=1)
    

    full_df 形状是 (60,5),最后第一列有 30 个 nan 值。

    要进行预测必须再次使用 for 循环,我们在拆分 trainX 和 trainY 中的数据时所做的。 但是这次我们只有 X,没有 Y 值

    full_df_scaled_array=full_df.values
    all_data=[]
    time_step=30
    for i in range(time_step,len(full_df_scaled_array)):
        data_x=[]
        data_x.append(
         full_df_scaled_array[i-time_step :i , 0:full_df_scaled_array.shape[1]])
        data_x=np.array(data_x)
        prediction=my_model.predict(data_x)
        all_data.append(prediction)
        full_df.iloc[i,0]=prediction
    

    对于第一个预测,有之前的 30 个值,当 for 循环第一次运行时它会检查前 30 个值并预测第 31 个“Open”数据。

    当第二个 for 循环将尝试运行时,它将跳过第一行并尝试获取下 30 个值 [1:31] 。这里会报错错误因为Open列最后一行是 “nan”,所以需要每次都用预测替换“nan”。

    最后还需要对预测进行逆变换→

    new_array=np.array(all_data)
    new_array=new_array.reshape(-1,1)
    prediction_copies_array = np.repeat(new_array,5, axis=-1)
    y_pred_future_30_days = scaler.inverse_transform(np.reshape(prediction_copies_array,(len(new_array),5)))[:,0]
    print(y_pred_future_30_days)
    

    这样一个完整的流程就已经跑通了。

    如果你想看完整的代码,可以在这里查看:

    https://www.overfit.cn/post/1a36216705f2441b80fca567ea61e365

    作者:Sksujanislam

    展开全文
  • 对于较为简单的时间序列预测问题,可以使用Exponential Smoothing和ARIMA等传统模型非常方便地求解。然而,对于复杂的时间序列预测问题,LSTM不失为一种很好的选择。因此,本文旨在探讨如何利用LSTM神经网络求解时间...

            对于较为简单的时间序列预测问题,可以使用Exponential Smoothing和ARIMA等传统模型非常方便地求解。然而,对于复杂的时间序列预测问题,LSTM不失为一种很好的选择。因此,本文旨在探讨如何利用LSTM神经网络求解时间序列预测问题。首先,需要明白时间序列预测问题是如何转换为传统的监督学习问题的,即时间窗方法。有关时间序列预测问题转换为监督学习的过程请移步:Time Series Forecasting as Supervised Learning

    1.分析时间序列的特点        

            时间序列预测关键:确定已有的时间序列的变化模式,并假定这种模式会延续到未来。下面首先介绍一下时间序列的一般特点,具体请移步:时间序列分析和预测

    (1)平稳序列(stationary series)
           基本上不存在趋势的序列,序列中的各观察值基本上在某个固定的水平上波动,在不同时间段波动程度不同,但不存在某种规律,随机波动。

    (2)非平稳序列(non-stationary series)
           包含趋势、季节性或周期性的序列,只含有其中一种成分,也可能是几种成分的组合。可分为:有趋势序列、有趋势和季节性序列、几种成分混合而成的复合型序列。

           趋势(trend):时间序列在长时期内呈现出来的某种持续上升或持续下降的变动,也称长期趋势。时间序列中的趋势可以是线性和非线性。

           季节性(seasonality):季节变动(seasonal fluctuation),是时间序列在一年内重复出现的周期波动。销售旺季,销售淡季,旅游旺季、旅游淡季,因季节不同而发生变化。季节,不仅指一年中的四季,其实是指任何一种周期性的变化。含有季节成分的序列可能含有趋势,也可能不含有趋势。

            周期性(cyclicity):循环波动,是时间序列中呈现出来的围绕长期趋势的一种波浪形或振荡式波动。

            除此之外,还有偶然性因素对时间序列产生影响,致使时间序列呈现出某种随机波动。时间序列除去趋势、周期性和季节性后的偶然性波动,称为随机性(random),也称不规则波动(irregular variations)。

    2.单变量时间序列预测

            有关航班乘客流量预测问题的具体细节,请移步:用 LSTM 做时间序列预测的一个小例子

    问题:航班乘客预测 
    数据:1949 到 1960 一共 12 年,每年 12 个月的数据,一共 144 个数据,单位是 1000 
    下载地址 
    目标:预测国际航班未来 1 个月的乘客数

    '''
    Created on 2019年2月16日
        时间序列预测问题可以通过滑动窗口法转换为监督学习问题
    @author: Administrator
    '''
    
    import numpy
    import matplotlib.pyplot as plt
    from pandas import read_csv
    import math
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.layers import LSTM
    from sklearn.preprocessing import MinMaxScaler
    from sklearn.metrics import mean_squared_error
    from keras.utils.vis_utils import plot_model
    
    # 创建数据集
    def create_dataset(dataset, look_back=1):
        dataX, dataY = [], []
        for i in range(len(dataset)-look_back-1):
            a = dataset[i:(i+look_back), 0]
            dataX.append(a)
            dataY.append(dataset[i + look_back, 0])
        return numpy.array(dataX), numpy.array(dataY)
    
    if __name__ == '__main__':
        # 加载数据
        dataframe = read_csv('international-airline-passengers.csv', usecols=[1], engine='python', skipfooter=3)
        dataset = dataframe.values
        # 将整型变为float
        dataset = dataset.astype('float32')     
        
        # 数据处理,归一化至0~1之间
        scaler = MinMaxScaler(feature_range=(0, 1))
        dataset = scaler.fit_transform(dataset)
        
        # 划分训练集和测试集
        train_size = int(len(dataset) * 0.67)
        test_size = len(dataset) - train_size
        train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
        
        # 创建测试集和训练集
        look_back = 1
        trainX, trainY = create_dataset(train, look_back)           #单步预测
        testX, testY = create_dataset(test, look_back)
        
        # 调整输入数据的格式
        trainX = numpy.reshape(trainX, (trainX.shape[0], look_back, trainX.shape[1]))       #(样本个数,1,输入的维度)
        testX = numpy.reshape(testX, (testX.shape[0], look_back, testX.shape[1]))
        
        # 创建LSTM神经网络模型
        model = Sequential()
        model.add(LSTM(120, input_shape=(trainX.shape[1], trainX.shape[2])))            #输入维度为1,时间窗的长度为1,隐含层神经元节点个数为120
        model.add(Dense(1))
        model.compile(loss='mean_squared_error', optimizer='adam')
        model.fit(trainX, trainY, epochs=100, batch_size=1, verbose=2)
        
        # 绘制网络结构
        plot_model(model, to_file='E:/model.png', show_shapes=True);
        
        # 预测
        trainPredict = model.predict(trainX)
        testPredict = model.predict(testX)
        
        # 反归一化
        trainPredict = scaler.inverse_transform(trainPredict)
        trainY = scaler.inverse_transform([trainY])
        testPredict = scaler.inverse_transform(testPredict)
        testY = scaler.inverse_transform([testY])
        
        # 计算得分
        trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0]))
        print('Train Score: %.2f RMSE' % (trainScore))
        testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0]))
        print('Test Score: %.2f RMSE' % (testScore))
        
        # 绘图
        trainPredictPlot = numpy.empty_like(dataset)
        trainPredictPlot[:, :] = numpy.nan
        trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
        testPredictPlot = numpy.empty_like(dataset)
        testPredictPlot[:, :] = numpy.nan
        testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict
        plt.plot(scaler.inverse_transform(dataset))
        plt.plot(trainPredictPlot)
        plt.plot(testPredictPlot)
        plt.show();

            实验结果:

    Using TensorFlow backend.
    Epoch 100/100
     - 0s - loss: 0.0022
    Train Score: 22.79 RMSE
    Test Score: 50.42 RMSE
    

           注意,在进行数据处理时,将输入trainX改造为LSTM的输入格式,即[samples,timesteps,features]。

    3.多变量时间序列预测

            有时,为了充分利用已有的信息,需要利用除了预测变量之外的其他若干个变量同时进行预测,即所谓的多变量时间序列预测。与单变量时间序列预测不同之处在于数据处理。

            例如,对于下述数据集:北京的美国大使馆在2010年至2014年共5年间每小时采集的天气及空气污染指数,其中包括日期、PM2.5浓度、露点、温度、风向、风速、累积小时雪量和累积小时雨量。

            在单变量时间序列预测中,数据通常被处理为下述格式:

       pollution(t-1)  pollution(t)
    1   0.129779   0.148893
    2   0.148893   0.159960
    3   0.159960   0.182093
    4   0.182093   0.138833
    5   0.138833   0.109658

            然而,在多变量时间序列预测时,数据通常被处理为下述格式: 

       pollution(t-1)  dew(t-1)  temp(t-1)  press(t-1)  wnd_dir(t-1)  wnd_spd(t-1)  \
    1   0.129779   0.352941   0.245902   0.527273   0.666667   0.002290
    2   0.148893   0.367647   0.245902   0.527273   0.666667   0.003811
    3   0.159960   0.426471   0.229508   0.545454   0.666667   0.005332
    4   0.182093   0.485294   0.229508   0.563637   0.666667   0.008391
    5   0.138833   0.485294   0.229508   0.563637   0.666667   0.009912
    
       snow(t-1)  rain(t-1)   pollution(t)
    1   0.000000        0.0  0.148893
    2   0.000000        0.0  0.159960
    3   0.000000        0.0  0.182093
    4   0.037037        0.0  0.138833
    5   0.074074        0.0  0.109658

            多变量时间序列预测的具体实例请移步:基于Keras的LSTM多变量时间序列预测

    展开全文
  • 基于聚类和神经网络的多变量时间序列预测方法,单傲,闫丹凤,变量时间序列数据在日常生活中分布广泛,并且在很领域中得到广泛研究。但是其中仍然存在着一些挑战,比如提取时间序列内部的
  • PyTorch搭建LSTM实现多变量时间序列预测(负荷预测)
  • 深度学习多变量时间序列预测:LSTM算法构建时间序列变量模型预测交通流量+代码实战 LSTM(Long Short Term Memory Network)长短时记忆网络,是一种改进之后的循环神经网络,可以解决 RNN 无法处理长距离的依赖的...
  • 原标题:教程 | 基于Keras的LSTM多变量时间序列预测选自machinelearningmastery参与:朱乾树、路雪长短期记忆循环神经网络等几乎可以完美地模拟个输入变量的问题,这为时间序列预测带来极大益处。本文介绍了如何在...
  • 在Keras中使用LSTM模型进行多变量时间序列预测

    万次阅读 多人点赞 2019-08-25 20:59:50
    今天我给大家介绍一个国外深度学习大牛Jason Brownlee写的一篇关于多变量时间序列预测的博客,我在原文的代码基础上做了一点点修改,只是为了便于大家更好的理解。在本文中,您将了解如何在Keras深度学习库中为...
  • 深度学习多变量时间序列预测:Encoder-Decoder LSTM算法构建时间序列变量模型预测交通流量+代码实战 LSTM是一种时间递归神经网络,适合于处理和预测时间序列中间隔和延迟相对较长的重要事件。在自然语言处理、...
  • Tensorflow使用LSTM模型中的多变量时间序列预测 # Copyright 2017 The TensorFlow Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not ...
  • 变量时间序列预测 数据类型:单列 ​ import numpy import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM from keras....
  • 基于Keras的LSTM多变量时间序列预测

    万次阅读 多人点赞 2018-01-12 17:48:51
     传统的线性模型难以解决多变量输入问题,而神经网络如LSTM则擅长于处理变量的问题,该特性使其有助于解决时间序列预测问题。    在接下来的这篇博客中,你将学会如何利用深度学习库Keras搭建LSTM模型来...
  • 深度学习多变量时间序列预测:Encoder-Decoder LSTM算法构建时间序列变量模型预测交通流量+代码实战.pdf
  • Keras中的多变量时间序列预测-LSTMs

    千次阅读 2021-01-27 06:52:18
    在本教程中,您将了解如何在Keras深度学习库中,为多变量时间序列预测开发LSTM模型。学习该教程后,您将收获:如何将原始数据集转换为可用于时间序列预测的数据集;如何准备数据,并使LSTM模型适用于多变量时间序列...
  • LSTM实践多变量时间序列预测

    千次阅读 2019-01-23 23:26:38
    本文是 第一部分数据处理: 数据下载: ...如何将时间序列问题转化为监督学习问题 个人理解:与xs(t)也就是训练目标在DATAFRAME中相对应的应该ys(t+1),即其预测的值同时刻的真实值  
  • 深度学习多变量时间序列预测:卷积神经网络(CNN)算法构建时间序列变量模型预测交通流量+代码实战 卷积神经网络,听起来像是计算机科学、生物学和数学的诡异组合,但它们已经成为计算机视觉领域中最具影响力的...
  • 变量时间序列公开数据集,格式.csv,字段Datetime和AEP_MW,时间间隔为小时!
  • 变量和单变量时间序列预测 使用深度学习和浅层学习算法进行时间序列预测 Multivariate and Univariate Time Series Prediction Time Series Prediction by use of Deep learning and shallow learning algorithms
  • 本文为你介绍如何在Keras深度学习库中搭建用于多变量时间序列预测的LSTM模型。 长短期记忆循环神经网络等几乎可以完美地模拟个输入变量的问题,这为时间序列预测带来极大益处。本文介绍了如何在 Keras 深度...
  • 基于Keras的LSTM多变量时间序列预测  传统的线性模型难以解决变量或输入问题,而神经网络如LSTM则擅长于处理个变量的问题,该特性使其有助于解决时间序列预测问题。     在接下来的这篇博客中,你将学会...
  • PyTorch搭建LSTM实现多变量多步长时间序列预测(负荷预测)
  • LSTM在时间序列预测方面的应用非常广,但有相当一部分没有考虑使用长的数据预测下一个,类似AR模型中的阶数P。我基于matlab2021版编写了用LSTM模型实现多步预测时间序列的程序代码,可以自己调整使用的数据“阶数...
  • 时间序列预测 | Python实现LSTM多变量时间序列数据预测 目录时间序列预测 | Python实现LSTM多变量时间序列数据预测基本介绍程序设计参考资料 基本介绍 时间序列分析(Time-Series Analysis)是指将原来的销售分解为...
  • tensorflow下用LSTM网络进行时间序列预测,实时多变量预测以及对于未来数据的单变量预测。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 48,014
精华内容 19,205
关键字:

多变量时间序列预测