利用销售预测的人工智能优化零售商的收入
预测是一种技术,它使用历史数据和事件来建立对未来趋势、潜在灾难和任何主体的整体行为的估计。预测可以作为决策分析的概率支持,用来估计费用、收入和预算计划。
商业中的预测可以分为两个不同的类别:定性预测和定量预测。
- 定性预测。定性预测关注的是市场研究和市场战略,因此它更多的是由专家驱动,并受到人为因素的影响。它通常以短期战略建设为目标。
- 定量预测。定量预测排除了任何人为因素。它只取决于一个实体拥有的历史数据,旨在预测一些因素,如销售、价格和其他财务方面的长期情况。
这两种类型的预测都显示出很大的前景,并设法为许多实体创造业务提升。
我们可以利用定量预测解决的一个问题是需求预测或销售预测。
需求预测和销售预测的方法
假设你是一个经营很多商店的零售商,每个商店都有一个静态的产品库存补充系统,该系统是基于人类的决定,而这些决定是基于某些事件,如季节和市场趋势。
偶尔,你会遇到这样的问题,会导致两个主要问题。
- 产品库存过多。 拥有大量计划在某个时间段内销售的产品库存,但没有卖出去。
- 缺货的产品。有机会销售产品,但由于产品缺货而无法销售。
根据IHL集团对600个家庭和零售商的调查,由于缺货问题,零售商每年损失近1万亿美元的销售额。
"根据该报告,购物者在三次购物中经常会遇到缺货的问题,该报告通过电子邮件发给Retail Dive。在食品、药品和大众零售商中,他们每五次购物就有一次遇到缺货,在百货公司和专业零售商中,每四次就有一次,而在电子商店中,每三次就有一次," IHL集团发现。
就像现在看来,这两个问题都导致了收入的减少,因为我们要么失去了销售的概率,要么在未售出的产品上投入了更多的资金,这意味着拥有的资产不会很快产生收入来补偿其成本。
这显然不利于实体的现金流,为了解决这一风险,我们需要两件事
- 更多的投入来帮助我们做决定
- 一个能够为库存补给系统做长期战略规划的预测团队
因此,问题是:有哪些迹象表明你需要在你的公司采用人工智能来帮助你的预测过程?
为了做出这个决定,你需要对以下问题做出专业回答。
- 预测你的销售管道是否困难?
- 你的销售预测是否不准确,或不够准确(即使你有历史数据)?
- 你是否存在缺货或超量储存的问题?
- 你是否无法从你拥有的数据中提取描述性和推断性的见解来推动你的决策和规划?
这些问题的答案应该是一个明确的信号,帮助你决定是否开始将人工智能运用到你的预测策略中。
人工智能如何有益于销售预测过程?
在许多公司中,人工智能在超越人类预测方面显示出了巨大的成果,能够实现更快的决策和规划,以及更可靠的风险管理策略。这就是为什么顶级公司在其规划中采用人工智能。
在处理需求预测问题时,可以使用时间序列预测方法来预测每种产品的销售情况,从而使公司能够优化库存补充,并尽量减少上述问题的发生。然而,由于缺乏必要的功能,许多模型在单个产品层面,或产品类别层面的预测上很困难。因此,问题是:我们如何才能让它发挥作用,并最大限度地利用我们的数据?
对于现实生活中的零售商来说,这些问题绝非小事一桩。你要么有1000多种产品,在数据集中引入了很多非线性和多变量的依赖性,要么你需要提前很多时间得到关于预计补货量的警告,以便能够生产或购买,或者在需求实现之前做任何你需要的事情来获取它。
在这种情况下,像ARIMA和ETS这样的经典模型不会有什么表现,我们需要像RNN和XGBoost这样更稳健的方法,这就是为什么我们需要大量的特征创建来解决这个问题。
要做到这一点,我们需要
- 获得必要的输入特征,以解释产品的种类和多样性。
- 对我们的数据进行分类,因此每个类别都有相同的时间序列行为,每个类别将使用一个独立的模型来处理。
- 在获得的分类输入特征上训练我们的模型。
在这篇文章中,我们将以XGBoost作为这种模型的一个例子。
销售预测模型的必要特征
这个问题所需的特征集被分为四个主要组别。
- 与时间有关的特征
- 与销售有关的特征
- 与价格有关的特征
- 与库存有关的特征
时间相关的特征
与深度学习(循环神经网络)不同,机器学习模型如果不为日期时间特征创建一个手动特征提取层,就无法得到时间序列内的长期或短期依赖关系。
许多特征可以从日期中提取出来,如:
- 年
- 日
- 小时
- 周末或工作日(这一天是工作日还是周末)
- 一周中的一天
许多方法只是提取这些时间特征并将其作为输入和训练模型,但还可以做进一步的工程。我们可以看到,这些特征(日、小时、星期)是周期性的,这意味着它们有一系列重复的值。一个模型怎么能处理这个问题呢?
简短的答案是,它不能,因为模型看到的是小时00:00离23:00有23个小时的距离,但事实上,它离23:00有一个小时的距离。解决这个问题的一个方法是将这些特征转换为循环变换。
使用正弦和余弦的概念,或矢量表示法,可以将每个小时(24小时)转换成一个角度,使用它们的正弦和余弦,将使模型更容易检测到小时之间的真实比例,而不考虑周期性。
这将消除发生在周期性时间特征中的不连续性,或任何周期性特征。
在我们的文章中,我们将使用公开找到的Sample Superstore数据集,并尝试预测某个产品类别的目标月销售额。
此外,我们将使用Python 3.7环境和以下库
- NumPy
- Pandas
- XGBoost
- Sklearn
现在,我将向你展示如何构建周期特征转换函数,并测试它是否有帮助。
def convert_periodic(val,period):
theta = 2*np.pi*val/period
sin_period = np.sin(theta)
cos_period = np.cos(theta)
return sin_period,cos_period
def convert_month(x):
return convert_periodic(x,12)
df['sin_month'], df['cos_month'] = zip(*df['month'].map(convert_month))
有了这些,我们就可以测试所添加的特征是否会提高性能。
X = df.drop(['Order Date','Sales','sin_month', 'cos_month'],axis = 1)
y = np.log1p(df['Sales'])
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2, shuffle=False)
正如我们所看到的,我们已经为我们的目标销售特征做了对数1p转换,因为它是一个偏斜的特征(非正态分布)。
现在,我们将在数据上拟合一个XGBoost回归器。
y_pred = model.predict(X_test)
print(f'Loss without cyclic conversion on testing set is {sqrt(mean_squared_error(y_pred,y_test))}')
Loss without cyclic conversion on testing set is 0.4313676193485837
接下来,我们将用我们创建的特征进行尝试。
X = df.drop(['Order Date','Sales'],axis = 1)
y = np.log1p(df['Sales'])
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2, shuffle=False)
y_pred = model.predict(X_test)
print(f'Loss with cyclic conversion on testing set is {sqrt(mean_squared_error(y_pred,y_test))}')
Loss with cyclic conversion on testing set is 0.33868030449130826
我们可以看到,损失从0.43 RMSE改善到0.33 RMSE。
根据你的问题,你可以考虑的其他一些与时间有关的特征是。
- 该商品在商店里的月数
- 自上次销售以来的天数
与销售有关的特征
这是预测我们的销售所需的主要核心输入特征,那么如何从销售数据中获得最大的收益呢?我们可以利用滞后和自相关的概念来实现。
滞后特征是产品的历史销售记录。例如,如果我们把月度销售的12个滞后特征作为我们预测2020年5月销售的模型的输入,这意味着我们将向模型提供2019年5月至2020年4月之间的数据记录。这可能真的很有帮助。
此外,还可以用自相关图来解释,检查目标特征与其滞后特征的相关程度。这也有助于在滞后特征中只选择相关的特征,所以我们减少内存的使用和特征的冗余。
这就是我们如何将滞后特征添加到我们的数据框架中。
for i in range(3):
df[f'lag_{i+1}'] = df['Sales'].shift(i+1)
df = df.dropna()
df.head()
在这里,我选择了一个三滞后特征的值来包含在我们的训练集中。这个特征是一个超参数--你可以根据自相关图来选择它,或者通过尝试许多值,在调谐阶段选择最佳值即可。
X = df.drop(['Order Date','Sales'],axis = 1)
y = np.log1p(df['Sales'])
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2, shuffle=False)
y_pred = model.predict(X_test)
print(f'Loss with lag features on testing set is {sqrt(mean_squared_error(y_pred,y_test))}')
Loss with lag and aggregated sales features on testing set is 0.2862175857169188
现在,RMSE已经提高到0.28,同时使用滞后特征和循环转换。
一些额外的与销售有关的特征,你可以添加。
- 已售商品的分数(已售商品在商店总销售额中的分数)
- 物品类别的销售事件的频率
- 增加资历的概念
资历是一个引入的概念,为商店中的新商品分配一个资历等级。
- 资历0:新进入公司的商品
- 资历1:从未在本店销售过但在公司其他店面销售过的物品
- 资历2:以前曾在本店销售过的商品。
与价格有关的特征
一个简单的论点是,销售上升和下降的直接原因之一是价格和促销活动。价格是区分不同类别、子类别和超级类别产品的最佳方法之一。
例如,假设已经为每个产品分配了一个类别和一个子类别,就可以创建以下价格特征。
- (平均数、最大值、最小值、中位数)跨类别的价格
- (平均数、最大值、最小值、中位数)跨子类别的价格
- 这些统计数字之间的比较,如类别和子类别中每个统计数字之间的差异
这种汇总可以使用许多按主题分组的方式多次进行(假设我们的目标是预测月度需求),比如说。
- 每月, 商店, 类别
- 每月, 商店, 子类别
- 每月, 商店, 项目, 类别
- 月度,商店,项目,子类别
另外,还可以在月度分组之外添加更多的特征,以研究价格的整体行为。
与库存有关的功能
这个在零售商和销售预测者中并不常见,但它在销售预测模型中却有很大的不同。库存数据集主要有每个产品的库存数据,每天在每个商店的库存数据。由此,我们可以把它与销售数据结合起来,得到每个产品的月周转率。这个比率将表明一种产品的库存被完全售出的速度,它有两个主要的好处:
- 它可以帮助模型在当前库存水平的基础上预测销售。
- 它可以帮助我们利用这个值将产品聚类为慢速、中速和快速流动的产品。这种聚类将帮助我们进行决策和建模。
为此,你需要每个产品的每日库存数据,以及销售数据,然后你可以按以下方法计算库存周转率。
提示: 这些汇总是基于一个时间范围来完成的。例如,如果我们正在进行月度销售预测,那么ITO将被计算为上个月的总销售额超过同一月的平均库存值。
销售预测可以将数据转化为机会
综上所述,销售预测可以帮助企业增加收入并实现盈利,前提是他们拥有正确的数据管道并使用正确的特征工程方法。这篇文章是一个试验,表明各种数据在解决这个问题时都可以发挥作用。
每家公司都应该调查其预测问题是否需要人工智能,如果需要,就需要专业的人工智能工程师和机器学习工程师的建议来创建一个属于自己的销售预测系统。
如果你是一家愿意应用这种销售预测技术的公司/零售商,首先要收集所有可以收集的数据,特别是每日销售、每日库存和每日交易。
一旦你掌握了这些数据,你就可以用它来增加收入,优化库存补充策略,让你的企业在现有资源的基础上获得最高的利润,正如上面几个例子以及领先的零售商所使用的销售预测实践所证明的那样。
了解基础知识
你如何计算销售预测(在产品层面)?
通过收集销售、库存、价格数据,为它们创建一个数据库,对它们进行预处理,并进行特征工程以创建可解释的特征,然后应用XGBoost或RNN等预测方法。
准备销售预测的四个步骤是什么?
销售预测过程分为四个步骤:数据收集、数据预处理、特征工程和数据建模。
什么是销售的最佳预测方法?
ARIMA和ETS对总的销售来说是完美的,但在产品层面,像XGBoost或RNN表现得更好。
为什么需求/销售预测很重要?
因为它解决了需求和销售的两个主要问题,也就是库存过多和缺货问题。这导致了更高的收入和更好的现金流。
销售潜力和销售预测之间的区别是什么?
销售潜力回答了这样一个问题:"某个品牌的产品可以卖出多少单位?"另一方面,销售预测回答的是 "将销售多少单位 "的问题。