菜鸟—需求预测与分仓规划亚军——“天亮”团队赛后总结

在菜鸟—需求预测与分仓规划比赛上,“天亮”团队获得了亚军。“天亮”团队主要分享了团队的特征分析以及方案实现过程。

背景介绍

此次比赛希望选手利用大数据技术预测商品的未来需求来优化整个菜鸟物流的供应链。比赛给出的数据包括商品的销量、价格品牌等信息,预测后两个星期的销量。

特征分析

通过观察一件商品的时序图,我们可以发现一件商品有上架时间,在双十一、双十二会有销量的突增,这些突增在时序的最后端,会对接下来两周的预测产生干扰。此次,训练样本采用滑窗法,主要有13个窗口,每个窗口有14天(不重叠)。第一个窗口作为线上预测的样本,第二个窗口作为线下评测系统的评价,后面的窗口作为线下模型的训练样本。

在特征提取过程中,赛方给出的数据包括label型的特征和数字型的特征。label型的数据,比如一些品牌有些类目型的数据,经典的处理方式是One-Hot编码,但是没有太大的意义。所以我们应该对其进行统计获得该品牌在整个历史时期的统计特征,包括总和、方差、均值。同样的,对数字型特征也会进行同样的处理。此外,还会加入一些先验知识补充规则特征,涉及一些业务特征。有一个比较明显的特征是某个商品在一段时间内的销量占所有产品销量的百分比。

通过观察数字型特征,我们可以发现一个很严重的常规效应:很多商品的销量很少但是有少部分商品的销量特别大。这有很明显的一个区分性,可以用于分类。但是并不适合回归,所以需要进行Log平滑处理。

在数据清洗方面,直接剔除了双十一、双十二的销量数据。细节方面,对这两个时序进行遍历,根据某个销量大于阈值的情况进行替换。

方案设计

有了线下评测和特征之后,就可以设计方案了。为了提升建模的效果,额外增加了两个过程:样本选择,特征选择。样本选择是通过训练模型继续对训练样本进行预测,剔除训练误差较大的一些样本。特征选择是用xgboost训练出一些特征的重要性,选取了top 50的特征放入线性模型。

针对此次比赛设定了两条显著的规则:统计预测时间点前两周的销量均值,取其最小值乘以14作为后期的一个预测,这是因为在双十一之后销量会出现下滑,如果不引入人为的先验知识,模型效果较差;基于权重加权的滑窗技术,首先剔除促销数据,假设销量是大于均值的三个标准差的话用均值替换,寻找与预测实际窗比较接近的时间窗,将这几个时间窗均值进行加权,权值参数是根据时间长度和标准化的和进行倒数。

除此之外,基于官方的评价函数进行模型自定制,“天亮”团队自定制了一个线性模型。由于传统模型用的是RMSE,与官方函数不同,所以采用了SGD随机梯度下降法进行优化训练,但由于平台的约束(可能是安全性问题),导致MapReduce无法不断迭代。这个平台只允许调用一次MapReduce过程,所以把模型的训练迭代放在Reduce中实现,但是可以用Map做一个具体分发的过程。将数据分为10份,每份数据中训练出一个线性模型,最终将权重均值加权。

GBDT的窗口框架每次迭代分为三个步骤:对损失函数求梯度,用决策树去拟合函数梯度,再用一维线性搜索寻找最优步长。用决策树去拟合函数梯度时,关键是优化树模型、叶子节点的结构参数。假设训练样本用到某个节点的样本,样本形成一个集合,对其进行目标值的排序,在过程中可以消除评价函数中Max符号,最终对进行求导,根据公式做临界值的选择,即从负号到正号的两个临界点,取损失较小的临界点作为叶子节点的T值。融合规则和模型的过程中需要进行微调,调整模型融合的权重。

总结和展望

充分利用模型的差异性和融合会产生比最优单模型最好的效果。基于特征选择和样本选择的过程实际上能进一步提升机器学习的效果。

如果菜鸟提供更多业务知识,能够设计出更多稳定的物流规则、先验知识,效果会变得更好。
需求预测分仓规划是一个很常见的问题,一般需要使用时间序列分析和优化算法来解决。以下是一个简单的Python代码示例,可以帮助你对需求进行预测和进行分仓规划。 首先,我们需要导入一些必要的库: ```python import pandas as pd import numpy as np import matplotlib.pyplot as plt from statsmodels.tsa.arima_model import ARIMA from sklearn.metrics import mean_squared_error import pulp ``` 接下来是数据预处理部分。我们需要读取销售数据和库存数据,并将它们合并成一个数据框: ```python sales_data = pd.read_csv('sales_data.csv') inventory_data = pd.read_csv('inventory_data.csv') df = pd.merge(sales_data, inventory_data, on='date') df['date'] = pd.to_datetime(df['date']) df.set_index('date', inplace=True) ``` 接下来是时间序列分析部分。我们可以使用ARIMA模型来预测销售量: ```python def arima_model(series): model = ARIMA(series, order=(3,1,0)) model_fit = model.fit(disp=0) return model_fit.forecast()[0] sales_prediction = [] for i in range(len(df)): if i < 7: sales_prediction.append(np.nan) else: sales_prediction.append(arima_model(df['sales'][i-7:i])) df['sales_prediction'] = sales_prediction plt.plot(df['sales']) plt.plot(df['sales_prediction']) plt.show() ``` 然后,我们可以使用线性规划来进行分仓规划。我们可以使用pulp库来构建和求解线性规划问题: ```python def optimize_warehouses(num_warehouses, max_capacity): prob = pulp.LpProblem("Warehouse Planning", pulp.LpMinimize) inventory_vars = [] for i in range(num_warehouses): inventory_vars.append(pulp.LpVariable(f"inventory_{i}", lowBound=0, upBound=max_capacity)) total_cost = 0 for i in range(len(df)): demand = df['sales_prediction'][i] if np.isnan(demand): continue shortfall = [] for j in range(num_warehouses): shortfall.append(demand - inventory_vars[j]) prob += pulp.lpSum(shortfall) == 0 total_cost += pulp.lpSum([inventory_vars[j] for j in range(num_warehouses)]) * 0.01 prob += total_cost prob.solve() inventory_levels = [] for v in prob.variables(): inventory_levels.append(v.varValue) return inventory_levels ``` 最后,我们可以调用optimize_warehouses函数来进行分仓规划,并将结果保存到一个新的数据框中: ```python inventory_levels = optimize_warehouses(num_warehouses=3, max_capacity=1000) df['inventory_level'] = inventory_levels plt.plot(df['inventory_level']) plt.show() ``` 这是一个简单的示例,你可以根据自己的需求进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值