连锁店销量预测

news2024/9/21 5:47:27

目录

  • 任务
  • 数据解读及简单探索
  • 解决思路
  • 传统机器学习方法
    • 代码
    • 评估
  • 深度学习方法
    • 代码
    • 评估
  • 建议
  • 参考文献

任务

利用深度学习、强化学习等机器学习手段为某连锁商店预测每个商店未来12周的销售额进行估计,以便对商店的经营更好掌握和对库存调拨更好管理。

数据解读及简单探索

所有数据包含store.csv,train.csv 和 test.csv一共3个csv文件,其中store.csv主要是介绍每个商店的情况,具体表格包含的字段如下

字段名称描述
商店ID商店的唯一标识符
商店模式有四种:a,b,c,d
商店级别有三种:a,b,c。 注:a = 基本,b = 额外,c = 扩展
竞争者最近距离商店的竞争者中距离该商店的最近距离

从store表可以看到一共有1115个门店,每个店的经营模式是直营,特许经营,管理合同还是战略联盟,每个店的级别高低是属于基本,额外还是扩展,以及通过与竞争者的距离可以大致判断该店的竞争激烈程度,一般来说,距离越远竞争压力越小,距离越近竞争压力会越大,这种竞争对于直营的低级别模式的店铺显得尤为明显。

train.csv 和 test.csv分别用于模型的训练和估计值的生成,包含的字段如下

字段名称描述
商店ID商店的唯一标识符
所处年份
所处年份的第几周
营业天数该周开门营业天数
打折天数该周有打折活动的天数
非节日该周无节日的天数
节日A该周拥有节日类型为A的天数
节日B该周拥有节日类型为B的天数
节日C该周拥有节日类型为C的天数
Sales该周销售额(即:真实标签值)

通过train和test表可以看到不同商店在不同时期的实际销量走势情况,可以分析出打折等营销手段对销量的影响,可以分析节假日对销量的影响。

相关性探索

关系矩阵
从相关性矩阵图可以看到折扣天数,营业天数和非节日对周销量影响大,且是正向影响,节日A,节日B,节日C和距离对周销量影响小,且是负向影响。

解决思路

销量预测作为供应链域的核心算法,算法设计应该围绕准确率高,响应快,运行稳健三个方面进行,既然是要为所有商店未来12周的销售额进行预测,而且商店数量算中等,从生成预测值的数据量来说至少有1115*12约13000左右,这种多主体多期的预测常规的时间序列会显得很吃力,宜采用传统的机器学习方法和深度学习方法。

传统机器学习方法

对于这种结构化的数据,传统机器学习方法还是很巴适的,只是稍微要多做一些特征工程,对于类别型变量可以适当分多类别和少类别。

代码

# -*- encoding: utf-8 -*-
'''
@Project :   sales_train
@Desc    :   连锁店销量预测
@Time    :   2023/02/02 15:19:28
@Author  :   帅帅de三叔,zengbowengood@163.com
'''
import math
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['Simhei'] 
plt.rcParams['axes.unicode_minus']=False
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, OrdinalEncoder, StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_absolute_percentage_error
import pickle

store = pd.read_csv(r"D:\项目\商简智能\回归预测题目\store.csv")
train = pd.read_csv(r"D:\项目\商简智能\回归预测题目\train.csv")
train_df = pd.merge(left=train, right=store, left_on='商店ID', right_on='商店ID', how='left')

train_df = train_df.query("周销量>0")
train_df['商店ID'] = train_df['商店ID'].astype('str')
train_df['年'] = train_df['年'].astype('str')
train_df['周'] = train_df['周'].astype('str')
train_df['节日A'] = train_df['节日A'].astype('bool')
train_df['节日B'] = train_df['节日B'].astype('bool')
train_df['节日C'] = train_df['节日C'].astype('bool')
print(train_df.info)
X, y =  train_df.drop(['周销量'], axis=1), train_df.周销量 #特征和目标
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, shuffle=True, random_state=0) #划分训练测试集
less_cat_col = [col_name for col_name in X_train.columns if X_train[col_name].dtype=='object' and X_train[col_name].nunique()<10] #少类别型变量
more_cat_col = [col_name for col_name in X_train.columns if X_train[col_name].dtype=='object' and X_train[col_name].nunique()>=10] #多类别型变量
num_col = [col_name for col_name in X_train.columns if X_train[col_name].dtype in ['int64', 'float64']] #数值型特征
print(less_cat_col, more_cat_col, num_col)
print(train_df.corr())
# sns.heatmap(train_df.corr())
# plt.show()

less_cat_transform = Pipeline(steps = [('imputer', SimpleImputer(strategy='most_frequent')),
                                ('encoder', OneHotEncoder(handle_unknown='ignore'))]
                        ) #类别型变量先用众数填充再独热编码
more_cat_transform = Pipeline(steps = [('imputer', SimpleImputer(strategy='most_frequent')),
                                ('encoder', OrdinalEncoder(handle_unknown='use_encoded_value', unknown_value=-1))]
                        ) #类别型变量先用众数填充再普通编码

num_transform = Pipeline(steps = [('imputer', SimpleImputer(strategy='mean')),
                            ('scaler', StandardScaler())]
                    ) #数值型变量采用均值填充和标准化
preprocessor = ColumnTransformer(transformers = [('less_cat', less_cat_transform, less_cat_col),
                                        ('more_cat', more_cat_transform, more_cat_col),
                                    ('num', num_transform, num_col)]
                            ) #不同的预处理步骤打包到一起
model = GradientBoostingRegressor(n_estimators = 500, learning_rate = 0.05, max_depth = 9,  min_samples_leaf= 3, random_state=0) # 模型初始化
pipe = Pipeline(steps=[('preprocessing', preprocessor),
                ('model', model)]
            )
pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_test)

RMSPE = math.sqrt(sum([((x - y)/x) ** 2 for x, y in zip(y_test, y_pred)]) / len(y_test)) #均方根百分比误差
score = pipe.score(X_test, y_test)
print("Root Mean Square Percentage Error: {}, and model score: {}".format(RMSPE, score))
with open(r"D:\项目\商简智能\回归预测题目\sales_predict.pickle", "wb") as model_file: #保存model/
    pickle.dump(pipe, model_file)

# model = GradientBoostingRegressor(random_state=0) #
# pipe = Pipeline(steps=[('preprocessing', preprocessor),
#                 ('model', model)]
#             )
# params = {
#     'model__n_estimators':[100, 200, 300],
#     'model__learning_rate':[0.01, 0.05, 0.1, 0.2],
#     'model__max_depth': [3, 5, 7, 9,],
#     'model__max_features':[9, 11, 14],
#     'model__min_samples_leaf': [1, 2, 3]
# }
# gs = GridSearchCV(pipe, param_grid = params)
# gs.fit(X_train, y_train)
# print(gs.best_params_)
# y_pred = gs.best_estimator_.predict(X_test)
# RMSPE = math.sqrt(sum([((x - y)/x) ** 2 for x, y in zip(y_test, y_pred)]) / len(y_test)) #均方根百分比误差
# score = gs.score(X_test, y_test)
# print("Root Mean Square Percentage Error: {}, and model score: {}".format(RMSPE, score))

评估

按照以往的业务经验,采用均方根百分比误差 (Root Mean Square Percentage Error, RMSPE) 指标作为评价标准会比较好,公式如下:
R M S P E = 1 n ∑ i = 1 n ( y i − y ^ i y i ) 2 R M S P E=\sqrt{\frac{1}{n} \sum_{i=1}^n\left(\frac{y_i-\hat{y}_i}{y_i}\right)^2} RMSPE=n1i=1n(yiyiy^i)2

  • 其中 y i y_i yi 代表门店当天的真实销售额, y ^ i \hat{y}_i y^i 代表相对应的预测销售额, n n n 代表样本的数量。

  • 如果真实销售额为 0 ,计算误差时可忽略该条数据。

  • R M S P E RMSPE RMSPE 值越小代表误差就越小,评分越高。

本案例在测试集上的模型得分和均方根百分比误差如下

Root Mean Square Percentage Error: 0.10308496736657641, and model score: 0.9485827177221499

深度学习方法

后续有机会再补上

代码

评估

建议

参考文献

1,https://blog.csdn.net/hba646333407/article/details/128529557
2,https://mp.weixin.qq.com/s/Zdx3gcgEoT_VyfPdrNKAGw

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/196791.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(十二) Docker-compose容器编排

Docker-compose一、概述1、简介2、作用3、下载二、核心概念三、使用步骤四、Compose常用命令五、Compose编排微服务实践一、构建项目的镜像1、建立数据库表2、POM文件3、YAML4、主启动类5、业务类1、生成简易代码2、配置类3、实体类4、Mapper5、Service6、Controller6、打 Jar …

3.SQL

梳理 名词解释 视图&#xff1a;视图是一个虚表&#xff0c;其本质就是一条SELECT语句&#xff0c;而查询结果被赋予了一个名字&#xff0c;也即视图名字。或者说视图本身不包含任何数据&#xff0c;它只包含映射到基表的一个查询语句&#xff0c;当基表数据发生变化时&#x…

【JavaGuide面试总结】Spring篇·中

【JavaGuide面试总结】Spring篇中1.谈谈自己对于 AOP 的了解2.Spring AOP 和 AspectJ AOP 有什么区别&#xff1f;3.AspectJ 定义的通知类型有哪些&#xff1f;4.Spring AOP多个切面的执行顺序如何控制&#xff1f;5.说说自己对于 Spring MVC 了解?6.Spring MVC 的核心组件有哪…

企业数字化转型的五大关键要素

数字化转型是顺应新一轮科技革命和产业变革趋势&#xff0c;不断深化应用云计算、大数据、物联网、人工智能、区块链等新一代信息技术&#xff0c;激发数据要素创新驱动潜能&#xff0c;打造提升信息时代生存和发展能力&#xff0c;加速业务优化升级和创新转型&#xff0c;改造…

软测(概念) · 开发模型 · 软件的生命周期 · 瀑布模型 · 螺线模型 · 增量模型 · 迭代模型 · 敏捷模型 · scrum

一、开发模型的由来二、软件的生命周期三、瀑布模型&#xff08;Waterfall Model&#xff09;四、螺线模型&#xff08;Spiral Model&#xff09;五、增量模型&#xff08;Incremental Model&#xff09;六、迭代模型&#xff08;Rational UnifiedProcess&#xff09;七、敏捷模…

daz ue和maya插件配置

daz ue插件配置用这个插件方便导入材质&#xff0c;毕竟材质球还是挺多的我安装的时候DAZ Install Manager需要定位&#xff0c;没成功就直接用dll放在daz安装里面也可以直接用&#xff0c;daz ue插件放在插件目录daz maya2022插件配置首先用DAZ Install Manager安装daz maya插…

进程间通信之共享内存(简单介绍消息队列和信号量)

进程间通信之共享内存system V共享内存共享内存示意图常见的共享内存操作共享内存数据结构共享内存函数消息队列信号量&#x1f4cc;————本章重点————&#x1f4cc; &#x1f517;基本掌握system V共享内存的使用方法 &#x1f517;了解消息队列&#x1f517;了解信号量…

vue v-model的详细介绍

v-model是什么&#xff1f; v-model 是Vue框架的一种内置的API指令&#xff0c;本质是一种语法糖写法。它负责监听用户的输入事件以更新数据&#xff0c;并对一些极端场景进行一些特殊处理 为什么使用v-model&#xff1f; v-model指令可以在表单input、textarea以及select元素上…

Power BI中如何实现移动平均功能

一、移动平均 移动平均&#xff0c;是一种常用的统计分析方法&#xff0c;它是指将一定时间范围内的数据&#xff0c;按一定的时间间间隔进行计算平均&#xff0c;然后将平均值形成一条折线。常用的时间间隔有10天、20天、30天、60天等。 当原数据折线图波动比较大时&#xff…

利用GPAC生成MP4文件

GPAC主要针对学生和内容创作者&#xff0c;代表了一个跨平台的多媒体框架&#xff0c;开发人员可以使用它在 LGPL 许可下制作开源媒体。GPAC多媒体框架兼容范围广泛的流行文件类型&#xff0c;从常见格式(如 AVI、MPEG 和 MOV)到复杂格式(如 MPEG-4 系统或 VRML/X3D)和 360 电影…

哈工大机器学习复习笔记(二)

本篇文章是在参考西瓜书、PPT课件、网络上相关博客等资料的基础上整理出的机器学习复习笔记&#xff0c;希望能给大家的机器学习复习提供帮助。这篇笔记只是复习的一个参考&#xff0c;大家一定要结合书本、PPT来进行复习&#xff0c;有些公式的推导最好能够自己演算一遍。由于…

JVM结构 类加载

类加载 类加载子系统 类加载器子系统负责从文件系统或者网络中加载class文件。classLoadr只负责class文件的加载&#xff0c;至于它是否可以运行&#xff0c;则由Exception Engine&#xff08;执行引擎&#xff09;决定。加载类的信息存放于一块成为方法区的内存空间 class fi…

【GPLT 二阶题目集】L2-007 家庭房产

给定每个人的家庭成员和其自己名下的房产&#xff0c;请你统计出每个家庭的人口数、人均房产面积及房产套数。 输入格式&#xff1a; 输入第一行给出一个正整数N&#xff08;≤1000&#xff09;&#xff0c;随后N行&#xff0c;每行按下列格式给出一个人的房产&#xff1a; 编号…

Java创建线程的七种方法,全网最全面总结~

目录 前言 一、继承Thread&#xff0c;重写run方法 二、实现Runnable接口&#xff0c;重写run方法 三、使用匿名内部类创建 Thread 子类对象 四、使用匿名内部类&#xff0c;实现Runnable接口 五、lambda表达式 六、实现Callable接口 七、使用线程池创建线程 前言 属于基…

末端工具重力辨识

辨识工具重力 法一&#xff1a;6点标定 已知&#xff0c;工件重力在世界坐标系的大小为{0,0,−G}\{0,0,-G\}{0,0,−G},假设工件重心在工具坐标系下的坐标为 {Lx,Ly,Lz}\{L_x,L_y,L_z\}{Lx​,Ly​,Lz​}&#xff0c;重力在工件的三个坐标轴分量为 {Gx,Gy,Gz}\{G_x,G_y,G_z\}{G…

Docker安装MySQL8数据库

&#x1f388; 作者&#xff1a;互联网-小啊宇 &#x1f388; 简介&#xff1a; CSDN 运维领域创作者、阿里云专家博主。目前从事 Kubernetes运维相关工作&#xff0c;擅长Linux系统运维、开源监控软件维护、Kubernetes容器技术、CI/CD持续集成、自动化运维、开源软件部署维护…

为什么要拒绝嵌套代码?

linux 内核的最早作者 linus torvalds 在 linux 内核样式指南 第一节中提到&#xff1a; if you need more than 3 levels of indentation, you’re screwed anyway, and should fix your program. 如果你需要超过3级的缩进&#xff0c;你无论如何都搞砸了&#xff0c;应该修复…

ABBYY15免费照片识别文字识别软件

照片识别文字的软件有哪些&#xff1f;在日常的工作的时候&#xff0c;小伙伴们是不是经常会借助拍摄照片记录一些比较重要的事情或者是一些比较重要的笔记&#xff0c;等回头空闲出来的时候在去整理&#xff0c;那么这时候&#xff0c;如果我们运用好图片识别文字这项技术&…

线性代数篇

主线为花书第二章-线性代数&#xff0c;但其上面一些表述属实费解&#xff0c;于是参考B站3Blue1Brown线性代数和B站同济子豪兄的视频讲解。 先放一句3B1B的话共勉&#xff0c;伙计们不要被数学公式吓到&#xff0c;慢慢钻研&#xff0c;慢慢推肯定能学懂。线性代数这一部分相信…

cannot redeclare block-scoped variable

使用 Vue3.0 的时在模块类中声明方法的时候抛出了如下的异常:cannot redeclare block-scoped variable解决办法检查是否集成了 Vetur 插件,若存在禁用或卸载即可,该插件Vue3.0 的时候会冲突;Vue3.0 集成如下两款即可:名称: TypeScript Vue Plugin (Volar)ID: Vue.vscode-typesc…