使用 Keras 向 NN 输入时间序列数据

Posted

技术标签:

【中文标题】使用 Keras 向 NN 输入时间序列数据【英文标题】:Time series data input to NN using Keras 【发布时间】:2018-05-11 16:24:16 【问题描述】:

进入代码之前,先对数据做一点说明:

具有 14 个特征的时间序列,但我们只专注于预测指数 2 处的温度。此外,给定数据的间隔为 10 分钟:

["Date Time","p (mbar)","T (degC)","Tpot (K)","Tdew (degC)","rh (%)","VPmax (mbar)","VPact (mbar)","VPdef (mbar)","sh (g/kg)","H2OCmmol/mol)","rho (g/m**3)","wv (m/s)","max. wv (m/s)","wd (deg)"]

接下来,作者解析文件并将其存储为numpy数组(注意:float_data不包含时间戳

import numpy as np

float_data = np.zeros((len(lines), len(header) - 1))
for i, line in enumerate(lines):
    values = [float(x) for x in line.split(',')[1:]]
    float_data[i, :] = values

接下来是一个规范化步骤,我在此略过。到目前为止,这很简单。以下步骤定义了一个生成元组(samples, targets) 的生成器,其中samples 是一批输入数据,targets 是相应的目标温度数组。它采用以下参数:

    data:浮点数据的原始数组,我们刚刚在上面的代码sn-p中进行了归一化。

    lookback:我们的输入数据应该回退多少时间步。

    延迟:我们的目标应该在未来多少个时间步长。

    min_index 和 max_index:数据数组中的索引,用于界定要从中提取的时间步长。这对于保留一部分数据进行验证和另一部分进行测试很有用。

    shuffle:是打乱我们的样本还是按时间顺序绘制它们。

    batch_size:每批次的样本数。

    step:我们对数据进行采样的时间段,以时间步长为单位。我们将其设置为 6,以便每小时绘制一个数据点。

    def generator(data, lookback, delay, min_index, max_index,
          shuffle=False, batch_size=128, step=6):
    
        if max_index is None:
            max_index = len(data) - delay - 1
        i = min_index + lookback
        while 1:
            if shuffle:
                 rows = np.random.randint(
                 min_index + lookback, max_index, size=batch_size)
            else:
                if i + batch_size >= max_index:
                    i = min_index + lookback
            rows = np.arange(i, min(i + batch_size, max_index))
            i += len(rows)
    
            samples = np.zeros((len(rows),
                       lookback // step,
                       data.shape[-1]))
            targets = np.zeros((len(rows),))
            for j, row in enumerate(rows):
                indices = range(rows[j] - lookback, rows[j], step)
                samples[j] = data[indices]
                targets[j] = data[rows[j] + delay][1]
            yield samples, targets
    
    
     lookback = 1440  # Basically, going back 10 days
     step = 6         # Taking an hourly sample     
     delay = 144      # Want to forecast temperature for the next 24 hours
     batch_size = 128
    
     train_gen = generator(float_data,
                  lookback=lookback,
                  delay=delay,
                  min_index=0,
                  max_index=200000,
                  shuffle=True,
                  step=step,
                  batch_size=batch_size)
    
     val_gen = generator(float_data,
                lookback=lookback,
                delay=delay,
                min_index=200001,
                max_index=300000,
                step=step,
                batch_size=batch_size)
    

现在,我了解了代码的作用。如果我错了,请纠正我。它将生成以下格式的输入数据:

每批将有 128 个序列,其中每个序列的长度为 240。例如:

批次 0:[[0-239],[1-240],[2-241],...[127-366]]

第 1 批:[[128-367],...,.... ]

在此之后,作者训练了一个简单的模型:

from keras.models import Sequential
from keras import layers
from keras.optimizers import RMSprop

model = Sequential()
model.add(layers.Flatten(input_shape=(lookback // step,   float_data.shape[-1])))
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(1))

model.compile(optimizer=RMSprop(), loss='mae')
history = model.fit_generator(train_gen,
                          steps_per_epoch=500,
                          epochs=20,
                          validation_data=val_gen,
                          validation_steps=val_steps)

我的问题

首先,我不明白为什么数据会以这种方式生成并输入神经网络。换句话说,为什么数据不能如下所示?:

第 0 批:[[0-240],[241-479],............]

第二,在train_gen中为什么shuffle参数设置为True?会导致数据失去时序性。

【问题讨论】:

第二个问题:是的,你的数据会洗牌。 关于问题1。你的代码不理解顺序,除非你告诉它你想要什么顺序,也许一些排序功能是合适的。 【参考方案1】:

数据的索引从0开始:因为序列长度是240:

len([0-239]) = 240

当你想要训练时,shuffle 设置为 True,当你想要评估时,你将它设置为 False

【讨论】:

【参考方案2】:

我猜这是 Francois Chollet 的 Python 深度学习示例。 回顾是建立样本观察的观察次数。

Step 将定义观察序列:

第 i 个观察指标如下:-

X -- [i, i+step, i+(2*Step), i+(3*step),...  .. ,(i+look_back/step)] 
y --- [(i+look_back/step)+delay]

batch_size = 此类观察的数量

例如:输入数据

   [[996.57,  -8.41, 265.01],
   [996.53,  -8.51, 264.91],
   [996.51,  -8.31, 265.12],
   [996.51,  -8.27, 265.15],
   [996.5 ,  -8.05, 265.38],
   [996.5 ,  -7.62, 265.81],
   [996.5 ,  -7.62, 265.81],
   [996.5 ,  -7.91, 265.52],
   [996.53,  -8.43, 264.99],
   [996.62,  -8.76, 264.66],
   [996.62,  -8.88, 264.54],
   [996.63,  -8.85, 264.57],
   [996.74,  -8.83, 264.58],

以下参数:

lookback = 6 step = 2 delay = 2 batch_size = 3

输出是:

 array([[[996.57,  -8.41, 265.01],
     [996.51,  -8.31, 265.12],
     [996.5 ,  -8.05, 265.38]],

    [[996.53,  -8.51, 264.91],
     [996.51,  -8.27, 265.15],
     [996.5 ,  -7.62, 265.81]],

    [[996.51,  -8.31, 265.12],
     [996.5 ,  -8.05, 265.38],
     [996.5 ,  -7.62, 265.81]]]), array([-8.43, -8.76, -8.88])]

设置 shuffle=True 并不重要,因为观察总是从索引回溯到特定索引。

过去 10 天的每小时读数用于预测 24 小时后的温度。因此,以这种格式生成数据 [[0-240],[241-479],.......] 不会给出预测(24 小时 + 10 分钟)温度的观测值

【讨论】:

【参考方案3】:

每个sample 包含batch_size 序列数,每个序列包含10 天的数据,即每小时的数据点,因此考虑到每天24 个数据点,这将是10 天的24*10 = 240 数据点。因此[0-239] 有 240 个数据点对应 10 天的数据。

shuffle 参数设置为True 以便为rows numpy 数组选择的索引将包含起点和终点之间的随机但连续的索引,即min_index + lookback, max_index, size=batch_size,大小为128。使用这个rows 数组我们构建了sample

因此总结: sample 3D 张量的形状 (128,240,14) 对应于 batch_size,考虑到我们在 10 天内每小时获取一个数据点,因为 step = 614 列的特征为每个数据点。

【讨论】:

以上是关于使用 Keras 向 NN 输入时间序列数据的主要内容,如果未能解决你的问题,请参考以下文章

如何格式化从keras转换的coreml中conv1d/lstm nn的输入数据

无法向自定义损失输入数据:渴望执行函数的输入不能是 Keras 符号张量

Keras - NN 预测计量测量中的误差。 [关闭]

拟合时 Keras GRU NN KeyError:“不在索引中”

使用 Keras 的 NN 将类预测为 dtype=float32 与 1、2、3 的真实类值相反,为啥?

2034:例5.1反序输出