个性化阅读
专注于IT技术分析

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

在本教程中, 我们将使用带有时间序列数据的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()
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 = 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)建立模型

要创建模型, 我们需要定义三个部分:

  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 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()
RNN中的时间序列

循环神经网络是一种用于时间序列和文本分析的体系结构。前一状态的输出用于保存一段时间或字序列上的系统内存。

在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})

赞(0) 打赏
未经允许不得转载:srcmini » RNN中的时间序列详细示例解释
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

微信扫一扫打赏