在本教程中, 我们将使用带有时间序列数据的RNN。时间序列取决于以前的时间, 这意味着过去的值包括网络可以学习的重要信息。时间序列预测是为了估计任何序列的未来价值, 例如股票价格, 温度, GDP等。
RNN和时间序列的数据准备有些棘手。目的是预测该系列的其他值, 我们将使用过去的信息来估算t +1时的成本。标签等于一个周期的输入连续。
其次, 输入的数量设置为1, 即每次观察一次。最后, 时间步长等于数值的顺序。如果将时间步长设置为10, 则输入序列将连续返回十次。
看下面的图, 我们必须在左侧表示时间序列数据, 在右侧表示虚拟输入序列。我们创建一个函数以返回2001年1月至2016年12月的每一天的随机值数据集
# To plotting amazing figure
%matplotlib inline
import matplotlib
import pandas as pd
import matplotlib.pyplot as plt
def 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 ts
ts= create_ts(start = '2001', n = 192, freq = 'M')
ts.tail(5)
输出
2016-08-31 -93.459631
2016-09-30 -95.264791
2016-10-31 -95.551935
2016-11-30 -105.879611
2016-12-31 -123.729319
Freq: M, dtype: float64
ts = create_ts(start = '2001', n = 222)
# Left plotting diagram
plt.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 Diagram
plt.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()
图的右侧部分显示了所有系列。它开始于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 = 20
n_input = 1
n_output = 1
size_train = 201
之后, 我们将数组分成两个数据集。
# Split data
train = 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 = 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 X
x_data = train[:size_train-1] # Select the data
X_batches = x_data.reshape(-1, windows, input) # Reshaping the data in this line of code
## Create y
y_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 windows
input = n_input, output = n_output)
我们可以打印形状以确保尺寸正确。
print(X_batches.shape, y_batches.shape)
(10, 20, 1) (10, 20, 1)
我们只需要使用一批数据和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)建立模型
要创建模型, 我们需要定义三个部分:
- 带张量的变量
- RNN
- 损失与优化
1.变量
我们需要以适当的形状指定X和y变量。这一步很简单。张量与对象X_batches和对象y_batches的尺寸相同。
例如, 张量X是一个占位符, 几乎具有三个维度:
- 注意:批量大小
- n_windows:窗户的长度。
- n_input:输入数
结果是:
tf.placeholder(tf.float32, [None, n_windows, n_input])
## 1. Construct the tensors
X = 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 model
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])
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 tensors
X = tf.placeholder(tf.float32, [None, n_windows, n_input])
y = tf.placeholder(tf.float32, [None, n_windows, n_output])
## 2. creating our models
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])
## 3. Loss optimization of RNN
learning_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})
"0 MSE: 502893.34
150 MSE: 13839.129
300 MSE: 3964.835
450 MSE: 2619.885
600 MSE: 2418.772
750 MSE: 2110.5923
900 MSE: 1887.9644
1050 MSE: 1747.1377
1200 MSE: 1556.3398
1350 MSE: 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()
循环神经网络是一种用于时间序列和文本分析的体系结构。前一状态的输出用于保存一段时间或字序列上的系统内存。
在TensorFlow中, 我们可以使用be; ow给出的代码来训练时间序列的递归神经网络:
模型参数
n_windows = 20
n_input = 1
n_output = 1
size_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.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()
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})
评论前必须登录!
注册