返回列表

21st Place Solution (Nodalpoints)

390. M5 Forecasting - Accuracy | m5-forecasting-accuracy

开始: 2020-03-03 结束: 2020-06-30 销量与需求预测 数据算法赛
第21名方案

M5 预测 - 准确度竞赛方案总结

致谢

我和 Ouranos 要感谢主办方举办了如此大规模的杰出竞赛。我们还需要提到,我们参与 M5 竞赛是由我们的公司(Nodalpoint LTD,希腊雅典)指派和赞助的。这使我们有大约一个半月的时间积极参与竞赛。

热身

首先,我想分享一个关于本次竞赛层级性质的个人观点。我在一个半月前开始研究层级相关的内容,主要关注 R 语言的 'forecast'、'hts'(层级时间序列)包以及 Hyndman 教授的 m4 获胜方案代码库。我对每个层级的时间序列进行了建模,其中 level-1 是最聚合的层级,level-12 是最细粒度的层级(item_ids)。

在对 30490 个底层时间序列进行建模后,我在第 10、11、12 层级上取得了一些不错的成绩(优于表现最好的 LightGBM 模型),但当聚合到顶层时,结果却变差了。因此,即使 LightGBM 模型无法捕捉每个商品的具体销售数量,但通过每日聚合,误差相互抵消,从而产生了更好的高层时间序列预测。这一认识让我放弃了经典的时间序列方法,在最后一个月转向其他方向。

我目前正在实验,看看这种方法(hts 和 m4 获胜预测方案)最终会如何评分,以及它是否有助于我们的融合。

解决方案

我们遵循了最常用的策略:“将问题视为回归问题”。因此,没有使用经典的时间序列模型或甚至适当的循环神经网络。我们方法的关键要素之一是验证集的选择:

  • 验证集 1:['d_1914', 'd_1915', …, 'd_1941'](= 公共 LB 数据)
  • 验证集 2:['d_1886', 'd_1887', …, 'd_1913']
  • 验证集 3:['d_1578', 'd_1579', …, 'd_1605'](恰好是私有 LB 数据的一年前)

所有的建模和融合都基于改善这三个折次的加权均值和标准差。我们在最终融合中使用了 4 个模型:

模型 1 (lgb_nas):在每个商店上使用 10 个 LightGBM 模型的表格回归

  • 特征:我们使用了公开可用的特征(感谢 Konstantin Yakovlev 的杰出工作)。特征分为以下几类:
    1. 类别型:item_id, dept_id, cat_id
    2. 价格相关:price_max, price_min, price_std, price_mean, price_norm, price_unique, price_momentum, momentum_m, momentum_y
    3. 日历相关:event_name_1, event_name_2, event_type_1, event_type_2, snap_CA, snap_TX, snap_WI, tm_d, tm_w, tm_m, tm_y, tm_wm, tm_w_end
    4. 滞后相关
      • 仅滞后(15 个特征):sales_lag_28, sales_lag_29, …, sales_lag_42
      • 仅滚动(8 个特征):rolling_mean_7, rolling_mean_14, rolling_mean_30, rolling_std_30, rolling_mean_60, rolling_std_60, rolling_mean_180, rolling_std_180
      • 滞后和滚动(12 个特征):rolling_mean_tmp_i, j,其中 i 在 [1, 7, 14] 中,j 在 [7, 14, 30, 60] 中。这些特征比较棘手,因为它们在预测期间需要递归评估。
    5. 均值编码:enc_cat_id_mean, enc_cat_id_std, enc_dept_id_mean, enc_dept_id_std, enc_item_id_mean, enc_item_id_std
  • 模型:使用以下配置的 LightGBM 模型:
    {
      'boosting_type': 'gbdt',
      'objective': 'tweedie',
      'tweedie_variance_power': 1.1,
      'metric': 'rmse',
      'subsample': 0.6,
      'subsample_freq': 1,
      'learning_rate': 0.02,
      'num_leaves': 2**11-1,
      'min_data_in_leaf': 2**12-1,
      'feature_fraction': 0.6,
      'max_bin': 100,
      'n_estimators': …,
      'boost_from_average': False,
      'verbose': -1,
      'num_threads': 12
    }

    我们训练了 10 个模型,每个商店一个,使用不同数量的估计器:

    rounds_per_store1={
     'CA_1': 700, 'CA_2': 1100, 'CA_3': 1600, 'CA_4': 1500,
     'TX_1': 1000, 'TX_2': 1000, 'TX_3': 1000,
     'WI_1': 1600, 'WI_