当前位置:   article > 正文

时间序列预测_在时间序列预测中,数据集怎么做

在时间序列预测中,数据集怎么做

参考:

  • https://tensorflow.google.cn/tutorials/structured_data/time_series

一、时间序列预测

1.1、数据集

#显示所有列(参数设置为None代表显示所有行,也可以自行设置数字)
pd.set_option('display.max_columns',None)
#禁止自动换行(设置为Flase不自动换行,True反之)
pd.set_option('expand_frame_repr', False)

def loadWeatherData():
    # 如果直接下载不了,将提前下载好的数据集放到指定的dataset目录(xx\.keras\datasets\)
    zip_path = tf.keras.utils.get_file(
        origin='https://storage.googleapis.com/tensorflow/tf-keras-datasets/jena_climate_2009_2016.csv.zip',
        fname='jena_climate_2009_2016.csv.zip',
        extract=True)
    csv_path, _ = os.path.splitext(zip_path)
    print(csv_path)

    # 使用pands读取csv文件
    df = pd.read_csv(csv_path)
    print(df.head())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

每10分钟一条记录
在这里插入图片描述
如上所示,每10分钟记录一次观察。这意味着,在一个小时内,你将有6次观察。同样,一天将包含144 (6x24)次观测。

给定一个特定的时间,假设你想预测未来6小时的温度。为了做出预测,你选择使用5天的观测。因此,您将创建一个包含最后720(5x144)次观察的窗口来训练模型。可能有许多这样的配置,这使这个数据集成为一个很好的实验对象。

下面的函数返回上面描述的模型训练时间窗口。参数history_size是信息的过去窗口的大小。target_size是需要预测的标签。

def univariate_data(dataset, start_index, end_index, history_size, target_size):
    '''
    dataset:
    start_index:
    end_index:
    history_size:
    target_size:

    @return: 特征, 标签
    '''

    data = []
    labels = []

    start_index = start_index + history_size
    if end_index is None:
        end_index = len(dataset) - target_size

    for i in range(start_index, end_index):
        indices = range(i-history_size, i)
        # Reshape data from (history_size,) to (history_size, 1)
        data.append(np.reshape(dataset[indices], (history_size, 1)))
        labels.append(dataset[i+target_size])

    return np.array(data), np.array(labels)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

1.2、单一变量预测

1.2.1、提取单一便利,此例中提取温度

# 抽取单一变量, 此处为温度,以供使用预测
uni_data = df['T (degC)']
# 线性的数据结构, series是一个一维数组
# Pandas 会默然用0到n-1来作为series的index, 但也可以自己指定index( 可以把index理解为dict里面的key )
uni_data.index = df['Date Time']
print(type(uni_data), '\n' ,uni_data.head())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

数据可视化

#可视化
uni_data.plot(subplots=True)
plt.show()
  • 1
  • 2

在这里插入图片描述

1.2.2、数据集归一化

Note: The mean and standard deviation should only be computed using the training data.

# 训练数据的平均及标准差
uni_train_mean = uni_data[:TRAIN_SPLIT].mean()
uni_train_std = uni_data[:TRAIN_SPLIT].std()

# 归一化
uni_data = (uni_data - uni_train_mean)/uni_train_std
  • 1
  • 2
  • 3
  • 4
  • 5

1.2.3、拆分训练集与验证数据集

# 训练集
x_train_uni, y_train_uni = univariate_data(uni_data, 0, TRAIN_SPLIT,
                                           univariate_past_history,
                                           univariate_future_target)
# 验证集
x_val_uni, y_val_uni = univariate_data(uni_data, TRAIN_SPLIT, None,
                                   univariate_past_history,
                                   univariate_future_target)

print ('Single window of past history')
print (x_train_uni[0])
print ('\n Target temperature to predict')
print (y_train_uni[0])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

下图中蓝色线是给网络训练的数据, 红色叉叉是要预测的数据

def create_time_steps(length):
    return list(range(-length, 0))

def baseline(history):
    # 历史的平均值,作为预测的对比基线
    return np.mean(history)

def show_plot(plot_data, delta, title):
    labels = ['History', 'True Future', 'Model Prediction']
    marker = ['.-', 'rx', 'go']
    time_steps = create_time_steps(plot_data[0].shape[0])
    if delta:
        future = delta
    else:
        future = 0

    plt.title(title)
    for i, x in enumerate(plot_data):
        if i:
            plt.plot(future, plot_data[i], marker[i], markersize=10,
                     label=labels[i])
        else:
            plt.plot(time_steps, plot_data[i].flatten(), marker[i], label=labels[i])
    plt.legend()
    plt.xlim([time_steps[0], (future+5)*2])
    plt.xlabel('Time-Step')
    return plt

show_plot([x_train_uni[0], y_train_uni[0]], 0, 'Sample Example')
plt.show()
  • 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

在这里插入图片描述

在继续训练模型之前,让我们首先设置一个简单的基线。给定一个输入点,基线方法查看所有历史记录,并预测下一个点是最近20个观察值的平均值。

show_plot([x_train_uni[0], y_train_uni[0], baseline(x_train_uni[0])], 0,
          'Baseline Prediction Example')
plt.show()
  • 1
  • 2

在这里插入图片描述
让我们看看你是否可以使用递归神经网络来超越这个基线。

1.2.4、 RNN

1.2.4.1、构建输入数据
BATCH_SIZE = 256
BUFFER_SIZE = 10000

train_univariate = tf.data.Dataset.from_tensor_slices((x_train_uni, y_train_uni))
train_univariate = train_univariate.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()

val_univariate = tf.data.Dataset.from_tensor_slices((x_val_uni, y_val_uni))
val_univariate = val_univariate.batch(BATCH_SIZE).repeat()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

1.2.4.2、模型
# 创建一个LSTM模型
simple_lstm_model = tf.keras.models.Sequential([
    tf.keras.layers.LSTM(8, input_shape=x_train_uni.shape[-2:]),
    tf.keras.layers.Dense(1)
])
# 编译模型
simple_lstm_model.compile(optimizer='adam', loss='mae')

for x, y in val_univariate.take(1):
    print(simple_lstm_model.predict(x).shape)

# 训练模型
EVALUATION_INTERVAL = 200
EPOCHS = 10
simple_lstm_model.fit(train_univariate, epochs=EPOCHS,
                      steps_per_epoch=EVALUATION_INTERVAL,
                      validation_data=val_univariate, validation_steps=50)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
1.2.4.3、预测
# 预测
for x, y in val_univariate.take(3):
    plot = show_plot([x[0].numpy(), y[0].numpy(),
                      simple_lstm_model.predict(x)[0]], 0, 'Simple LSTM model')
    plot.show()
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3、多变量预测

1.3.1、提取多变量

# 原数据集中有14个特征, 此处为了方便,暂时只提取3个特征
features_considered = ['p (mbar)', 'T (degC)', 'rho (g/m**3)']
uni_data = df[features_considered]
# 线性的数据结构, series是一个一维数组
# Pandas 会默然用0到n-1来作为series的index, 但也可以自己指定index( 可以把index理解为dict里面的key )
uni_data.index = df['Date Time']
print(type(uni_data), '\n', uni_data.head())

# 可视化
uni_data.plot(subplots=True)
plt.show()

print(type(uni_data))
uni_data = uni_data.values

# 数据的平均及标准差 axis=0 按照列计算
uni_train_mean = uni_data[:TRAIN_SPLIT].mean(axis=0)
uni_train_std = uni_data[:TRAIN_SPLIT].std(axis=0)

# 归一化
uni_data = (uni_data - uni_train_mean) / uni_train_std
print(uni_data.shape, uni_train_mean.shape, uni_train_std.shape)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在这里插入图片描述

1.3.2、Single Step

  在单一步骤设置中,模型会根据提供的历史预测未来的单一点。

下面的函数执行与下面相同的窗口任务,但是,这里它根据给定的步长采样过去的观察结果。

def multivariate_data(dataset, target, start_index, end_index, history_size,
                      target_size, step, single_step=False):
    data = []
    labels = []

    start_index = start_index + history_size
    if end_index is None:
        end_index = len(dataset) - target_size

    for i in range(start_index, end_index):
        indices = range(i - history_size, i, step) # 五天数据, 每小时抽取一次, 本来5天720份数据,现在使用120份数据代替过去5天的历史
        data.append(dataset[indices])

        if single_step:
            labels.append(target[i + target_size])
        else:
            labels.append(target[i:i + target_size])

    return np.array(data), np.array(labels)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
1.3.2.1、构建输入数据
BATCH_SIZE = 256
BUFFER_SIZE = 10000

train_univariate = tf.data.Dataset.from_tensor_slices((x_train_single, y_train_single))
train_univariate = train_univariate.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()

val_univariate = tf.data.Dataset.from_tensor_slices((x_val_single, y_val_single))
val_univariate = val_univariate.batch(BATCH_SIZE).repeat()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
1.3.2.2、模型
# 创建一个LSTM模型
simple_lstm_model = tf.keras.models.Sequential([
    tf.keras.layers.LSTM(32, input_shape=x_train_single.shape[-2:]),
    tf.keras.layers.Dense(1)
])
# 编译模型
simple_lstm_model.compile(optimizer=tf.keras.optimizers.RMSprop(), loss='mae')

for x, y in val_univariate.take(1):
    print(simple_lstm_model.predict(x).shape, simple_lstm_model.predict(x))

# 训练模型
EVALUATION_INTERVAL = 200
EPOCHS = 10
history = simple_lstm_model.fit(train_univariate, epochs=EPOCHS,
                      steps_per_epoch=EVALUATION_INTERVAL,
                      validation_data=val_univariate, validation_steps=50)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

训练与验证数据集的损失

# 绘制训练、验证数据的损失
def plot_train_history(history, title):
    loss = history.history['loss']
    val_loss = history.history['val_loss']

    epochs = range(len(loss))

    plt.figure()

    plt.plot(epochs, loss, 'b', label='Training loss')
    plt.plot(epochs, val_loss, 'r', label='Validation loss')
    plt.title(title)
    plt.legend()

    plt.show()
 


plot_train_history(history, 'Single Step Training and validation loss')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在这里插入图片描述

1.3.2.3、预测未来点
for x, y in val_univariate.take(3):
    plot = show_plot([x[0][:, 1].numpy(), y[0].numpy(),
                      simple_lstm_model.predict(x)[0]], 12,
             'Single Step Prediction')
    plot.show()
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3.3、Multi Step

在多步预测模型中,给定过去的历史,模型需要学习预测未来的一系列值。因此,与只预测单个未来点的单步模型不同,多步模型预测未来的序列。对于多步骤模型,训练数据同样由过去5天每小时采样的记录组成。然而,在这里,模型需要学习预测未来12小时的温度。由于每10分钟进行一次对话,因此输出72个预测。对于这个任务,需要相应地准备数据集,因此第一步只是再次创建它,但是使用不同的目标窗口。

1.3.3.1、构建输入数据

# 原数据集中有14个特征, 此处为了方便,暂时只提取3个特征
features_considered = ['p (mbar)', 'T (degC)', 'rho (g/m**3)']
uni_data = df[features_considered]
# 线性的数据结构, series是一个一维数组
# Pandas 会默然用0到n-1来作为series的index, 但也可以自己指定index( 可以把index理解为dict里面的key )
uni_data.index = df['Date Time']
uni_data = uni_data.values

# 数据的平均及标准差
uni_train_mean = uni_data[:TRAIN_SPLIT].mean(axis=0)
uni_train_std = uni_data[:TRAIN_SPLIT].std(axis=0)

# 归一化
dataset = (uni_data - uni_train_mean) / uni_train_std
print(dataset.shape, dataset[0: 1])

past_history = 720  # 过去5天总共有720份观测数据(每10分钟一次)
future_target = 72  # 由于60min不会出现大的巨变,所以进行抽样,每小时一次
STEP = 6  #

future_target = 72
x_train_multi, y_train_multi = multivariate_data(dataset, dataset[:, 1], 0,
                                                 TRAIN_SPLIT, past_history,
                                                 future_target, STEP)
x_val_multi, y_val_multi = multivariate_data(dataset, dataset[:, 1],
                                             TRAIN_SPLIT, None, past_history,
                                             future_target, STEP)

print('Single window of past history : {}'.format(x_train_multi[0].shape))
print('\n Target temperature to predict : {}'.format(y_train_multi[0].shape))

BATCH_SIZE = 256
BUFFER_SIZE = 10000
train_data_multi = tf.data.Dataset.from_tensor_slices((x_train_multi, y_train_multi))
train_data_multi = train_data_multi.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()

val_data_multi = tf.data.Dataset.from_tensor_slices((x_val_multi, y_val_multi))
val_data_multi = val_data_multi.batch(BATCH_SIZE).repeat()

for x, y in train_data_multi.take(1):
    multi_step_plot(x[0], y[0], np.array([0]))
  • 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 multi_step_plot(history, true_future, prediction, STEP=6):
    plt.figure(figsize=(12, 6))
    num_in = create_time_steps(len(history))
    num_out = len(true_future)

    plt.plot(num_in, np.array(history[:, 1]), label='History')
    plt.plot(np.arange(num_out) / STEP, np.array(true_future), 'bo', label='True Future')
    if prediction.any(): # 预测
        plt.plot(np.arange(num_out) / STEP, np.array(prediction), 'ro', label='Predicted Future')
    plt.legend(loc='upper left')
    plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这里插入图片描述

1.3.3.2、模型
# 构建模型
multi_step_model = tf.keras.models.Sequential()
multi_step_model.add(tf.keras.layers.LSTM(32,
                                          return_sequences=True,
                                          input_shape=x_train_multi.shape[-2:]))
multi_step_model.add(tf.keras.layers.LSTM(16, activation='relu'))
multi_step_model.add(tf.keras.layers.Dense(72))
# 训练模型
multi_step_model.compile(optimizer=tf.keras.optimizers.RMSprop(clipvalue=1.0), loss='mae')

EVALUATION_INTERVAL = 200
EPOCHS = 10
multi_step_history = multi_step_model.fit(train_data_multi, epochs=EPOCHS,
                                          steps_per_epoch=EVALUATION_INTERVAL,
                                          validation_data=val_data_multi,
                                          validation_steps=50)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

loss

# loss
plot_train_history(multi_step_history, 'Multi-Step Training and validation loss')
  • 1

在这里插入图片描述

1.3.3.3、预测
# 预测
for x, y in val_data_multi.take(3):
    multi_step_plot(x[0], y[0], multi_step_model.predict(x)[0])
  • 1
  • 2

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

闽ICP备14008679号