对时间序列数据怎样进行分析(5行代码提升时间序列预测)
对时间序列数据怎样进行分析(5行代码提升时间序列预测)即建模来预测第t时间的数据,时间序列预测任务可以形式化表达如下:根据这个时间窗的数据,
微|信|公|众|号 包包算法笔记
本文从NeurIPS2021一篇用于提升时间序列预测效果的论文讲起:Adjusting for Autocorrelated Errors in Neural Networks for Time Series。文章简单,效果显著。
并最后给出时间序列任务中,其他常用的trick。
背景
时间序列预测任务可以形式化表达如下:
根据
这个时间窗的数据,
来预测第t时间的数据,
即建模
,
输入是
输出是Xt。
论文改进
这个东西的操作起来其实是比较简单的,实验效果也非常不错。
作者的理论是,用最大似然估计训练神经网络的一个常见假设是多个时间节点的误差是不相关的。但是这和实际的情况并不相符,很多数据的内在的误差,都是有自相关性的。这篇论文把这个自相关误差的相关参数,进行显示的学习。
看的云里雾里。如果看着难受的话,建议先直接看代码部分。
论文通过一个引入一个可以学习的变量 p(其实是\rho那个希腊字母,微信一直吞特别小的图片,观众姥爷将就看)
输入转变为一阶自回归误差。
即输入是 下面这个式子:
模型的预测也转变为
【公式1】
这就是开头提高那个自相关的误差。理论上这里面有规律的话,可以学出一点东西来。
其实我感觉这里过度简化离他开头的理论太远了,这哪里是误差了,明明就是变种的一阶差分。
你可以理解为,输入的数据变成了,错位加系数的一阶差分。
根据上文公示1,输出转化为 是
。
所以在计算loss的时候,使用普通的回归损失。
代码实现
嗯,论文大概就是这样。
看一下代码实现就很清楚了,这是正常的时间序列预测。
## x:输入特征X
prd_y = model(X) #模型预测
loss = criterion(y prd_y) #通常为mse
loss.backward() #反传
这是调整后的时间序列预测。
## rho可训练参数
## bs: batch_size
#sample开头拼上均值方便计算差分 X0-xbar X1-X0 X2-X1.. Xn-Xn-1
inp = torch.cat([X.mean(axis=0)[None].repeat(bs 1 1) x] dim=1)
inp = inp[: 1:] - rho * inp[: :-1] #输入修正
prd_y = model(inp) #模型预测
prd_y = rho * x[: -1] #输出修正
loss = criterion(y prd_y) #计算loss 同上
loss.backward() #反传 同上
注意,论文在调参数的时候,引入了单独的优化器来对单独优化。这里没写出来。
这个修改在超级多的数据集上起作用了。w/是加了这个操作在各个模型和数据集上的提升,平均有个17%的相对提升吧。比较惊人。
其实我对他理论不太感冒,因为实在是和假设相比,相差太远了,感兴趣的小伙伴可以再精度下论文。
看了下审稿人的评价,也是褒贬不一,5765分,算不上高分作文。
其实这种类似的操作,在时间序列任务预测中用的比较多,作者比较创新的地方是显示地学习这个差分上的参数,然后在理论上提出了自己的想法,效果也挺扎实的。
其他时间序列trick
既然作者中了,我就帮他翻出一些冷饭吧,在我实际使用时候。基本也都有用。
- 输一阶差分,二阶差分当输入特征
- 把一阶差分预测的损失当成一个loss,最为一个多目标预测的加权loss。
- 把cumsum预测的损失当成一个loss,作为一个多目标预测的加权loss。
- 把不同时间窗,不同跨度的预测作为模型融合的角度。这有点像量化选股里面的操作。