<- bake(rec_obj, df)
df_processed_tbl
## # A tibble: 720 x 3
## index value key
## <date> <dbl> <fct>
## 1 1949-11-01 1.25 training
## 2 1949-12-01 0.929 training
## 3 1950-01-01 0.714 training
## 4 1950-02-01 0.617 training
## 5 1950-03-01 0.825 training
## 6 1950-04-01 0.874 training
## 7 1950-05-01 0.777 training
## 8 1950-06-01 0.450 training
## 9 1950-07-01 0.561 training
## 10 1950-08-01 0.474 training
## # ... with 710 more rows
接着,记录中心化和标度化的信息,以便在建模完成之后可以将数据逆向转换回去。平方根转换可以通过乘方运算逆转回去,但要在逆转中心化和标度化之后。
center_history <- rec_obj$steps[[2]]$means["value"]
scale_history <- rec_obj$steps[[3]]$sds["value"]
c("center" = center_history, "scale" = scale_history)
## center.value scale.value
## 7.549526 3.545561
5.1.4 规划 LSTM 模型
我们需要规划下如何构建 LSTM 模型。首先,了解几个 LSTM 模型的专业术语:
张量格式(Tensor Format):
- 预测变量(X)必须是一个 3 维数组,维度分别是:
samples
、timesteps
和 features
。第一维代表变量的长度;第二维是时间步(滞后阶数);第三维是预测变量的个数(1 表示单变量,n 表示多变量)
- 输出或目标变量(y)必须是一个 2 维数组,维度分别是:
samples
和 timesteps
。第一维代表变量的长度;第二维是时间步(之后阶数)
训练与测试:
- 训练与测试的长度必须是可分的(训练集长度除以测试集长度必须是一个整数)
批量大小(Batch Size):
- 批量大小是在 RNN 权重更新之前一次前向 / 后向传播过程中训练样本的数量
- 批量大小关于训练集和测试集长度必须是可分的(训练集长度除以批量大小,以及测试集长度除以批量大小必须是一个整数)
时间步(Time Steps):
- 时间步是训练集与测试集中的滞后阶数
- 我们的例子中滞后 1 阶
周期(Epochs):
- 周期是前向 / 后向传播迭代的总次数
- 通常情况下周期越多,模型表现越好,直到验证集上的精确度或损失不再增加,这时便出现过度拟合
考虑到这一点,我们可以提出一个计划。我们将预测窗口或测试集的长度定在 120 个月(10年)。最优相关性发生在 125 阶,但这并不能被预测范围整除。我们可以增加预测范围,但是这仅提供了自相关性的最小幅度增加。我们选择批量大小为 40,它可以整除测试集和训练集的观察个数。我们选择时间步等于 1,这是因为我们只使用 1 阶滞后(只向前预测一步)。最后,我们设置 epochs = 300
,但这需要调整以平衡偏差与方差。
# Model inputs
lag_setting <- 120 # = nrow(df_tst)
batch_size <- 40
train_length <- 440
tsteps <- 1
epochs <- 300
5.1.5 2 维与 3 维的训练、测试数组
下面将训练集和测试集数据转换成合适的形式(数组)。记住,LSTM 模型要求预测变量(X)是 3 维的,输出或目标变量(y)是 2 维的。
# Training Set
lag_train_tbl <- df_processed_tbl %>%
mutate(value_lag = lag(value, n = lag_setting)) %>%
filter(!is.na(value_lag)) %>%
filter(key == "training") %>%
tail(train_length)
x_train_vec <- lag_train_tbl$value_lag
x_train_arr <- array(
data = x_train_vec, dim = c(length(x_train_vec), 1, 1))
y_train_vec <- lag_train_tbl$value
y_train_arr <- array(
data = y_train_vec, dim = c(length(y_train_vec), 1))
# Testing Set
lag_test_tbl <- df_processed_tbl %>%
mutate(
value_lag = lag(
value, n = lag_setting)) %>%
filter(!is.na(value_lag)) %>%
filter(key == "testing")
x_test_vec <- lag_test_tbl$value_lag
x_test_arr <- array(
data = x_test_vec,
dim = c(length(x_test_vec), 1, 1))
y_test_vec <- lag_test_tbl$value
y_test_arr <- array(
data = y_test_vec,
dim = c(length(y_test_vec), 1))
5.1.6 构建 LSTM 模型
我们可以使用 keras_model_sequential()
构建 LSTM 模型,并像堆砖块一样堆叠神经网络层。我们将使用两个 LSTM 层,每层都设定 units = 50
。第一个 LSTM 层接收所需的输入形状,即[时间步,特征数量]。批量大小就是我们的批量大小。我们将第一层设置为 return_sequences = TRUE
和 stateful = TRUE
。第二层和前面相同,除了 batch_size
(batch_size
只需要在第一层中指定),另外 return_sequences = FALSE
不返回时间戳维度(从第一个 LSTM 层返回 2 维数组,而不是 3 维)。我们使用 layer_dense(units = 1)
,这是 Keras 序列模型的标准结尾。最后,我们在 compile()
中使用 loss ="mae"
以及流行的 optimizer = "adam"
。
model <- keras_model_sequential()
model %>%
layer_lstm(
units = 50,
input_shape = c(tsteps, 1),
batch_size = batch_size,
return_sequences = TRUE,
stateful = TRUE) %>%
layer_lstm(
unit