设为首页 加入收藏

TOP

时间序列深度学习:seq2seq 模型预测太阳黑子(五)
2019-09-03 02:41:26 】 浏览:337
Tags:时间序列 深度 学习 seq2seq 模型 预测 太阳黑子
tbl_time(index = index) df
# A time tibble: 1,800 x 3
# Index: index
   index      value key     
   <date>     <dbl> <chr>   
 1 1849-06-01  81.1 training
 2 1849-07-01  78   training
 3 1849-08-01  67.7 training
 4 1849-09-01  93.7 training
 5 1849-10-01  71.5 training
 6 1849-11-01  99   training
 7 1849-12-01  97   training
 8 1850-01-01  78   training
 9 1850-02-01  89.4 training
10 1850-03-01  82.6 training
# ... with 1,790 more rows

recipe 做数据预处理

LSTM 算法通常要求输入数据经过中心化并标度化。我们可以使用 recipe 包预处理数据。我们用 step_sqrt 来转换数据以减少异常值的影响,再结合 step_centerstep_scale 对数据进行中心化和标度化。最后,数据使用 bake() 函数实现处理转换。

rec_obj <- recipe(
    value ~ ., df) %>%
    step_sqrt(value) %>%
    step_center(value) %>%
    step_scale(value) %>%
    prep()

df_processed_tbl <- bake(rec_obj, df)

df_processed_tbl
# A tibble: 1,800 x 3
   index      value key     
   <date>     <dbl> <fct>   
 1 1849-06-01 0.714 training
 2 1849-07-01 0.660 training
 3 1849-08-01 0.473 training
 4 1849-09-01 0.922 training
 5 1849-10-01 0.544 training
 6 1849-11-01 1.01  training
 7 1849-12-01 0.974 training
 8 1850-01-01 0.660 training
 9 1850-02-01 0.852 training
10 1850-03-01 0.739 training
# ... with 1,790 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
    6.694468     3.238935

调整数据形状

Keras LSTM 希望输入和目标数据具有特定的形状。输入必须是 3 维数组,维度大小为 num_samplesnum_timestepsnum_features

这里,num_samples 是集合中观测的数量。这将以每份 batch_size 大小的分量分批提供给模型。第二个维度 num_timesteps 是我们上面讨论的隐含状态的长度。最后,第三个维度是我们正在使用的预测变量的数量。对于单变量时间序列,这是 1。

隐含状态的长度应该选择多少?这通常取决于数据集和我们的目标。如果我们提前一步预测,即仅预测下个月,我们主要关注的是选择一个状态长度,以便学习数据中存在的任何模式。

现在说我们想要预测 12 个月的数据,就像 SILSO(世界数据中心,用于生产、保存和传播国际太阳黑子观测)所做的。我们通过 Keras 实现这一目标的方法是使 LSTM 隐藏状态与后续输出有相同的长度。因此,如果我们想要产生 12 个月的预测,我们的 LSTM 隐藏状态长度应该是 12。(译注:原始数据的周期大约是 10 到 11 年,使用相邻两年的数据不能涵盖一个完整的周期,致使模型无法学习到和周期有关的模式,最终表现可能不佳。)

然后使用 time_distributed() 包装器将这 12 个时间步连接到 12 个线性预测器单元。该包装器的任务是将相同的计算(即,相同的权重矩阵)应用于它接收的每个状态输入。

目标数组的格式应该是什么?由于我们在这里预测了几个时间步,目标数据也需要是 3 维的。维度 1 同样是批量维度,维度 2 同样对应于时间步(被预测的),维度 3 是包装层的大小。在我们的例子中,包装层是单个单元的 layer_dense(),因为我们希望每个时间点只有一个预测。

所以,让我们调整数据形状。这里的主要动作是用滑动窗口创建长度 12 的输入,后续 12 个观测作为输出。举个更简单的例子,假设我们的输入是从 1 到 10 的数字,我们选择的序列长度(状态大小)是 4,下面就是我们希望我们的训练输入看起来的样子:

1,2,3,4
2,3,4,5
3,4,5,6

相应的目标数据:

5,6,7,8
6,7,8,9
7,8,9,10

我们将定义一个简短的函数,对给定的数据集进行调整。最后,我们形式上添加了需要的第三个维度(即使在我们的例子中该维度的大小为 1)。

# these variables are being defined just because of the order in which
# we present things in this post (first the data, then the model)
# they will be superseded by FLAGS$n_timesteps, FLAGS$batch_size and n_predictions
# in the following snippet
n_timesteps <- 12
n_predictions <- n_timesteps
batch_size <- 10

# functions used
build_matrix <- function(tseries,
                         overall_timesteps)
{
    t(sapply(
        1:(length(tseries) - overall_timesteps + 1),
        function(x) tseries[x:(x + overall_timesteps - 1)]))
}

reshape_X_3d <- function(X)
{
    dim(X) <- c(dim(X)[1], dim(X)[2], 1)
    X
}

# extract values from data frame
train_vals <- df_processed_tbl %>%
    filter(key == "training") %>%
    select(value) %>%
    pull()
valid_vals <- df_processed_tbl %>%
    filter(key == "validat
首页 上一页 2 3 4 5 6 7 8 下一页 尾页 5/11/11
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇基于R语言的结构方程:lavaan简明.. 下一篇时间序列分析工具箱——tidyquant

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目