darts官方地址

  • GitHub:https://github.com/unit8co/darts
  • 文档:https://unit8co.github.io/darts/index.html

本笔记可作为以下内容的教程:

  • 在多个时间序列上训练单个模型
  • 使用预训练模型来获得训练期间看不到的任何时间序列的预测
  • 训练和使用带协变量的模型

首先,一些必要的import:


import pandas as pd
import numpy as np
import torch
import matplotlib.pyplot as pltfrom darts import TimeSeries
from darts.utils.timeseries_generation import gaussian_timeseries, linear_timeseries, sine_timeseries
from darts.models import RNNModel, TCNModel, TransformerModel, NBEATSModel
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, MonthlyMilkDatasettorch.manual_seed(1); np.random.seed(1)  # for reproducibility

读取数据

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


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();

预处理

通常,神经网络对标准化数据的处理效果更好。在这里,我们将使用Scaler类对时间序列进行标准化至0和1之间:

scaler_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();

分割训练集/验证集

让我们将这两个序列的最后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:]

全局预测模型

Darts包含了许多预测模型,但并不是所有的预测模型都可以在多个时间序列上进行训练。支持多序列训练的模型称为全局模型。在撰写本文时,共有4种全局模型:

  • RNN
  • Temporal Convolutional Networks(TCNs)
  • N-Beats
  • Transformer model

下面,我们将区分两种时间序列:

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

上面列出的所有全局模型都支持多个序列的训练。此外,他们也都有多变量和协变量支持:

  • 多元支持意味着它们可以无缝地用于多个维度的时间序列;目标序列可以包含一个维度(通常是这样)或多个维度。多维时间序列的每个时间戳的值都是向量而不是标量。
  • 协变量支持意味着它们支持接收输入中的协变量序列(外部数据)。

在内部,这些模型包含一个神经网络,它在输入中获取大量时间序列,并输出大量(预测的)未来时间序列值。输入维数是目标序列的维数(分量)加上所有协变量的分量叠加在一起。输出维度只是目标系列的维度数:

好消息是,作为一个用户,我们不必担心不同的输入/输出维度;这些都是由模型根据训练数据自动推断出来的。注意,这意味着实际的内部神经网络模型只在训练时创建。

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

  • input_chunk_length:这是模型的回望窗口的长度;因此,每个输出都将由模型通过读取先前的input_chunk_length个点来计算。
  • output_chunk_length:这是内部模型生成的输出(预测)的长度。但是,当不使用协变量时,可以调用“外部”Darts模型的predict()方法(例如,RNNModel、TCNModel等中的方法)以获得更长的时间范围。在这些情况下,如果为比output_chunk_length更长的时间段调用predict(),则只需重复调用内部模型,以自动回归的方式输入其自身以前的输出。

单序列举例

让我们看第一个例子。我们将构建一个N-BEATS模型,它有一个24点的回望窗口(input_chunk_length=24),并预测接下来的12个点(output_chunk_length=12)。我们选择了这些值,这样我们的模型就可以一次连续预测一年,看看过去两年。

model_air = NBEATSModel(input_chunk_length=24, output_chunk_length=12, n_epochs=200)

此模型可以像任何其他Darts预测模型一样使用,适用于单个时间序列:

model_air.fit(train_air, verbose=True)[2021-01-20 21:09:18,336] INFO | darts.models.torch_forecasting_model | Train dataset contains 73 samples.
[2021-01-20 21:09:18,336] INFO | darts.models.torch_forecasting_model | Train dataset contains 73 samples.

HBox(children=(FloatProgress(value=0.0, max=200.0), HTML(value='')))

Training loss: 0.0002

和其他Darts预测模型一样,我们可以通过调用predict()获得预测。请注意,下面我们调用的predict()的范围是36,这比模型内部输出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)))
MAPE = 9.45%

训练过程(幕后)

当我们在上面代码中调用model_air.fit()之后发生了什么呢?

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

默认情况下,大多数模型都会实例化一个darts.utils.data.SequentialDataset,它只是构建序列中存在的所有连续的输入/输出子序列对(长度input\u chunk\u length和output\u chunk\u length)。

........(省略)

多时间序列模型的训练

所有这些机器都可以无缝地用于多个时间序列。

下面是一个input_chunk_length=4,output_chunk_length=2的连续数据集如何查找两个长度为N和M的序列:

注意以下几点:

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

航空乘客牛奶生产序列训练

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

model_air_milk = NBEATSModel(input_chunk_length=24, output_chunk_length=12, n_epochs=100)

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

model_air_milk.fit([train_air, train_milk], verbose=True)[2021-01-20 21:10:11,009] INFO | darts.models.torch_forecasting_model | Train dataset contains 194 samples.
[2021-01-20 21:10:11,009] INFO | darts.models.torch_forecasting_model | Train dataset contains 194 samples.

HBox(children=(FloatProgress(value=0.0), HTML(value='')))

Training loss: 0.0002

在一个序列的结束后产生预测

现在,重要的是,在计算预测时,我们必须指定要预测未来的时间序列。

我们之前没有这个限制。当只在一个序列上拟合模型时,模型会在内部记住这个序列,如果调用predict()时不带series参数,则会返回(唯一)训练序列的预测。

当一个模型适合多个序列时,这种方法就不再有效了——在这种情况下,predict()的序列参数变成了必需的。

所以,假设我们想预测未来的空中交通。在本例中,我们将series=train_air 指定给predict()函数,以表示我们希望获得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)))

MAPE = 5.72%

这是否意味着牛奶消费有助于预测空中交通??

好吧,在这个模型的特殊实例中,似乎是这样(至少在MAPE error

方面)。不过,仔细想想,这并不奇怪。空中交通具有明显的季节性和上升趋势。牛奶系列也展示了这两个特征,在这种情况下,它可能有助于模型捕捉它们。
注意,这一点指向了训练前预测模型的可能性;一次性训练模型,稍后使用它们来预测不在训练集中的序列。有了我们的玩具模型,我们真的可以预测任何其他系列的未来价值,即使是训练中从未见过的系列。举个例子,假设我们想预测一些任意正弦波序列的未来:

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()函数的参数中给出一个序列列表,在这种情况下,它将返回一个forecast序列列表。例如,我们可以一次性得到空中交通量和牛奶系列的预测,如下所示:


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();

返回的两个序列分别对应于 train_air和train_milk结束后的预测。

协变量序列

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

构建协变量

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

# build year and month series:
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')# stack year and month to obtain series of 2 dimensions (year and month):
air_covariates = air_year.stack(air_month)
milk_covariates = milk_year.stack(milk_month)# scale them between 0 and 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)# split in train/validation sets:
air_train_covariates, air_val_covariates = air_covariates[:-36], air_covariates[-36:]
milk_train_covariates, milk_val_covariates = milk_covariates[:-36], milk_covariates[-36:]# plot the covariates:
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)');

好的,所以对于每个目标系列(空气和牛奶),我们建立了一个具有相同时间轴的协变量系列,包含年份和月份。
注意,这里的协变量序列是多元时间序列:它们包含两个维度——一个维度是年份,一个是月。

协变量训练

让我们再次回顾我们的例子,这次是协变量。我们将构建一个RNNModel,因为在编写本文时,NBEATSModel还不支持协变量。

model_cov = RNNModel(input_chunk_length=24, output_chunk_length=12, n_epochs=300)

现在,要使用协变量训练模型,只需将协变量(以与目标序列匹配的列表形式)作为协变量参数提供给fit()函数:

model_cov.fit(series=[train_air, train_milk], covariates=[air_train_covariates, milk_train_covariates], verbose=True)[2021-01-20 21:11:12,009] INFO | darts.models.torch_forecasting_model | Train dataset contains 194 samples.
[2021-01-20 21:11:12,009] INFO | darts.models.torch_forecasting_model | Train dataset contains 194 samples.HBox(children=(FloatProgress(value=0.0, max=300.0), HTML(value='')))
Training loss: 0.0019

协变量预测

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

pred_cov = model_cov.predict(n=12, series=train_air, covariates=air_train_covariates)series_air_scaled.plot(label='actual')
pred_cov.plot(label='forecast')
plt.legend();

上面的主要问题是,我们不能直接调用predict(),因为horizon n大于我们训练模型时使用的输出块长度。这是因为当使用协变量时,我们不能使用自回归“技巧”,即我们对模型本身的输出进行迭代调用,因为在这种情况下,我们没有相应的协变量。

协变量回溯检验

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

backtest_cov = model_cov.historical_forecasts(series_air_scaled,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)))HBox(children=(FloatProgress(value=0.0, max=47.0), HTML(value='')))MAPE (using covariates) = 8.22%

当前限制、未来协变量和其他条件

目前,Darts支持的协变量本身就是时间序列。此外,这些时间必须与目标序列共享相同的时间轴。唯一真正的区别是,这些协变量序列将只作为模型的输入,而不是作为输出。

然而,即使协变量和目标需要共享它们的时间轴,协变量仍然可以表示已知的未来值。例如,如果目标受到某些外部因素(例如,天气)的影响,并且提前7天知道天气,那么可以简单地构建协变量序列,使其在时间T的值表示T+7的“前一周”预测(这可以简单地通过移动原始序列来实现)。

在编写本文时,Darts不支持非时间序列的协变量,例如类标签信息或其他条件变量。解决这个问题的一个简单方法(尽管可能是次优的)是构建时间序列,该序列中填充了对类标签进行编码的常量值。支持更一般类型的条件反射是Darts开发路线图上的一个未来特性。

多变量时间序列、预训练模型和协变量相关推荐

  1. ML:机器学习算法中—因子模型(多变量)、时序模型/时间序列模型(主要以单变量)算法对比的简介、带有时序性的因子模型概述、案例应用之详细攻略

    ML:机器学习算法中-因子模型(多变量).时序模型/时间序列模型(主要以单变量)算法对比的简介.带有时序性的因子模型概述.案例应用之详细攻略 目录 因子模型和时序模型/时间序列模型算法的简介 1.因子 ...

  2. 预训练模型应用工具 PaddleHub情感分析、对话情绪识别文本相似度

    文章目录 1. 预训练模型的应用背景 1.1 多任务学习与迁移学习 1.2 自监督学习 2. 快速使用PaddleHub 2.1 通过Python代码调用方式 使用PaddleHub 2.1.1 CV ...

  3. PaddlePaddle模型资源之一:预训练模型应用工具 PaddleHub

    文章目录 1. 预训练模型的应用背景 1.1 多任务学习与迁移学习 1.2 自监督学习 2. 快速使用PaddleHub 2.1 通过Python代码调用方式 使用PaddleHub 2.1.1 CV ...

  4. 【深度学习 项目实战】Keras深度学习多变量时间序列预测的LSTM模型

    无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家.教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家.点这里可以跳转到教程.人工智能教程 本篇文章将介绍基于 ...

  5. 基于Keras的LSTM多变量时间序列预测(北京PM2.5数据集pollution.csv)

                                 基于Keras的LSTM多变量时间序列预测 传统的线性模型难以解决多变量或多输入问题,而神经网络如LSTM则擅长于处理多个变量的问题,该特性使 ...

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

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

  7. 参数量110亿,附赠750GB数据集,Google提NLP预训练模型T5

    整理 | Just,夕颜 出品 | AI科技大本营(ID:rgznai100) 近日,Google 在最新一篇共有 53 页的论文<Exploring the Limits of Transfe ...

  8. 新一届最强预训练模型上榜,出于BERT而胜于BERT

    作者 | Facebook AI译者 | Lucy编辑 | Jane出品 | AI科技大本营(ID: rgznai100) [导读]预训练方法设计有不同的训练目标,包括语言建模.机器翻译以及遮蔽语言建 ...

  9. SpanBERT:提出基于分词的预训练模型,多项任务性能超越现有模型!

    作者 | Mandar Joshi, Danqi Chen, Yinhan Liu, Daniel S. Weld, Luke Zettlemoyer, Omer Levy 译者 | Rachel 责 ...

最新文章

  1. Android中对话框的工具类
  2. bizagi simulation 仿真学习
  3. **PHP中替换换行符
  4. 【算法】剑指 Offer 48. 最长不含重复字符的子字符串
  5. [转载] python类内部成员的访问及外部访问(入门)
  6. 腾讯会议发布3.0版本;微软将推出元宇宙产品;Firefox启动最大WebRTC升级|WebRTC风向
  7. ros与arduino通讯(一)ros_arduino_bridge功能包
  8. 阿里云商标智能注册申请图文教程(亲踩坑)
  9. 北京将广纳贤才 建设国际人才社区
  10. Unity内置管线升级URP之色彩空间(伽马、sRGB、Gamma Space和Linear Space)
  11. Android适配全面屏/刘海屏
  12. C++ 11字符数组/字符串/数字转换/字符串拼接
  13. 组织机构树型数据库结构
  14. 如何用计算机做函数图像,用计算机画函数图像 优秀教学实录
  15. 3dsmax游戏建模掌握这些技巧方法,6个月学会就业!
  16. Ubuntu(WSL)安装3b1b的manim
  17. jira的详细安装和破解
  18. 机器学习——照片OCR
  19. 【笔记】设计心理学 [美] 唐纳德·A·诺曼
  20. 罗马数字转换阿拉伯数字(Java版,考虑较为全面)

热门文章

  1. JB的阅读之旅-软件测试52讲(下)
  2. IDEA 使用补丁 patch
  3. css拖动音乐进度条,利用CSS3实现3D滑块进度条拖动动画特效
  4. 如何对全国麦当劳、KFC这些餐饮巨头做空间分析
  5. 学习设计模式的好网站
  6. ARM 伪指令和 ARM 宏指令
  7. IT行业干什么最赚钱
  8. IOS利用AVPlayer开发多媒体在线播放器
  9. Li Fei-fei写给她学生的一封信!
  10. GIS教程之如何从 Open Street Map 上的点击事件中获取纬度和经度