文章目录

  • 一、项目介绍
  • 二、建立假设(部分)
  • 三、数据探索分析
    • 1.导入数据
    • 2. 单变量分析
      • 2.1) 分类特征
        • a) Item_Fat_Content‘ 脂肪含量(重复名字处理)
        • b) Item_Type物品类别
        • c) Outlet特征 (大小、位置、类型)
      • 2.2) 数值特征
    • 3. 多变量分析
      • 3.1) 目标变量(销量)VS数值特征
      • 3.2) 目标变量(销量)VS分类特征
        • a) 物品类别VS销量关系
        • b) 物品脂肪含量VS销量关系
        • c) 商店情况VS销量
    • 4. 缺失值处理
      • 4.1)查找缺失值
      • 4.2)缺失值处理
      • 4.3)检查结果
  • 四、特征工程
    • 1.提取新特征
      • 1.1) Item_Type_new 减少物品类别
      • 1.2) Item_category
      • 1.3) Outlet_Years和 price_per_unit_wt
      • 1.4) Item_MRP_clusters
    • 2. 特征转换
    • 3. 数据预处理
      • 1. 消除偏态(Removing Skewness)
      • 2. 归一化
      • 3. 相关性分析(Correlated Variables)
      • 4. 导出数据
  • 五、建模
    • 1. 切分数据集
    • 2. 模型选择
      • 2.1) LinearRegression
      • 2.2) RandomForestRegressor
      • 2.3) KNeighborsRegressor
      • 2.4) GradientBoostingRegressor
      • 2.5) XGBRegressor
      • 2.6)模型对比
    • 4. 模型调参
      • 4.1)RandomizedSearchCV
      • 4.2) GridSearchCV (n_estimator)
    • 5. 测试模型
    • 6. 特征重要性
  • 六、总结

一、项目介绍

该项目目的是建立一个模型去预测每个产品在具体商场的销售情况,以协助决策者提高整体的销售情况。

数据集介绍:
BigMart数据集收集了2013年不同城市中10个商场、1559个产品的销售数据。训练集和测试集一共是14204行,12列的数据。

数据集字段含义:

名称 类型 含义
Item_Identifier object 物品识别号
Item_Weight float64 物品种类
Item_Fat_Content object 物品脂肪含量
Item_Visibility float64 物品可见度
Item_Type object 物品类型
Item_MRP float64 物品MRP
Outlet_Identifier object 商场识别号
Outlet_Establishment_Year int64 商城成立年份
Outlet_Size object 商城大小
Outlet_Location_Type object 商城位置
Outlet_Type object 商场类型
Item_Outlet_Sales float64 物品商场销量(目标变量)

问题和数据集下载链接


二、建立假设(部分)

可以从店铺、产品、顾客、整体情况四个角度建立假设,虽然一些假设不一定能用数据去证明和测试,但是这个过程有助于我们去理解问题。

  • 店铺

    • 城市类型:位于城市/一线城市的商店有较高的销售额,因为当地人们的收入水平较高。
    • 位置:受欢迎的商业区比其他地方的销售额应该更高。
    • 商店容量:规模很大的商店应该有更高的销售额,因为它们就像一站式商店,人们更喜欢从一个地方得到所有东西
    • 位置:位于热门市场的商店应该有更高的销售额,因为更容易接近客户。
  • 产品
    • 物品类型:与特定用途产品相比,食物、日用品应具有更高的销售倾向。
    • 陈列区:商店里货架大的产品可能会先引起注意,卖得更多。
    • 可见性:产品在店内的位置会影响销售。在入口处的那些会首先吸引顾客的眼球,而不是后面的。
    • 价格:价格会影响产品的销售额,越贵的产品越少人购买。
  • 顾客情况
    • 工作概况:与入门级或中高层员工相比,在高管级别工作的客户有更高的机会购买大额产品。
    • 家庭规模:家庭成员越多,顾客购买产品的花费就越大
    • 过去的购买历史:这些信息的可用性可以帮助我们确定用户购买产品的频率。
  • 宏观层面的假设
    • 环境:如果政府宣称环境是安全的,顾客就更有可能购买产品而不必担心它是否环保。
    • 经济增长:如果当前经济持续增长,人均收入会上升,因此消费者的购买力也会增加。

三、数据探索分析

1.导入数据

关于数据,有几点是需要知道的:

  • 数据的维度(Dimensions of Data),一共有几行几列数据,.shape()
  • 数据特征(Features of Data),每组数据个代表什么意思。
  • 数据结构(Structure of Data),是数值型还是类别型?各有多少?
  • *合并训练集和测试集(根据需要):这里两个数据集是分开的,为了减少重复工作,可以先将两个数据集合并,一起做数据处理,之后再分开。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline#读取数据
train=pd.read_csv('train_v9rqX0R (1).csv')
test=pd.read_csv('test_AbJTz2l.csv')## 合并两个报表
Features=['Item_Identifier', 'Item_Weight', 'Item_Fat_Content', 'Item_Visibility','Item_Type', 'Item_MRP', 'Outlet_Identifier','Outlet_Establishment_Year', 'Outlet_Size', 'Outlet_Location_Type','Outlet_Type']
combine=pd.merge(train,test,on=Features, how='outer')
print(combine.shape)


合并两个数据表后,得到了一个14204行,12列的数据集。

combine.head()

2. 单变量分析

按照特征的下面类别做单变量分析。

分类类型(7) Item_Identifier物品标识符、Item_Fat_Content脂肪含量、Item_Type物品种类、Outlet_Identifier商场标识符、Outlet_Size商场大小、Outlet_Location_Type位置、Outlet_Type商场类型
浮点类型(4) Item_Weight 物品重量、Item_Visibility 物品可见度、Item_MRP 物品MRP、Item_Outlet_Sales 销售
数值类型(1) Outlet_Establishment_Year int64 商场成立年份

2.1) 分类特征

a) Item_Fat_Content‘ 脂肪含量(重复名字处理)

#画出直方图看数据情况
combine['Item_Fat_Content'].value_counts(normalize=True).plot.bar(figsize=(10,5), title= 'Item_Fat_Content')


脂肪含量中有重复的名字,Low Fat、LF和 low fat; Regular 和reg。一共分成两类,但是出现了五类,需要替换名字。

# !!有重复的不同名字
combine['Item_Fat_Content'].replace({'LF':'Low Fat','reg':'Regular','low fat':'Low Fat'},inplace=True)#确认结果
combine['Item_Fat_Content'].value_counts(normalize=True).plot.bar(figsize=(10,5), title= 'Item_Fat_Content')


可见产品中约有65%是低脂肪,35%是正常标准。

b) Item_Type物品类别

combine['Item_Type'].value_counts(normalize=True).plot.bar(figsize=(10,5), title= 'Item_Type')

  • 一共有16个物品类别,水果蔬菜和零食最多,海鲜最少。

c) Outlet特征 (大小、位置、类型)

#观察Outlet特征情况
plt.figure(1)
combine['Outlet_Identifier'].value_counts(normalize=True).plot.bar(figsize=(20,5), title= 'Outlet_Identifier')plt.figure(2)
plt.subplot(131)
combine['Outlet_Size'].value_counts(normalize=True).plot.bar(figsize=(20,5), title= 'Outlet_Size')
plt.subplot(132)
combine['Outlet_Location_Type'].value_counts(normalize=True).plot.bar(figsize=(20,5), title= 'Outlet_Location_Type')
plt.subplot(133)
combine['Outlet_Type'].value_counts(normalize=True).plot.bar(figsize=(20,5), title= 'Outlet_Type')# Outlet_Establishment_Year
plt.figure(3)
combine['Outlet_Establishment_Year'].value_counts(normalize=True).plot.bar(figsize=(10,5), title= 'Outlet_Establishment_Year')


  • 从商场位置上看, Tier3城市观察到的数值是最多的。
  • 超市类型Type1是最多的商场类型。
  • 与其他年份相比,1998年设立的零售店的数据中观察到的数据较少。

2.2) 数值特征

一共有四个数值特征,可以画直方图看它们各自的分布情况。

  1. Item_Outlet_Sales 销售量 (目标变量)
  2. Item_Weight 物品重量
  3. Item_Visibility 物品可见度
  4. Item_MRP 物品MRP值
import seaborn as snsplt.figure(1)
plt.subplot(221)
sns.distplot(combine['Item_Outlet_Sales'])
plt.subplot(222)
sns.distplot(combine['Item_Weight'])
plt.subplot(223)
sns.distplot(combine['Item_Visibility'])
plt.subplot(224)
sns.distplot(combine['Item_MRP'])

  • 右上角的物品重量的分布没有明确区别。
  • 物品可见度(左下)可见分布是向右偏的,需要进行转换改变其偏度,而且有不少值是0。
  • 物品MRP(右下角)可以清楚地看到有四组不同的产品分布。

3. 多变量分析

3.1) 目标变量(销量)VS数值特征

由于两个变量都是数值型,可以用scatter plots 用散点图观察变量之间的关系。

#物品重量 和 销售量的相关性
plt.figure(1)
fig,ax=plt.subplots(figsize=(10,2.5))
ax.scatter(combine['Item_Weight'], combine['Item_Outlet_Sales'],color='pink')#物品可见度 和 销售量的相关性
plt.figure(2)
fig,ax=plt.subplots(figsize=(10,2.5))
ax.scatter(combine['Item_Visibility'], combine['Item_Outlet_Sales'],color='pink')
#物品可见度 和 销售量的相关性# tem_MRP 和销量相关性
plt.figure(3)
fig,ax=plt.subplots(figsize=(10,2.5))
ax.scatter(combine['Item_MRP'], combine['Item_Outlet_Sales'],color='pink')

  • 图1: Item_Outlet_的销售额分布在整个Item_重量范围内,两者似乎没有任何管来呢
  • 图2: 在Item_Visibility和Item_Outlet_Sales中,Item_Visibility=0.0处有一系列点,这很奇怪,因为没有物品是看不见的。我们将在以后阶段处理这个问题。
  • 图3: Item_MRP vs Item_Outlet_Sales:我们可以清楚地看到4个部分的价格,它们可以用于特征工程,以创建一个新的变量。

3.2) 目标变量(销量)VS分类特征

a) 物品类别VS销量关系

#物品类别和销量关系
import seaborn as sns
plt.figure(1)
fig,ax=plt.subplots(figsize=(20,8))
sns.set(style="whitegrid")
sns.boxenplot(x=combine['Item_Type'], y=combine['Item_Outlet_Sales'],scale="linear",color="yellow")

  • Other 和 Seafood 的销量比较少,水果和蔬菜相对较高。
  • 商品类别和销量没有明显的相关性,

b) 物品脂肪含量VS销量关系

#脂肪含量
sns.violinplot(x=combine['Item_Fat_Content'], y=combine['Item_Outlet_Sales'])

  • 脂肪含量的高低和销量没有明显的关系。

c) 商店情况VS销量

#商店编号
plt.figure(1)
fig,ax=plt.subplots(figsize=(10,3))
sns.violinplot(x=combine['Outlet_Identifier'], y=combine['Item_Outlet_Sales'])
plt.figure(2)
fig,ax=plt.subplots(figsize=(10,3))
sns.set(style="whitegrid")
sns.boxenplot(x=combine['Outlet_Identifier'], y=combine['Item_Outlet_Sales'],scale="linear",color="yellow")

  • OUT010 和 OUT019 两个商店和其他的明显不一样。
  • OUT027 的销量跨度是最大的
f,ax=plt.subplots(1,3,figsize=(18,3))
#商店大小
sns.violinplot(x=combine['Outlet_Size'], y=combine['Item_Outlet_Sales'],ax=ax[0])
#位置
sns.violinplot(x=combine['Outlet_Location_Type'],y=combine['Item_Outlet_Sales'],ax=ax[1])
#商店类型
sns.violinplot(x=combine['Outlet_Type'], y=combine['Item_Outlet_Sales'],ax=ax[2])

  • Grocery Store 的销量数值都明显比其他类型的商店低

4. 缺失值处理

4.1)查找缺失值

#查缺失值
print(combine.isnull().sum())#查看Item_Visibility有多少个0
(combine['Item_Visibility'] == 0).value_counts()

三个特征有缺失情况:Item_Weight 2439; Outlet_Size 4016; Item_Visibility 有879个值等于0。

4.2)缺失值处理

  • 根据Item_Identifier, 将Item_Weight 和 Item_Visibility的缺失值用均值替换;
#利用数据透视表计算平均值,根据Item_Identifier,计算出重量、可见度的均值
pd.pivot_table(combine,index=['Item_Identifier'],values=['Item_Weight','Item_Visibility'],aggfunc=[np.mean])#处理Item_Weight
item_avg_weight = combine.pivot_table(values='Item_Weight', index='Item_Identifier')
miss_bool = combine['Item_Weight'].isnull()
combine.loc[miss_bool,'Item_Weight'] = combine.loc[miss_bool,'Item_Identifier'].apply(lambda x: item_avg_weight.loc[x])#处理等于0的Item_Visibility
visibility_avg = combine.pivot_table(index='Item_Identifier', values='Item_Visibility')
miss_bool = (combine['Item_Visibility'] == 0)#这里是要替代0值,不是空值。
combine.loc[miss_bool,'Item_Visibility'] =combine.loc[miss_bool,'Item_Identifier'].apply(lambda x: visibility_avg.loc[x])
  • 根据Outlet_Identifier找出每个商店的Size, 并将缺失的4016个Outlet_Size补充完整。
#查看每个商店的大小
pd.crosstab(combine.Outlet_Identifier,combine.Outlet_Size).T.style.background_gradient(cmap='summer_r')


结果得出7个商店的Size, 表明有3个商店的Size是缺失的,分别是OUT010、OUT017、OUT045因此不能直接使用identifier,接下来改变使用Outlet_Type 做分析:

#查看大小和类型的关系
pd.crosstab(combine.Outlet_Identifier,[combine.Outlet_Type,combine.Outlet_Size]).T.style.background_gradient(cmap='summer_r')

  • Grocery Store: small
  • Supermarket Type1: 最多是SMall
  • Supermarket Type2 和 Type3 都是Medium

再继续查看每个商店的类型

#查看10个商店的类型
pd.crosstab(combine.Outlet_Identifier,combine.Outlet_Type).T.style.background_gradient(cmap='summer_r')

  • OUT010 是 grocery store 和OUT019 一样,联系之前分析Sales情况时,两个店铺的情况也是一样的。所以OUT010的Size 和OUT019一样, 为SMALL
  • OUT017、OUT045 是Supermarket Type1, 取众数Small替代缺失值。
## 替换方法
combine.loc[(combine.Outlet_Size.isnull())&(combine.Outlet_Identifier=='OUT010'),'Outlet_Size']='Small'
combine.loc[(combine.Outlet_Size.isnull())&(combine.Outlet_Identifier=='OUT017'),'Outlet_Size']='Small'
combine.loc[(combine.Outlet_Size.isnull())&(combine.Outlet_Identifier=='OUT045'),'Outlet_Size']='Small'

4.3)检查结果

#检查结果
print(combine.isnull().sum())#画图观察结果
plt.figure(2)
plt.subplot(221)
sns.distplot(combine['Item_Weight'])
plt.subplot(222)
sns.distplot(combine['Item_Visibility'])



缺失值都处理完,数据分布比原来的更加平滑,Visibility 的0值也去掉了。

四、特征工程

1.提取新特征

在原始数据集中,为了再提取出更多有用的数据信息,接着介绍5个新特征:Item_Type_new、Item_category、Outlet_Years、price_per_unit_wt、Item_MRP_clusters。

1.1) Item_Type_new 减少物品类别

在之前的分析中,物品有十几个类别,不方便后续分析,这里将这些类别根据保存时间简单分成两类:perishable(易腐烂的)、non_perishable(不易腐烂的)

perishable = ["Breads", "Breakfast", "Dairy", "Fruits and Vegetables", "Meat", "Seafood"]
non_perishable = ["Baking Goods", "Canned", "Frozen Foods", "Hard Drinks", "Health and Hygiene", "Household", "Soft Drinks"]newtype=[]
for z in range(0,len(combine['Item_Type'])):z = combine['Item_Type'][z]if z in perishable:newtype.append("perishable") else:newtype.append("non_perishable")combine['Item_Type_new']=newtype

1.2) Item_category

通过观察Item_Identifier的结构,分别是由两个字母和数字构成,开头两个字母是‘DR’, ‘FD’, and ‘NC’,即饮料、食物和消费品。从这里,我们可以提取出一个新的特征:

## 取Item_Identifier的前两位作为新特征
combine['Item_category']=[x[:2] for x in combine['Item_Identifier']]#观察各类的观测值数量。
combine["Item_category"].value_counts()#查看每类具体有什么类型商品
pd.pivot_table(combine,index=["Item_Type"],values=["Item_Identifier"],columns=["Item_category"],aggfunc='count')

1.3) Outlet_Years和 price_per_unit_wt

继续创建下面两个特征:

  • Outlet_Years:商店经营了多少年。相比起具体的建立年份,经营了多少年对我们分析更有价值。
  • price_per_unit_wt :每单位重量的价格(Item_MRP/Item_Weight)
#假设今年是2013年,和课程假设一致
combine['Outlet_Years']=2013-combine['Outlet_Establishment_Year']
combine['price_per_unit_wt']=combine['Item_MRP']/combine['Item_Weight']

1.4) Item_MRP_clusters

在之前Item_MRP 和 Item_Outlet_Sales 的分析中,明显看出整体被分成了四个区,我们这里也重新根据Item_MRP 分四组。

bins=[0,69,136,203,300]
group=['1st','2nd','3rd','4th']
combine['Item_MRP_clusters']=pd.cut(combine['Item_MRP'],bins,labels=group)#查看结果
combine.head(5)

2. 特征转换

对于一些文字型的特征,需要将它们转换成数值型。比如位置、商品/商店类型等。这里使用两种常用的方法:

  • 标签编码:将变量中的每个类别转换成一个数字
  • 独热编码:分类变量的每个类别都转换为一个新的二进制列(1/0)
#标签编码
from sklearn.preprocessing import LabelEncoder
LE = LabelEncoder()
laber_features = ['Item_Fat_Content','Outlet_Size','Outlet_Location_Type','Item_Type_new','Item_MRP_clusters']
for i in laber_features:combine[i] = LE.fit_transform(combine[i])# 独热编码
#One Hot Coding:
combine['Outlet'] = combine['Outlet_Identifier'] #结果需要保留Outlet_Identifier
combine = pd.get_dummies(combine, columns=['Outlet','Outlet_Type','Item_category'])#删除多余的两列
combine.drop(['Item_Type','Outlet_Establishment_Year'],axis=1,inplace=True)

部分结果显示:除了两个Identifier, 其余特征都转换为数字。

3. 数据预处理

1. 消除偏态(Removing Skewness)

price_per_unit_wt 和 Item_Visibility 的都是右偏态,为了令两个特征分布更偏向于正态分布,使用对数转换,这里使用log+1是为了避免有0的情况。(log0没有意义)

#Removing Skewness
combine['Item_Visibility']=np.log((combine['Item_Visibility']+1).astype('float'))
combine['price_per_unit_wt']=np.log((combine['price_per_unit_wt']+1).astype('float'))
#查看结果
combine['price_per_unit_wt'].hist(bins=20)
combine['Item_Visibility'].hist(bins=20)
对数转换前 对数转换后
Item_Visibility
price_per_unit_wt

2. 归一化

数值型特征,比如重量、价格等,范围都不一样,所以需要把所有的数值型特征都缩放到[0,1]之间。

#Scaling numeric predictors
from sklearn.preprocessing import MinMaxScaler
combine['Item_Weight'] = MinMaxScaler().fit_transform(combine[['Item_Weight']])
combine['Item_MRP'] = MinMaxScaler().fit_transform(combine[['Item_MRP']])
combine['price_per_unit_wt'] = MinMaxScaler().fit_transform(combine[['price_per_unit_wt']])
combine['Item_Visibility'] = MinMaxScaler().fit_transform(combine[['Item_Visibility']])
combine['Outlet_Years'] = MinMaxScaler().fit_transform(combine[['Outlet_Years']])#查看结果
combine.describe().T #后面加T转置表格

选中的数值型特征都在0-1的范围内。

3. 相关性分析(Correlated Variables)

#Correlated Variables
corr = combine.corr()
mask = np.zeros_like(corr)
mask[np.triu_indices_from(mask)] = True
with sns.axes_style("white"):f, ax = plt.subplots(figsize=(10, 8))ax = sns.heatmap(corr, mask=mask, vmax=.3, square=True)

4. 导出数据

#切分数据集
train = combine.loc[combine['Item_Outlet_Sales'].notnull()]
test = combine.loc[combine['Item_Outlet_Sales'].isnull()]#删掉test 中多余的列
test.drop(['Item_Outlet_Sales'],axis=1,inplace=True)#导出数据
train.to_csv("train_modified.csv",index=False)
test.to_csv("test_modified.csv",index=False)print(train.shape,test.shape)

结果输出: (8523, 30)(5681, 29)
训练集有8523条数据,测试集有5681条数据。

#查看
combine.dtypes

#结果输出

Item_Identifier                   object
Item_Weight                      float64
Item_Fat_Content                   int64
Item_Visibility                  float64
Item_MRP                         float64
Outlet_Identifier                 object
Outlet_Size                        int64
Outlet_Location_Type               int64
Item_Outlet_Sales                float64
Item_Type_new                      int64
Outlet_Years                     float64
price_per_unit_wt                float64
Item_MRP_clusters                  int64
Outlet_OUT010                      uint8
Outlet_OUT013                      uint8
Outlet_OUT017                      uint8
Outlet_OUT018                      uint8
Outlet_OUT019                      uint8
Outlet_OUT027                      uint8
Outlet_OUT035                      uint8
Outlet_OUT045                      uint8
Outlet_OUT046                      uint8
Outlet_OUT049                      uint8
Outlet_Type_Grocery Store          uint8
Outlet_Type_Supermarket Type1      uint8
Outlet_Type_Supermarket Type2      uint8
Outlet_Type_Supermarket Type3      uint8
Item_category_DR                   uint8
Item_category_FD                   uint8
Item_category_NC                   uint8
dtype: object

五、建模

1. 切分数据集

#导入清洗好的数据
train=pd.read_csv('train_modified.csv')
test=pd.read_csv('test_modified.csv')#提取两个Identifier
test_ID=test[['Item_Identifier','Outlet_Identifier']]
train_ID=train[['Item_Identifier','Outlet_Identifier']]test=test.drop(['Item_Identifier','Outlet_Identifier'],1)
train=train.drop(['Item_Identifier','Outlet_Identifier'],1)#数据集切分
X=train.drop('Item_Outlet_Sales',1)
y=train.Item_Outlet_Sales
from sklearn.model_selection import train_test_split
#import LogisticReression and accuracy_score from sklearn and fit the lofistic regression model
x_train, x_cv, y_train, y_cv = train_test_split(X,y, test_size =0.3)

2. 模型选择

def mae(y_true, y_pred):return np.mean(abs(y_true - y_pred))def fit_and_evaluate(model):# Train the modelmodel.fit(x_train, y_train)# Make predictions and evalutemodel_pred = model.predict(x_cv)model_mae = mae(y_cv, model_pred)# Return the performance metricreturn model_mae

2.1) LinearRegression

from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr_mae = fit_and_evaluate(lr)print('Linear Regression Performance on the test set: MAE = %0.4f' % lr_mae)

Linear Regression Performance on the test set: MAE = 857.2215

2.2) RandomForestRegressor

from sklearn.ensemble import RandomForestRegressor
random_forest = RandomForestRegressor(random_state=60)
random_forest_mae = fit_and_evaluate(random_forest)print('Random Forest Regression Performance on the test set: MAE = %0.4f' % random_forest_mae)

Random Forest Regression Performance on the test set: MAE = 808.5536

2.3) KNeighborsRegressor

from sklearn.neighbors import KNeighborsRegressor
knn = KNeighborsRegressor(n_neighbors=10)
knn_mae = fit_and_evaluate(knn)print('K-Nearest Neighbors Regression Performance on the test set: MAE = %0.4f' % knn_mae)

K-Nearest Neighbors Regression Performance on the test set: MAE = 826.7566

2.4) GradientBoostingRegressor

from sklearn.ensemble import GradientBoostingRegressor
gradient_boosted = GradientBoostingRegressor(random_state=60)
gradient_boosted_mae = fit_and_evaluate(gradient_boosted)print('Gradient Boosted Regression Performance on the test set: MAE = %0.4f' % gradient_boosted_mae)

Gradient Boosted Regression Performance on the test set: MAE = 784.4336

2.5) XGBRegressor

from xgboost import XGBRegressor
Xgboost= XGBRegressor(random_state=60)
Xgboost_mae = fit_and_evaluate(Xgboost)print('XGBRegressor Performance on the test set: MAE = %0.4f' % Xgboost_mae)

XGBRegressor Performance on the test set: MAE = 752.6979

2.6)模型对比

from IPython.core.pylabtools import figsizeplt.style.use('fivethirtyeight')
figsize(8, 6)# Dataframe to hold the results
model_comparison = pd.DataFrame({'model': ['Linear Regression','Random Forest', 'Gradient Boosted','K-Nearest Neighbors','XGBRegressor'],'mae': [lr_mae, random_forest_mae, gradient_boosted_mae, knn_mae,Xgboost_mae]})# Horizontal bar chart of test mae
model_comparison.sort_values('mae', ascending = False).plot(x = 'model', y = 'mae', kind = 'barh',color = 'red', edgecolor = 'black')# Plot formatting
plt.ylabel(''); plt.yticks(size = 14); plt.xlabel('Mean Absolute Error'); plt.xticks(size = 14)
plt.title('Model Comparison on Test MAE', size = 20)


五个模型中,XGBRegressor表现最好。

#查看模型具体参数
Xgboost

4. 模型调参

4.1)RandomizedSearchCV

先用random search可以找出大概找到合理的参数位置, 在用GridSearchCV查找最佳的参数。

from sklearn.model_selection import RandomizedSearchCV, GridSearchCV# 设置参数
n_estimators = [50, 100, 250]
max_depth = [5, 10]
min_child_weight = [1, 3, 6]
learning_rate = [0.1, 0.2, 0.3]hyperparameter_grid = {'n_estimators': n_estimators,'max_depth': max_depth,'min_child_weight': min_child_weight,'learning_rate': learning_rate}# Create the model to use for hyperparameter tuning
model= XGBRegressor(random_state = 60)# Set up the random search with 4-fold cross validation
random_cv_xgboost = RandomizedSearchCV(estimator=model,param_distributions=hyperparameter_grid,cv=4, n_iter=25, scoring = 'neg_mean_absolute_error',n_jobs = -1, verbose = 1, return_train_score = True,random_state=60)
#找出最佳的模型
random_model=random_cv_xgboost.best_estimator_
random_model

#查看新模型的结果
random_model_pred=random_model.predict(x_cv)
print('RandomSearc model performance on the test set:   MAE = %0.4f.' % mae(y_cv, random_model_pred))

RandomSearc model performance on the test set: MAE = 680.8172.

MAE降低到680.8172。

4.2) GridSearchCV (n_estimator)

用GridSearchCV查找最佳的n_estimator。

# 对比n_estimator在20-100范围内的结果
trees_grid = {'n_estimators': [20,30,40,50,60,70,100]}#这里导入上面的random_model的模型参数,删掉n_estimator。
model = XGBRegressor(base_score=0.5, booster='gbtree', colsample_bylevel=1,colsample_bynode=1, colsample_bytree=1, gamma=0,importance_type='gain', learning_rate=0.1, max_delta_step=0,max_depth=5, min_child_weight=3, missing=None,n_jobs=1, nthread=None, objective='reg:linear', random_state=60,reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None,silent=None, subsample=1, verbosity=1)grid_search = GridSearchCV(estimator = model, param_grid=trees_grid, cv = 4, scoring = 'neg_mean_absolute_error', verbose = 1,n_jobs = -1, return_train_score = True)# 训练模型
grid_search.fit(X, y)

将结果可视化

from IPython.core.pylabtools import figsize
# Get the results into a dataframe
results = pd.DataFrame(grid_search.cv_results_)# Plot the training and testing error vs number of trees
figsize(8, 4)
plt.style.use('fivethirtyeight')
plt.plot(results['param_n_estimators'], -1 * results['mean_test_score'], label = 'Testing Error')
plt.plot(results['param_n_estimators'], -1 * results['mean_train_score'], label = 'Training Error')
plt.xlabel('Number of Trees'); plt.ylabel('Mean Abosolute Error'); plt.legend();
plt.title('Performance vs Number of Trees');


可见最佳的n_estimator是30,超过30之后就有过拟合的现象。

5. 测试模型

  1. 计算MAE值
    MAE:Mean Abosolute Error 平均绝对误差,是绝对误差的平均值。可以更好地反映预测值误差的实际情况。
model_30tree=grid_search.best_estimator_thirtytree_pred=model_30tree.predict(x_cv)
print('thirtytree_pred model performance on the test set:   MAE = %0.4f.' % mae(y_cv, thirtytree_pred))
  • 输出结果:thirtytree_pred model performance on the test set: MAE = 723.8820.

  • 最后MAE结果为723.8820,比原来的752.6979下降了30。

  1. 计算RMSE值
    根据参考文章使用RMSE(Root Mean Square Error)均方根误差方法。
from sklearn import metrics
print ("RMSE : %.4g" % np.sqrt(metrics.mean_squared_error(y_cv, thirtytree_pred)))
  • 输出结果:RMSE : 1058
  1. 预测和真实之间的差异图
figsize(5, 5)# Density plot of the final predictions and the test values
sns.kdeplot(y_cv, label = 'Test Values')
sns.kdeplot(thirtytree_pred, label = 'Predictions')# Label the plot
plt.xlabel('Energy Star Score'); plt.ylabel('Item_Outlet_Sales');
plt.title('Test Values and Predictions');

#导出结果
test_predition=model_30tree.predict(test)submission=test_ID
submission['Outlet_Sales']=test_predition
submission.to_csv('Submission.csv')

6. 特征重要性

importances=pd.Series(model_30tree.feature_importances_, index=X.columns).sort_values(ascending=True)
importances.plot(kind='barh', figsize=(8,6))

  • 排名第一的是Outlt_Type_Grocery Store。在之前的双变量分析中,Grocery Store的销售情况和其他Supermarket类型的商店明显是两类分布,所以两类商店的销售情况差异很大。
  • Item_MRP: 产品价格是造成销售额的重要因素。
  • Outlet_Years 商店成立时间也是重要的特征之一。

六、总结

本项目从建立假设开始了解数据的基本情况;接着通过数据探索(单/双变量分析)深度挖掘和调整每项数据背后的信息;接着完成数据预处理和特征工程将数据信息进一步提炼;最后从5个模型结果中,选择了表现最好的XGBRegressor模型进行调参优化。

接下来还可以针对XGBRegressor的其他参数进行调整提升;或者根据特征重要性重新进行特征选择。

参考链接:
https://datahack.analyticsvidhya.com/contest/practice-problem-big-mart-sales-iii/#About
https://www.analyticsvidhya.com/blog/2016/02/bigmart-sales-solution-top-20/
欢迎大家纠错讨论~ 如果觉得这篇文章对你有帮助也请多多留言点赞哦!^ 0 ^

Big Mart Sales prediction 商场销售预测分析项目相关推荐

  1. Big Mart Sales:预测销售结果 |Python

    BigMart的数据科学家收集了2013年不同城市的10家商店中共1599种产品的销售数据(训练集),目的是建立预测模型并预测给定商店中每种产品的销售情况(测试集).显然,这是一个回归问题.本篇文章将 ...

  2. 基于hadoop的电商销售预测分析系统HDFS+MapReduce+springboot或springcloud+Echarts

    基于hadoop的电商销售预测分析系统 使用分布式文件存储系统HDFS+mapreduce+springboot和springcloud+Echarts实现的简单的电商销售数据预测分析系统. 主要通过 ...

  3. 遗传算法——基于Big Mart Sales数据集的TPOT库实现(python)

    遗传算法 写在最前面 参考 原理 遗传算法 TPOT库 代码部分 问题描述 Big Mart Sales数据集 下载 描述 安装库 设置清华镜像源 安装库 全部代码 写在最前面 这次实习有个项目要用遗 ...

  4. 舆情分析项目-重庆公交坠江原因

    舆情分析项目 1.分析事件:重庆公交坠江原因 2.分析对象: (1)网友评论(初级分类-分词匹配:高级分类-自然语言识别,映射人类情感和意图,比如:积极.消极.无奈.讽刺.建设.谩骂.理性分析.事后. ...

  5. Hadoop学习笔记—20.网站日志分析项目案例(一)项目介绍

    Hadoop学习笔记-20.网站日志分析项目案例(一)项目介绍 网站日志分析项目案例(一)项目介绍:当前页面 网站日志分析项目案例(二)数据清洗:http://www.cnblogs.com/edis ...

  6. Dataset:Big Mart Sales数据集的简介、下载、案例应用之详细攻略

    Dataset:Big Mart Sales数据集的简介.下载.案例应用之详细攻略 目录 Big Mart Sales数据集的简介 1.特征解释 Big Mart Sales数据集的下载 Big Ma ...

  7. 从一则笑话里分析项目需求的缺陷

    某日,老师在课堂上想考考学生们的智商,就问一个男孩:"树上有十只鸟,开枪打死一只,还剩几只?" 男孩反问:"是无声枪么?" "不是." &q ...

  8. jdeps_JDeps入门–分析项目的依赖关系

    jdeps JDeps是Java依赖关系分析工具 ,这是一个命令行工具,它处理Java字节码(意味着.class文件或包含它们的JAR),并分析类之间静态声明的依赖关系. 可以用各种方式过滤结果,并可 ...

  9. JDeps入门–分析项目的依赖关系

    JDeps是Java依赖关系分析工具 ,这是一个命令行工具,它处理Java字节码(意味着.class文件或包含它们的JAR),并分析类之间静态声明的依赖关系. 可以用各种方式过滤结果,并可以将其汇总到 ...

  10. Hadoop学习笔记—20.网站日志分析项目案例(三)统计分析

    网站日志分析项目案例(一)项目介绍:http://www.cnblogs.com/edisonchou/p/4449082.html 网站日志分析项目案例(二)数据清洗:http://www.cnbl ...

最新文章

  1. double a=25/2
  2. linux svn cleanup 用法,SVN命令之清理命令(clean up)的功能及使用技巧
  3. java getmonth_Java LocalDateTime类| 带示例的getMonth()方法
  4. 那天空飘过的梅花月饼,是今年中秋最好的礼物
  5. T研究:国内云BPM市场规模尚小,预计2018年仅为3.29亿元
  6. FPGA存储器DDR5简介
  7. jenkins的groovy脚本没权限
  8. linux进程泄漏如何定位,定位Linux下定位进程被谁KILL
  9. BZOJ5109 CodePlus 2017大吉大利,晚上吃鸡!(最短路+拓扑排序+bitset)
  10. 挑战华为社招:字节跳动上千道精选面试题还不刷起来
  11. 信用卡有很多好处,远不止解决你燃眉之急这么简单
  12. 苹果手机在未激活的状况下待机时间长了会自动关机吗
  13. 常用英雄胜率怎么刷_王者荣耀怎么刷英雄胜率和场次胜率方法解析
  14. 微软的IE 全称 变为,“Windows Internet Explorer“ ,从IE7 开始了!
  15. 智能手机选购建议(2018)
  16. 最长匹配括号子序列问题
  17. 兼容chrome、firebox、IE阻止冒泡问题
  18. Ubuntu下为你的Jupyter Notebook配置桌面快捷方式和应用图标
  19. Windows 找不到 gpedit.msc
  20. 考试反思计算机专业,期中考试总结反思

热门文章

  1. DTD语法 (元素、属性、实体声明)
  2. adb 详细使用文档(ADB命令使用大全)
  3. 高效的word转换成pdf转换器
  4. MySQL基础笔记(14)-使用Amoeba和Docker搭建MySQL读写分离架构
  5. Python3的Counter类
  6. 内网渗透结束,痕迹清理必备手段
  7. 【Linux c】sipc
  8. 深度解析蔚来ET7自动驾驶技术
  9. 数据挖掘学习:站在巨人的肩膀上
  10. php easyui filebox,EasyUI1.4 新控件TextBox,FileBox