在 R 中使用神经网络进行时间序列预测的示例

机器算法验证 r 时间序列 机器学习 神经网络 网络
2022-03-15 06:16:39

任何人都有一个简短的教育示例,如何使用神经网络(nnet例如在 R 中)进行预测?

这是 R 中时间序列的示例

T <- seq(0,20,length=200)
Y <- 1 + 3*cos(4*T+2) +.2*T^2 + rnorm(200)
plot(T,Y,type="l")

这只是一个例子,但我所拥有的是跳跃的季节性数据。

2个回答

Rob Hyndman 正在积极研究神经网络的预测。他最近将nnetar()函数添加到forecast包中,该函数利用nnet您引用的包来适应时间序列数据。

http://cran.r-project.org/web/packages/forecast/index.html

帮助文档中的示例:

fit <- nnetar(lynx)
fcast <- forecast(fit)
plot(fcast)

Rob 在他的在线文本的这个特定部分中提供了更多背景信息:预测:原则和实践

(显然,非常感谢 Rob。)

正在寻找同样的东西并偶然发现了这个问题。由于我还没有找到一个例子,我决定自己做一个。请注意,我不是神经网络或预测方面的专家 :)

为了使用神经网络 (nnets) 有效地对时间序列进行建模,我认为 nnets 应该具有的一个重要属性是某种记忆(跟踪过去发生的事情)。因此,简单的前馈网络可能不是一个好主意。nnets 中可以有效模拟记忆的家族之一是循环神经网络家族,其中最知名的循环神经网络类型之一可能是 Elman 网络(连同我想说的长短期记忆 (LSTM) 网络)。要查找有关 Elman 网络的更多信息,您可以查看介绍该概念的原始论文或通过Wikipedia简而言之,它们有一个称为上下文的附加层,用作一种内存。下图(来源)说明了这个想法

Elman 类型的简单循环网络

对我们来说幸运的是,R 中的 RSNNS 包能够安装 Elman 网。该软件包在此处详细描述。

现在我们已经了解了基础知识,让我们看看如何使用 RSNNS 包在 R 中实现一个示例。

library(RSNNS)

#
# simulate an arima time series example of the length n
#
set.seed(10001)
n <- 100
ts.sim <- arima.sim(list(order = c(1,1,0), ar = 0.7), n = n-1)

#
# create an input data set for ts.sim
# sw = sliding-window size
#
# the last point of the time series will not be used
#   in the training phase, only in the prediction/validation phase
# 
sw <- 1
X <- lapply(sw:(n-2),
       function(ind){
           ts.sim[(ind-sw+1):ind]
       })
X <- do.call(rbind, X)
Y <- sapply(sw:(n-2),
       function(ind){
           ts.sim[ind+1]
       })

# used to validate prediction properties
# on the last point of the series
newX <- ts.sim[(n-sw):(n-1)]
newY <- ts.sim[n]

# build an elman network based on the input
model <- elman(X, Y,
               size = c(10, 10),
               learnFuncParams = c(0.001),
               maxit = 500,
               linOut = TRUE)

#
# plot the results
#
limits <- range(c(Y, model$fitted.values))

plot(Y, type = "l", col="red",
     ylim=limits, xlim=c(0, length(Y)),
     ylab="", xlab="")
lines(model$fitted.values, col = "green", type="l")

points(length(Y)+1, newY, col="red", pch=16)
points(length(Y)+1, predict(model, newdata=newX),
       pch="X", col="green")

此代码应导致下图 在此处输入图像描述

所以我们对代码所做的事情如下。首先,我们创建了一个时间序列示例(来自 ARIMA 模型)。之后,我们将时间序列示例解耦/切片为形式的输入(sw 前一个点,下一个点),用于除最后一对之外的所有对(下一个点作为时间序列示例的最后一个点)。参数 sw 用于定义“滑动窗口”。我不会在这里讨论什么是滑动窗口的合适大小,但请注意,由于 Elman 网络具有内存,大小为 1 的滑动窗口不仅仅是一种合理的方法(另外,请查看这篇文章)。

准备工作完成后,我们可以简单地使用 elman 函数构建一个 Elman 网络。您应该注意两个参数;大小和 learnFuncParams。size 参数为您提供了一种定义网络(隐藏层)大小的方法,您选择此参数的方式更像是一门艺术而不是一门科学。learnFuncParams 的经验法则是在可行的情况下保持较小(您的处理能力允许您保持较小/您有足够的时间等待:D)。

瞧,你的神经网络能够预测一个/未来的点/值。对于我们的示例,这种方法的预测能力如上图所示。红色曲线表示我们模拟的时间序列(没有最后一点),绿色曲线表示使用拟合的 Elman 网络获得的结果。红点表示最后一个点(在拟合过程中未使用的点),绿点表示拟合网络预测的点。一点也不差 :)

这是一个关于如何使用 RNN(Elman 网络)和 R 进行预测/预测的示例。有些人可能会争辩说,RNN 并不是解决问题的最佳选择,并且有更好的 nnet 模型用于预测。由于我不是该领域的专家,我将避免讨论这些问题。

如果您想了解有关 RNN 的更多信息,那么一本有趣的读物是序列学习论文中对 RNN的批判性评论。