返回列表

1st student - 12th overall solution

389. M5 Forecasting - Uncertainty | m5-forecasting-uncertainty

开始: 2020-03-03 结束: 2020-06-30 销量与需求预测 数据算法赛
第1名学生 - 第12名整体方案

第1名学生 - 第12名整体方案

作者: Tobias Tesch
发布时间: 2020年7月1日

在2019年数据科学碗比赛中,我因为选错了提交文件而错失了金牌区,这次我又以一名之差错过了,真可惜。不过,如果这能成为我继DSB之后的第二个学生第一名奖项,我也非常开心。

以下是我的方案简述:

我主要关注比赛的准确性部分(尽管我最终的私榜排名并不是很好(274/5558)),并决定采用逐日的LGBM模型。用于创建我对时间跨度 h=8 的不确定性预测的笔记本可以在这里找到:
https://www.kaggle.com/tobiit/m5-uncertainty-lgbm-f8-eval/
其他预测时间跨度的笔记本与此类似。

对于每个时间跨度,执行以下步骤:

1. 预处理

  • 处理日历数据框: 以获取更多特征。
  • 处理销售价格数据框: 首先,我通过取聚合时间序列的平均值来构建聚合时间序列的销售价格(例如,对于“总计”聚合,我将所有销售价格的平均值作为 sell_price);其次,我构建了更多特征,如 sell_prices_std 等。
  • 处理销售数据框: 首先,我构建了所有层级的聚合时间序列。对于 state_id 列等,我使用了以下策略:如果所有聚合时间序列具有相同的值,我就使用它,否则设为 nan(例如,对于 CA_1 聚合,所有聚合时间序列都有 state_id CA,所以我保留了它;另一方面,对于 FOODS 聚合,聚合时间序列有不同的 state_id,所以我将 state_id 设为 nan)。接下来,我移除了一些异常值(圣诞节、感恩节等),对每个时间序列进行了标准化(详见下文),并计算了进一步的特征,如滚动平均值、日历特征的目标编码等。

2. 建模

对于每个分位数 q,我在所有时间序列上训练了一个 LGBM 模型,目标函数为 'quantile','alpha'=q。最后28天留作早停的验证集。训练期间使用了 WSPL 权重,将其传递给 LGBM 数据集:
train = lgb.Dataset(train[features],train[['demand']],weight=train['weight'])

销售时间序列的标准化

基于我在准确性部分工作中的一些交叉验证测试,我想出了以下针对所有销售时间序列(聚合的和普通的)的标准化方法:
首先,我将每个时间序列除以其非零均值。
其次,为了去除趋势,我考虑了某种形式的差分,并为每个均值标准化的时间序列 a[t] 设定:
a_trendRemoved[t]=a[t]+maxRollMean(28)-laggedRollMean(28,h)
这里 maxRollMean(28) 是时间序列在提供的1941天中任意28天期间的最大滚动平均值。laggedRollMean(28,h) 是 a[t-28-h+1],...,a[t-h] 的平均值。
那么我是怎么想到这个的呢?其实我想用类似这样的东西:
a_trendRemoved[t]=a[t]-rollMean(28)
意思是时间 t 的销售额与过去28天平均值的差异。然而,在预测后撤销这种预处理需要使用 F1,...,F(h-1) 天的预测值来构建 rollMean(28),我希望每个时间跨度的预测独立于所有其他预测,以防止误差传播。因此,我决定用 laggedRollMean(28,h) 代替 rollMean(28)。进一步添加 maxRollMean(28) 项确保所有值保持为正。我以为这不重要,但在我的交叉验证实验中,它给出了更好的结果,所以我使用了它。

旁注

  • 由于我只使用 Kaggle 内核而没有其他资源,将所有内容放入内存和9小时的运行时间限制内相当艰难。因此,我只使用 dstart=1100 之后的天数进行训练,并且只考虑预测工作日和一个相似的工作日进行训练(例如,F8 是星期一,所以对于时间跨度 h=8 的模型,我只使用星期一和星期五进行训练,丢弃了所有其他天数)。
  • 调整 LGBM 参数对我来说根本行不通,我简单地使用了我在准确性部分的一些公开内核中找到的参数(当然除了 objective=quantile 和 alpha=q)。
  • 我尝试了准确性部分的特征选择。总是留出一个特征,重新训练模型并检查我的 CV 分数是否提高。由于我没有观察到任何稳定的改进,我在这里简单地使用了所有特征。
  • 我上面提到的一些 CV 测试是这样进行的:我只考虑准确性部分,并选择了2个时间跨度,即8天和22天,为此我使用了最后3个28天周期进行交叉验证。我做出的所有参数、特征和标准化决定都基于那里获得的结果。然而,我不确定这是否是一个好主意,因为这些实验中获得的 CV 分数比我在准确性私榜上最终获得的
同比赛其他方案