帮好友进行“销量预测”建模

好友是做海外市场工作的,为了更科学的制定今年的销量KPI,希望能根据往年数据进行建模预测。

数据说明

好友公司此前没有做过类似事情,搜罗了一顿历史数据也只能找出过去4年的历史销量数据,其形如下:

销量是按周统计的,因为每年有52周,因此往年数据共4*52=208条,可以拿来训练的数据

文件末尾还包含了今年的前17周销量,可以拿来当做测试数据

当面了解了好友需求,他目前利用excel做了一些简单的线性回归和人工干预来预测今年后面每周的销量,听下来因为缺乏计算机编程与建模知识,所以使用的模型和特征都是简单和原始的,我想我所擅长的机器学习和数据分析应该可以帮助建立一个表达力更强的模型吧。

思路

这个需求最大的痛点就是“少”,体现在“特征太少”、“数据太少“。

数据只提供了week和销量的关系,而没有其他能够影响销量的因素被统计进来,这种情况下模型能学到的知识也是显而易见的:

  • 周与周之间的销量关系
  • 年与年之间的销量关系

无论如何,模型并不知道是什么导致销量变化的,因此最终模型只会具备预测趋势的能力,不过这对于好友的需求来说也足够用了。

经过思考,我选择了如下的建模设计(特征输入与输出):

模型能够根据往年的一些特征,预测出今年某周的销量。

举个例子,以预测今年第5周销量为目标,它可能与”去年第5周销量“、”前年第5周销量“、”去年第5周占全年销量比例”,“前年第5周占全年销量比例”等等呈现相关性,这很容易理解:

模型根据”前年与去年之间的销量变化“,应该也能推断出”去年与今年之间的销量变化“。

出于这种客观现实考虑而设计的特征,理应与预测目标之间存在一定的数学相关关系。

比较可惜的是训练样本只有4年的数据,因此特征里只能考虑到去年+前年,再往前就没有数据可以看了,现状比较尴尬。

虽然预计效果不可能尽如人意,但还是试试看吧,毕竟是个练手的好机会。

数据预处理

首先把原始数据读进来:

然后我们需要以每一行样本为基准,为其计算生成所有特征,这些特征大多是依赖于往年数据的,因此我们对销量这一列进行循环,”向前“计算历史特征:

总之我们关注到每一行样本丰富了N列特征,因为4年数据是顺序排列的,所以只有第3年开始的数据才拥有完整的“去年同周销量”、”前年同周销量“,而1~2年的样本特征不全无法用于训练。

可视化分析

我们可以为每个特征绘制与真实销量之间相关性图像,我们观察到去年/前年销量 与 今年销量是存在一点点相关性的,同时每年越靠后的周/季度其销量越高,也就是每年都是呈现一个增长趋势的。

我们可以将过去4年每年的销量画成一条折线,可以看出好友的公司每年销量呈现明显的规律性:

但是我们也应该意识到,前3年之间的销售量没有明显的增高,只有第4年的全年销量有明显上升,也肯定与好友公司的业务经营有关,但是我们没有其他信息所以无法推断。

特征预处理

准备好了样本之后,我们应该将前4年数据用作训练,今年数据用作测试。

在真正送入模型之前,我们可以进一步丰富特征,例如我们求出了:

  • 去年周占比、前年周占比
  • sin去年同周销量、sin前年同周销量
  • sin去年周占比、sin前年周占比

这些特征都可以从上面准备好的训练样本简单处理得到,目的还是为了让特征更符合数据分布,比如对特征求sin函数,可以引入周期性形状,也许可以更好的拟合销量的波动情况,这些全凭场景理解和经验而来。

另外需要做好特征工程的基本操作,例如:

  • 对“第几周”、“第几季度”做Onehot编码
  • 对所有特征进行3次项全交叉
  • 对所有特征进行标准化

我们利用sklearn Pipeline进行特征工程处理,先在训练集上fit_transform,再应用到测试集上,这样2个数据集都完成了onehot编码、标准化等操作。

模型训练

我们采用tensorflow全连接神经网络,用keras api开发一个回归模型即可:

因为训练数据太少了,所以对所有的链接权重做了L2正则化,避免模型对训练集过拟合。

然后我们将训练样本的真实销量按顺序绘制成绿色折线,将模型预测的销量绘制成蓝色折线,神经网络拟合这样的简单数据简直是小儿科(因为主动做了正则化降低模型过拟合风险,所以才没有完全重合):

测试集的拟合效果

现在我们用今年前17个周的特征作为输入,用模型预测销量绘制成蓝色,真实销量绘制成绿色。

我们发现模型的蓝色折线趋势平缓,并且与真实销量的区间也接近,只是年初的时候不知道好友公司做了什么事情销量暴增了几周,因为没有外界因素的特征,所以模型当然无法预测出这个事情,另外波形的起伏也难以预测,毕竟历史数据少,而且不知道外界因素有什么。

看一下周预测误差和年预测误差,可见差距还是无法直视,虽然图形上看着还凑活事:

结论

正如开头所说,特征太少了,所以模型只是根据销量预测趋势而已,没有其他能力。

好友也许应该多收集一些相关信息,即便是大环境经济走势,同期的进出口贸易额之类的宏观经济数据也好。

另外建模的思路也可以做一些变化,目前我是基于往年统计来预测今年,也许可以利用LSTM等时序模型来根据前N周预测下1周,但鉴于目前没有特征可用的情况估计循环神经网络是不会有任何作用的,因此未做尝试。

你是否也有类似需求呢?留言让我们讨论一下吧。

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~