1.实验目的

此笔记本用作以下目的:

  • 在多个时间序列上训练单个模型
  • 使用预训练模型获取训练期间未见的任何时间序列的预测
  • 使用协变量训练和使用模型

2.导库

# fix python path if working locally
from utils import fix_pythonpath_if_working_locallyfix_pythonpath_if_working_locally()import pandas as pd
import numpy as np
import torch
import matplotlib.pyplot as plt
from darts.models import NBEATSModel
from darts.models import *
from darts import TimeSeries
from darts.utils.timeseries_generation import (gaussian_timeseries,linear_timeseries,sine_timeseries,
)
from darts.models import (RNNModel,TCNModel,TransformerModel,NBEATSModel,BlockRNNModel,
)
from darts.metrics import mape, smape
from darts.dataprocessing.transformers import Scaler
from darts.utils.timeseries_generation import datetime_attribute_timeseries
from darts.datasets import AirPassengersDataset, MonthlyMilkDataset
%load_ext autoreload
%autoreload 2
%matplotlib inlineimport pandas as pd
import numpy as np
import matplotlib.pyplot as pltfrom darts import TimeSeries
from darts.datasets import AirPassengersDataset,MonthlyMilkDataset# for reproducibility
torch.manual_seed(1)
np.random.seed(1)

3.读取数据

从阅读两个时间序列开始——一个包含每月的航空乘客数量,另一个包含每头奶牛每月的产奶量。这些时间序列彼此没有太大关系,只是它们都具有明显的年度周期性和上升趋势的月频率,并且(完全巧合)它们包含可比较数量级的值。

series_air = AirPassengersDataset().load()
series_milk = MonthlyMilkDataset().load()series_air.plot(label="Number of air passengers")
series_milk.plot(label="Pounds of milk produced per cow")
plt.legend()

4. 预处理

通常,神经网络倾向于在标准化/标准化数据上工作得更好。在这里,将使用Scaler该类来规范化 0 和 1 之间的时间序列:

from darts.dataprocessing.transformers import Scalerscaler_air, scaler_milk = Scaler(), Scaler()
series_air_scaled = scaler_air.fit_transform(series_air)
series_milk_scaled = scaler_milk.fit_transform(series_milk)series_air_scaled.plot(label="air")
series_milk_scaled.plot(label="milk")
plt.legend()

5.拆分数据集【训练集、验证集】

保留这两个系列的最后 36 个月作为验证:

train_air, val_air = series_air_scaled[:-36], series_air_scaled[-36:]
train_milk, val_milk = series_milk_scaled[:-36], series_milk_scaled[-36:]

6.全局预测模型

Darts 包含许多预测模型,但并非所有模型都可以在多个时间序列上进行训练。支持多系列训练的模型称为全局模型。目前有 5 个全局模型:

  • BlockRNN模型
  • RNN模型
  • 时间卷积网络 (TCN)
  • N-Beats 模型
  • Transformer 模型

将区分两种时间序列:

  • 目标时间序列是我们有兴趣预测的时间序列(鉴于其历史)
  • 协变量时间序列是可能有助于预测目标序列的时间序列,但对预测不感兴趣。有时也称为外部数据。

进一步区分协变量系列,这取决于它们是否可以提前知道:

  • 过去协变量表示其过去值在预测时已知的时间序列。这些通常是必须测量或观察的事情。
  • 未来协变量表示其未来值在预测时间范围内已知的时间序列。例如,这些可以代表已知的未来假期或天气预报。

有些模型只使用过去的协变量,有些只使用未来的协变量,有些模型可能同时使用两者。

  • BlockRNNModel, TCNModel,NBEATSModel和TransformerModel都使用past_covariates
  • RNNModel使用future_covariates

上面列出的所有全局模型都支持多个序列的训练。此外,它们还都支持多变量序列。这意味着它们可以无缝地用于多维时间序列;目标系列可以包含一个(通常是这种情况)或多个维度。具有多个维度的时间序列实际上只是一个常规时间序列,其中每个时间戳的值是向量而不是标量。

例如,支持past_covariates的4个模型遵循 “块”架构 。它们包含一个神经网络,该网络以时间序列的块作为输入,并输出(预测的)未来时间序列的块。输入维数是目标序列的维数(组件),加上所有协变量的组件数——堆叠在一起。输出维数为目标序列的维数:

RNNModel的工作方式不同,以一种循环的方式(这也是它们支持未来协变量的原因)。 好消息是,作为用户,我们不需要太担心不同的模型类型和输入/输出维度。维度由模型基于训练数据自动推断出来,对过去或未来协变量的支持由past_covariatesfuture_covariates参数简单地处理。

在构建模型时,仍然需要指定两个重要参数:

  • input_chunk_length:这是模型的回溯窗口的长度;因此模型将通过读取前面的input_chunk_length点来计算每个输出。
  • Output_chunk_length:这是内部模型产生的输出(预测)的长度。然而**,“outer” dart模型** (例如,NBEATSModel、TCNModel等的模型)的predict()方法可以在更长的时间范围内被调用。在这些情况下,如果在超过output_chunk_length的范围内调用predict(),内部模型将被重复调用,以一种自回归的方式依赖于它自己以前的输出。如果使用了past_covariates,它需要这些协变量提前足够长的时间被知道。

7.训练-预测-单变量

构建一个 N-BEATS 模型,该模型具有 24 个点 ( input_chunk_length=24) 的回溯窗口并预测接下来的 12 个点 ( output_chunk_length=12)。选择这些值,这样模型就会在过去的两年里,每次产生连续的预测。
这个模型可以像任何其他dart预测模型一样使用,适用于单个时间序列:

model_air = NBEATSModel(input_chunk_length=24, output_chunk_length=12, n_epochs=200, random_state=0
)
model_air.fit(train_air, verbose=True)


和其他dart预测模型一样,可以通过调用predict()来获得预测。注意,下面,调用的窗口为36的predict(),比模型内部output_chunk_length为12的视界要长。这在这里不是问题——正如上面所解释的,在这种情况下,内部模型将被简单地称为自回归输出。在本例中,它将被调用三次,以便三个12点输出构成最后的36点预测——但所有这些都是在幕后透明地完成的。

pred = model_air.predict(n=36)series_air_scaled.plot(label="actual")
pred.plot(label="forecast")
plt.legend()
print("MAPE = {:.2f}%".format(mape(series_air_scaled, pred)))

(1).训练过程【后台训练过程】

调用model_air.fit()时发生了什么呢?

为了训练内部神经网络,dart首先从提供的时间序列(在本例中为series_air_scaled)中创建一个输入/输出示例数据集。有几种方法可以做到这一点,并且dart在dart .utils.data包中包含一些不同的数据集实现。

默认情况下,NBEATSModel将实例化 一个 darts.utils.data.PastCovariatesSequentialDataset,它只是构建序列中存在的所有连续的输入/输出子序列对(长度为input_chunk_lengthoutput_chunk_length)。

对于长度为14的序列,input_chunk_length=4, output_chunk_length=2,它看起来如下:

对于这样的数据集,一系列长度为N的数据集会得到 N - input_chunk_length - output_chunk_length + 1个样本的“训练集”。在上面的示例中,我们有N=14, input_chunk_length=4和output_chunk_length=2,所以用于训练的样本数量是K = 9。在这种情况下,训练阶段包含对所有样本的完全遍历(可能包含几个小批量)。

请注意,默认情况下,不同的模型容易使用不同的数据集。例如,darts.utils.data.HorizonBasedDataset受到N-BEATS 论文的启发,并生成了“接近”系列结尾的样本,甚至可能忽略了序列的开头。

如果您需要控制从实例生成训练样本的方式,可以通过继承抽象类TimeSeries来实现自己的训练数据集。darts.utils.data.TrainingDatasetDarts 数据集继承自 torch Dataset,这意味着很容易实现不会一次将所有数据加载到内存中的惰性版本。一旦有了自己的数据集实例,就可以直接调用该fit_from_dataset()方法,所有全球预测模型都支持该方法。

8.在多个时间序列(多变量)上训练模型

所有这些机器都可以与多个时间序列无缝使用。下面是一个顺序数据集如何查找两个长度为 N 和 M 的序列 input_chunk_length=4output_chunk_length=2

注意几点:

  • 不同的系列不需要具有相同的长度,甚至不需要共享相同的时间戳。
  • 事实上,它们甚至不需要具有相同的频率。
  • 训练数据集中的样本总数将是每个系列中包含的所有训练样本的并集;所以一个训练时期现在将跨越所有系列的所有样本。

(1). 训练 空中交通数据集 和牛奶数据序列

在两个时间序列(航空乘客和牛奶生产)上拟合另一个模型实例。由于使用(大致)相同长度的两个系列(大致)会使训练数据集大小翻倍,因此我们将使用一半的 epoch 数:

train_air, val_air = series_air_scaled[:-36], series_air_scaled[-36:]
train_milk, val_milk = series_milk_scaled[:-36], series_milk_scaled[-36:]model_air_milk = NBEATSModel(input_chunk_length=24, output_chunk_length=12, n_epochs=100, random_state=0
)

在两个(或更多)序列上拟合模型,就像在fit()函数的参数中给出一个序列列表(而不是单个序列)一样简单:

model_air_milk.fit([train_air, train_milk], verbose=True)

(2).在训练结束后生成预测

重要的是,在计算预测时,必须指定要预测未来的时间序列:之前没有这个约束。当仅在一个系列上拟合模型时,模型会在内部记住该系列,如果predict()在没有series参数的情况下调用,它会返回(唯一)训练系列的预测。一旦模型适用于多个系列,这将不再起作用 - 在这种情况下,series参数成为predict()强制性的。

假设想预测空中交通的未来。在本例中,为predict()函数指定了series=train_air,目的是为了预测train_air之后的内容:

pred = model_air_milk.predict(n=36, series=train_air)series_air_scaled.plot(label="actual")
pred.plot(label="forecast")
plt.legend()
print("MAPE = {:.2f}%".format(mape(series_air_scaled, pred)))

(3).牛奶消耗是否真的有助于预测空中交通?

在这个模型的这个特殊例子中,情况(有助于)似乎就是这样(至少在 MAPE 错误方面)。不过,如果你仔细想想,这并不奇怪。空中交通的特点是年度季节性和上升趋势。牛奶系列也表现出这两个特征,在这种情况下,它可能有助于模型捕捉它们。

请注意,这指向了预训练预测模型的可能性;一劳永逸地训练模型,然后使用它们来预测不在训练集中的序列,可以预测一个变量的未来,也可以预测多个变量的未来。使用模型,可以真正预测任何其他系列的未来值,甚至是训练期间从未见过的系列。

举个例子,假设要预测一些任意正弦波序列的未来:【使用训练好的模型,预测多个变量的未来】
这个预测并不好(sin甚至没有每年的季节性),但您可以理解。

any_series = sine_timeseries(length=50, freq="M")
pred = model_air_milk.predict(n=36, series=any_series)any_series.plot(label='"any series, really"')
pred.plot(label="forecast")
plt.legend()

fit()函数所支持的类似,也可以在参数中为predict()函数提供一个序列列表,在这种情况下,它将返回一个预测序列列表。例如,可以一次得到空中交通和牛奶系列的预测,这两个序列分别对应于train_air和train_milk结束后的预测:

pred_list = model_air_milk.predict(n=36, series=[train_air, train_milk])
for series, label in zip(pred_list, ["air passengers", "milk production"]):series.plot(label=f"forecast {label}")
plt.legend()

9. 协变量序列

到目前为止,一直使用的模型只使用目标序列的历史 来 预测其未来。然而,如上所述,全局dart模型也支持使用协变量时间序列。这些是“外部数据” 的时间序列,也许不一定对预测感兴趣,但仍然希望将其作为模型的输入,因为它们可能包含有价值的信息。

(1)构建协变量

看一个关于空气和牛奶系列的简单例子,在这个例子中,将尝试使用年份和月份作为协变量:

# 构建年和月系列:
air_year = datetime_attribute_timeseries(series_air_scaled, attribute="year")
air_month = datetime_attribute_timeseries(series_air_scaled, attribute="month")milk_year = datetime_attribute_timeseries(series_milk_scaled, attribute="year")
milk_month = datetime_attribute_timeseries(series_milk_scaled, attribute="month")# 堆叠年和月,得到二维(年和月)序列:
air_covariates = air_year.stack(air_month)
milk_covariates = milk_year.stack(milk_month)# 缩放到 0和1之间:
scaler_dt_air = Scaler()
air_covariates = scaler_dt_air.fit_transform(air_covariates)scaler_dt_milk = Scaler()
milk_covariates = scaler_dt_milk.fit_transform(milk_covariates)# 拆分训练/验证集:
air_train_covariates, air_val_covariates = air_covariates[:-36], air_covariates[-36:]
milk_train_covariates, milk_val_covariates = (milk_covariates[:-36],milk_covariates[-36:],
)# 绘制协变量:
plt.figure()
air_covariates.plot()
plt.title("Air traffic covariates (year and month)")plt.figure()
milk_covariates.plot()
plt.title("Milk production covariates (year and month)")


很好,因此对于每个目标序列(空气和牛奶),我们已经构建了具有相同时间轴并包含年和月的协变量系列。

注意,这里的协变量序列是多元时间序列:它们包含两个维度——一个维度代表年份,一个维度代表月份。

(2)训练【协变量+特征、目标数据】

构建一个BlockRNNModel 训练:

model_cov = BlockRNNModel(model="LSTM",input_chunk_length=24,output_chunk_length=12,n_epochs=300,random_state=0,
)

现在,要用协变量训练模型,只需将协变量(以匹配目标序列的列表的形式)作为future_covariates参数提供给fit()函数即可。参数名为future_covariates,以提醒模型可以使用这些协变量的未来值来进行预测。

model_cov.fit(series=[train_air, train_milk],past_covariates=[air_train_covariates, milk_train_covariates],verbose=True,
)

(3)使用协变量进行预测未来【无需输入未来的真实值】

类似地,获得预测现在只需要为predict()函数指定future_covariates参数

pred_cov = model_cov.predict(n=36, series=train_air, past_covariates=air_covariates)series_air_scaled.plot(label="actual")
pred_cov.plot(label="forecast")
plt.legend()


注意,这里调用了predict(),其预测范围n大于训练模型时使用的output_chunk_length。之所以能够做到这一点,是因为即使BlockRNNModel使用了过去的协变量,在这种情况下,这些协变量也知道未来的情况,所以dart能够对未来的n个时间步进行自回归计算预测。

(4)使用协变量进行回测

可以使用协变量对模型进行回测。例如,评估 12 个月的运行精度,从 75% 的空气系列开始:

backtest_cov = model_cov.historical_forecasts(series_air_scaled,past_covariates=air_covariates,start=0.6,forecast_horizon=12,stride=1,retrain=False,verbose=True,
)series_air_scaled.plot(label="actual")
backtest_cov.plot(label="forecast")
plt.legend()
print("MAPE (using covariates) = {:.2f}%".format(mape(series_air_scaled, backtest_cov)))

时间序列 工具库学习(5) Darts模块-多个时间序列、预训练模型和协变量的概念和使用相关推荐

  1. 时间序列 工具库学习(1) tsfresh特征提取、特征选择

    1. 更新清单: 2022.01.07:初次更新文章 2. 了解.安装tsfresh tsfresh 可以自动计算大量的时间序列特性,包含许多特征提取方法和强大的特征选择算法.tsfresh 用于从时 ...

  2. 时间序列 工具库学习(6) Darts模块-使用DataTransformer和Pipelin进行数据预处理

    https://github.com/unit8co/darts 1.DataTransformer抽象 DataTransformer旨在提供一种统一的方式来处理TimeSeries的转换: Tra ...

  3. 时间序列 工具库学习(18)adtk模块-异常类型

    1.异常类型 异常是一个广义的概念,它可以指代时间序列中许多不同类型的事件.根据具体情况,价值飙升.波动性转变.违反季节性模式等都可能是异常的或正常的.ADTK 提供了一组通用组件,可以针对不同场景组 ...

  4. Moment工具库学习

    Moment工具库 一.解析 二.取值赋值 三.操作显示 四.查询 Moment是JavaScript 日期处理类库,由于是获取设置时间,所以本文的注释可能会有偏差,学者可以自行试验. 一.解析 mo ...

  5. pythonurllib标准_Python标准库学习笔记 urllib模块

    利用缓存实现简单的获取 import urllib import os def reporthook(blocks_read,block_size,total_size): if not blocks ...

  6. POCO C++库学习和分析 -- 序

    POCO C++库学习和分析 -- 序 1. POCO库概述: POCO是一个C++的开源库集.同一般的C++库相比,POCO的特点是提供了整一个应用框架.如果要做C++程序应用框架的快速开发,我觉得 ...

  7. POCO C++库学习和分析 -- 字符编码

    POCO C++库学习和分析 -- 字符编码 1. 字符编码 1.1 字符编码的概念 字符编码可以理解为在计算机上语言符号和二比特数之间的映射.不同的编码方式对应着不同映射方法,对于映射集的双方而言, ...

  8. 【070】千千秀字-文字处理类集成工具库

    今天分享一个强大的文字处理类工具库,在线提供字体转换.字体预览.文字在线生成.汉字工具书.字符编码解码.字符加密解密等近200项功能.即开即用类的工具库谁又嫌多呢? 地址:参见文末图 "千千 ...

  9. Pytorch:NLP 迁移学习、NLP中的标准数据集、NLP中的常用预训练模型、加载和使用预训练模型、huggingface的transfomers微调脚本文件

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) run_glue.py微调脚本代码 python命令执行run ...

  10. Paddle预训练模型应用工具PaddleHub

    Paddle预训练模型应用工具PaddleHub • 本文主要介绍如何使用飞桨预训练模型管理工具PaddleHub,快速体验模型以及实现迁移学习.建议使用GPU环境运行相关程序,可以在启动环境时,如下 ...

最新文章

  1. PHP: How to print a debug log?
  2. python不包含某字符,查找不包含某些文本字符串的所有文本文件
  3. Scala重写父类普通方法
  4. 用 JMeter 测量性能--测试您的 DB2 数据库
  5. Linux下的字符集问题
  6. cmd.exe启动参数说明
  7. spring mvc学习(8):springmvc常用注解代码
  8. (转)Windows 批处理实现 定时打开IE 延时一段时间后 关闭IE
  9. 欧拉定理(洛谷-P5091)(扩展欧拉定理实现)
  10. Android开发环境搭建之Eclipse/AndroidStudio
  11. 彻底关闭Excle进程的几个方法
  12. 有关异或符号'^'在c++编程中的应用
  13. tomcat普通用户启动不了
  14. 构架高性能的InterBase/FireBird系统
  15. python背单词游戏,python背单词小程序
  16. 计算机系统关键服务有多少项,你好,QQ电脑管家启动项说系统关键项启动100多秒。怎么回事?...
  17. 【译】前端开发者的基本要求
  18. ndarray数组基本结构和操作
  19. 2542: 弟弟的作业
  20. 219年北京移动校园卡200打一年究竟是不是骗局?到底有没有坑?

热门文章

  1. 【Trailhead题目解析】Prepare your salesforce org for users - 2Update the Exchange Rate with ACM
  2. POR BOR LVD
  3. 19.IIC通信:PCF8591:数模/模数转换芯片
  4. 字符串后#号导致导出excel换行问题
  5. 均衡发展计算机教室材料,均衡发展汇报材料
  6. 在虚拟机中ping了停不下来怎么办?
  7. CSS3渐变、过渡、2D、3D和动画
  8. 线下交易如何避免微信和支付宝交易风控
  9. 监控Linux磁盘情况,进行邮件告警
  10. 【第一组】第七次冲刺例会纪要