代码主要包含4个开发用的ipython notebook
### 历史信息 Rossmann是欧洲的一家连锁药店,在7个欧洲国家拥有3,000家药店。 目前,罗斯曼店经理的任务是提前六周预测其日销量。 商店销售受到诸多因素的影响,包括促销,竞争,学校和国家假日,季节性和地点。 成千上万的个人经理根据其独特的情况预测销售量,结果的准确性可能会有很大的变化。
Rossmann希望你能通过给出的数据来预测德国各地1,115家店铺的6周销量。
在此次项目中,我将模拟自己参加kaggle比赛,用train.csv来建模,之后用test.csv来预测,通过提交到 Kaggle来评估模型表现。
### 项目意义 可靠的销售预测使商店经理能够创建有效的员工时间表,从而提高生产力和动力,比如更好的调整供应链和合理的促销策略与竞争策略。 通过帮助Rossmann创建一个强大的预测模型,您将帮助仓库管理人员专注于对他们最重要的内容:客户和团队!
### 实现可能性 Rossmann给出的数据足够丰富,并且各个特征都和销售有关系。这是一个明显的监督学习的项目,有有标签的数据集。
### 引用说明 最后会用到xgboost这个现成的混合模型,不仅运算速度快,而且集成了一系列算法。因为源码涉及大量C语音因此没有太看懂,主要参见了几个大神的博客,了解了xgboost的运行原理以及此模型的参数设置与调整方案。
以上数据都由kaggle提供,没有引入其他的数据集,因为这个问题比较特定并且已经足够充分了,不像自然语言处理类需要额外的数据
根据不同的特征的情况,选择继承临近的数据或者取平均值来进行填充,具体方案要case by case。
现在我们知道这是一个回归问题。 为了测试每个模型的准确性,我们通过划分训练数据创建一个测试集。 然后我们使用均方根预测误差来确定我们预测的准确性。 均方根误差(RMSE)或RMSD是模型或估计器预测的值(测试值和列车值)与实际观测值之间的差异的常用量度。 RMSE表示预测值和实际值之间的差异的样本标准偏差。 因此0意味着完美的分数。
最终的评估结果主要是Kaggle在此项目中的pravite_data与自己预测结果的“均根方差rmspe”
自己训练的时候评估主要是看自己进行充分的特征工程后 合并后的数据集在经过训练后在train和test上的“均根方差rmspe”数值
In [3]:
import os
from IPython.display import display, Image
names = [f for f in os.listdir('C:/Users/Administrator/Desktop/report/') if f.endswith('.png')]
In [42]:
for name in names[:2]:
display(Image('C:/Users/Administrator/Desktop/report/' + name, width=800))
In [44]:
for name in names[2:3]:
display(Image('C:/Users/Administrator/Desktop/report/' + name, width=1000))
In [51]:
display(Image('C:/Users/Administrator/Desktop/report/' + "4.png", width=1000))
In [52]:
display(Image('C:/Users/Administrator/Desktop/report/' + "5.png", width=1000))
In [53]:
display(Image('C:/Users/Administrator/Desktop/report/' + "6.png", width=1000))
In [55]:
display(Image('C:/Users/Administrator/Desktop/report/' + "7.png", width=1000))
In [56]:
display(Image('C:/Users/Administrator/Desktop/report/' + "8.png", width=1000))
In [58]:
display(Image('C:/Users/Administrator/Desktop/report/' + "9.png", width=1000))
In [62]:
display(Image('C:/Users/Administrator/Desktop/report/' + "11.png", width=1000))
In [63]:
display(Image('C:/Users/Administrator/Desktop/report/' + "12.png", width=1000))
In [65]:
display(Image('C:/Users/Administrator/Desktop/report/' + "13.png", width=1000))
In [68]:
display(Image('C:/Users/Administrator/Desktop/report/' + "14.png", width=1000))
In [69]:
display(Image('C:/Users/Administrator/Desktop/report/' + "15.png", width=1000))
In [70]:
display(Image('C:/Users/Administrator/Desktop/report/' + "16.png", width=1000))
In [72]:
display(Image('C:/Users/Administrator/Desktop/report/' + "17.png", width=1000))
先从特征开始讲起把:
从上述部分可以看出,仅通过使用客户数量数据或仅仅是促销是不能能预测销售的。销售受到每个属性的影响。为了对销售进行预测,首先我们将摆脱“客户”功能和“销售”功能中的异常值,因为数字过高或过低可能会出现异常情况。
这样的数据会影响模型的精度。处理异常值后,我们可以开始预处理数据。这包括摆脱Null值,encoding一些特征,如StoreType,StateHoliday等。 处理Missing Data是根据特征的现实意义进行填补和丢弃的,比如除每个星期天外,我都默认商店是处于“open”状态的,这比较符合我们的生活常识
如前所述,日期的转换对于预测而言是非常重要的,这也是视觉化中证明的,因为日期,月份和日期的销售变化很大。
我们也可以处理竞争的细节,因为它肯定会影响到真正影响销售的客户数量。促销可能有助于让客户回来,这就是为什么我们需要对所有Promo列进行编码的原因。一旦我们对数据进行了预处理,我们就可以使用cross_validation.train_test_split方法进行拆分。
该方法随机洗牌数据并返回两套训练和测试。可以定义测试的大小。然后,训练集用于训练几个模型 -
梯度增强产生一个预测模型,它以弱预测模型(通常是决策树)的形式组成。它以像其他增强方法一样的阶段性方式构建模型,并且通过允许优化任意不同的损失函数来推广它们。
由于以下属性,这些模型已被选择用于此问题 - •考虑到影响销售的功能,数据可以轻松地分解为使用if-then-else决策规则对输入特征进行决策。这需要可以轻松完成的数据准备,所以我们不需要担心这里的主要缺点。
虽然决策树可能不稳定,但处理分类数据和数值也是非常好的。
因此,我们的数据集中的多种类型的功能将不会成为问题。我们可以通过查看模型的测试分数来确定是否对我们的数据不稳定,然后决定是否可以使用。
•我们的数据集有大量的数据点。 Kneighbours使用强力执行快速计算,这有助于我们降低模型的成本。另一方面,仅在某些输入特征不是连续值的情况下才是有效的。我们可以通过测试分数找出影响模型准确性的程度。
•GradientBoost是一个缓慢的模型,因此模型的成本将会很高。另一方面,它通过优化任意不可分解的损失函数使用不同的方法。如果我们无法通过任何其他模型获得良好的成绩,我们可以通过这种方法获得良好的成绩。
首先我们首先处理异常值。 检测数据中的异常值在任何数据预处理步骤中都非常重要的分析。 异常值的存在常常会使结果不好
考虑到这些数据点。 有很多“规则“是什么构成数据集中的异常值? 使用Tukey's方法来识别异常值:离群值是计算为四分位数范围(IQR)的1.5倍。 数据点具有超出IQR之外的异常值的功能该功能被认为是异常的。
因此,我写了一个代码,用可视化的方法辅助,发现客户和中的异常值 销售,然后看到哪些异常值在这两个特征中是常见的。然后常见的异常值被丢弃。
如前所述,数据需要适量的处理。直接使用一些具有数值的功能 - “存储”,“竞争力”,“促销”,“促销2”,“学校”。处理数据的初始步骤是用零填充所有的NaN值。
这里我们假设列没有被填写,因为该特征的abcense。然后为了加快处理速度,我放弃了商店关闭的行,这就是开放设置为零的地方,因为我们只想在商店开放的日子里培训模型,因此有销售。那么具有分类值“StoreType”,“Assortment”和“StateHoliday”的特征具有可以在模型中使用的替代值的所有值。之后,我们转到日期。给出的日期格式是aribtrary,需要处理。
因此,所有的日期都被分为“DayOfWeek”,“Month”,“Day”,“Year”,“WeekOfYear”的功能。然后处理以年或月为单位的竞赛特征的日期。我们将所有的值转换成几个月,以便有一个单位进行比较。
在“PromoOpen”这一年以来,从星期以来给出了同样的步骤。最后,“IsPromoMonth”映射为月份值,并根据该值分配0和1。为了使模型创建更快一点,销售为0的所有行都将被删除,因为它可能是一个未填充的值,这只会对模型产生负面影响。
实施首先,将步骤分为各种功能,以计算每个功能为检查成本所花费的时间。
第一个函数列出它所用的分类器作为参数。它适用于拟合方法并报告时间。
然后第二个函数运行训练集本身的预测,并返回均方根误差率。它还返回了对训练集进行预测所需的时间。然后第三个函数对测试集进行预测,并报告时间和分数。
首先,将销售数据转换为日志值,以便更容易预测。然后,前面部分提到的每个模型都被调用并作为函数的参数传递,并为每个函数报告时间和分数。一旦报告了分数,则选择最有效的模型并计算特征重要性。功能重要性告诉我们哪些功能在做出预测时最相关。这可以与我们的分析进行比较,同时探索数据。然后在条形图上表示特征重要性。
然后将整个数据集训练在所选择的模型上,最后的预测被做出并保存到测试文件中。
选择细化决策回归。 最初,错误率很高。 因此,将模型训练的销售数据转换为日志以降低错误率。 测试组的均方误差值为0.1819,远高于预期值。 然后通过应用GridSearchCV,错误率降低到0.164。 GridSearchCV详尽地考虑了在参数网格中传递的所有参数组合。 在这种情况下,优化了决策树算法的叶样本和样本分割值,以获得最佳分数。
在上一节中,错误率的基准值几乎为0.20。 由于DecisionTree回归,错误率几乎是预期值的三分之二。 如果可以预测销售额的错误率只有0.16,
那么管理者很容易做出必要的改变,看看是什么增加或减少了销售。
DecisonTree回归创建了一个模型,通过学习从数据特征推断出的简单决策规则来预测销售额的价值。 错误是如此之低,因为每个功能都被应用,如果另外决定规则来预测销售,并且由于功能和数字以及分类的模型是完美契合。
因此,对整个数据集进行了最后的训练,并且预测了测试集的销售。 可以肯定地说,这个模型将精确地预测所需的值。 因此,这个项目的任务已经完成了!
In [5]:
display(Image('C:/Users/Administrator/Desktop/report/' + "19.png", width=1000))
如图所见,商店,DayOfWeek和Date是最重要的feature,似乎在销售上有最大的差异。 这个预测是正确的。 另一方面,假期和促销也似乎有很大的差异,但这些特征已经被降低了
这里有我后来用xgboost实现了低于0.1的error的时候进行的特征的分析,和上面的结果有较显著的区别,如下图所示。尤其是排名3-10的特征,在xgboost运算后明显有了更大的权重,也就是说,xgboost更具有发现特征对于预测结果的能力,不像单模型那样过于简单,靠常识也能知道过于依赖某个特征可信度会有比较大风险。所以最后结果也自然有了区别
In [6]:
display(Image('C:/Users/Administrator/Desktop/report/' + "20.png", width=1000))
项目的分析最初是项目的一个有意义的部分,因为它能够告诉我们哪个功能会影响销售,几乎和DecisionTree回归函数的feature_importance属性一样。
优化模型是一个挑战,因为处理的索引错误(如代码中所述)。 现在这个模型可以用于预测销售,即使有更多的商店或不同的业务来了,如果有类似的功能,那么这个模型可以用于适当的预测
In [8]:
display(Image('C:/Users/Administrator/Desktop/report/' + "21.png", width=1000))
In [9]:
display(Image('C:/Users/Administrator/Desktop/report/' + "22.png", width=1000))
那个最后一版的xgboost算了大概有4-5个小时才弄完