Anders Wang


我所认识的每个人都是榜样,都有值得我去尊敬和学习的地方。


Kaggle - Rossmann Store Sales 销量预测项目

本篇内容大纲目录如下[支持页内跳转]:

I. 问题的定义
II. 分析
III. 方法
IV. 结果
V. 项目结论

I. 问题的定义

项目概述

无论是飞速发展的互联网电商行业还是传统的零售行业,销售预测在企业的整个运营体系中都是必不可少的环节。所谓销售预测,是在对影响市场供求变化的众多因素上进行系统地调查和研究,并在此基础上运用科学的方法对未来市场产品的供需发展趋势以及有关的各种因素的变化,进行分析、预见、估计和判断。传统的销售预测方法往往只考虑了一部分影响销售的因素,其建立的模型也相对简单。而数据挖掘技术是一种科学有效的数据处理方式,它为应对信息爆炸,海量信息的处理提供了科学有效的手段。计算机数据挖掘技术顺应了时代和社会的发展,也逐渐成为社会关注的焦点。为了优化企业商品销售决策方案,提高商品销售预测的准确率,应用数据挖掘方法对销售数据库进行分析,提高销售预测的准确率无疑是十分有意义的。麻省理工学院(MIT)和宾夕法尼亚大学(University of Pennsylvania)的经济学家进行的一项研究发现,在数据驱动的决策规模上,一个标准差高的公司生产率高5%,利润高6%,市值高50%。

本项目是Kaggle1上的一个数据科学竞赛项目,项目的目的是通过由一家名为Rossmann的公司所提供的往年销售数据,运用机器学习的手段进行数据挖掘并构建出一个高效和尽可能精准的数据预测模型,通过这个模型以后只需要输入相关特征信息就可以预测未来一段时间内的销售额。相对于传统低效而又不精准的人工销售预测方式,对于Rossmann这样一家拥有3500家门店、47500名员工、2015年销售收入79亿欧元的公司来说,通过这个数据模型来预测未来一定时间段内的销售额,相信这对公司的市场战略把握和对门店方面的管理来说是非常有价值的。2

问题陈述

Rossmann是德国最大的日化用品超市,它在欧洲7个国家拥有超过3500家的连锁商店。当前,为了更加有效地管理采购和库存,Rossmann商店的门店经理有一项重要的任务就是预测未来6周时间内每家分店的每日销售额。而商店的销售额会受到很多因素的影响,其中包括促销活动、竞争对手、节假日和一些季节性和局部的因素。

我们需要通过Rossmann公司所提供的1115家门店的历史销售数据来训练和测试一个最佳销售预测模型,这个模型最终可以用来预测未来一段时间内接近真实销售额的数据。

预测销售额这在机器学习中属于一个回归性问题,其本质就是构建一个最佳映射函数 $\hat{y}=f(x)$,既给定任意新的输入变量来预测输出变量值。在这里,x 为输入变量,变量经过函数 $f$ 后预测输出最终的销售额 $\hat{y}$。预测建模主要关注的是如何最小化模型的误差,这里的误差则通过真实的销售额 $y$ 值与预测的销售额 $\hat{y}$ 之间的差值来评估。

评价指标

模型所采纳的评估指标为Kaggle在竞赛中所推荐的 Root Mean Square Percentage Error (RMSPE) 指标。

$RMSPE = \sqrt{\frac{1}{n}\sum\limits_{i=1}^n\left(\frac{y_i-\hat{y}_i}{y_i}\right)^2} = \sqrt{\frac{1}{n}\sum\limits_{i=1}^n\left(\frac{\hat{y}_i}{{y}_i}-1\right)^2}$

其中 $y_i$ 代表门店当天的真实销售额,$\hat{y}_i$ 代表相对应的预测销售额,$n$ 代表样本的数量。如果有任何一天的销售额为0,那么将会被忽略。最后计算得到的这个RMSPE值越小代表误差就越小,相应就会获得更高的评分。

II. 分析

数据的探索

Rossmann所提供的数据可以到Kaggle网站上下载3,下载的数据包中一共包含四个文件,分别是train.csv, test.csv, store.csv, sample_submission.csv,这几个文件的相关描述如下。

train.csv 数据集文件共有 1,017,209 个数据样本(由 9列 x 1017209行 数据组成),是用于训练模型的数据集。其中包含了1115家商店从 2013年1月1日 至 2015年7月31日 范围内每家商店每天销售的相关信息,例如有当天是否营业、当天的顾客数量、是否参加促销、当天的销售额,等信息。其中有180家商店缺少从2014年7月1日至 2014年12月31日约半年的数据。

要说明一点是,其中存在的Sales字段就是我们用于训练的预测数据标签,其余的字段信息将归类于特征数据,但最终需要经过一定特征工程处理后用来作为模型的训练输入数据。

(train.csv数据集示例部分如下)

store.csv 数据集文件共有 1115 个数据样本(由 10列 x 1115行 数据组成),其中包含了对应1115家门店的额外补充信息,例如有商店等级、商店类型、与附近的竞争对手商店,等相关信息。

提示:由于原始字段的长度不易于排版展示,所以对某些字段里的部分单词进行了缩写展示,如:CompetitionOpenSince缩写为COS、Promo2Since缩写为P2S。

(store.csv数据集示例部分如下)

test.csv 数据集文件共有 41,088 个数据样本(由 8列 x 41088行 数据组成),其中包含了1115家商店从 2015年8月1日 至 2015年9月17日 范围内每家商店每天销售的相关信息,包含的信息与 train.csv 数据集类似,仅仅区别是其中剔除了Sales销售额字段,因为这是一个独立的测试数据集,用来测试我们的模型最终得分。由于真实的销售额并没有在数据集中公开,所以在进行模型最终测试后预测出来的结果(销售额)最终需要上传到Kaggle网站上才能看到实际得分排名。

(test.csv数据集示例部分如下)

samplesubmission.csv 作用是提供一个上传到Kaggle测试评分的标准格式文件,也就是基于之前提到的预测模型与test.csv 测试集文件所测试出来的预测数据,并把这个预测数据以按照 samplesubmission.csv 的格式上传到Kaggle上。

(sample_submission.csv数据集示例部分如下)

考虑到数据预处理在进行机器学习训练数据前是非常重要的一个步骤,经过技术手段初步筛查、统计后发现:在train.csv数据集中一共有172,871个样本销售额为0,但其中有54个销售额为0的样本当天属于营业状态。在store.csv数据集中字段名为 CompetitionDistance 缺失值有 3 个,CompetitionOpenSinceMonth和CompetitionOpenSinceYear 缺失值 354 个,Promo2SinceWeek和Promo2SinceYear和PromoInterval 缺失值 544 个。在test.csv数据集中Open字段中存在 11 个缺失值。在后面数据预处理环节,我们会对这部分缺失的数据和异常值的进行预处理。

在所有这些数据集中,大部分字段的含义都是一目了然的。另外,仍然有一些需要说明的数据字段,包括如下:

探索性可视化

在项目的早期阶段,我们已经大致弄清楚如何构建数据,确定如何操纵可用的数据以获得所需的答案,比如包括获取对数据的直觉、比较变量的分布、对数据进行检查、发现数据中的缺失值和异常值等。

而通过可视化去探索数据也是数据分析工作中的重要组成部分。在庞大的数据面前,通过图形的方式去呈现数据分析的结论,可以帮助我们更加直观的理解数据。

  • 所有数据样本的销售额分布情况

img1

图1:所有数据样本销售额分布情况

如上,图1 左小图展示的是在训练集中,所有数据样本的销售额的分布情况。从图中可以观测到,数据主要是左偏态分布的情况,销售额为0的样本量非常高,接近竖轴刻度标记的17500数值。除此以外,从局部看剩下的大部分数据形成了一个小正态分布,从蓝色柱状图比例看大致集中的范围在0到15000。为了便于观测,我将销售额集中的区域进行了选取放大。如上图中,右小图是基于左小图进行了缩放后的结果,可以发现销售额在5000左右的样本量频率是最高的,也就是说大约有125000个样本量数据它们所产生的消费额在5000左右。

为了进一步探究为什么之前显示销售额为0的样本量非常高,我将所有销售为0的数据筛选出来,进行了查询分类并做了可视化,如下图。

img1

图2:销售额为0的情况

从 图2 左小图中可以发现,可以说几乎占比100%的商店由于没有营业属于休业状态才导致了销售为0。由于在之前的数据探索部分,我已经通过技术手段筛查出所有销售额为0的数据,并从数据中发现了在超过17万个样本中仅仅只有54个样本显示销售额为0但是商店是属于营业状态的。初步认为,这种极小的情况是合理的,因为不管当天有没有顾客访问商店,当天没有产生实际销售额的情况也是有可能的。同时,为了可视化能更清晰的查看,右小图通过缩放范围来展示。

  • 促销对销售额的影响

img1

图3:促销对销售额产生的影响

图3 使用小提琴图形的方式展示了每周几中某一天,进行促销与不促销对销售额产生的影响。可以很清楚的发现进行了促销活动后的商店销售额(橙色)明显高于没有进行促销的商店。我们还可以发现一个特别的现象,在周六和周日,商店均没有开展过促销活动。且周日的销售额非常低,这也是符合逻辑的,因为在德国,绝大多数情况下 (除了节假日前后),绝大部分商店都是不营业的,因此总的销售额会远低于工作日以及周六。

另外,从图上可以发现小提琴图的顶端非常高,说明样本存在很高的异常值区间,我们会在后面数据处理环节进行处理。

  • 销售与竞争对手商店距离的影响

img0006

图4:促销对销售额产生的影响

考虑到store.csv数据集是对商店相关信息的额外补充,为了探索潜在的数据信息,所以我将store.csv数据集和train.csv数据集进行了合并,并对 商店的销售额 与 附近竞争对手商店的距离(也就是数据集里的CompetitionDistance字段)进行了一个可视化输出,从 图4 展示可以发现并没有因为竞争对手离Rossmann商店的距离越远,Rossmann商店的消费额就变多,所以没有产生什么影响(其中要说明的是,由于总样本数据超过百万数量,为了方便展示所以我抽取了1%的数据点在不影响分布的情况下进行展示。以及原点的颜色越深代表该样本量的销售额越高,原点的大小越大代表该样本的顾客量越大)。相反离竞争对手越近的一些商店它的销售额都很高。

  • 销售额与顾客数量之间的关系

img0012

图5:销售额与顾客数量

图5 第一二两张子图分别展示了 不同商店的销售额分布 与 不同商店的顾客数量分布。从两张图的比对结果可以发现,当第一张子图中每家商店对应的销售额增高时,第二张子图中相同区域的顾客数量也出现一定峰值,所以可以考虑给为数据集增加一个 人均消费 (PerCustomerSale字段) 。第三张子图展现的是不同商店的人均消费分布,我们可以通过观察大致发现在人均消费分布上并没有之前两张子图显示的波动明显,相对适中。

最后从第一二张子图与第三张子图对应的人均消费来看,峰值区域没有形成相互对应,说明在人均消费额差距不大的情况下,几家商店销售额的突出是以跑量的方式换来的。

  • 销售额与商店类型之间的关系

img0005

图6:商店类型与销售额

销售额的多少也可能与商店的类型有一定关联,所以我对不同商店类型的累积销售额进行了分类统计。如 图6 所示,a类型商店的累积销售额远远超过b类型商店。

  • 假期对销售额的影响

img0007

图7:假期与销售额

图7 显示了国定假日与学校放假时对销售额的影响情况,可以观察发现,国定假日期间的销售额有一定的提升说明假日对销售额是有一定影响的。而学校放假与不放假对销售额几乎没有多少影响。

  • 2013~2015年中每月的销售额分布情况

因为数据集中包含了不同时间年份的数据,为了根据不同日期维度来统计信息,我将日期(Date字段)进行了分割处理,其中由于训练集的数据只包含时间跨度为 2013年1月1日 至 2015年7月31日 的范围,所以2015年8月份以后的数据并没有显示。

img0008

图8:每月的销售额分布

如上图,显示了2013到2015年三年中每个月的销售额分布情况。可以发现销售额在12月份时会比之前几个月有一个很明显的回升趋势。考虑到12月份正值国外各种节假日与新年,所以是会提高一定销售额。

算法和技术

最初,考虑的是决策树回归作为基准模型,但是观察看到许多商店的销售模式明显偏离了平均行为,一个单一的模型将很难处理这些商店提供的所有特殊情况,以及考虑到在Kaggle上得分比较高的模型算法都使用了XGBoost集成算法。所以我认为集成大量模型的方法最适合在当前的情况下进行预测,在这里将XGBoost作为目标模型。

决策树回归使用的是 CART 算法,既可用于分类也可用于回归,如果待预测结果是连续型数据,则 CART 生成回归决 策树。区别于 ID3 和 C4.5,CART 假设决策树是二叉树,回归树选取 Gainσ为评 价分裂属性的指标。选择具有最小 Gainσ的属性及其属性值作为最优分裂属性 以及最优分裂属性值。Gain_σ值越小,说明二分之后的子样本的“差异性”越小,说明选择该值作为分裂值的效果越好7

XGBoost是集成学习中 Boosting 流派中的其中一种算法,其本质上还是一个 GBDT,XGBoost与GDBT的区别主要有12

  1. XGBoost生成CART树考虑了树的复杂度,GDBT未考虑,GDBT在树的剪枝步骤中考虑了树的复杂度。

  2. XGBoost是拟合上一轮损失函数的二阶泰勒展开,GDBT是拟合上一轮损失函数的一阶泰勒展开,因此,XGBoost的准确性更高,且满足相同的训练效果,需要的迭代次数更少。

  3. XGBoost与GDBT都是逐次迭代来提高模型性能,但是XGBoost在选取最佳切分点时可以开启多线程进行,大大提高了运行速度。

XGBoost核心算法原理基本为:

(1)不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数,去拟合上次预测的残差。

(2)当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数。

(3)最后只需要将每棵树对应的分数加起来就是该样本的预测值。8

基准模型

预测销售额是一个定量的数值,所以使用回归模型而不是分类模型。由于这个项目与波士顿房价(Boston Housing)项目比较类似都是属于回归预测的问题,而且波士顿房价项目作为入门项目,其中所用到的模型简单易于理解,所以这里决定选用决策树作为基准模型。可以通过引入 sklearn 库中的 DecisionTreeRegressor模块来创建一个回归决策树模型,然后用网格搜索训练法指定不同的参数组合,把所有可能的组合生成网格,然后用交叉验证进行评估,最后遍历寻找出最优的模型参数,使用这个最优参数得到的 RMSPE 得分即基准模型的分数。

III. 方法

数据预处理

在训练一个模型之前需要做数据的预处理,数据预处理的目的是为了保证数据的质量,以便能够更好的为后续的分析、建模工作服务,因为模型的最终效果决定于数据的质量和数据中蕴含的有用信息的数量。通常在拿到数据以后,首先要判断此数据是否可为我们所用,也就是我们根据需求目标所拿到的数据的质量是否过关。3

在之前的数据的探索环节,已经提到过在正式训练模型前有一些前提准备工作要做。如,解决数据的不一致,用合理的值替换缺失值,删除不必要的数据,将分类变量转换为数值,检查异常值并纠正等。下面我将对这些处理的步骤进行描述。

  • 数据集合并

在之前的数据的探索环节已经提及到为了更好的探索数据,考虑到store.csv数据集是对商店相关信息的额外补充,所以已经使用pandas模块库将store.csv数据集和train.csv数据集进行了成功合并。

在合并时考虑到store.csv数据集包含了1115家商铺信息正好与train.csv里的1115家商店编号标签吻合,所以我使用pandas.DataFrame.merge函数并设置on参数来合并,on参数值就是用于指定连接两个数据表的相同列名,这里设置为(on="Store")

  • 数据不一致与缺失值处理

在之前的(图2)探索性可视化部分,从数据中探索出了超过17万个数据样本因为门店是休业状态所以销售额为0,但是其中依然有45家门店为营业状态而销售额也是0。据Kaggle推测,这在某些情况下是由于商店进行了改造,或进行了试营业,实际上并没有向公众开放。所以我将这45家销售额为0的门店的Open状态从营业更改为休业状态(Open = 1改为Open = 0),这样它们就不会对预测模型构建产生负面影响。4

接着是对缺失值的处理,通过对缺失值筛查后发现在store.csv数据集中字段名为 CompetitionDistance 缺失值有 3 个,CompetitionOpenSinceMonth和CompetitionOpenSinceYear 缺失值 354 个,Promo2SinceWeek和Promo2SinceYear和PromoInterval 缺失值 544 个。在test.csv数据集中Open字段中存在 11 个缺失值。处理缺失值的方式有很多,必须要以分析环境和模型的需求来考虑。通常在数据量很多的情况下可以考虑删除法来删除整行数据,也可以考虑数据填补补齐的方式使数据表更加完备。因为已经提前将store.csv与train.csv两个数据表进行了整合,再次查看显示的缺失值信息与单独查看store数据集的空值会多很多,在这里我选择填补的方式进行缺失值处理。我分别对CompetitionOpenSinceMonth、CompetitionOpenSinceYear、Promo2SinceWeek、Promo2SinceYear进行了中位数的填充。

  • 检测并处理异常值

异常值会大幅度地改变数据分析和统计建模的结果。检测异常值的方法有许多,这里我使用了箱线图的四分位距(IQR)对异常值进行检测5,也叫Tukey's Test,下图(图9)就是箱线图去除异常值的原理。

IQR

图9:箱线图

箱线图中间是一个箱体,也就是粉红色部分,箱体左边,中间,右边分别有一条线,左边是下四分位数(Q1),右边是上四分位数(Q3),中间是中位数(Median),上下四分位数之差是四分位距(称IQR),IQR也可以说指的是两个四分值之间的范围大小。用 Q1-1.5*IQR 得到下边缘(最小值),Q3+1.5*IQR 得到上边缘(最大值),在上边缘之外的数据就是极大异常值,在下边缘之外的数据极小异常值,总之在上下边缘之外的数据就是异常值。另外要说明的是图中的数值 1.5 是一个可变的系数,表示的是中度异常;对于重度异常的情况,可以视情况而定将系数提高至 3。

我在处理异常值时预先使用了常规的中度异常系数1.5去实现箱线图最小值与最大值的划分。经过异常值处理后保留了990,515个样本数据,正常数据保留占比约97.37%,去除了约2.63%的异常数据,所以对整体的数据质量不会产生多少影响。

  • 时间格式字段分离处理

在数据集中Date字段默认显示的时间格式为年-月-日,这个格式的数据是不能在机器学习中直接被处理的,所以需要进行一个时间格式的字段分离处理,这里直接单独分离为年(Year)、月(Month)、日(Day)三个新字段变量。同时去除原始的Date日期字段变量数据。

  • 数据类型转换

对于一些特殊字段它们的值是a、b、c、d,为了使模型能够顺利对它们进行处理,分别修改为对应的1、2、3、4。

执行过程

在本项目中,如之前的算法和技术环节提到,我使用了两个模型进行销售额预测分别为DecisionTreeRegressor作为基准模型以及XGboost作为目标模型。

  • 数据探索

在训练模型前将所有原始数据进行数据探索与可视化探索,从而可以进一步发现各类数据变量之间的关联和潜在信息。

  • 数据清洗与特征工程

这个项目存在多个数据集文件,所以在进一步数据探索后进行数据集文件的合并,由于数据集的合并产生新的特征信息,结合特供工程化处理对特征变量进行了构建补充与删除。

  • 定义评价函数

基于本项目推荐使用的RMSPE评价指标,所以定义了RMSPE函数来作为模型的预测结果评分。

  • 构建数据模型并预测

在构建模型前先需要划分训练模型和验证模型的必备数据,而测试数据集test.csv已经额外提供给我们,所以可以将train.csv中的数据全部都用来训练,换句话说,只需要将train.csv中的数据分为训练集和验证集。考虑到这个项目属于一个有关时间序列的预测类问题,因为这是和时间序列有关的数据集,所以我将train.csv训练集数据进行了细分,按照时间顺序划分验证集和训练集,其中取最后6周时间作为验证集,剩下的为训练集。

接着是对模型的参数定义,DecisionTreeRegressor的参数定义是我鉴于在曾经用机器学习预测波士顿房价(Boston Housing)项目时的经验,使用了网格化搜索指定不同的参数组合的方式来选择最优参数。

对于XGBoost我之前并不了解,XGBoost模型有许多参数可以设置,我参考了Kaggle和其它资料进行了参数的指定6。因为在构建模型过程中定义了RMSPE评估函数,所以将参考最优的train eval rmspe的得分来决定最终模型。为了得到最低的RMSPE得分,我对参数进行了一定调整其中调整最多的是eta参数,这个参数可以理解为是学习速率,我将eta从0.03调整为0.01后发现迭代的次数也逐步增加,在eta为0.03时2900次就终止了迭代,当设置为0.01后迭代次数增加,直到6000次才停止,花费了更多的训练迭代次数,也味着要花很长时间才会收敛。最后我根据最优的RMSPE得分设定eta为0.02训练了出最终模型。最后,用这个模型进行对项目提供的test.csv测试集进行预测,预测的值同时会乘以权重因子以得到更精确的预测值(权重因子参考Kaggle10),然后提交的到Kaggle进行最终评测。

要说明的一点是,关于模型的调参其实可以选择GridSearch方式来选择一系列最佳参数,在本项目中考虑到当前的模型得分已经满足条件,所以受限于时间和运算能力的情况下我并没有最终使用GridSearch来进行参数优化。

完善

在XGBoost模型测试的过程中,我在参考了网上以及Kaggle上一些资料后,曾尝试调整增加了一些看似有用的特征,但发现在上传到Kaggle后最终模型的预测得分却反而非常不理想。然后在参数选择方面,一开始是使用默认的参数,发现训练结果一直存在不少的过拟合现象,本地的RMSPE得分非常不错,但是上传到Kaggle上最终预测时十分不理想。然后通过查阅资料9在XGBoost中调整参数(Complete Guide to Parameter Tuning in XGBoost with codes in Python),在参数调整后尽管得分有了一定的上升,但是我发觉经过多次的迭代后上升的幅度很小。于是我开始尝试在特征组合选取方面进行改动,发现特征的改动极大的使得分出现了改变。 所以,如果要进一步提高预测的精度,我认为未来应该需要重点在特征工程和 Xgboost 的调参上下更多功夫。

IV. 结果

模型的评价与验证

DecisionTreeRegressor模型使用网格化搜索对参数maxdepth, minsamplesleaf参数进行了搜索选择了,maxdepth = 20,minsamplesleaf = 6 为最优参数,使用这些参数建立的模型的最终训练集RMSPE得分是 0.21064,Kaggle最终得为0.63305。XGBoost的本地测试集得分为0.084679,Kaggle最终得分为0.11170,存在一定过拟合现象,但XGBoost依然优于DecisionTreeRegressor。

合理性分析

因为这是 Kaggle 上的一个竞赛,而且项目中提供的test.csv文件是一个独立的测试数据集,在一开始的test.csv作用描述中提到过它是用来测试模型的最终得分。由于真实的销售额并没有在数据集中公开,所以在进行模型最终测试后预测出来的结果(销售额)最终需要上传到Kaggle网站上才能看到实际得分排名。

对于DecisionTreeRegressor模型我多次测试下来本地的R2分数在0.2左右,通过上传到Kaggle后最好得分一直徘徊在0.63上下。而使用XGBoost的算法模型一开始并没有得到理想的得分,通过参考Kaggle上的资料10以及对特征变量的持续优化后,我得到了符合预期的RMSPE得分并在Kaggle上的Private Score得分最好的为0.11170,显然XGBoost作为目标模型是优于DecisionTreeRegressor。同时也已经满足项目要求的达到Top 10%。

result

V. 项目结论

结果可视化

图10展现了预测模型构建好之后的特征重要性,从图中看出 有关于时间的Day、PromoOpen 与 Store 这几特征的分数远高于其他特征。在构建模型的过程中我尝试调整了许多特征,但这几个特征的重要性一直都比较高,可以从这些特征中了解到销售额的高低与不同商店的类型和时间以及附近竞争对手开业的时间有极大的关系。

img0014

图10:特征重要性

对项目的思考

尽管之前做过类似几个价格预测的项目,但是更多的是带有引导性去完成。通过这个数据挖掘项目,从头到尾拿到原始数据去构建整个分析和建模的过程,使我对整个数据挖掘的过程有了更清晰的认识。如:了解行业领域背景、数据探索、数据预处理、数据特征工程、模型的选择、模型的评价、最终验证。

基于时间问题,很多探索性测试没有完全去尝试,可以考虑把原来删除的异常值,用反预测的方式,去预测那些应该被删除的异常值数据他们原始的正常值应该是多少,这样在保持数据更齐全的情况下再去构建预测模型可能效果更好。

另外,从Kaggle上提交的分数排名看大家的分数之间差距并不是太大,也就是说大家在方法使用上,或者数据理解上,基本上差异性很小。而且基本上都使用了最好的XGBoost模型,可能在具体的尝试过程中,由于数据的准备不同才带来了一些细微差异。我们也并没有看到出现那种差距极大的队伍出现,也许提供的数据本身就代表了这个项目得分的局限性。因为在这个项目中可能存在更多潜在未知的信息可以影响模型的预测精准性,如当天天气变化情况,当地国情等。

需要作出的改进

在这个项目中依然还有特别多需要改进和完善的地方,比如数据探索的可视化部分,如果先从行业背景角度去理解然后再分析数据的关联性,结合之前的行业背景信息逐步推理相信可以进一步挖掘潜在的信息。而且这也为后续的特征工程构建和删除特征时可以提供更进一步的合理支撑。

在模型方面也可以尝试比其他优秀的Boosting类模型,如LightGBM,LightGBM是个快速的、分布式的、高性能的基于决策树算法的梯度提升框架,在速度上比XGBoost更快。11

在特征选取方面,我认为特征的选择对模型的影响也是巨大的,在测试模型的过程中,我尝试了多种特征组合得到了非常大的分数反差,所以特征选择这块依然有很大的改进空间。考虑到Kaggle在讨论区里也有提供额外相关数据,例如各个药店所在的州统计的天气和降雨量数据等,通过增加更多的特征维度提升模型的精准度。

对于算法参数的改进,XGBoost是在数据分析中比较流行的集成算法,对于这个算法的很多参数我还没有很好的去理解,所以由于我的参数选择可能不是很合理导致模型最终得分并不十分理想,调参方面可以考虑使用GridSearchCV或者RandomizedSearchCV来进行合理参数的选择。

参考文献

最近的文章

COVID-19疫情数据动态排行

很久之前,我在抖音app上看到有用动态的数据排行效果来展示各种经济,人口增长等数据,非常震撼又很有视觉直观性。而2020年疫情爆发期时的每日疫情数据又是大家最关心的。所以我就想着自己仿造类似的效果。…

Python, 技术博文, 数据分析详细阅读
更早的文章

数据处理 - 异常值分析及可视化

异常值(Outlier) 是指样本中的个别值,其数值明显偏离所属样本的其余观测值。大多数情况下,异常值是由于数据录入或者数据后台数据运算错误导致。但是要说明的一点,异常值只是代表这个值属于异常而不一定…

Python, 技术博文, 数据分析详细阅读
comments powered by Disqus