【第十一届泰迪杯B题产品订单的数据分析与需求预测产品订单的数据分析与需求预测 】第二大问代码分享+解题思路(EDA数据再探索+LightGBM模型)_第十一届“泰迪杯”数据挖掘挑战赛 b题 优秀论文-程序员宅基地

技术标签: 数据分析  泰迪杯数据挖掘挑战赛  数据挖掘  泰迪杯  

【第十一届泰迪杯B题产品订单的数据分析与需求预测】第二大问代码分享+解题思路(EDA数据再探索+LightGBM模型)

写在前面:

​ 拖了这么长时间,一方面是我在找实习面试准备、另一方面是在做第二问的过程中,我始终坚持要做出真实的、负责的、优秀的作品,为此我查阅了很多资料,做了很多实验我做了很多工作,尝试了很多模型,有LSTM、传统的Arima等等、写了很多代码,看到很多粉丝私信问我什么更新第二题我也很着急,还有粉丝给我展示了他买的其他博主的作品,真就两块儿代码,还不能运行,这不纯纯骗人嘛!!,所谓失败乃是成功它娘,经过无数次尝试失败,最后终于做出来了,选择了LGBM模型并且预测效果很好!

​ 我将我所有写的代码分为了解题的代码文件夹和其他代码文件夹,这不仅仅只是为了解题,更是希望其他的代码能为大家带来一定的帮助,以后可能用的上代码,就大大减少了工作量了。我将会在明天录制第二问的讲解代码视频,以及配套解题工作流程的思维导图,我希望不单单是为了解题而解题,而是能真正帮助大家达到以赛促学的目的。

内容概述:

本题解仅我个人的解法!!!

题解流程简述:

  • 根据第一问的简单分析,和衍生出了一些特征,例如年月日、价格标签、是否节假日、week等

  • 读入第一问保存的文件csv,process1.csv,进行数据再探索,发现需要对价格进行更细致的分区间,我采用最优分箱操作,将每个产品的价格归为不同的价位区间,因为相同的产品,它在不同的地区,不同的时间,价格会有波动,所以使用分箱,可以大致归纳价格特征。

  • 然后再在此基础上,衍生出其他特征,星期几、是否工作日等(因为跟据EDA数据探索和第一问可视化分析,发现周末、还有不是工作日时,需求量会有所上升。)

  • 然后主线任务思想是,先将现有的各种产品(3931种产品)进行以地区、销售区域编码 产品编码 产品大类编码 产品细类编码组合,先设置其在2018-12-21到2019-1-31的需求量都为0。作为表sub1(先预测出19年的1月)

  • 然后将sub1进行衍生特征,构造为与df相同的特征列,然后sub1和df进行拼接为一个大表

  • 然后将大表经过特征工程处理后,划分天数大于等于1207(2018-12-21日)的数据为预测集、天数大于1176小于1207的数据作为验证集,天数小于1176的作为训练集。

  • 分地区进行LGBM建模训练,并且预测未来大于1207的预测集,

  • 然后将预测的数据,增加回原数据中作为训练集,再如上诉步骤构建19年2月,进行预测2月的,如此重复,又预测3月的。

    由于样例数据,数据不完整,所以我暂时值预测了19年的1月,然后我们预测目标文件predict_sku0.csv中的产品在样例数据中没有,(数据不完整),所以预测1、2、3月就等完整数据出来再进行预测

题解主要部分目录内容:

在这里插入图片描述

EDA数据再探索:

以地区101为例:

sns.barplot(x='是否节假日', y='订单需求量', data=df_101)
sns.barplot(x='销售渠道名称', y='订单需求量', data=df_101)

在这里插入图片描述

可以看出是节假日和线上销售的需求量要高些,这将会在特征工程时进行需求量趋势构建时有一定的帮助

我们再看看101地区各个细类编码的产品需求量如何

其总需求量和平均需求量:

x = df_101['产品细类编码']
y = df_101['订单需求量']
plt.figure(figsize=(15,5))
plt.title('订单需求量 by 产品细类编码')
plt.xlabel('产品细类编码')
plt.ylabel('订单需求量')
plt.scatter(x,y)
plt.show()
plt.figure(figsize=(20,6))
fig = sns.barplot(x='产品细类编码', y='订单需求量', data=df_101)

在这里插入图片描述

在这里插入图片描述

可以发现细类编码为407的需求量总的最高,可是平均需求量却是402的最高,说明101地区的407可能存在某一时间段销量暴增的情况。这在建模的特征工程处理时,可以以平均值进行拉平处理。

我们再看看时间对需求量的影响

在这里插入图片描述

可以发现101地区在10月和2017年的需求量最高,以及平均下来的每个月需求量,可以发现其在4月和10月,12月的需求量居多,这可能是促销日、节假日等影响,所以后续我们需要衍生这些特征。

再看看week周对销售量分布

在这里插入图片描述

在这里插入图片描述

可以看出week其实与month的特征没太大差别,所以week列衍生可能用不上

数据处理

在这里插入图片描述

数据处理部分主要是做了个价格分箱处理,像上面说过的,因为相同的产品,它在不同的地区,不同的时间,价格会有波动,所以使用分箱,可以大致归纳价格特征。

from scipy.stats import stats
def optimal_bins(Y,X,n):
    """
    :Y  目标变量
    :X  待分箱特征
    :n 分箱数初始值
    return : 统计值,分箱边界值列表、woe值、iv值
    """
    r = 0  #xia相关系数的初始值
    total_bad = Y.sum()  #总的坏样本数
    total_good = Y.count() - total_bad   #总的好样本数
    #分箱过程
    while np.abs(r) <1:   #相关系数的绝对值等于1结束循环,循环目的找寻最好正反相关性
     XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
     XXXXXXXXXXXXXXXXXXXXXXXX
        qua = X.quantile(i/(n+1)) #quantile把给定的乱序的数值有小到大并列分成n等份,参数表述取出第百分之多少大小的数值
                                    #i的取值范围是1->n 1/n.2/n 3/n...n/n
        cut.append(round(qua,6))
   
    return cut
#对RevolvingRatio列进行分箱操作:
cut_bins = optimal_bins(df.订单需求量,df.产品价格,n=10)
cut_bins
df['价格区间'] = pd.cut(df['产品价格'],cut_bins,labels=[x for x in range(len(cut_bins)-1)])
df

在这里插入图片描述

分箱后生成6个区间,价格由高到低。这将有利于我们对预测数据时,不同区域、不同产品的价格进行区间编码匹配。

特征工程+LGBM建模预测

通过数据再探索和第一问的分析,我们需要构造一些特征,最后主要准备的数据格式为:

在这里插入图片描述

增加待预测的三个月数据(2019年1,2,3,月)

以增加2019年1月数据为例:

先构造各产品的的2019年一月数据:

我们需要借助销售区域编码+大类编码+细类编码+产品编码为zuhe列:

df['zuhe'] = df['销售区域编码'].astype(str)+'_'+df['产品大类编码'].astype(str)+'_'+df['产品细类编码'].astype(str)+'_'+df['产品编码'].astype(str)
df

在这里插入图片描述

然后构建一月的数据:

​ 现阶段给出的数据,有3931种,我们将先构造一下这3931种产品,每天的需求量为0,加入到原数据中
先预测一个月的,再将一个月的数据加入到原始作为训练集,再去预测第二个月的
意思是先预测出3931种产品2019-1月的需求量,再去预测2019-2,最后时2019-3月

#从2018-12-21到2019-1-31日的数据

dt1 = pd.date_range(start="20181221", end="20190131", freq="D")
dt1
len(dt1)
dates=[]
need=[]
ids =[]
for d in dt1:
    date = str(d).split(' ')[0] #得到日期xx-xx-xx
    dates=dates+[date]*len(set(df['zuhe']))
    need = need+[0]*len(set(df['zuhe']))
    ids=ids+list(set(df['zuhe']))
    xxxxx

在这里插入图片描述

然后对temp表格进行处理和构造特征,得到与df相同的数据格式,以及数据类型:

在这里插入图片描述

可以看出,我们先设置出各种产品每天的需求量为0,165102行是因为有3931产品,从2018-20-21到2019-1-31有42天,所有3931*42=165102。

拼接temp和df为整个数据集:

在这里插入图片描述

这样就看的懂了构建的什么数据集了。

特征工程:

滞后特征:

滞后特征是将时间序列预测问题转化为监督学习问题的经典方法。对销售的目标变量引入滞后。我使用的最大延迟是60天。这完全取决于你想引入多少滞后。

在这里插入图片描述

均值编码:

在这里插入图片描述

df['产品编码_avg'] = df.groupby('产品编码')['订单需求量'].transform('mean').astype(np.float16)
df['销售区域编码_need_avg'] = df.groupby('销售区域编码')['订单需求量'].transform('mean').astype(np.float16)
df['产品大类编码_need_avg'] = df.groupby('产品大类编码')['订单需求量'].transform('mean').astype(np.float16)
df['产品细类编码_need_avg'] = df.groupby('产品细类编码')['订单需求量'].transform('mean').astype(np.float16)
df['销售渠道名称_need_avg'] = df.groupby('销售渠道名称')['订单需求量'].transform('mean').astype(np.float16)
xxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

在这里插入图片描述

滑动窗口统计

我将计算每周销售的滚动平均数。更多的特征,如滚动最小值,最大值或总和也可以计算。同样,同样的功能也可以用于计算需求量

df['rolling_need_mean'] = df.groupby(['销售区域编码','产品编码','产品大类编码','产品细类编码'])['订单需求量']xxxxx

在这里插入图片描述

开窗数据拓展:

这是滚动窗口技术的高级版本。在滚动窗口的情况下,当窗口随着时间向前移动而滑动时,窗口的大小是恒定的。因此,我们只考虑最近的值,而忽略过去的值。 我将计算需求量的扩大平均值。还可以计算更多的特征,如扩展最小值、最大值或总和。同样,同样的功能也可以用于计算需求量。

在这里插入图片描述

需求量趋势构建

我将创建一个需求量趋势特征,如果每日需求量大于整个持续时间的平均值(d_1 - d_1248),则为负值。可以添加更多的趋势特性,但我只添加这一个以保持简单。

在这里插入图片描述

建立模型:

data = pd.read_pickle('data4_5.pkl')
valid = data[(data['D']>=1176) & (data

建立每个销售区域的模型:

for store in states:
    df = data[data['销售区域编码']==store]
	#Split the data
	xxxxx
	
	#Train and validate
	model = LGBMRegressor(
	    n_estimators=1000,
	    learning_rate=0.3,
	    subsample=0.8,
	    XXXXX
	)
	print('*****Prediction for 销售区域: {}*****'.format(store))
	model.fit(X_train, y_train, eval_set=[(X_train,y_train),(X_valid,y_valid)],
	         eval_metric='rmse', verbose=20, early_stopping_rounds=20)
	valid_preds[X_valid.index] = model.predict(X_valid)
	eval_preds[X_test.index] = model.predict(X_test)
	filename = 'model'+str(store)+'.pkl'
	# save model
	joblib.dump(model, filename)
	del model, X_train, y_train, X_valid, y_valid

在这里插入图片描述

RMSE值很小,模型效果很不错。

挑选出101区域的模型进行模型验证:

model = joblib.load("models\model_101.pkl")
model
df = data[data['销
y_valid
x_axis=np.linspace(1,len(y_valid),len(y_valid))
font1 = {'family' : 'SimSun','weight' : 'normal','size'   : 20,}
colors =['black','green','yellow','blue','cyan','red','orange','pink']
plt.figure(dpi=300,figsize=(28,12))


plt.plot(x_axis[:200],y_valid[:200])
plt.plot(x_axis[:200],s[:200])
plt.legend(['true','prediction'],prop = {'size':20})
# plt.scatter(x_data,y_data_yuemo,color='blue')
plt.tick_params(labelsize=20)  #修改刻度显示大小

在这里插入图片描述

在这里插入图片描述

可以看出,模型预测的结果拟合的很好,需求量走势和峰值等都相差不多。相信完整数据出来后,模型效果会更好。

查看模型特征重要性,验证我们前期特征工程:

在这里插入图片描述

可以看出我们前期的特征工程处理的很好。

预测样例数据结果

我们现在将19年1月的预测结果进行汇总处理,然后再去predict_sku0.csv进行匹配,得到每个产品的1月需求量:

读取待预测的predict_sku0.csv:

在这里插入图片描述

制作透视表,计算各产品一月的总需求量:

#制作透视表得到所有产品19年1月的需求量
result_df = pd.pivot_table(result_df, index=['销售区域编码','产品大类编码','产品细类编码','产品编码'], columns='订单日期',
                                  values='订单需求量', aggfunc=np.sum,fill_value=0).reset_index()
result_df
xxxxx

在这里插入图片描述

匹配最终:

在这里插入图片描述

你会发现进行匹配后,结果变少了,这是因为predict_df中有的产品,在result_df中没有,这是因为目前只有样例数据,没有完整的数据导致的。 等完整的数据出来后,匹配将会很完美。所以现在暂时不去做预测2、3月无意义的事了。等完整数据发布了,再运行代码。

写在最后:

压缩包内容为:

在这里插入图片描述

在这里插入图片描述

代码获取:

在这里插入图片描述

会更新代码讲解视频和B题论文给大家借鉴。

如需获取代码详情请看。社区
应粉丝建议,我创建了一个交流群,欢迎各位小伙伴入群交流问题:
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/shine_Lee_/article/details/129997532

智能推荐

eNSP综合实验合集(eNSP综合大作业合集)_可先收藏_ensp的无线网络技术大作业3000字-程序员宅基地

文章浏览阅读10w+次,点赞123次,收藏1.1k次。该文章对eNSP的综合实验做了一个归纳和总结,文章中包含了多个综合实验,可以自由的切换到相应的文章中进行查看_ensp的无线网络技术大作业3000字

【爬虫实战】python文本分析库——Gensim-程序员宅基地

文章浏览阅读2.1k次,点赞25次,收藏37次。Gensim 允许你使用 TF-IDF 权重和其他算法来提取文档中的关键词。当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。_gensim

Android分享一张图片_android 分享一张图片到basequickadapter中-程序员宅基地

文章浏览阅读1k次。public class Act_Share extends Activity { private ShareCustomAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(_android 分享一张图片到basequickadapter中

Linux所有服务开放对应端口大全_linux服务器端口全部开放-程序员宅基地

文章浏览阅读4.7k次。Linux所有服务开放对应端口大全_linux服务器端口全部开放

php连接mysql实现简单注册登陆页面_php连接数据库登录和注册-程序员宅基地

文章浏览阅读1.6w次,点赞33次,收藏226次。PHP7连接数据库的方式:使用mysqli及PDOhttps://blog.csdn.net/zwliang98/article/details/82997349php输出执行sql语句的错误信息:mysqli_query($conn,$sql) or die(mysqli_error( $conn ));问题一:Incorrect integer value: ‘’ for colu..._php连接数据库登录和注册

深度学习之——防止过拟合的方法_加噪声防止过拟合-程序员宅基地

文章浏览阅读3.2k次,点赞8次,收藏13次。1、过拟合定义:在training data上的error渐渐减小,但是在验证集上的error却反而渐渐增大——因为训练出来的网络过拟合了训练集,对训练集外的数据却不work。模型越复杂,越容易过拟合。因此,原先以最小化损失(经验风险最小化)为目标:现在以最小化损失和模型复杂度(结构风险最小化)为目标:通过降低复杂模型的复杂度来防止过拟合的规则称为正则化。2、..._加噪声防止过拟合

随便推点

CSR8675的DSP学习笔记——离线调试与仿真_csr adk4.2-程序员宅基地

文章浏览阅读1.2w次,点赞2次,收藏22次。写在最前面:很多读者反馈希望可以有硬件平台配合学习。现与思度科技联合推出CSR867x学习板【淘宝链接:思度科技CSR867x学习板】,进QQ群获取激活码购买学习板享受如下优惠: 1. 价格优惠 2. 免费提供开发教程和项目源码 3. 免费提供入门级技术支持QQ群号:743434463—————————–正文分割线———————————1. 引言CSR8675的DSP..._csr adk4.2

由于高精度事件计时器(HPET)驱动过时导致AMD机器装Win10的卡死蓝屏问题记录_win10关闭高精度事件计时器-程序员宅基地

文章浏览阅读1.5w次。AMD记性频繁卡死,蓝屏,特征在于:打游戏等高负载条件,电脑没有问题;闲置一定时间之后蓝屏或者死机,鼠标键盘无反应,界面全部卡死,只能按开机键重启。未保存的数据全部丢失。近日蓝屏代码 有两类,一,IRQL NOT LESS OR EQUAL 。驱动程序使用了不正确的内存地址造成。第二种是 KMODE_EXCEPTION_NOT_HANDLED。这种主要是由于过时或损坏的设备驱动程序文件。以下..._win10关闭高精度事件计时器

java通过ksoap调用_[Java教程]ksoap2-程序员宅基地

文章浏览阅读242次。[Java教程]ksoap20 2020-06-19 18:04:38 Android连接远程数据库,目前看来最好的解决办法就是webservice,利用webservice进行通讯就要soap协议,目前android没有内建相关的函数,需要借助第三方ksoap2-android进行操作。soap2-android官网地址https://simpligility.githu..._java ksoap2

MySQL中SELECT ... INTO的用法_select id into-程序员宅基地

文章浏览阅读2.7k次。MySQL中SELECT ... INTO的用法官方文档表述:1.SELECT ... INTO var_list selects column values and stores them into variables.2.SELECT ... INTO OUTFILE writes the selected rows to a file. Column and line termi_select id into

重装系统详细指南_电脑重装系统怎么操作csdn-程序员宅基地

文章浏览阅读7.4k次,点赞89次,收藏67次。电脑使用时间久了,无论是正常的系统升级,还是出了故障无法正常使用,都免不了要重装系统,本文详细地给大家介绍下如何重装系统,轻松完成。_电脑重装系统怎么操作csdn

出了国才能知道的十个小秘密_国国际海员-程序员宅基地

文章浏览阅读1.2k次。在国内时,了解“外面的世界”并不难,然而,认识的误区只有在国外住久了,慢慢地体会才能逐渐消除。下面十个方面如果不出国,我是不会知道很清楚的……   一、英语不努力学,是掌握不了的。 出国以前我以为到了国外,有了英语环境,自己会不费力地通过语言关。然而,除了小孩子,成年人欲消除语言障碍谈何容易?难怪许多在国外生活了半辈子的老侨,其英语程度还属初级。   二、从中国出口海外的食品,是给华人吃_国国际海员

推荐文章

热门文章

相关标签