e) +
scale_color_tq() +
labs(
title = glue("Split: {split$id}"),
subtitle = glue(
"{train_time_summary$start} to {test_time_summary$end}"),
y = "",
x = "") +
theme(legend.position = "none")
if (expand_y_axis)
{
sun_spots_time_summary <- sun_spots %>%
tk_index() %>%
tk_get_timeseries_summary()
g <- g +
scale_x_date(
limits = c(
sun_spots_time_summary$start,
sun_spots_time_summary$end))
}
return(g)
}
plot_split()
函数接受一个分割(在本例中为 Slice01
),并可视化抽样策略。我们使用 expand_y_axis = TRUE
将横坐标范围扩展到整个数据集的日期范围。
rolling_origin_resamples$splits[[1]] %>%
plot_split(expand_y_axis = TRUE) +
theme(legend.position = "bottom")
第二个函数是 plot_sampling_plan()
,使用 purrr
和 cowplot
将 plot_split()
函数应用到所有样本上。
# Plotting function that scales to all splits
plot_sampling_plan <- function(sampling_tbl,
expand_y_axis = TRUE,
ncol = 3,
alpha = 1,
size = 1,
base_size = 14,
title = "Sampling Plan")
{
# Map plot_split() to sampling_tbl
sampling_tbl_with_plots <- sampling_tbl %>%
mutate(
gg_plots = map(
splits, plot_split,
expand_y_axis = expand_y_axis,
alpha = alpha, base_size = base_size))
# Make plots with cowplot
plot_list <- sampling_tbl_with_plots$gg_plots
p_temp <- plot_list[[1]] +
theme(legend.position = "bottom")
legend <- get_legend(p_temp)
p_body <- plot_grid(
plotlist = plot_list, ncol = ncol)
p_title <- ggdraw() +
draw_label(
title, size = 14,
fontface = "bold",
colour = palette_light()[[1]])
g <- plot_grid(
p_title, p_body,
legend, ncol = 1,
rel_heights = c(0.05, 1, 0.05))
return(g)
}
现在我们可以使用 plot_sampling_plan()
可视化整个回测策略!我们可以看到抽样计划如何平移抽样窗口逐渐切分出训练和测试子样本。
rolling_origin_resamples %>%
plot_sampling_plan(
expand_y_axis = T, ncol = 3,
alpha = 1, size = 1, base_size = 10,
title = "Backtesting Strategy: Rolling Origin Sampling Plan")
此外,我们可以让 expand_y_axis = FALSE
,对每个样本进行缩放。
rolling_origin_resamples %>%
plot_sampling_plan(
expand_y_axis = F, ncol = 3,
alpha = 1, size = 1, base_size = 10,
title = "Backtesting Strategy: Zoomed In")
当在太阳黑子数据集上测试 LSTM 模型准确性时,我们将使用这种回测策略(来自一个时间序列的 6 个样本,每个时间序列分为 100/50 两部分,并且样本之间有大约 22 年的偏移)。
LSTM 模型
首先,我们将在回测策略的某个样本上用 Keras 开发一个状态 LSTM 模型,通常是最近的一个。然后,我们将模型套用到所有样本,以测试和验证模型性能。
example_split <- rolling_origin_resamples$splits[[6]]
example_split_id <- rolling_origin_resamples$id[[6]]
我么可以用 plot_split()
函数可视化该分割,设定 expand_y_axis = FALSE
以便将横坐标缩放到样本本身的范围。
plot_split(
example_split,
expand_y_axis = FALSE,
size = 0.5) +
theme(legend.position = "bottom") +
ggtitle(glue("Split: {example_split_id}"))
数据准备
为了帮助进行超参数调整,除了训练集之外,我们还需要一个验证集。例如,我们将使用一个回调函数 callback_early_stopping
,当验证集上没有显着的表现时,它会停止训练(多少算显著由你决定)。
我们将分析集的三分之二用于训练,三分之一用于验证。
df_trn <- analysis(example_split)[1:800, , drop = FALSE]
df_val <- analysis(example_split)[801:1200, , drop = FALSE]
df_tst <- assessment(example_split)
首先,我们将训练和测试数据集合成一个数据集,并使用列 key
来标记它们来自哪个集合(training
或 testing
)。请注意,tbl_time
对象需要在调用 bind_rows()
时重新指定索引,但是这个问题应该很快在 dplyr
包中得到纠正。
df <- bind_rows(
df_trn %>% add_column(key = "training"),
df_val %>% add_column(key = "validation"),
df_tst %>% add_column(key = "testing")) %>%
as_