Python时间序列处理库Dart从入门到实战干货!

目录

文档

快速开始

安装Darts

构建和操作TimeSeries

读数据并创建一个TimeSeries

创建训练和验证序列

训练预测模型并预测

玩一下玩具模型

检查季节性

一个不幼稚的模型

计算误差度量

快速尝试几个模型

用Theta方法搜索超参数

回溯测试:模拟历史预测

机器学习和全局模型

两个时间序列的玩具

使用深度学习:N-BEATS的例子

协变量:使用外部数据

用户指导

API 参考

案例

Transformer Model

RNN Model


Dart是一个Python库,用于对时间序列进行用户友好的预测和异常检测。它包含了各种各样的模型,从经典的ARIMA到深度神经网络。预测模型都可以以相同的方式使用,使用fit()和predict()函数,类似于scikit-learn。该库还使回测模型、组合多个模型的预测以及考虑外部数据变得容易。Dart支持单变量和多变量时间序列和模型。基于机器学习的模型可以在包含多个时间序列的潜在大型数据集上进行训练,其中一些模型为概率预测提供了丰富的支持。

Dart还提供了广泛的异常检测功能。例如,在时间序列上应用PyOD模型以获得异常分数,或者包装任何Dart预测或过滤模型以获得完全成熟的异常检测模型都是很简单的。

官方网址GitHub:Unit8 SA · GitHubdarts

文档

快速开始

此处将详细介绍该库的主要功能:

安装Darts

推荐使用虚拟环境,主要有两种安装方式

用pip进行安装

pip install darts
  • 1

用conda进行安装

conda install -c conda-forge -c pytorch u8darts-all
  • 1

首先是导包,一些必要的导包。

%matplotlib inline  
import pandas as pd  
import numpy as np  
import matplotlib.pyplot as plt  
from darts import TimeSeries  
from darts.datasets import AirPassengersDataset
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意:%matplotlib inline (魔法函数)可以在Ipython编译器比如jupyter notebook 或者 jupyter qtconsole里直接使用,功能是可以内嵌绘图,并且省略掉plt.show()。

构建和操作TimeSeries

TimeSeries是Darts中的主要数据类。TimeSeries表示具有适当时间索引的单变量或多变量时间序列。时间索引可以是pandas类型。DatetimeIndex(包含日期时间),或pandas类型的。RangeIndex(包含整数);用于表示没有特定时间戳的顺序数据)。在某些情况下,TimeSeries甚至可以表示概率序列,例如为了获得置信区间。Darts中的所有模型都使用TimeSeries并生成TimeSeries。

读数据并创建一个TimeSeries

使用一些工厂方法可以很容易地构建TimeSeries:

使用
TimeSeries.from_dataframe() (docs)
从整个Pandas DataFrame中获取。

使用
TimeSeries.from_times_and_values() (docs)
从时间索引和相应值的数组中获取。

从NumPy数组的值,使用
TimeSeries.from_values() (docs)。

从Pandas系列中,使用
TimeSeries.from_series() (docs)。

从一个xarray。使用
TimeSeries.from_xarray() (docs)。

从CSV文件,使用
TimeSeries.from_csv() (docs)。

下面,我们通过直接从Dart中可用的一个数据集加载航空乘客系列来获得一个TimeSeries:

series = AirPassengersDataset().load()  
series.plot()
  • 1
  • 2

一些TimeSeries的操作

TimeSeries支持不同类型的操作——这里有几个例子。

划分

我们还可以在序列的一小部分、一个pandas时间戳或一个整数索引值上进行分割。

series1, series2 = series.split_before(0.75)  
series1.plot()  
series2.plot()
  • 1
  • 2
  • 3

切片

series1, series2 = series[:-36], series[-36:]  
series1.plot()  
series2.plot()
  • 1
  • 2
  • 3

算术运算

series_noise = TimeSeries.from_times_and_values(  
    series.time_index, np.random.randn(len(series))  
)  
(series / 2 + 20 * series_noise - 10).plot()
  • 1
  • 2
  • 3
  • 4

堆叠

连接一个新的维度以产生一个新的单多元序列。

(series / 50).stack(series_noise).plot()
  • 1

映射

series.map(np.log).plot()
  • 1

映射时间戳和值

series.map(lambda ts, x: x / ts.days_in_month).plot()
  • 1

添加一些datetime属性作为额外的维度(产生多变量序列):

(series / 20).add_datetime_attribute("month").plot()
  • 1

添加一些二进制假日组件:

(series / 200).add_holidays("US").plot()
  • 1

差分

series.diff().plot()
  • 1

填充缺失值

from darts.utils.missing_values import fill_missing_values  
  
values = np.arange(50, step=0.5)  
values[10:30] = np.nan  
values[60:95] = np.nan  
series_ = TimeSeries.from_values(values)  
  
(series_ - 10).plot(label="with missing values (shifted below)")  
fill_missing_values(series_).plot(label="without missing values")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

创建训练和验证序列

接下来,我们将把TimeSeries分成训练系列和验证系列。注意:一般来说,将测试系列放在一边并且在测试过程结束之前不要碰它也是一个很好的做法。这里,为了简单起见,我们只构建一个训练和验证系列。

训练系列将是一个包含到1958年1月(不包括)的值的TimeSeries,验证系列将是一个包含其余值的TimeSeries:

train, val = series.split_before(pd.Timestamp("19580101"))  
train.plot(label="training")  
val.plot(label="validation")
  • 1
  • 2
  • 3

训练预测模型并预测
玩一下玩具模型

在Darts中有一组“原始的”基线模型,这对于了解人们所期望的最低精度非常有用。例如,naivesasional (K)模型总是“重复”K个时间步之前发生的值。

在最朴素的形式中,当K=1时,该模型总是简单地重复训练序列的最后一个值:

from darts.models import NaiveSeasonal  
  
naive_model = NaiveSeasonal(K=1)  
naive_model.fit(train)  
naive_forecast = naive_model.predict(36)  
  
series.plot(label="actual")  
naive_forecast.plot(label="naive forecast (K=1)")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在TimeSeries上拟合模型并做出预测是非常容易的。所有模型都有一个fit()和一个predict()函数。这类似于Scikit-learn,除了它是特定于时间序列的。fit()函数的参数是拟合模型的训练时间序列,predict()函数的参数是要预测的时间步数(在训练序列结束之后)。

检查季节性

我们上面的模型可能有点太天真了。我们已经可以通过利用数据中的季节性来改进。很明显,数据具有年度季节性,我们可以通过查看自相关函数(ACF)来确认这一点,并突出显示滞后m=12:

from darts.utils.statistics import plot_acf, check_seasonality  
  
plot_acf(train, m=12, alpha=0.05)
  • 1
  • 2
  • 3

ACF在x = 12处呈现峰值,这表明每年的季节性趋势(以红色突出显示)。蓝色区域确定统计数据的显著性,置信水平为(\alpha = 5\%)。我们还可以对每个候选时期m的季节性进行统计检查:

for m in range(2, 25):  
    is_seasonal, period = check_seasonality(train, m=m, alpha=0.05)  
 if is_seasonal:  
        print("There is seasonality of order {}.".format(period))
  • 1
  • 2
  • 3
  • 4
一个不幼稚的模型
seasonal_model = NaiveSeasonal(K=12)  
seasonal_model.fit(train)  
seasonal_forecast = seasonal_model.predict(36)  
  
series.plot(label="actual")  
seasonal_forecast.plot(label="naive forecast (K=12)")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这是更好的,但我们仍然错过了趋势。幸运的是,还有另一个朴素的基线模型可以捕捉到这一趋势,它被称为NaiveDrift。该模型简单地产生线性预测,其斜率由训练集的第一个和最后一个值决定:

from darts.models import NaiveDrift  
  
drift_model = NaiveDrift()  
drift_model.fit(train)  
drift_forecast = drift_model.predict(36)  
  
combined_forecast = drift_forecast + seasonal_forecast - train.last_value()  
  
series.plot()  
combined_forecast.plot(label="combined")  
drift_forecast.plot(label="drift")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

那里发生了什么?我们只是拟合一个朴素的漂移模型,并将其预测添加到我们之前的季节性预测中。我们还从结果中减去训练集的最后一个值,以便得到的组合预测从正确的偏移量开始。

计算误差度量

这看起来已经是一个相当不错的预测,而且我们还没有使用任何非幼稚模型。事实上,任何模型都应该能够克服这个问题。

我们要克服的误差是多少?我们将使用平均绝对百分比误差(MAPE)(请注意,在实践中经常有很好的理由不使用MAPE -我们在这里使用它,因为它非常方便并且与比例无关)。在Darts中,它是一个简单的函数调用:

from darts.metrics import mape  
  
print(  
    "Mean absolute percentage error for the combined naive drift + seasonal: {:.2f}%.".format(  
        mape(series, combined_forecast)  
    )  
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

darts.metric 度量包含更多的度量来比较时间序列。当两个序列不对齐时,度量将只比较序列的公共片段,并对大量序列对进行并行计算——但我们不要过于超前。

快速尝试几个模型

构建Darts是为了方便地以统一的方式训练和验证多个模型。让我们再训练几个,并在验证集上计算它们各自的MAPE:

from darts.models import ExponentialSmoothing, TBATS, AutoARIMA, Theta  
  
  
def eval_model(model):  
    model.fit(train)  
    forecast = model.predict(len(val))  
    print("model {} obtains MAPE: {:.2f}%".format(model, mape(val, forecast)))  
  
  
eval_model(ExponentialSmoothing())  
eval_model(TBATS())  
eval_model(AutoARIMA())  
eval_model(Theta())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
用Theta方法搜索超参数

Theta模型包含Assimakopoulos和Nikolopoulos的Theta方法的实现。这种方法取得了一些成功,特别是在m3比赛中。虽然Theta参数的值在应用程序中经常被设置为0,但我们的实现支持一个变量值,以便进行参数调优。我们试着找一个合适的值。

# Search for the best theta parameter, by trying 50 different values  
thetas = 2 - np.linspace(-10, 10, 50)  
  
best_mape = float("inf")  
best_theta = 0  
  
for theta in thetas:  
    model = Theta(theta)  
    model.fit(train)  
    pred_theta = model.predict(len(val))  
    res = mape(val, pred_theta)  
  
 if res < best_mape:  
        best_mape = res  
        best_theta = theta  
best_theta_model = Theta(best_theta)  
best_theta_model.fit(train)  
pred_best_theta = best_theta_model.predict(len(val))  
  
print(  
    "The MAPE is: {:.2f}, with theta = {}.".format(  
        mape(val, pred_best_theta), best_theta  
    )  
)  
train.plot(label="train")  
val.plot(label="true")  
pred_best_theta.plot(label="prediction")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

回溯测试:模拟历史预测

在这一点上,我们有了一个在验证集上表现良好的模型,这很好。但是,如果我们历史上一直使用这个模型,我们如何知道我们将获得的性能呢?回溯测试模拟了历史上用给定模型得到的预测结果。它可能需要一段时间来生成,因为每次模拟预测时间向前推进时(默认情况下)都会重新训练模型。这种模拟预报总是根据预报范围来定义的,预报范围是将预报时间与预报时间分开的时间步长。在下面的例子中,我们模拟未来3个月的预测(与预测时间相比)。调用historical_forecasts()的结果(默认情况下)是一个包含3个月预测的TimeSeries:

historical_fcast_theta = best_theta_model.historical_forecasts(  
    series, start=0.6, forecast_horizon=3, verbose=True  
)  
  
series.plot(label="data")  
historical_fcast_theta.plot(label="backtest 3-months ahead forecast (Theta)")  
print("MAPE = {:.2f}%".format(mape(historical_fcast_theta, series)))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

因此,当我们回测它时,我们在验证集上的最佳模型似乎不再做得那么好了(我是否听到过拟合:D)为了更仔细地查看误差,我们还可以使用backtest()方法来获得我们的模型本可以获得的所有原始误差(例如,MAPE误差):

best_theta_model = Theta(best_theta)  
  
raw_errors = best_theta_model.backtest(  
    series, start=0.6, forecast_horizon=3, metric=mape, reduction=None, verbose=True  
)  
  
from darts.utils.statistics import plot_hist  
  
plot_hist(  
    raw_errors,  
    bins=np.arange(0, max(raw_errors), 1),  
    title="Individual backtest error scores (histogram)",  
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

最后,使用backtest(),我们还可以得到历史预测平均误差的更简单视图:

average_error = best_theta_model.backtest(  
    series,  
    start=0.6,  
    forecast_horizon=3,  
    metric=mape,  
    reduction=np.mean,  # this is actually the default  
    verbose=True,  
)  
  
print("Average error (MAPE) over all historical forecasts: %.2f" % average_error)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

例如,我们也可以指定参数reduction=np。中位数来得到中位数MAPE。

我们来看一下当前Theta模型的拟合值残差,即通过对所有之前的点进行模型拟合得到的每个时间点的一步预测与实际观测值之间的差:

from darts.utils.statistics import plot_residuals_analysis  
  
plot_residuals_analysis(best_theta_model.residuals(series))
  • 1
  • 2
  • 3

我们可以看到分布不是以0为中心的,这意味着我们的Theta模型是有偏差的。我们还可以看出,滞后处的ACF值较大,等于12,这表明残差中包含了模型未使用的信息。

我们能用简单的指数平滑模型做得更好吗?

model_es = ExponentialSmoothing(seasonal_periods=12)  
historical_fcast_es = model_es.historical_forecasts(  
    series, start=0.6, forecast_horizon=3, verbose=True  
)  
  
series.plot(label="data")  
historical_fcast_es.plot(label="backtest 3-months ahead forecast (Exp. Smoothing)")  
print("MAPE = {:.2f}%".format(mape(historical_fcast_es, series)))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

plot_residuals_analysis(model_es.residuals(series))
  • 1

残差分析也反映了性能的改进,因为我们现在有一个以值0为中心的残差分布,而ACF值虽然不是不显著,但具有较低的幅度。

机器学习和全局模型

Darts对机器学习和深度学习预测模型有丰富的支持;例如:
RegressionModel可以围绕任何与sklearn兼容的回归模型生成预测(它在下面有自己的部分)。
RNNModel是一种灵活的RNN实现,可以像DeepAR一样使用。
NBEATSModel实现N-BEATS模型。
TFTModel实现了时间融合转换器模型。TCNModel实现了时间卷积网络。
除了支持与其他模型相同的基本fit()/predict()接口外,这些模型也是全局模型,因为它们支持在多个时间序列上进行训练(有时称为元学习)。
这是使用基于ML的模型进行预测的关键点:通常情况下,ML模型(尤其是深度学习模型)需要在大量数据上进行训练,这通常意味着大量独立但相关的时间序列。
在Darts中,指定多个TimeSeries的基本方法是使用一个TimeSeries序列(例如,一个简单的TimeSeries列表)。

两个时间序列的玩具

这些模型可以在数千个序列上进行训练。在这里,为了便于说明,我们将加载两个不同的系列——空中交通乘客数量和另一个包含每头奶牛每月产出的牛奶磅数的系列。我们也将级数转换为np。Float32,因为这将稍微加快训练:

from darts.datasets import AirPassengersDataset, MonthlyMilkDataset  
  
series_air = AirPassengersDataset().load().astype(np.float32)  
series_milk = MonthlyMilkDataset().load().astype(np.float32)  
  
# set aside last 36 months of each series as validation set:  
train_air, val_air = series_air[:-36], series_air[-36:]  
train_milk, val_milk = series_milk[:-36], series_milk[-36:]  
  
train_air.plot()  
val_air.plot()  
train_milk.plot()  
val_milk.plot()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

首先,让我们将这两个系列在0和1之间进行缩放,因为这将有利于大多数ML模型。我们将使用标量:

from darts.dataprocessing.transformers import Scaler  
  
scaler = Scaler()  
train_air_scaled, train_milk_scaled = scaler.fit_transform([train_air, train_milk])  
  
train_air_scaled.plot()  
train_milk_scaled.plot()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

使用深度学习:N-BEATS的例子

接下来,我们将构建一个N-BEATS模型。该模型可以使用许多超参数(如堆栈数量、层数等)进行调优。这里,为了简单起见,我们将它与默认超参数一起使用。我们只需要提供两个超参数:

Input_chunk_length:这是模型的“回看窗口”——也就是说,神经网络将多少时间步长的历史作为输入,在向前传递中产生输出。

Output_chunk_length:这是模型的“前向窗口”——也就是说,神经网络在前向传递中输出的未来值的时间步长。

random_state参数在这里只是为了获得可重复的结果。

Darts中的大多数神经网络都需要这两个参数。在这里,我们将使用季节性的倍数。现在,我们准备在两个序列上拟合我们的模型(通过给出包含要拟合的两个序列的列表()):

from darts.models import NBEATSModel  
  
model = NBEATSModel(input_chunk_length=24, output_chunk_length=12, random_state=42)  
  
model.fit([train_air_scaled, train_milk_scaled], epochs=50, verbose=True);  
pred_air = model.predict(series=train_air_scaled, n=36)  
pred_milk = model.predict(series=train_milk_scaled, n=36)  
  
# scale back:  
pred_air, pred_milk = scaler.inverse_transform([pred_air, pred_milk])  
  
plt.figure(figsize=(10, 6))  
series_air.plot(label="actual (air)")  
series_milk.plot(label="actual (milk)")  
pred_air.plot(label="forecast (air)")  
pred_milk.plot(label="forecast (milk)")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

协变量:使用外部数据

除了目标序列(我们有兴趣预测的序列)之外,Darts中的许多模型也接受协变量序列作为输入。协变量是我们不想预测的序列,但它可以为模型提供有用的附加信息。目标变量和协变量都可以是多变量或单变量。

在Darts中有两种协变量时间序列:

past_covariates是在预测时间之前不一定知道的序列。例如,这些可以表示必须测量并且事先不知道的东西。模型在进行预测时不使用过去协变量的未来值。

future_covariates是预先知道的序列,直至预测范围。它可以表示诸如日历信息、假日、天气预报等。接受future_covariates的模型在进行预测时将查看未来值(直至预测范围)

from darts import concatenate  
from darts.utils.timeseries_generation import datetime_attribute_timeseries as dt_attr  
  
air_covs = concatenate(  
    [  
        dt_attr(series_air.time_index, "month", dtype=np.float32) / 12,  
        (dt_attr(series_air.time_index, "year", dtype=np.float32) - 1948) / 12,  
    ],  
    axis="component",  
)  
  
milk_covs = concatenate(  
    [  
        dt_attr(series_milk.time_index, "month", dtype=np.float32) / 12,  
        (dt_attr(series_milk.time_index, "year", dtype=np.float32) - 1962) / 13,  
    ],  
    axis="component",  
)  
  
air_covs.plot()  
plt.title(  
    "one multivariate time series of 2 dimensions, containing covariates for the air series:"  
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

用户指导

https://unit8co.github.io/darts/userguide.html

API 参考

案例

https://unit8co.github.io/darts/examples.html

Forecasting Models预测模型

安装

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple darts  
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy  
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib  
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas  
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple torch
  • 1
  • 2
  • 3
  • 4
  • 5

关于缺少依赖

Install Darts with all available models: pip install "u8darts[all]"  
Install core only (without neural networks, Prophet, LightGBM and Catboost): pip install u8darts  
Install core + Prophet + LightGBM + CatBoost: pip install "u8darts[notorch]"  
Install core + neural networks (PyTorch): pip install "u8darts[torch]" (equivalent to pip install darts)  
Install Darts with all available models: conda install -c conda-forge -c pytorch u8darts-all  
Install core only (without neural networks, Prophet, LightGBM and Catboost): conda install -c conda-forge u8darts  
Install core + Prophet + LightGBM + CatBoost: conda install -c conda-forge u8darts-notorch  
Install core + neural networks (PyTorch): conda install -c conda-forge -c pytorch u8darts-torch
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

一个入门案例

数据集下载地址:https://download.csdn.net/download/Daniel_Singularity/88298763

import pandas as pd  
import matplotlib.pyplot as plt  
from darts import TimeSeries  
from darts.models import ExponentialSmoothing  
df = pd.read_csv("data/AirPassengers.csv",delimiter=",")  
series = TimeSeries.from_dataframe(df,"Month","#Passengers")  
train,val = series[:-36],series[-36:]  
model = ExponentialSmoothing()  
model.fit(train)  
prediction = model.predict(len(val), num_samples=1000)  
series.plot()  
prediction.plot(label="forecast", low_quantile=0.05, high_quantile=0.95)  
plt.legend()  
plt.show()

运行结果

Transformer Model

class darts.models.forecasting.transformer_model.TransformerModel(input_chunk_length, output_chunk_length, d_model=64, nhead=4, num_encoder_layers=3, num_decoder_layers=3, dim_feedforward=512, dropout=0.1, activation=‘relu’, norm_type=None, custom_encoder=None, custom_decoder=None, **kwargs)

Transformer是2017年推出的最先进的深度学习模型。它是一个编码器-解码器架构,其核心特征是“多头注意”机制,它能够在输入向量和输出向量中绘制内部依赖关系(“自我注意”),以及输入和输出向量之间的相互依赖关系(“编码器-解码器注意”)。多头注意机制具有高度的并行性,使得transformer架构非常适合用GPU进行训练。

Transformer的经典论文Attention is all your need

“Attention Is All You Need”, 2017. In Advances in Neural Information Processing Systems, pages 6000-6010. https://arxiv.org/abs/1706.03762. …[2] Shazeer, Noam, “GLU Variants Improve Transformer”, 2020. arVix https://arxiv.org/abs/2002.05202.

该模型支持过去的协变量(已知为预测时间之前的input_chunk_length点)。

参数的意义:

input_chunk_length (int) :要输入到预测模块的时间步数。

output_chunk_length (int):预测模块要输出的时间步数。

d_model (int):预期的特征数,默认是64。

nhead (int):nhead (int) -多头注意机制中的多头数(默认=4)。

num_encoder_layers (int):编码器中的编码器层数(默认=3)。

num_decoder_layers (int):解码器中的解码器层数(默认=3)。

dim_feedforward (int):前馈网络模型的维数(默认=512)。

dropout (float):受Dropout影响的神经元比例(默认值=0.1)。

activation (str):编码器/解码器中间层激活函数,(default= ’ relu ')。可以是glu变体的前馈网络(FFN)之一[2]。前馈网络是一个具有激活的全连接层。glu变体的前馈网络是一系列ffn,旨在更好地与基于Transformer的模型一起工作。[" GLU ", " Bilinear ", " ReGLU ", " GEGLU ", " SwiGLU ", " ReLU ", " GELU “]或一个pytorch内部激活[” ReLU ", " GELU "]

norm_type :(str | nn.Module) -要使用的LayerNorm变量的类型。默认值:没有。可用的选项是[" LayerNorm ", " RMSNorm ", " LayerNormNoBias "],或者提供一个自定义的n. module。

custom_encoder (Optional[Module]):自定义编码器模块(default=None)。

custom_decoder (Optional[Module]):自定义解码器模块(default=None)。

使用案例

import pandas as pd  
from matplotlib import pyplot as plt  
from darts import TimeSeries  
from darts.dataprocessing.transformers import Scaler  
from darts.models import RNNModel,TransformerModel  
from darts.metrics import mape  
from darts.utils.timeseries_generation import datetime_attribute_timeseries  
import warnings  
warnings.filterwarnings("ignore")  
import logging  
logging.disable(logging.CRITICAL)  
df = pd.read_csv('data\Alcohol_Sales.csv')  
series = TimeSeries.from_dataframe(df, 'DATE', 'S4248SM144NCEN')  
# 划分训练集和测试集  
train, val = series.split_after(pd.Timestamp('20170101'))  
  
scaler = Scaler()  
train_scaled = scaler.fit_transform(train)  
val_scaled = scaler.transform(val)  
series_scaled = scaler.transform(series)  
print("the 'air passengers' dataset has {} data points".format(len(series)))  
  
# 创建年和月的协变量序列  
# year_series = datetime_attribute_timeseries(pd.date_range(start=series.start_time(), freq=series.freq_str, periods=400),  
#                                              attribute='year', one_hot=False)  
# year_series = Scaler().fit_transform(year_series)  
# month_series = datetime_attribute_timeseries(year_series, attribute='month', one_hot=True)  
# covariates = year_series.stack(month_series)  
# cov_train, cov_val = covariates.split_after(pd.Timestamp('20170101'))  
my_model = TransformerModel(  
    input_chunk_length=12,  
    output_chunk_length=1,  
    batch_size=32,  
    n_epochs=200,  
    model_name="air_transformer",  
    nr_epochs_val_period=10,  
    d_model=16,  
    nhead=8,  
    num_encoder_layers=2,  
    num_decoder_layers=2,  
    dim_feedforward=128,  
    dropout=0.1,  
    activation="relu",  
    random_state=42,  
    save_checkpoints=True,  
    force_reset=True,  
)  
# my_model.fit(train_transformed, covariates=cov_train, val_series=val_transformed, val_covariates=cov_val, verbose=True)  
#Darts的model.fit()中covariates和val_covariates分别变成了future_covariates和val_future_covariates  
# my_model.fit(train_transformed, future_covariates=cov_train, val_series=val_transformed, val_future_covariates=cov_val, verbose=True)  
my_model.fit(series=train_scaled,val_series=val_scaled,verbose=True)  
  
  
  
def eval_model(model, n, series, val_series):  
    pred_series = model.predict(n=n)  
    plt.figure(figsize=(8, 5))  
    series.plot(label="actual")  
    pred_series.plot(label="forecast")  
    plt.title("MAPE: {:.2f}%".format(mape(pred_series, val_series)))  
    plt.legend()  
    plt.show()  
  
  
eval_model(my_model, 26, series_scaled, val_scaled)

运行结果

RNN Model

案例

数据集地址:https://download.csdn.net/download/Daniel_Singularity/88299085

import pandas as pd  
from matplotlib import pyplot as plt  
from darts import TimeSeries  
from darts.dataprocessing.transformers import Scaler  
from darts.models import RNNModel  
from darts.metrics import mape  
from darts.utils.timeseries_generation import datetime_attribute_timeseries  
import warnings  
warnings.filterwarnings("ignore")  
import logging  
logging.disable(logging.CRITICAL)  
df = pd.read_csv('data\Alcohol_Sales.csv')  
series = TimeSeries.from_dataframe(df, 'DATE', 'S4248SM144NCEN')  
# 划分训练集和测试集  
train, val = series.split_after(pd.Timestamp('20170101'))  
  
transformer = Scaler()  
train_transformed = transformer.fit_transform(train)  
val_transformed = transformer.transform(val)  
series_transformed = transformer.transform(series)  
  
# 创建年和月的协变量序列  
year_series = datetime_attribute_timeseries(pd.date_range(start=series.start_time(), freq=series.freq_str, periods=400),  
                                             attribute='year', one_hot=False)  
year_series = Scaler().fit_transform(year_series)  
month_series = datetime_attribute_timeseries(year_series, attribute='month', one_hot=True)  
covariates = year_series.stack(month_series)  
cov_train, cov_val = covariates.split_after(pd.Timestamp('20170101'))  
my_model = RNNModel(  
    model='LSTM',  
    hidden_dim=100,  
    dropout=0,  
    batch_size=1,  
    n_epochs=100,  
    optimizer_kwargs={'lr': 1e-3},  
    model_name='Alcohol_RNN',  
    log_tensorboard=True,  
    random_state=42,  
    training_length=12,  
    input_chunk_length=12,  
    force_reset=True  
)  
# my_model.fit(train_transformed, covariates=cov_train, val_series=val_transformed, val_covariates=cov_val, verbose=True)  
#Darts的model.fit()中covariates和val_covariates分别变成了future_covariates和val_future_covariates  
my_model.fit(train_transformed, future_covariates=cov_train, val_series=val_transformed, val_future_covariates=cov_val, verbose=True)  
  
def eval_model(model, lag):  
 # pred_series = model.predict(n=24,covariates=covariates)  
    pred_series = model.predict(n=24,future_covariates=covariates)  
  
    plt.figure(figsize=(8,5))  
    series_transformed[-lag:].plot(label='actual')  
    pred_series.plot(label='forecast')  
    plt.title('MAPE: {:.2f}%'.format(mape(pred_series, val_transformed)))  
    plt.legend();  
    plt.show()  
  
eval_model(my_model,0)  
eval_model(my_model,30)

---------------------------END---------------------------

  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当然可以!以下是一个使用Informer模型进行预测的示例代码: ```python import torch from torch import nn from torch.utils.data import DataLoader from torch.optim import Adam from torch.optim.lr_scheduler import LambdaLR from informer.models import Informer from informer.data.datasets import TimeSeriesDataset from informer.data.transforms import TimeSeriesTransform from informer.utils.losses import masked_mse_loss # 设定模型参数和超参数 input_dim = 1 # 输入维度 output_dim = 1 # 输出维度 seq_len = 24 # 输入序列长度 label_len = 12 # 预测序列长度 pred_len = 12 # 输出序列长度 d_model = 512 # Transformer模型的隐藏层维度 n_heads = 8 # 注意力头数 e_layers = 2 # 编码器层数 d_layers = 1 # 解码器层数 d_ff = 2048 # 前馈神经网络的隐藏层维度 dropout = 0.05 # Dropout概率 # 加载数据集和数据转换 dataset = TimeSeriesDataset(data, seq_len=seq_len, label_len=label_len, pred_len=pred_len) transform = TimeSeriesTransform() dataset.transform(transform) # 划分训练集和测试集 train_size = int(0.8 * len(dataset)) test_size = len(dataset) - train_size train_dataset, test_dataset = torch.utils.data.random_split(dataset, [train_size, test_size]) # 创建数据加载器 batch_size = 32 train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False) # 创建模型 model = Informer( input_dim=input_dim, output_dim=output_dim, seq_len=seq_len, label_len=label_len, pred_len=pred_len, d_model=d_model, n_heads=n_heads, e_layers=e_layers, d_layers=d_layers, d_ff=d_ff, dropout=dropout ) # 定义损失函数和优化器 criterion = masked_mse_loss optimizer = Adam(model.parameters(), lr=0.001) # 训练模型 num_epochs = 10 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model.to(device) for epoch in range(num_epochs): model.train() for i, (inputs, labels) in enumerate(train_loader): inputs = inputs.to(device) labels = labels.to(device) optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() if (i + 1) % 10 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}') # 测试模型 model.eval() with torch.no_grad(): test_loss = 0.0 for inputs, labels in test_loader: inputs = inputs.to(device) labels = labels.to(device) outputs = model(inputs) loss = criterion(outputs, labels) test_loss += loss.item() * inputs.size(0) test_loss /= len(test_dataset) print(f'Test Loss: {test_loss:.4f}') # 使用模型进行预测 model.eval() with torch.no_grad(): inputs = torch.Tensor([1, 2, 3, 4, 5]).unsqueeze(0).unsqueeze(2).to(device) outputs = model(inputs) predicted_values = outputs.squeeze().cpu().numpy() print(f'Predicted Values: {predicted_values}') ``` 请注意,这只是一个示例,具体的实现取决于您的数据和模型架构。您需要根据您的数据集和需求进行适当的修改。此外,为了运行此代码,您需要安装Informer模型和相关依赖项。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

twinkle 222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值