《现代库存管理:模型、算法与Python实现》 课件 第2章-需求预测_第1页
《现代库存管理:模型、算法与Python实现》 课件 第2章-需求预测_第2页
《现代库存管理:模型、算法与Python实现》 课件 第2章-需求预测_第3页
《现代库存管理:模型、算法与Python实现》 课件 第2章-需求预测_第4页
《现代库存管理:模型、算法与Python实现》 课件 第2章-需求预测_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

现代库存管理:模型、算法与Python实现第2章需求预测基础2.1需求预测的基本结构一般认为需求的实现值由两部分构成:可预测的需求模式:这部分由商品特征、经济规律等客观规律决定不可预测的随机因素:由一些难以刻画的顾客购买行为和随机影响导致

2.1需求预测的基本结构

2.1需求预测的基本结构产品的需求模式同时受到内在规律和外生因素的影响内在规律可以进一步分解为趋势性、季节性这两种共通的需求变动规律和产品本身决定的需求特性,由产品本身的性质决定外生影响的来源则非常广泛,往往需要针对具体的产品进行具体分析和刻画2.2需求预测方法的分类时间序列方法

宏观趋势

2.2需求预测方法的分类时间序列方法在使用时间序列模型时,最重要的是理解模型采用了哪一种分解模型,以及刻画的是序列中的哪一部分

宏观因素微观因素

趋势性季节性一元多元简单指数平滑√√

Holt-Winters√√

ARIMA

sARIMA

√√

VARMA

√sVARMA

√HTS

√prophet√√√

2.2需求预测方法的分类机器学习方法特点优势劣势线性模型简单的线性回归形式,可以通过正则化项演化为LASSO或Ridge模型形式简单只能拟合线性关系CART树基于二分树的结构构建,是后续许多集成方法的基础结构简单,拟合能力强大对数据敏感,容易过拟合神经网络由线性变换、非线性激活函数和网络结构组成多层网络理论上可以以任意精度逼近任意函数,具有强大的拟合能力网络结构复杂,模型参数较多,容易调试不当或过拟合随机森林以并行的决策树为基础模型,通过简单加权集成最终结果相比决策树更加稳健,可以并行运算,计算速度快相比于GBDT集成方法效果较差XGBoost以决策树为基础模型,不断强化对残差的学习基于GBDT思想改进,能在实现较好模型效果同时以较快的速度完成运算对于较大的数据运行较慢;参数设置复杂,容易过拟合lightGBM以决策树为基础模型,不断强化对残差的学习在海量数据的场景下,能够以较小的内存和较快的速度完成计算参数设置复杂,容易过拟合Stacking以多种预测模型为基础模型,通过机器学习模型集成最终结果模型形式简单,效果强大,能够集成不同模型的优势,包容性强容易过拟合2.2需求预测方法的分类比较和总结机器学习方法是数据驱动的,时间序列方法是模型驱动的机器学习模型的效果受到特征选择、模型选择、参数选择等诸多因素的影响,实际运用效果还要取决于业务场景、数据性质和模型调试等诸多方面由于强大的拟合能力,在一个数据规模相对较小或是内在规律简单的数据集上,机器学习很容易过度拟合随机扰动因素,从而导致较差的泛化能力;而时间序列则能够集中于把握宏观趋势,较好地剔除随机扰动的偶然影响机器学习得到的结果往往较难得到直观理解,解释力较弱,较难结合已有经验进行辅助判断和调整;时间序列模型具有简单清晰的模型结构,非常便于使用、解读和调整2.3数据预处理在进行需求预测之前,通常要对数据进行预处理及分析。尽管不同企业的业务场景与产品的需求规律不同,但数据处理的步骤与方法是类似的本节以食品饮料快消品公司W2018年1月1日~2020年7月30日77个产品在18个分销中心(distributioncenter,DC)的销售数据为对象一般而言,尽管原始数据的具体格式不尽相同,需求预测任务的数据集至少包含以下信息:

商品名,有时存在品类信息,构成两级及以上的产品类别层级结构销售地点,有时存在国家/区域—城市—终端销售点的地理层级结构时间,一般以日为颗粒度实际销量首先,从数据文件夹读入销售数据表格,并查看表格前十行,以获得对数据结构的基本了解注意数据路径的设置,相比于将文件地址作为一个完整字段,单独指定文件夹路径和表格名称更具灵活性,更适用于具有较多数据表格需要管理以及可能存在数据迁移的场景2.3数据预处理数据导入及基础操作importpandasaspd

data_dir=

'../../data/forecast_data/'

sales_data=pd.read_csv(data_dir+

'sales_data.csv')

print(sales_data.head(10))2.3数据预处理数据导入及基础操作可以看到,本节所使用的数据集恰好对应了需求预测任务的四个基本元素,并通过dc_id和sku_id组合成unit_id,从而标识更细致的颗粒度

datedc_idsku_idunit_idsale

02018-05-01DC001SKU024DC001_SKU0240

12018-05-01DC001SKU070DC001_SKU0700

22018-05-01DC001SKU078DC001_SKU0789

32018-05-01DC001SKU044DC001_SKU044589

42018-05-01DC001SKU051DC001_SKU05143

52018-05-01DC001SKU063DC001_SKU0632751

62018-05-01DC001SKU099DC001_SKU09996

72018-05-01DC001SKU100DC001_SKU100200

82018-05-01DC001SKU101DC001_SKU10142

92018-05-01DC001SKU102DC001_SKU102102.3数据预处理数据导入及基础操作

数据类型转换时间数据在csv等文件中常以字符串形式储存,对这种格式的数据无法使用一些针对时间戳格式的便捷操作。因此,在读入带有时间的数据时,往往需要确认时间数据类型并进行数据类型的转换sales_data['date']=pd.to_datetime(sales_data['date'])2.3数据预处理数据导入及基础操作

数据整理当拿到的原始数据的排列并不按照商品、DC和时间顺序进行排列时,我们并不知道数据从何时开始、到何时结束,也不知道究竟有多少种商品和DC。所以接下来我们进行对表格的排序、时间范围的识别、商品种类和DC个数的统计工作表格的排序#排序

sales_data=sales_data.sort_values(

by=['dc_id','sku_id','date']).reset_index(drop=True)

print(sales_data.head())

datedc_idsku_idunit_idsale

02018-02-02DC001SKU001DC001_SKU0017

12018-02-03DC001SKU001DC001_SKU0010

22018-02-04DC001SKU001DC001_SKU0010

32018-02-05DC001SKU001DC001_SKU0012

42018-02-06DC001SKU001DC001_SKU0010时间范围的识别商品种类及DC个数的统计2.3数据预处理数据导入及基础操作

#商品种类和DC个数统计

all_sku_list=sales_data['sku_id'].unique().tolist()

print(f'商品个数为:{len(all_sku_list)}')

all_dc_list=sales_data['dc_id'].unique().tolist()

print(f'DC个数为:{len(all_dc_list)}')#时间范围的识别

print(f'数据起始时间为:{sales_data["date"].min()}')

print(f'数据结束时间为:{sales_data["date"].max()}')数据起始时间为:2018-01-0100:00:00

数据结束时间为:2020-07-3000:00:00

商品个数为:77

DC个数为:182.3数据预处理数据导入及基础操作

部分数据筛选上述数据表格包含了所拥有的全部信息,但当我们仅需要其中部分信息时,可以将这部分数据存放到一个新的数据表中,便于之后取用unit_id=

'DC001_SKU044'

unit_df=sales_data[sales_data['unit_id']==unit_id]

print(unit_df.head())

datedc_idsku_idunit_idsale

212282018-01-01DC001SKU044DC001_SKU04479

212292018-01-02DC001SKU044DC001_SKU044492

212302018-01-03DC001SKU044DC001_SKU0441261

212312018-01-04DC001SKU044DC001_SKU0441067

212322018-01-05DC001SKU044DC001_SKU0445352.3数据预处理数据导入及基础操作

描述性统计pandas自带的数据分析函数describe()可以自动统计数值型数据的均值方差等信息,也可以自动统计非数值型数据的个数、唯一值数量、最高频率等信息print(unit_df['sale'].describe())count940.000000

mean1199.408511

std913.354405

min0.000000

25%628.000000

50%1106.000000

75%1661.750000

max7777.000000

Name:sale,dtype:float642.3数据预处理数据导入及基础操作

数据聚合对于非时间类型的类别信息,我们一般可以通过groupby方法,将原始数据按照某一类进行聚合下面的代码展示了将原始的销售数据按照商品进行聚合,统计每一类产品的日度销售情况,并按照日期和商品类别进行排序print(sales_data.groupby(['sku_id','date'])['sale']\

.agg(['sum','mean','median','std'])\

.sort_values(by=['date','sku_id']).reset_index()[:5])2.3数据预处理数据导入及基础操作

数据聚合由于日度销量往往波动性较高,有时需要将原始的日销量数据聚合为一段时间内的总销量数据,例如周销量、月销量等可以通过resample方法实现,下列代码展示了我们如何将原始数据聚合得到每个unit的周销量数据weekly_sales_df=sales_data.groupby('unit_id')[['date','sale']]\

.resample('W',on='date').sum().reset_index()

print(weekly_sales_df.head())2.3数据预处理数据导入及基础操作缺失值处理由于对于真实数据,往往需要考察其完整性,并对缺失值做出一定的处理一般地,我们需要针对每个商品单元考察记录完整性,即每个商品标识下的数据是否完整覆盖了数据集时间对于缺失数据,不同的成因对应了不同的解决方式这可能是正常的商业现象,即某天的销售量为零,对此我们可以用0填充缺失数据;这可能是数据遗失导致的,缺失部分存在销售,但销量并未被记录,此时可以用插值的方式进行填充也可能是因为产品上市和销售时间不一致,某些新品、促销品、季节品本身在市时间就较短,此时可以选择将这些产品与常规品区别开,单独构建模型,或者通过定性分析的方式单独进行分析和处理2.3数据预处理数据导入及基础操作数据输出在完成上述的基本数据整理工作后,我们可以将得到的新数据表格输出,在后续进行深入分析和模型构建时,可以直接读取整理好的结果,从而避免重复的数据预处理工作weekly_sales_df.to_csv(data_dir+

'weekly_sales_data.csv',index=False)2.3数据预处理时序数据可视化导入Python中常用的可视化工具包,matplotlib和seaborn,并统一绘图格式代码示例#导入绘图包

importmatplotlib.pyplotasplt

importseabornassns

#设置画图风格

sns.set_theme(style='darkgrid')

#设置画布大小

plt.rcParams['figure.figsize']=(12.0,6.0)

#设置清晰度

plt.rcParams['figure.dpi']=

500#导入绘图包

importmatplotlib.pyplotasplt

importseabornassns

2.3数据预处理时序数据可视化(接上页)#设置画图风格

sns.set_theme(style='darkgrid')

importmatplotlib

matplotlib.rc('font',family='SongtiSC')

parameters={'figure.figsize':[12.0,6.0],

'figure.dpi':500,

'axes.labelsize':14,

'xtick.labelsize':14,

'ytick.labelsize':14,

'legend.fontsize':14,

'font.weight':'bold'

}

plt.rcParams.update(parameters)2.3数据预处理时序数据可视化下列代码定义了针对某一个产品销量的季节性绘制函数,通过将不同年份的数据叠加,可以更直观地看到不同年份间是否存在相似的季节性变动

#季节性绘制函数

defplot_year_seasonality(data,date_col,qty_col):

"""

data:pd.DataFrame格式数据

date_col:data中标识日期的列名,需转换为日期格式

qty_col:data中标识销量的列名

"""

#以1-12月设置横坐标

month_all_list=list(range(1,12

+

1))

plt.xticks(range(len(month_all_list)),month_all_list,rotation=60)

#设置曲线颜色和曲线标识

color=['#787878','#1c79d9','black']

marker=['o','^','s']

#初始化标签列表

legend_list=[]

2.3数据预处理时序数据可视化color=['#787878','#1c79d9','black']

marker=['o','^','s']

#初始化标签列表

legend_list=[]

#将传入数据按照月份聚合

data=data.resample('M',on=date_col).agg({qty_col:'sum'})

#提取数据涉及年份,并逐年遍历

plot_year=list(set(data.index.year))

color_idx=

0

foryearinplot_year:

#提取当年所有数据,以月份为横坐标,月总销量为纵坐标绘制折线图

data_year=data[data.index.year==year]

data_inds=data_year.index.month

data_val=data_year[qty_col]

plt.plot(data_inds-

1,data_val,c=color[color_idx],

marker=marker[color_idx])

#为曲线添加标签

legend_list.append(year)

#动态改变下一次绘图曲线颜色

color_idx+=

1

2.3数据预处理时序数据可视化

#展示绘制图像

plt.xlabel('月份')

plt.ylabel('销量')

plt.legend(legend_list,loc='upperright')

plt.show()

2.3数据预处理时序数据可视化分别考察’SKU044’和’SKU008’在’DC001’的销量季节性。可以发现,’SKU044’的销量季节性并不明显,相比之下’SKU008’则呈现出一定的季节规律:在3-7月呈现出销量上升的共同趋势,在9月~次年2月呈现出销量下降的共同趋势2.3数据预处理时序数据可视化下列代码定义了针对某一个产品销量的趋势性绘制函数,利用产品的月销量数据绘制折线图,来直观地考察其上升下降趋势#趋势性绘制函数

defplot_trend(data,date_col,qty_col):

data=data.resample('M',on=date_col).sum()

plt.plot(data['sale'],color='#1c79d9',marker='o')

plt.xlabel('时间')

plt.ylabel('销量')

plt.show()

2.3数据预处理时序数据可视化选择’DC001_SKU044’和’DC017_SKU002’两个unit分别绘制其趋势图像。可以看到,前者呈现出一定的上升趋势,同时叠加了一定的季节性波动;而后者则出现了较为明显的下降趋势。在针对这两个unit进行需求预测时,为了获得更好的预测效果,需要将产品的趋势性纳入模型考虑2.3数据预处理时序数据可视化当一个商品在多个地区进行销售时,其在各区域之间的需求可能存在一定的相关性,这是由商品属性决定的共同趋势。同时,不同产品之间也可能存在相互关联不管是在模型构建还是特征构建中,我们都可以将相关因素纳入其中,以提升预测模型的准确性这一操作在经过格式转换的数据上可以通过调用内置函数corr()实现,同时,也可以通过绘制热力图,更直观地观察相关性sku_df=sales_data[sales_data[‘sku_id’]==

‘SKU076’]

corr=sku_df[[‘date’,‘dc_id’,‘sale‘]]\

.pivot(index='date',columns='dc_id',values='sale').corr()

sns.heatmap(corr,annot=True,cmap="Blues")<AxesSubplot:xlabel='dc_id',ylabel='dc_id'>

2.3数据预处理时序数据可视化热力图解读可以通过图中标注出的相关系数考察变量相关性,相关系数的取值范围在-1到1之间,越接近于1表明正相关程度越高,越接近于-1表明负相关程度越高,越接近于0表明相关性越弱也可以结合图例,从色块颜色直观地考察变量之间的相关性2.3数据预处理异常点检验

2.3数据预处理异常点检验下面两个函数定义了上述两种异常值检测方法,输入DataFrame格式的数据并指定要考察异常值的数据列名,函数便会返回离群值的标识defsigma_outlier(data,qty_col):

upper=data[qty_col].mean()+

3

*data[qty_col].std()

lower=data[qty_col].mean()-

3

*data[qty_col].std()

returndata[

(data[qty_col]>upper)|(data[qty_col]<lower)].index.tolist()defquantile_outlier(data,qty_col):

q1=data[qty_col].quantile(q=0.25)

q3=data[qty_col].quantile(q=0.75)

upper=q3+

1.5

*(q3-q1)

lower=q1-

1.5

*(q3-q1)

returndata[(data[qty_col]>upper)|(data[qty_col]<lower)].index

2.4评价预测模型的方法在预测任务中,两组不同的预测结果何者更好,往往并不直观。在某些数据集上一种方法可能比另一种方法的预测结果更接近真实值,而在其他数据集上则可能反之因此,我们需要一套规范化的指标对预测结果进行评估,以便选择最合适的预测方法2.4评价预测模型的方法样本内外误差数据泄露(dataleakage):其实质是进行模型评估的数据同时被用于模型训练,为了更好地预测未来值,而不是最优拟合历史数据,所以需要避免数据泄露模型在已知数据集上表现优于在未知数据集上表现的现象,被称为过拟合,这样的模型被称为泛化能力差。这种现象是预测中常常会遇到的,需要尽力避免进行模型训练和模型评估所用的数据集应该没有交集,以避免因数据泄露导致的对模型的不公允评估与选择2.4评价预测模型的方法样本内外误差在实践中,将数据集按照一定的比例切分为训练集(即用于模型训练的数据)和测试集(即用于模型评估的数据)在和时间顺序无关的数据集中,一般随机选择数据划分为这两个集合,以保证两个集合具有类似的数据结构在时序场景下,需要遵循数据集的时间属性,将靠前的数据划分为训练集,靠后的数据划分为测试集。在进行切分的时候,也不再按照比例的方式决定两个数据集合的大小,而是根据一个指定的时间,对数据进行前后切分模型在训练集上给出的预测结果与真实

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论