同样是数据分析方法,为什么时间序列分析没有数据挖掘或机器学习那么火?

同样是数据分析方法,为什么时间序列分析没有数据挖掘或机器学习那么火?

最近这一个月Arxiv上多了很多时间序列预测的文章,应该都是投今年的NIPS的,对序列预测的最新文章可以看一下我整理的这个库,更新很快,基本上Arxiv最新的文章也有收录到:

这些文章中,最感兴趣的是清华龙明盛老师组的一个文章,采用Koopman理论,从动态系统的角度来设计了一个时间序列预测模型Koopa(具体结构是用MLP实现的,所以算是一个基于MLP的预测模型),效果好,速度快。

放个图展示一下效果:

这是在两个数据集上的效果,横轴是训练时间(越小越快)、纵轴是预测的MSE指标(越低越好),圈的大小代表所需内存,红色的就是Koopa。和各种模型比如PathTST、DLinear、TimesNet都有对比,Koopa能预测更准、速度更快、所需内存也更小。

时间序列本质上来说就是一个动态系统。对于非平稳时间序列来说,可以通过一个测量函数 将其转化到非线性动态空间中,如上图左侧所示。在这个非线性系统中,根据Koopman理论,动态的变化可以近似由线性转移算子 决定。对于时间序列的不同时期,可能这个算子 是不同的,如上图右侧所示。

对于一个动态系统 , 可能很难求。为了分析这个动态系统,可以先用测量函数 对其进行变换,即 。然后为了分析 和 之间的关系,引入无限维Koopman算子 (可用有限维矩阵来近似),将其变为一个线性系统:

同时,大规模非线性动态系统一般可以分离成时变动态系统(time-variant dynamics)和时不变动态系统(time-invariant dynamics)。时不变动态系统一般是在整个时间序列中共享的,不随时期变化而变化,比如时间序列中固定的周期,具有全局性;时变动态系统一般是一段时期特定的,比如有一段时间序列值突然逐渐下降具有局部性。

以上两点是本文的理论基础和灵感启发。

Koopa模型的总览图如上图中左下角所示,它由许多个Koopa Block组成,每个Koopa Block的预测输出是预测的未来时变分量 和未来时不变分量 之和,最后的模型预测结果是所有的Koopa Block的预测输出之和。

对于每一个Koopa Block,又可以分为三部分,分别是:

下面详细介绍这三个部分。

深度序列预测中,收集训练样本是采用滑动窗口法来获取的,每个滑动窗口包括过去窗口的序列和未来窗口的序列,过去序列的长度为 ,未来序列的长度为 。对于训练样本集中所有过去窗口序列,可以对每个序列分别做傅里叶变换,得到频谱集合 中每个频率对应的幅值。对于每个频率,可以将所有过去窗口序列的该频率对应的幅值进行平均,可得到样本总体的主要频率大小(平均幅值高的频率就是主要频率)。具体取多少个主要频率呢?文中取平均幅值高的前 比例的频率,选出来的集合为 。这个集合中的频率是所有过去窗口序列中最主要最普适的,代表了整个时间序列中不变的因素,也就是无论什么时期,这些频率都会经常出现,所以可以用滤波器将这些频率筛选出来,即可得到时不变分量 。对于 的补集 中的频率,则反应了可能在某些时期出现的特定频率,对应时变分量 。具体步骤如下:

其中做傅里叶变换 变换到频域后对 或者 集合中的频率进行滤波Filter,对滤波后的再进行逆傅里叶变换 回到时域。

时不变Koopman预测器很简单,它的结构如上图所示,就是一个编解码器的结构,中间隐变量加上一个变换矩阵 。它的目的是从过去窗口的时不变分量直接预测未来窗口的时不变分量。既然是时不变的,可以直接一个从过去窗口映射到未来窗口的预测模型,然后不同时期(不同训练样本)都用这个模型(这和后面的时变Koopman预测器有区别,时变Koopman预测器中有特定于时期的因素在里面)。

时不变Koopman预测器的输入就是过去窗口序列的时不变分量 ,它的shape为 , 是过去窗口大小, 是多元序列的变量个数。先用一个编码器将它映射到 的隐空间:

再在隐空间用大小为 的可学习矩阵 做一个变换:

最后用一个解码器映射到 , 是未来窗口长度,就相当于得到了未来窗口的时不变分量 :

作者选用MLP作为编码器和解码器结构。

整体的思路如上图。在这个示意图中,红色的区域为过去窗口,被分为了三段( )。核心思想就是,先用Encoder将每个时间段的序列映射到非线性空间(特征 ),然后用Koopma算子 来近似时间段之间的变化动态,即后一段的特征 是可以前一段的特征 通过 来获得的。然后我们其实已知所有过去窗口内时间段的特征,那么就可以根据每一对前后相邻段的特征来拟合出Koopma算子 本身(注意,这里的Koopma算子 不同于时不变Koopman预测器中的 ,因为 是可学习的,而 是不可学习的、可以解析计算得到的)。得到Koopma算子 之后,就可以拟合过去窗口时间段特征( ),以及预测未来窗口时间段特征( ),然后解码即可得到过去窗口时间段的序列值( )和未来窗口时间段的序列值( )。具体的步骤如下:

首先,过去窗口输入序列被分成等长的小段,段长度为 ,则一共可以分为 段,第 段为:

时变Koopman预测的核心思想是,对于每个小段来说,可以通过测量函数(其实就是一个Encoder)映射到非线性动态空间:

其中Encoder也是一个MLP, 也是处于 空间内的。然后根据前面提到的Koopman算子来将非线性近似为线性 ,即可得到下面的关系:

其中

因为上面的 和 都只包含过去窗口内的时间段特征,所以均是已知的。则可以解析地计算出Koopma算子( 表示 的Moore–Penrose逆):

然后,根据计算出的Koopma算子,可以得出拟合出来的过去窗口时间段特征:

对未来窗口的时间段特征(长度为 ,所以有 段),也可以外推预测出来:

无论是上面拟合出来的过去窗口时间段特征,还是未来窗口预测出来的时间段特征,都可以用一个Decoder来解码出具体的时间段序列值:

真实的过去窗口时间段序列值减去拟合出来的过去窗口时间段序列值作为残差输入给后面的Koopa Block,未来窗口预测出来的时间段序列值其实就是 ,表示未来窗口的时变分量。

预测效果的对比实验:

消融实验,作者发现分为时变预测和时不变预测是很重要的,两者缺一不可:

下面两个图是模型研究实验,左图可以证明傅里叶滤波确实将序列分解成了时变分量和时不变分量;右图是不同时间段的时变Koopman算子,可以看到在下降阶段和上升阶段,Koopman算子都是不同的,也反应了不同的时间动态。

论文将动力学理论和时间序列预测相结合,比较有创新,效果也很好。我觉得这篇论文也向我们揭示了对于序列预测来说,可能模型本身的设计并不是最重要的(Koopa里的Encoder、Decoder就是简单的MLP,不是各种花里胡哨的模型,DLinear也证明了这一点),而是框架的设计,比如Koopa对时变和时不变分量分别进行处理,时不变分量由全局来学习,时变分量则由局部来学习。论文里关于时变分量和时不变分量,如果能可视化这两个分量的一些例子就好了,类似于季节-趋势分解中将季节分量和趋势分量可视化出来。