作者:徐瑞龙,量化分析师,R语言中文社区专栏作者
博客专栏:
https://www.cnblogs.com/xuruilong100
本文翻译自《Time Series Deep Learning, Part 2: Predicting Sunspot Frequency With Keras Lstm in R》,略有删减。
深度学习于商业的用途之一是提高时间序列预测的准确性。之前的教程显示了如何利用自相关性预测未来 10 年的月度太阳黑子数量。本教程将借助 RStudio 重新审视太阳黑子数据集,并且使用到 TensorFlow for R 中一些高级的深度学习功能,展示基于 keras
的深度学习教程遇到 tfruns
(用于追踪、可视化和管理 TensorFlow 训练、实验的一整套工具)后产生出的有趣结果。
学习路线
该深度学习教程将教会你:
时间序列深度学习如何应用于商业
深度学习预测太阳黑子
如何建立 LSTM 模型
如何回测 LSTM 模型
事实上,最酷的事之一是你能画出 LSTM 预测的回测结果。
商业中的时间序列深度学习
时间序列预测是商业中实现投资回报率(ROI)的一个关键领域。想一想:预测准确度提高 10% 就可以为机构节省数百万美元。这怎么可能?下面让我们来看看。
我们将以 NVIDIA 为例,一家为 Artificial Intelligence 和 Deep Learning 生产最先进芯片的半导体厂商。NVIDIA 生产的图形处理器或 GPU,这对于高性能深度学习所要求的大规模数值计算来说是必需的。芯片看起来像这样。
与所有制造商一样,NVIDIA 需要预测其产品的需求。为什么? 因为他们据此可以为客户提供合适数量的芯片。这个预测很关键,需要很多技巧和一些运气才能做到这一点。
我们所讨论的是销售预测,它推动了 NVIDIA 做出的所有生产制造决策。这包括购买多少原材料,有多少人来制造芯片,以及需要多少预算用于加工和装配操作。销售预测中的错误越多,NVIDIA 产生的成本就越大,因为所有这些活动(供应链、库存管理、财务规划等)都会变得没有意义!
商业中应用时间序列深度学习
时间序列深度学习对于预测具有高自相关性的数据非常准确,因为包括 LSTM 和 GRU 在内的算法可以从序列中学习信息,无论模式何时发生。这些特殊的 RNN 旨在具有长期记忆性,这意味着它们善于在最近发生的观察和很久之前发生的观察之间学习模式。这使它们非常适合时间序列!但它们对销售数据有用吗?也许,来!我们讨论一下。
销售数据混合了各种特征,但通常有季节性模式和趋势。趋势可以是平坦的、线性的、指数的等等。这通常不是 LSTM 擅长的地方,但其他传统的预测方法可以检测趋势。但是,季节性不同。销售数据中的季节性是一种可以在多个频率(年度、季度、月度、周度甚至每天)上出现的模式。LSTM 非常适合检测季节性,因为它通常具有自相关性。因此,LSTM 和 GRU 可以很好地帮助改进季节性检测,从而减少销售预测中的整体预测误差。
深度学习时间序列预测:使用 keras
预测太阳黑子
这一节我们将借助基本的 R 工具在太阳黑子数据集上做时间序列预测。太阳黑子是太阳表面的低温区域,这里有一张来自 NASA 的太阳黑子图片。
我们使用月度数据集 sunspots.month
(也有一个年度频率的版本),它包括 265 年间(1749 - 2013)的月度太阳黑子观测。
预测该数据集具有相当的挑战性,因为短期内的高变异性以及长期内明显的不规则周期性。例如,低频周期达到的最大幅度差异很大,达到最大低频周期高度所需的高频周期步数也是如此。(译注:数据中的局部高点之间间隔大约为 11 年)
我们的文章将重点关注两个主要方面:如何将深度学习应用于时间序列预测,以及如何在该领域中正确应用交叉验证。对于后者,我们将使用 rsample
包来允许对时间序列数据进行重新抽样。对于前者,我们的目标不是达到最佳表现,而是显示使用递归神经网络对此类数据进行建模时的一般操作过程。
递归神经网络
当我们的数据具有序列结构时,我们就用递归神经网络(RNN)进行建模。
目前为止,在 RNN 中,建立的最佳架构是 GRU(门递归单元)和 LSTM(长短期记忆网络)。今天,我们不要放大它们自身独特的东西,而是集中于它们与最精简的 RNN 的共同点上:基本的递归结构。
与通常称为多层感知器(MLP)的神经网络的原型相比,RNN 具有随时间推移的状态。来自 Goodfellow 等人的著作——“深度学习的圣经”,从这个图中可以很好地看出这一点:
每次,状态是当前输入和先前隐含状态的组合。这让人联想到自回归模型,但是对于神经网络,我们必须在某种程度上停止依赖。
因为那是为了确定权重,我们会不断计算输入变化后我们的损失如何变化。现在,如果我们必须考虑的输入在任意时间步无限地返回,那么我们将无法计算所有这些梯度。然而,在实践中,我们的隐含状态将在每次迭代中通过固定数量的步骤继续前进。
一旦我们加载并预处理数据,我们就会回过头来。
设置、预处理与探索
所用的包
这里是该教程所涉及到的包。
# Core Tidyverse library(tidyverse) library(glue) library(forcats) # Time Series library(timetk) library(tidyquant) library(tibbletime) # Visualization library(cowplot) # Preprocessing library(recipes) # Sampling / Accuracy library(rsample) library(yardstick) # Modeling library(keras) library(tfruns)
如果你之前没有在 R 中运行过 Keras,你需要用 install_keras()
函数安装 Keras。
# Install Keras if you have not installed before install_keras()
数据
数据集 sunspot.month
是一个 ts
类对象(非 tidy
类),所以我们将使用 timetk
中的 tk_tbl()
函数转换为 tidy
数据集。我们使用这个函数而不是来自 tibble
的 as.tibble()
,用来自动将时间序列索引保存为zoo
yearmon
索引。最后,我们将使用 lubridate::as_date()
(使用 tidyquant
时加载)将 zoo
索引转换为日期,然后转换为 tbl_time
对象以使时间序列操作起来更容易。
sun_spots <- datasets::sunspot.month %>% tk_tbl() %>% mutate(index = as_date(index)) %>% as_tbl_time(index = index) sun_spots
# A time tibble: 3,177 x 2 # Index: index index value <date> <dbl> 1 1749-01-01 58 2 1749-02-01 62.6 3 1749-03-01 70 4 1749-04-01 55.7 5 1749-05-01 85 6 1749-06-01 83.5 7 1749-07-01 94.8 8 1749-08-01 66.3 9 1749-09-01 75.9 10 1749-10-01 75.5 # ... with 3,167 more rows
探索性数据分析
时间序列很长(有 265 年!)。我们可以将时间序列的全部(265 年)以及前 50 年的数据可视化,以获得该时间系列的直观感受。
使用 cowplot
可视化太阳黑子数据
我们将创建若干 ggplot
对象并借助 cowplot::plot_grid()
把这些对象组合起来。对于需要缩放的部分,我们使用 tibbletime::time_filter()
,可以方便的实现基于时间的过滤。