时序序列预测-温度

最近看了一些关于时序序列预测的论文,找了一份耶拿天气数据集,数据集维度:(420551, 14),时间跨度:2009~2016,每10min采样一次。
预测要求:根据给出的前10天的观测数据(气压、风速、温度等),预测未来24h时的温度。
数据项如下:

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

1. 生成train、val、test数据集

假设数据取样的周期为每小时,即step=6,则一条训练样本的格式如下,维度:(240,14),可以发现数据集第0列在1000左右,第二列在20左右。因此数据集生成前需要进行归一化。
假设一批数据的batch_size为128,则一批训练数据的维度:(128,240,14),预测标签的维度为(128,)

[[9.8723e+02 1.6850e+01 2.9108e+02 ... 3.0900e+00 4.8000e+00 1.4690e+02]
 [9.8631e+02 1.8250e+01 2.9256e+02 ... 3.4400e+00 5.4400e+00 1.7520e+02]
 [9.8576e+02 1.9000e+01 2.9336e+02 ... 4.0400e+00 7.1200e+00 2.1110e+02]
 ...
 [9.9341e+02 1.2670e+01 2.8637e+02 ... 1.6700e+00 3.8000e+00 1.6400e+02]
 [9.9338e+02 1.7280e+01 2.9099e+02 ... 8.5000e-01 1.5200e+00 1.0590e+02]
 [9.9273e+02 2.1720e+01 2.9550e+02 ... 2.1100e+00 4.3600e+00 2.2110e+02]]
14.04
def generator(data, lookback, delay, min_index, max_index,
              shuffle=False, batch_size=128, step=6):
    """   
    :param data:  原始数据集
    :param lookback:  前M个步长的已知数据
    :param delay:  后N个步长的待预测数据的target
    :param min_index: 数据集划分的起始行
    :param max_index: 数据集划分的结束行
    :param shuffle:  是否打乱顺序,生成训练集一般设置为True
    :param batch_size: 
    :param step: 步长,取样间隔
    :return: 
    """
    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

2. 搭建网络模型

之前,学习神经网络的时候基本是多分类问题,输出层的激活函数使用的是一般是Softmax。查了一下输出层激活函数的设计:根据输出值的区间范围来分类讨论。

❑ o ∈ R d :输出属于整个实数空间,如函数值趋势的预测,年龄的预测问题等。输出层可以不加激活函数,误差的计算直接基于最后一层的输出o和真实值 y 进行计算。
❑ o ∈ [0,1] :输出值特别地落在[0, 1]的区间,如二分类问题的概率,Sigmoid!!
❑ o ∈ [0, 1]:输出值落在[0, 1]的区间,并且所有输出值之和为 1,如多分类问题,Softmax!!
❑ o ∈ [−1, 1] :输出值在[-1, 1]之间,tanh!!

采用单层GRU模型跑一下,loss结果如图,在发生过拟合前,loss约为0.26

def gru(xt_data, xv_data, xt_shape, xv_step, epoch_step=500, epochs=20):
    model = Sequential()
    # 门控循环单元GRU
    model.add(layers.GRU(32, dropout=0.2, input_shape=(None, xt_shape)))
    # 全连接Dense层没有使用激活函数,在输出属于整个实数空间的预测问题中是常见的
    model.add(layers.Dense(1))
    # MAE作为损失函数
    model.compile(optimizer=RMSprop(), loss='mae')
    model.summary()
    # fit_generator函数输入为generator对象,返回一个history对象
    history = model.fit_generator(xt_data,
                                  steps_per_epoch=epoch_step,
                                  epochs=epochs,
                                  validation_data=xv_data,
                                  validation_steps=xv_step)
    return history

在这里插入图片描述

3. 增加网络层数

layers中封装了很多的结构,LSTM、Conv2D、MaxPool1D等,可以根据需要搭建。
在 Keras 中逐个堆叠循环层,所有中间层都应该返回完整的输出序列(一个3D 张量),即指定 return_sequences=True。

model = Sequential()
model.add(layers.LSTM(32, dropout=0.2,
						return_sequences=True,
			            input_shape=(None, xt_shape)))
model.add(layers.LSTM(64, activation='relu',                      
						dropout=0.1)) 
model.add(layers.Dense(1))

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/shlhhy/article/details/109090209