介绍 PyTorch 预测-使用神经网络进行最先进的预测变得简单

为什么准确的预测如此重要?

预测时间序列在许多情况下都很重要,并且与机器学习从业者高度相关。以许多用例派生的需求预测为例。几乎每个制造商都将从更好地了解对其产品的需求以优化生产数量中受益。生产不足,您将损失收入,生产过多,您将被迫以折扣价出售多余的产品。非常相关的是定价,它本质上是一种特别关注价格弹性的需求预测。定价几乎与所有公司都相关。

对于大量额外的机器学习应用程序,时间至关重要:预测性维护、风险评分、欺诈检测等——应有尽有。事件的顺序和它们之间的时间对于创建可靠的预测至关重要。

事实上,虽然时间序列预测可能不像图像识别或语言处理那样闪亮,但它在工业中更为普遍。这是因为图像识别和语言处理在该领域相对较新,通常用于为新产品提供动力,而预测已经存在了几十年,并且是许多决策(支持)系统的核心。使用高精度机器学习模型(例如PyTorch 预测中的模型)可以更好地支持决策制定甚至自动化决策,通常会直接带来数百万美元的额外利润。

深度学习成为一种强大的预测工具

深度学习(神经网络)直到最近才在时间序列预测方面优于传统方法,而且比在图像和语言处理方面的优势更小。事实上,在预测纯时间序列(即没有协变量,例如价格比需求)方面,深度学习仅在两年前就已经超越了传统的统计方法[1]。然而,随着该领域的快速发展,与神经网络相关的准确性优势变得显着,这值得它们在时间序列预测中得到更多使用。比如最新架构的N-BEATS与下一个最好的基于非神经网络的方法相比,M4 竞赛数据集上的 sMAPE 减少了 11%,后者是统计方法的集合 [2]。该网络也在PyTorch Forecasting中实现。

此外,即使与梯度提升树等其他流行的机器学习算法相比,深度学习也有两个优势。首先,可以根据对时间的固有理解来设计神经网络架构,即它们会自动在时间上接近的数据点之间建立连接。因此,他们可以捕获复杂的时间依赖性。相反,传统的机器学习模型需要手动创建时间序列特征,例如最近 x 天的平均值。这削弱了这些传统机器学习算法对时间依赖性进行建模的能力。其次,大多数基于树的模型都设计为输出阶跃函数。因此,它们无法预测输入变化的边际影响,而且众所周知,它们在域外预测中不可靠。例如,如果我们只观察到 30 欧元和 50 欧元的价格,基于树的模型无法评估将价格从 30 欧元更改为 35 欧元对需求的影响。因此,它们通常不能直接用于优化输入。然而,同时,神经网络采用连续激活函数,特别擅长在高维空间中进行插值,即它们可用于优化输入,例如价格。

什么是 PyTorch 预测?

PyTorch Forecasting旨在通过神经网络简化时间序列预测,以应对真实案例和类似研究。它通过提供最先进的时间序列预测架构来做到这一点,这些架构可以很容易地用pandas数据帧进行训练。

首先,文档中的详细教程展示了端到端的工作流程。我还将在本文后面讨论一个具体示例。

为什么我们需要这个包?

PyTorch 预测有助于克服使用深度学习的重要障碍。虽然深度学习在图像和语言处理领域占据主导地位,但在时间序列预测领域却并非如此。该领域仍然由 ARIMA 等传统统计方法和梯度提升等机器学习算法主导,但贝叶斯模型例外。深度学习尚未成为时间序列预测主流的原因有两个,所有这些都可以克服:

  1. 训练神经网络几乎总是需要 GPU,而 GPU 并不总是很容易获得。硬件要求通常是一个重要的障碍。然而,通过将计算转移到云中,这个障碍是可以克服的。
  2. 神经网络比传统方法更难使用。时间序列预测尤其如此。缺少可与流行框架(例如 Facebook 的 PyTorch 或 Google 的 Tensorflow)配合使用的高级 API。对于传统的机器学习,存在 sci-kit 学习生态系统,它为从业者提供了标准化的界面。

简而言之,PyTorch Forecasting旨在完成fast.ai在图像识别和自然语言处理方面所做的工作。这极大地促进了神经网络从学术界向现实世界的扩散。PyTorch Forecasting试图通过为PyTorch提供一个可以直接使用pandas数据帧的高级 API 来为时间序列预测做同样的事情。为了便于学习,与fast.ai不同,该包不会创建全新的 API,而是建立在成熟的PyTorchPyTorch Lightning API 之上。

如何使用 PyTorch 预测?

这个小示例展示了包的强大功能及其最重要的抽象。我们将

  1. 创建训练和验证数据集,
  2. 训练Temporal Fusion Transformer [2]。这是牛津大学和谷歌开发的架构,在基准测试中以 36-69% 的优势击败了亚马逊的 DeepAR,
  3. 检查验证集的结果并解释经过训练的模型。

注意:以下代码仅适用于 PyTorch Forecasting 0.4.1 版和 PyTorch Lightning 0.9.0 版。需要进行最少的修改才能使用最新版本运行。


创建用于训练和验证的数据集

首先,我们需要将时间序列转换为 pandas 数据框,其中每一行都可以用时间步长和时间序列来标识。幸运的是,大多数数据集已经采用这种格式。对于本教程,我们将使用来自 Kaggle 的 Stallion 数据集来描述各种饮料的销售情况。我们的任务是按库存单位 (SKU) 对代理商(即商店)销售的产品进行为期六个月的销售量预测。每月约有21 000条历史销售记录。除了历史销售额外,我们还提供有关销售价格、代理商位置、假期等特殊日子以及整个行业销售量的信息。

从 pytorch_forecasting.data.examples 导入 get_stallion_datadata = get_stallion_data() # 将数据加载为 pandas 数据帧

数据集的格式已经正确,但缺少一些重要特征。最重要的是,我们需要添加一个时间索引,每个时间步递增一个。此外,添加日期特征是有益的,在本例中这意味着从日期记录中提取月份。

# 添加时间索引
data["time_idx"] = data["date"].dt.year * 12 + data["date"].dt.monthdata["time_idx"] -= data["time_idx"].min( )# 添加附加功能
# 类别必须是字符串
data["month"] = data.date.dt.month.astype(str).astype("category") 
data [ "log_volume" ]  = np . 日志(数据。卷+  1e-8)
数据[ “avg_volume_by_sku” ]  =(
    数据
    。groupby ([ “time_idx” , “sku” ] ,观察=真)
    。卷。变换(“平均” ))数据[

“avg_volume_by_agency” ]  =(
    数据
    。groupby ([ “time_idx” , “ agency” ] ,观察=真)
    。volume。变换( “mean” ))
# 我们想将特殊日子编码为一个变量,    因此需要    首先
反转单热编码",     "regional_games", "fifa_u_17_world_cup", "football_gold_cup",     "beer_capital", "music_fest" ]





data[special_days] = ( 
    data[special_days] 
    .apply(lambda x: x.map({0: "-", 1: x.name})) 
    .astype("category") 
)# 显示样本数据
data.sample(10, random_state=521)

来自数据框的随机行样本

下一步是将数据框转换为PyTorch 预测数据集。除了告诉数据集哪些特征是分类的还是连续的,哪些是静态的还是随时间变化的,我们还必须决定如何规范化数据。在这里,我们分别对每个时间序列进行标准缩放,并指示值始终为正。

我们还选择使用最近六个月作为验证集。

从 pytorch_forecasting.data 导入(
    TimeSeriesDataSet,
    GroupNormalizer 
)max_prediction_length = 6 # 预测 6 个月
max_encoder_length = 24 # 使用 24 个月的历史
training_cutoff = data["time_idx"].max() - max_prediction_lengthtraining = TimeSeriesDataSet( 
    data[lambda x: x.time_idx <= training_cutoff], 
    time_idx="time_idx", 
    target="volume", 
    group_ids=["agency", "sku"], 
    min_encoder_length=0, # 允许没有历史的预测
    max_encoder_length=max_encoder_length,
    min_prediction_length=1,
    max_prediction_length=max_prediction_length,
    static_categoricals=[“agency”,“sku”],
    static_reals=[ 
        “avg_population_2017”,
        “avg_yearly_household_income_2017” 
    ],
    time_varying_known_categoricals=[“special_days”,“month”],
    # 一组分类变量可以被视为
    一个变量
    variable_groups={"special_days": special_days}, 
    time_varying_known_reals=[ 
        "time_idx", 
        "price_regular", 
        "discount_in_percent" 
    ], 
    time_varying_unknown_categoricals=[], 
    time_varying_unknown_reals=[ 
        "volume", 
        "log_volume", 
        "industry_volume", 
        "soda_volume", 
        "avg_max_temp", 
        "avg_volume_by_agency", 
        "avg_volume_by_sku", 
    ], 
    target_normalizer=GroupNormalizer( 
        groups=["agency", "sku"], coerce_positive=1.0 
    ),# 使用 softplus with beta=1.0 并按组归一化
    add_relative_time_idx=True, # 添加为特征
    add_target_scales=True, # 添加为特征
    add_encoder_length=True, # 添加为特征
)# 创建验证集 (predict=True) 这意味着预测
每个系列的最后一个 max_prediction_length 时间点
validation = TimeSeriesDataSet.from_dataset( 
    training, data, predict=True, stop_randomization=True 
)# 为模型创建数据加载器
batch_size = 128 
train_dataloader = training.to_dataloader( 
    train=True, batch_size=batch_size, num_workers=0 
) 
val_dataloader = validation.to_dataloader( 
    train=False, batch_size=batch_size * 10, num_workers=0 
)

训练 Temporal Fusion Transformer

现在是时候创建我们的模型了。我们使用 PyTorch Lightning 训练模型。在训练之前,您可以使用其学习率查找器确定最佳学习率(有关示例,请参阅文档)。

从 pytorch_lightning.callbacks 导入 pytorch_lightning 作为 pl
从 pytorch_lightning.loggers 导入(
    EarlyStopping,
    LearningRateLogger 
)从 pytorch_forecasting.metrics
导入 TensorBoardLogger从 pytorch_forecasting.models
导入 QuantileLoss
导入 TemporalFusionTransformer# 停止训练,当损失指标在验证集上没有改善时
early_stop_callback = EarlyStopping( 
    monitor="val_loss", 
    min_delta=1e-4, 
    patience=10, 
    verbose=False, 
    mode="min" 
) 
lr_logger = LearningRateLogger() # log学习率
记录器 = TensorBoardLogger("lightning_logs") # 记录到 tensorboard# 创建训练器
trainer = pl.Trainer( 
    max_epochs=30, 
    gpus=0, # 在 CPU 上训练,使用 gpus = [0] 在 GPU 上运行
    gradient_clip_val=0.1, 
    early_stop_callback=early_stop_callback, 
    limit_train_batches=30, # 每 30 个批次运行一次验证
    # fast_dev_run=True, # 评论以快速检查错误
    callbacks=[lr_logger], 
    logger=logger, 
)# 初始化模型tft = TemporalFusionTransformer.from_dataset(     training,     learning_rate=0.03,     hidden_size=16, # 最大影响网络大小    attention_head_size=1,     dropout=0.1,     hidden_continuous_size=8,     output_size=7, # QuantileLoss 默认有 7 个分位数    loss=QuantileLoss (),     log_interval=10, # log example every 10 batches     reduce_on_plateau_patience=4, # reduce learning automatically ) tft.size() # 模型中的 29.6k 个参数# 拟合网络
trainer.fit( 
    tft, 
    train_dataloader=train_dataloader, 
    val_dataloaders=val_dataloader 
)

在我的 Macbook 上训练大约需要三分钟,但对于更大的网络和数据集,可能需要几个小时。在训练期间,我们可以监控可以用 旋转起来的张量板tensorboard --logdir=lightning_logs。例如,我们可以监控训练集和验证集上的示例预测。从下图中可以看出,预测看起来相当准确。如果您想知道,灰线表示模型在进行预测时对不同时间点的关注程度。这是时空融合变形金刚的一个特殊之处。

显示训练示例的 Tensorboard 面板

评估经过训练的模型

训练后,我们可以评估验证数据集上的指标和几个例子,看看模型的表现如何。鉴于我们只处理 21000 个样本,结果非常令人放心,可以与梯度增强器的结果相媲美。

从 pytorch_forecasting.metrics 导入 MAE# 根据验证损失加载最佳模型(鉴于# 我们使用提前
停止,这不一定是最后一个 epoch )

# 计算验证集的平均绝对误差
actuals = torch.cat([y for x, y in iter(val_dataloader)]) 
predictions = best_tft.predict(val_dataloader)MAE(预测,实际)

查看 sMAPE 方面表现最差的模型可以让我们了解模型在哪些方面存在可靠预测问题。这些示例可以提供有关如何改进模型的重要指示。这种实际与预测图适用于所有模型。

从 pytorch_forecasting.metrics 导入 SMAPE# 计算显示
预测的指标,x = best_tft.predict(val_dataloader) 
mean_losses = SMAPE(reduction="none")(predictions, actuals).mean(1) 
indices = mean_losses.argsort(descending=True) # 排序损失raw_predictions, x = best_tft.predict(val_dataloader, mode="raw, return_x =True)
# 仅显示两个用于 idx in range(2)演示目的的示例: 
    best_tft.plot_prediction( 
        x, 
        raw_predictions, 
        idx=indices[idx], 
        add_loss_to_title=SMAPE() 
    )

验证集上的两个最差预测。白线是转换器对给定时间点的关注程度。

同样,我们也可以从我们的模型中可视化随机示例。PyTorch Forecasting的另一个特点是对训练模型的解释。例如,所有模型都允许我们轻松计算部分依赖图。然而,为简洁起见,我们将在这里展示 Temporal Fusion Transformer 的一些内置解释功能。它通过神经网络的设计实现可变重要性。

解释 = best_tft.interpret_output( 
    raw_predictions, reduction="sum" 
)best_tft.plot_interpretation(解释)

毫不奇怪,过去观察到的体积特征作为编码器中的顶级变量,而价格相关变量是解码器中的顶级预测变量。也许更有趣的是,该机构在静态变量中仅排名第五。然而,鉴于第二个和第三个变量与位置相关,如果模型中不包括这两个变量,我们可以预期代理商的排名要高得多。

概括

使用PyTorch Forecasting可以很容易地训练模型并深入了解其内部工作原理。作为从业者,您可以使用该包来训练和解释开箱即用的最先进模型。使用PyTorch Lightning集成训练和预测是可扩展的。作为研究人员,您可以利用该包为您的架构获取自动跟踪和自省功能,并将其无缝应用于多个数据集。

代码、文档以及如何贡献

本教程的代码可以在这个笔记本中找到:https://github.com/jdb78/pytorch-forecasting/blob/master/docs/source/tutorials/stallion.ipynb

安装PyTorch预测

pip 安装 pytorch-forecasting

或者

conda install -c conda-forge pytorch-预测

GitHub 存储库:https ://github.com/jdb78/pytorch-forecasting

文档(包括教程):https://pytorch-forecasting.readthedocs.io

该软件包在 MIT 许可下是开源的,允许商业使用。非常欢迎投稿!请提前阅读贡献指南,以确保您的贡献被迅速合并。

展开阅读全文

页面更新:2024-03-12

标签:神经网络   示例   序列   变量   深度   模型   特征   机器   简单   时间   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top