社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

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

蚂蚁学Python • 1 年前 • 765 次点击  

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

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

官方网址GitHub:https://github.com/unit8co/darts

文档

快速开始

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

安装Darts

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

用pip进行安装

pip install darts

用conda进行安装

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

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

%matplotlib inline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from darts import TimeSeries
from darts.datasets import AirPassengersDataset

注意:%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()



一些TimeSeries的操作

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

划分

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

series1, series2 = series.split_before(0.75)
series1.plot()
series2.plot()



切片

series1, series2 = series[:-36], series[-36:]
series1.plot()
series2.plot()



算术运算

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



堆叠

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

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



映射

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



映射时间戳和值

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



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

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



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

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



差分

series.diff().plot()



填充缺失值

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



创建训练和验证序列

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

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

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



训练预测模型并预测

玩一下玩具模型

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



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



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

一个不幼稚的模型

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



这是更好的,但我们仍然错过了趋势。幸运的是,还有另一个朴素的基线模型可以捕捉到这一趋势,它被称为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")



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

计算误差度量

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

我们要克服的误差是多少?我们将使用平均绝对百分比误差(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)
)
)

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

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



回溯测试:模拟历史预测

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



因此,当我们回测它时,我们在验证集上的最佳模型似乎不再做得那么好了(我是否听到过拟合: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)",
)



最后,使用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)

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

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

from darts.utils.statistics import plot_residuals_analysis

plot_residuals_analysis(best_theta_model.residuals(series))



我们可以看到分布不是以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)))



plot_residuals_analysis(model_es.residuals(series))



残差分析也反映了性能的改进,因为我们现在有一个以值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()



首先,让我们将这两个系列在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()



使用深度学习: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)")



协变量:使用外部数据

除了目标序列(我们有兴趣预测的序列)之外,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:"
);



用户指导

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

关于缺少依赖

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

一个入门案例

数据集下载地址: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)



如下是蚂蚁老师自己的广告:

学习更多Python技术,欢迎了解蚂蚁老师的Python全套课程:

蚂蚁老师我的视频全集

https://study.163.com/series/1202914611.htm
涵盖了8个学习路线,包含数据分析、WEB开发、机器学习、办公自动化等大路线;课程永久有效,新课全都免费看;蚂蚁老师本人提供答疑服务、群聊答疑等服务,课程重复回看,永久有效;

欢迎每晚来蚂蚁老师我的抖音直播间,每晚21:00~23:00直播,抖音账号:Python导师-蚂蚁。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/161377
 
765 次点击