序言:
时间序列是将某个统计量按照时间的先后顺序,按照其统计的值排列成的数列。
时间序列是通过已经发生的知识,即就是序列的规律,预测未来序列的数值情况,通常应用于连续的预测问题。比如:金融预测,商业销售,未来天气,电力负荷,以及医疗诊断等等都有广泛的应用。
近些年来随着深度学习的逐渐火热,越来越多的行业开始采用深度学习方法来解决该领域中所面临的问题,时间序列由于其受多方面因素影响,特征多而广,传统的方式更加难以对其规律进行总结和学习,而深度学习由于可以更加深入合理准确的学习其特征与特征之间的内在规律,因此时间序列这个大难题也开始逐渐被大家解决。
时间序列领域目前常见的一些任务包括有,预测,分类,异常检测等等。
原理模型
RNN
循环神经网络(Recurrent Neural Network, RNN)是一类以序列(sequence)数据为输入,在序列的演进方向进行递归(recursion)且所有节点(循环单元)按链式连接的递归神经网络(recursive neural network)。
循环神经网络常常被应用于自然语言处理方向,后面也逐渐开始用于时间序列问题。
后面有些比较有意思的讨论,循环神经网络究竟能不能理解时间序列的时间依赖关系,是不是只是单纯的理解了序列关系。
RNN做时间序列其实本质就是做单步预测,随着网络要预测的时间序列长度增加,就会出现梯度消失或者梯度爆炸的情况。
import numpy as np
from cnn import ReluActivator, IdentityActivator, element_wise_op
class RecurrentLayer(object):
def __init__(self, input_width, state_width,
activator, learning_rate):
self.input_width = input_width
self.state_width = state_width
self.activator = activator
self.learning_rate = learning_rate
self.times = 0 # 当前时刻初始化为t0
self.state_list = [] # 保存各个时刻的state
self.state_list.append(np.zeros(
(state_width, 1))) # 初始化s0
self.U = np.random.uniform(-1e-4, 1e-4,
(state_width, input_width)) # 初始化U
self.W = np.random.uniform(-1e-4, 1e-4,
(state_width, state_width)) # 初始化W
def forward(self, input_array):
self.times += 1
state = (np.dot(self.U, input_array) +
np.dot(self.W, self.state_list[-1]))
element_wise_op(state, self.activator.forward)
self.state_list.append(state)
def backward(self, sensitivity_array,
activator):
'''
实现BPTT算法
'''
self.calc_delta(sensitivity_array, activator)
self.calc_gradient()
def calc_delta(self, sensitivity_array, activator):
self.delta_list = [] # 用来保存各个时刻的误差项
for i in range(self.times):
self.delta_list.append(np.zeros(
(self.state_width, 1)))
self.delta_list.append(sensitivity_array)
# 迭代计算每个时刻的误差项
for k in range(self.times - 1, 0, -1):
self.calc_delta_k(k, activator)
def calc_delta_k(self, k, activator):
'''
根据k+1时刻的delta计算k时刻的delta
'''
state = self.state_list[k+1].copy()
element_wise_op(self.state_list[k+1],
activator.backward)
self.delta_list[k] = np.dot(
np.dot(self.delta_list[k+1].T, self.W),
np.diag(state[:,0])).T
def calc_gradient(self):
self.gradient_list = [] # 保存各个时刻的权重梯度
for t in range(self.times + 1):
self.gradient_list.append(np.zeros(
(self.state_width, self.state_width)))
for t in range(self.times, 0, -1):
self.calc_gradient_t(t)
# 实际的梯度是各个时刻梯度之和
self.gradient = reduce(
lambda a, b: a + b, self.gradient_list,
self.gradient_list[0]) # [0]被初始化为0且没有被修改过
def calc_gradient_t(self, t):
gradient = np.dot(self.delta_list[t],
self.state_list[t-1].T)
self.gradient_list[t] = gradient
def update(self):
'''
按照梯度下降,更新权重
'''
self.W -= self.learning_rate * self.gradient
LSTM
随着技术的发展迭代,秉承着哪有问题就点哪里的方式,为了解决梯度消失和梯度爆炸,导致网络不能太深以及不能看到更远的时间步长,因此诞生了LSTM(Long Short Term Memory )。LSTM中引入了门控时间单元,通过门的遗忘可以缓解梯度消失和梯度爆炸的情况。
GRU
GRU(Gate Recurrent Unit)是循环神经网络(Recurrent Neural Network, RNN)的一种。和LSTM(Long-Short Term Memory)一样,也是为了解决长期记忆和反向传播中的梯度等问题而提出来的。
GRU和LSTM在很多情况下实际表现上相差无几,那么为什么我们要使用新人GRU(2014年提出)而不是相对经受了更多考验的LSTM(1997提出)呢。
主要是因为在结果相似的情况下,GRU可以更加快速的计算,节省我们的时间和空间资源。
:::info
论文题目:Learning Phrase Representations using RNN Encoder–Decoderfor Statistical Machine Translation
论文地址:arxiv.org/abs/1406.10…
:::
CNN
CNN被广泛用于CV和NLP领域,在时间序列预测领域,论文An Empirical Evaluation of Generic Convolutional and Recurrent Networks for Sequence Modeling(2019)采用空洞卷积结合因果卷积的网络结构,该结构也称为基于CNN的时间序列预估模型的基础结构。因果卷积表示在t时刻的输出,是由t时刻及t时刻之前的输入进行卷积得到的(而一般的卷积是t时刻前后一个窗口内的输入进行卷积)。这样,t时刻的输出避免了对t时刻之后信息的依赖而导致的数据泄漏问题。
空洞卷积解决了原来CNN只能看到历史线性大小窗口内数据的问题,当历史序列较长时,普通的卷积需要增大卷积尺寸才能看到更久远的历史信息,导致训练效率较低。空洞卷积跳跃的对历史序列进行卷积,例如当空洞卷积尺寸为2时,t时刻会根据t、t-2、t-4等时刻的输入进行卷积。通过多层卷积的堆叠,层数越多对应的空洞尺寸也越大,这样实现了在时间复杂度不变的情况下引入更长历史信息,提升预测效果。
Transformer
Transformer模型首先在NLP领域中取得了比较显著的效果,由于NLP和时间序列都是序列问题,所以Transformer模型也被应用在了时间序列的预测任务上。Deep Transformer Models for Times Serise Forcasting:The Influenze Case(2022)采用了和GPT相似的Transformer结构尝试了时间序列的预测任务,但是,在时间序列预测任务当中,样本点的位置关系非常重要,Transformer虽然通过Attention机制实现了超长周期的特征对齐,位置信息只能依赖于position embeding,影响了Transformer在时间序列当中的预测应用。
针对这个问题,业内主要采用CNN + Transformer或LSTM + Transformer相结合的方式,使序列模型的序列建模能力和Attention模型的超长周期信息提取能力互补。
Enhancing the Locality and Breaking the Memory Bottieneck of Transformer on Time Serise Forcasting(2019)提出使用CNN和Transformer结合的方法,模型结构如下图所示,CNN模型增强了上下文信息的提取能力,左图中CNN尺寸为1,即无卷积的情况下,每个时刻的特征单独进行Transformer,当两个时刻特征相似时,由于上下文环境,即前后时刻的值不同,因此这两个时刻表达的信息不同,而左侧模型无法提取这个信息,右侧模型实验了尺寸为3的卷积,刻画了上下文信息不同的时刻不同信息,能够更好的发掘具有相似的模型序列片段。
Temporal Fusion Transformers for Interpretable Multi-hrizon Time Series Forecasting(2019)提出了LSTM和Transformer结合的方法。模型体现层采用LSTM的结构,利用LSTM的序列建模能力,先对输入序列进行预处理,这样不同时刻生成了考虑上下文的时序信息的表示。接下来,底层表示层输入到上层Transformer中,利用Attention的超长周期信息提取能力弥补序列遗忘的问题。
Informer:Beyond Efficent Transformer for Long Sequence Time-Series Forcasting (AAAI 2020)提出了一种针对长周期预估的Transformer的升级版。为了让Transformer在长周期估计当中提升运行效率,提出了ProbSparse self-attention,通过让key只和关键的query形成稀疏的attention减少大量的运算量。