RNN中的时间序列详细示例解释

在本教程中, 我们将使用带有时间序列数据的RNN。时间序列取决于以前的时间, 这意味着过去的值包括网络可以学习的重要信息。时间序列预测是为了估计任何序列的未来价值, 例如股票价格, 温度, GDP等。
RNN和时间序列的数据准备有些棘手。目的是预测该系列的其他值, 我们将使用过去的信息来估算t +1时的成本。标签等于一个周期的输入连续。
其次, 输入的数量设置为1, 即每次观察一次。最后, 时间步长等于数值的顺序。如果将时间步长设置为10, 则输入序列将连续返回十次。
看下面的图, 我们必须在左侧表示时间序列数据, 在右侧表示虚拟输入序列。我们创建一个函数以返回2001年1月至2016年12月的每一天的随机值数据集

# To plotting amazing figure %matplotlib inlineimport matplotlibimport pandas as pdimport matplotlib.pyplot as pltdef create_ts(start = '2001', n = 201, freq = 'M'):ring = pd.date_range(start=start, periods=n, freq=freq)ts =pd.Series(np.random.uniform(-18, 18, size=len(rng)), ring).cumsum()return tsts= create_ts(start = '2001', n = 192, freq = 'M')ts.tail(5)

输出
2016-08-31-93.4596312016-09-30-95.2647912016-10-31-95.5519352016-11-30-105.8796112016-12-31-123.729319Freq: M, dtype: float64ts = create_ts(start = '2001', n = 222)

# Left plotting diagramplt.figure(figsize=(11, 4))plt.subplot(121)plt.plot(ts.index, ts)plt.plot(ts.index[90:100], ts[90:100], "b-", linewidth=3, label="A train illustration in the plotting area")plt.title("A time series (generated)", fontsize=14)## Right side plotted Diagramplt.subplot(122)plt.title("A training instance", fontsize=14)plt.plot(ts.index[90:100], ts[90:100], "b-", markersize=8, label="instance")plt.plot(ts.index[91:101], ts[91:101], "bo", markersize=10, label="target", markerfacecolor='red')plt.legend(loc="upper left")plt.xlabel("Time")plt.show()

RNN中的时间序列详细示例解释

文章图片
图的右侧部分显示了所有系列。它开始于2001年, 结束于2019年。毫无意义地馈送网络中的所有数据;相反, 我们必须创建一批长度等于时间步长的数据。这批将是X变量。 Y变量与X相同, 但只移位了一个周期(即, 我们希望预测t + 1)。
两个向量的长度相同。我们可以在上图的右侧看到它。该行表示x输入的十个值, 而红点标签具有十个值y。请注意, 标签在X的前面开始一个周期, 在一个周期之后结束。
建立RNN以分析TensorFlow中的时间序列 现在是时候建立我们的第一个RNN来预测序列了。我们必须为模型指定一些超参数(模型的参数, 即神经元数量等)。
  • 输入数量:1
  • 时间步长(时间序列中的窗口):10
  • 神经元数量:120
  • 输出数量:1
我们的网络将从10天的序列中学习, 并包含120个复发神经元。我们用一个输入来输入模型。
在构建模型之前, 我们需要将数据集分为训练集和测试集。完整的数据集有222个数据点。我们将使用前201个点来训练模型, 并使用后21个点来测试模型。
定义训练和测试集后, 我们需要创建一个包含批次的对象。在这些批次中, 我们有X值和Y值。请记住, X值是一个周期散布。因此, 我们使用前200个观察值, 并且时间步长等于10。x_batches对象必须具有20个大小为10或1的批次。Y_batches的大小与X_batches对象相同, 但是带有一个周期。
步骤1)创建火车并测试
首先, 我们将序列转换为numpy数组;然后, 我们定义窗口(网络将从中学习的时间), 输入, 输出的数量以及火车的大小。
series = np.array(ts)n_windows = 20n_input =1n_output = 1size_train = 201

之后, 我们将数组分成两个数据集。
# Split datatrain = series[:size_train]test = series[size_train:]print(train.shape, test.shape)(201) (21)

步骤2)创建函数return X_batches和y_batches
我们可以创建一个函数, 该函数返回两个不同的数组, 一个返回X_batches, 另一个返回y_batches。为了使它更容易。
让我们创建一个构造批处理的函数。
请注意, X_batches记录了一个周期(我们取值t-1)。函数的输出具有三个维度。第一个尺寸等于批数量, 第二个尺寸等于窗口的尺寸, 最后一个尺寸等于输入的数量。
时间序列的棘手部分是正确选择数据点。对于X个数据点, 我们从t = 1到t = 200中选择观察值, 而对于Y个数据点, 我们从t = 2返回到201个观察值。一旦我们有了正确的数据点, 就可以轻松地重塑形状该系列。
要使用批次构造对象, 我们需要将数据集拆分为十个相同长度的批次。我们可以使用重塑方法并传递-1, 以便系列与批处理大小相同。值20是每批注释的数量, 值1是输入的数量。
我们需要对标签执行相同的步骤。
请注意, 我们需要将数据转移到我们要预测的次数。例如, 如果要预测一次, 则将序列偏移1。如果要预测两天, 则将数据偏移2点。
x_data = http://www.srcmini.com/train[:size_train-1]: Select the training instance.X_batches = x_data.reshape(-1, Windows, input): creating the right shape for the batch.def create_batches(df, Windows, input, output):## Create Xx_data = train[:size_train-1] # Select the dataX_batches = x_data.reshape(-1, windows, input)# Reshaping the data in this line of code## Create yy_data = train[n_output:size_train]y_batches = y_data.reshape(-1, Windows, output)return X_batches, y_batches #return the function

现在定义了函数, 我们将其称为创建批次。
Windows = n_Windows, # Creating windowsinput = n_input, output = n_output)

我们可以打印形状以确保尺寸正确。
print(X_batches.shape, y_batches.shape)(10, 20, 1) (10, 20, 1)

【RNN中的时间序列详细示例解释】我们只需要使用一批数据和20个观察值来创建测试集。
请注意, 我们的预测日复一日, 这意味着第二个预测值将基于测试数据集第一天(t + 1)的实际值。真实值是已知的。
如果要预测t + 2, 则需要使用预测值t + 1;如果要预测t + 3, 则需要使用期望值t + 1和t + 2。这使得很难准确地预测” t + n” 天。
X_test, y_test = create_batches(df = test, windows = 20, input = 1, output = 1)print(X_test.shape, y_test.shape)(10, 20, 1) (10, 20, 1)

我们的批次大小已准备就绪, 我们可以构建RNN架构。记住, 我们有120个复发神经元。
步骤3)建立模型
要创建模型, 我们需要定义三个部分:
  1. 带张量的变量
  2. RNN
  3. 损失与优化
1.变量
我们需要以适当的形状指定X和y变量。这一步很简单。张量与对象X_batches和对象y_batches的尺寸相同。
例如, 张量X是一个占位符, 几乎具有三个维度:
  • 注意:批量大小
  • n_windows:窗户的长度。
  • n_input:输入数
结果是:
tf.placeholder(tf.float32, [None, n_windows, n_input])## 1. Construct the tensorsX = tf.placeholder(tf.float32, [None, n_windows, n_input])y = tf.placeholder(tf.float32, [None, n_windows, n_output])

2.创建RNN
在第二部分中, 我们需要定义网络的体系结构。和以前一样, 我们使用TensorFlow估计器中的对象BasicRNNCell和dynamic_rnn。
## 2. create the modelbasic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu)rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)

下一部分比较棘手, 但可以加快计算速度。我们需要将运行输出转换为密集层, 然后将其转换为具有与输入字段相同的尺寸。
stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron])stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output)outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])

3.造成损失和优化
模型优化取决于我们正在执行的任务。
这种差异很重要, 因为它可以改变优化问题。连续变量的优化问题用于最小化均方误差。要在TF中构建这些指标, 我们可以使用:
tf.reduce_sum(tf.square(outputs - y))

持久代码与之前相同;我们使用Adam优化器来减少损失。
tf.train.AdamOptimizer(learning_rate=learning_rate)optimizer.minimize(loss)

我们可以将所有内容打包在一起, 并且我们的模型已经准备好进行训练。
tf.reset_default_graph()r_neuron = 120## 1. Constructing the tensorsX = tf.placeholder(tf.float32, [None, n_windows, n_input])y = tf.placeholder(tf.float32, [None, n_windows, n_output])

## 2. creating our modelsbasic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu)rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron])stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output)outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])## 3. Loss optimization of RNNlearning_rate = 0.001 loss = tf.reduce_sum(tf.square(outputs - y))optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)training_op = optimizer.minimize(loss)init = tf.global_variables_initializer()

我们将使用1500个时期来训练模型, 并每150次迭代打印一次损失。训练完模型后, 我们将在测试集中评估模型并创建一个包含预测的对象。
iteration = 1500 with tf.Session() as sess:init.run()for iters in range(iteration):sess.run(training_op, feed_dict={X: X_batches, y: y_batches})if iters % 150 == 0:mse = loss.eval(feed_dict={X: X_batches, y: y_batches})print(iters, "\tMSE:", mse)y_pred = sess.run(outputs, feed_dict={X: X_test})"0MSE: 502893.34150MSE: 13839.129300MSE: 3964.835450MSE: 2619.885600MSE: 2418.772750MSE: 2110.5923900MSE: 1887.96441050MSE: 1747.13771200MSE: 1556.33981350MSE: 1384.6113"

最后, 我们可以将序列的实际值与预测值一起绘制。如果我们的模型得到纠正, 则预测值应置于实际值之上。
我们可以看到, 该模型还有改进的空间。取决于我们如何更改超级参数(例如窗口), 当前文件中循环神经元数量的批处理大小。
plt.title("Forecast vs Actual", fontsize=14)plt.plot(pd.Series(np.ravel(y_test)), "bo", markersize=8, label="actual", color='green')plt.plot(pd.Series(np.ravel(y_pred)), "r.", markersize=8, label="forecast", color='red')plt.legend(loc="lower left")plt.xlabel("Time")plt.show()

RNN中的时间序列详细示例解释

文章图片
循环神经网络是一种用于时间序列和文本分析的体系结构。前一状态的输出用于保存一段时间或字序列上的系统内存。
在TensorFlow中, 我们可以使用be; ow给出的代码来训练时间序列的递归神经网络:
模型参数
n_windows = 20n_input =1n_output = 1size_train = 201

定义模型
X = tf.placeholder(tf.float32, [none, n_windows, n_input])y = tf.placeholder(tf.float32, [none, n_windows, n_output])basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu)rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron])stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output)outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])

构造优化函数
learning_rate = 0.001loss = tf.reduce_sum(tf.square(outputs - y))optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)training_op = optimizer.minimize(loss)

训练模型
init = tf.global_variables_initializer() iteration = 1500 with tf.Session() as sess:init.run()for iters in range(iteration):sess.run(training_op, feed_dict={X: X_batches, y: y_batches})if iters % 150 == 0:mse = loss.eval(feed_dict={X: X_batches, y: y_batches})print(iters, "\tMSE:", mse) y_pred = sess.run(outputs, feed_dict={X: X_test})

    推荐阅读