菜鸟-需求预测与分仓规划

题目描述:

https://tianchi.shuju.aliyun.com/competition/introduction.htm?spm=5176.100068.5678.1.ZBYlCN&raceId=231530
高质量的商品需求预测是供应链管理的基础和核心功能。本赛题以历史一年海量买家和卖家的数据为依据,要求参赛者预测某商品在未来二周全国和区域性需求量。

基本流程:

  和其他机器学习比赛的思路大致是一样的:数据按照分仓和全国分开处理,划分时间窗口提取特征,跑模型,模型融合等,可能这比赛中可以添加规则来提高成绩。
在这里,我主要讲的是比赛中的尝试,与以前不一样的是改变模型求解的损失函数使得更加符合本题。

损失函数分析:

  在赛题中,成本的计算受两个参数控制:补多成本和补少成本。当预测库存比实际库存少时,成本总和加上补少成本×库存之差;当预测库存比实际库存多时,成本总和加上补多成本×库存之差。因此补少成本和补多成本对于目标函数有着重大的影响,而如果直接调用模型进行训练,由于训练的损失函数不同,导致总的成本过高。
  举个例子:

补多 补少 实际成本
4 3 1
1 2 1
3 4 1
3 5 1
2 1 50

  如果忽略了补多成本和补少成本,可能全部预测为10(均值),得到的总成本为139。当预测为1的时候,总成本为49,所以能得到更好的结果。

思路方案:

  GBDT中,对于每个树节点的样本集合,其预测值为样本观察值的均值(如果有权重则是加权平均),如果考虑补多成本以及补少成本,可以有以下一个结论:
  样本集合的最优预测值为某个样本的观察值。
  因为当预测值不属于某个样本的观察值,由于损失函数中样本的观察值和预测值之差是线性关系。设观察值大于预测值的样本补少成本总和为a,观察值大于观测值的样本补多成本总和为b,当a<>b时,预测值减少或者增大时能取得更少的成本;当a=b时,预测值减少或增大一点点并不影响成本。因此,当预测值为某个样本的观察值时,预测值增大或者减少会影响补多成本总和a和补少成本总和b的改变,成本才达到最小值。
  所以GBDT树节点中,枚举某个特征值把样本集合划分为两个子集,每个样本子集选取某个样本观察值作为最优预测值,计算减少的成本,最终枚举得到最优的特征值使得成本最小。因此针对某个特征列,有以下几个思路去求解划分样本的最优特征集。

枚举计算

  枚举划分的特征值,对于划分的两个样本子集遍历计算成本。时间复杂度为$O(n^2)$,样本数量多的时候会耗时过大。

平衡树

  样本集按照特征值从小到大枚举,划分的两个样本子集是一个不断增加样本,另一个不断减少样本。每个样本子集可以维护一棵平衡树,平衡树的按照样本的观察值排序,每个树节点存储子树的补多成本、补少成本和、样本观察值总和,可以从平衡树的根节点向下递推得到最优的观测值(左儿子的样本观察值或者右儿子的样本观察值作为预测值,分别计算成本,选取最优的向下递推,最终到达树儿子节点的样本观察值为预测值)。平衡树的维护和查询时间复杂度为$O(log(n))$,所以总时间复杂度为$O(nlog(n))$。但是编程的难度相对会提升很大。

链表

  主要是在枚举特征值的时候,动态的维护两个样本子集,并且能够迅速的得到最优预测值。这里主要讨论样本子集不断减少样本的,因为增加样本的也就相当于反向枚举然后不断减少样本。
  假设存在5个样本,按照观察值从小到大排列并建立链表(链表的作用是为了动态维护样本之间的有序性)。可以得出最优预测值为3,成本为15。现从小到大枚举特征值,删除对应的样本并且计算其成本。

补多成本 补少成本 特征值 观察值
2 3 2 1
3 2 4 2
2 1 3 3
1 2 5 4
4 3 1 5

  删除特征值1的样本:

补多成本 补少成本 特征值 观察值
2 3 2 1
3 2 4 2
2 1 3 3
1 2 5 4

  当预测值为原来的3时,成本是9。而最优预测值为2,成本是7。这是因为删除的样本会减少补少成本总和b,对应的预测值可以适当减少平衡补少成本总和以及补多成本总和使得总成本变小。相应的,如果删除的样本减少补多成本总和a,可以适当的增加预测值。预测值的变化只需要沿着链表遍历动态维护成本的变化即可。
  通过这种方法可以求得各个划分的样本子集的最预测值和对应成本,即可求得最优划分特征值。最坏的时间复杂度为$O(n^2)$,每次动态维护成本变化时候都遍历整个链表。事实上在大数据中,平均的复杂度可以达到$O(n)$。

总结

  通过修改损失函数的方法,要比GBDT、XGBOOST等单模型结果好很多。但在这次比赛中是不够的,而且平台限制,对于迭代操作并不友好。