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

article/2025/11/10 5:14:35

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

在这里插入图片描述


http://chatgpt.dhexx.cn/article/WUvJeNfN.shtml

相关文章

Mplus数据分析:随机截距交叉之后的做法和如何加协变量,写给粉丝

记得之前有写过如何用R做随机截距交叉滞后,有些粉丝完全是R小白,还是希望我用mplus做,今天就给大家写写如何用mplus做随机截距交叉滞后。 做之前我们需要知道一些Mplus的默认的设定: observed and latent exogenous variables a…

中介变量、调节变量与协变量

在平时看论文过程中偶会接触到这几个概念,然而都没想过弄明白,每次总觉得只要看明白个大概反正自己又不用这种方法…作为科研人,还是应该保持谦逊,保持学习 一、中介变量 1.概念 中介变量(mediator)是自…

协变量偏移/标签偏移/概念偏移

协变量偏移 这里我们假设,虽然输入的分布可能随时间而改变,但是标记函数,即条件分布P(y∣x)不会改变。虽然这个问题容易理解,但在实践中也容易忽视。 想想区分猫和狗的一个例子。我们的训练数据使用的是猫…

R语言绘制校正协变量后的ROC曲线

ROC曲线也叫受试者工作曲线,原来用在军事雷达中,后面广泛应用于医学统计中。ROC曲线是根据一系列不同的二分类方式(分界值或决定阈),以真阳性率(灵敏度)为纵坐标,假阳性率(1-特异度)为横坐标绘制的曲线。 ROC曲线主要应用于二分类…

倾向值分析(协变量选择)

Hirano 和 Imbens 基于预设的临界t值来设定预测变量的方法 逻辑回归:逻辑回归虽然带有回归字样,但是逻辑回归属于分类算法。逻辑回归可以进行多分类操作,但由逻辑回归算法本身性质决定其更常用于二分类。 a.逻辑回归公式如下: 其…

使用aPCoA包实现校正协变量的主坐标分析(aPCoA)以排除混杂协变量的影响

使用aPCoA包实现校正协变量的主坐标分析(aPCoA)以排除混杂协变量的影响 主坐标分析(PCoA)广泛用于生态学和微生物学等领域,以描述样本之间的差异,例如群落的beta多样性等。然而混杂的协变量可能会使与感兴趣…

多变量时间序列、预训练模型和协变量

darts官方地址 GitHub:https://github.com/unit8co/darts文档:https://unit8co.github.io/darts/index.html 本笔记可作为以下内容的教程: 在多个时间序列上训练单个模型使用预训练模型来获得训练期间看不到的任何时间序列的预测训练和使用…

协变量偏移_恶意软件分类的协变量偏移

协变量偏移 介绍 (Introduction) Covariate shift in the data-generating distribution lowers the usefulness of generalization error as a measure of model performance. By unpacking the definitions, the previous sentence translates to “high accuracy on the dis…

matlab 去除协变量,求助协变量调整

花了一个礼拜的时间重新学习了一下协方差,回归,感觉自己的理解很多都是不对的。 协方差分析是方差分析线性回归,但它要求很多,比如至少有两个分组(一个分组就是线性回归了),协变量要是连续变量自变量和因变量要有线性关…

自变量/解释变量/因变量/响应变量/协变量等变量相关概念探析

概念探析 一般科学实验主要涉及以下三种变量: 自变量/独立变量(independent variable):自变量是指在实验中由实验者操作的变量,它被认为不会受其他变量的影响(即独立性)。 因变量&#xff08…

爬虫-猫眼电影票房

背景 最近也不知道咋了,一直遇到 字体反爬手段,起点中文网,抖音等等吧,猫眼我一直想搞,只是没有精力了,前面搞了2个了,不差这一个。搞完这个,不在搞字体反爬了。 目标网站 猫眼票房…

python爬虫实例——中国电影票房

刚好最近在做一个关于中国电影市场的分析,所以这篇实例就诞生啦!!! 一、观察网页 我所爬取的网站是:中国票房——年度票房。 网址甩出来:http://www.cbooo.cn/year?year2019 我们需要的数据是从2015年到…

python爬虫实战——猫眼电影案例

python爬虫实战——猫眼电影案例 背景 笔者上一篇文章《基于猫眼票房数据的可视化分析》中爬取了猫眼实时票房数据,用于展示近三年电影票房概况。由于数据中缺少导演/演员/编剧阵容等信息,所以爬取猫眼电影数据进行补充。关于爬虫的教学内容&#xff0c…

猫眼app产品分析和原型绘制

本项目为学习产品知识和技能过程中的一个小结,针对猫眼电影app的简单产品分析,顺便巩固xmind和axure技能。 项目名称 :猫眼电影app 产品背景:中国电影市场近10年(2009年-2019年)由高速增长阶段过渡到低速增…

Python爬虫实战+数据分析+数据可视化(猫眼电影)

一、爬虫部分 爬虫说明: 1、本爬虫是以面向对象的方式进行代码架构的 2、本爬虫爬取的数据存入到MongoDB数据库中 3、爬虫代码中有详细注释 代码展示 import re import timefrom pymongo import MongoClient import requests from lxml import html from urllib …

python爬虫基础案例——爬取猫眼电影并保存数据到excel

好久没更新博文了,最近忙于学习scrapy框架和微信小程序开发,今天看到一个自己之前写的但是中途放弃的爬虫小案例——爬取猫眼电影TOP100榜的相关数据,现在将它写好并分享给大家。 爬虫的套路就是通过url发送请求,获取数据&#x…

采集电影票房实时数据

网址:aHR0cDovL3BmLmZlLnN0Lm1hb3lhbi5jb20vZGFzaGJvYXJk 抓包分析 根据数据包可以发现,该网站在发送了ajax请求的同时又请求了一份woff文件,基本上可以确定这里使用了字体文件加密的方式了。 分析请求参数 不难看出,只有timestam…

【Python爬虫】猫眼电影榜单Top100

这是一个入门级的Python爬虫,结构易于理解。本文对编写此爬虫的全过程进行了讲述。希望对大家的Python爬虫学习有所帮助。 一、目标 爬取猫眼电影榜单Top100,将数据存入Excel文件中,并利用pyecharts库进行数据可视化得到.html文件和.png文件…

python爬虫阶段性总结和项目实操——爬取猫眼票房Top100

本博客通过爬取猫眼票房Top100来简要复习一下网页的HTML获取(requests库)解析(Beautiful Soup库)和数据保存(csv库)以及总结一下爬取过程中遇到的问题和解决方法 运行结果如下 1.获取网页源代码 def get_…

猫眼产品分析

一、前言 本文试图通过对猫眼电影的版本迭代历程分析、用户分析、功能分析、运营分析以及数据表现来回答以下几个问题: (1)猫眼电影的产品定位? (2)猫眼电影产品设计及运营中有哪些亮点和策略&#xff1f…