根据历史数据预测未来数据_XGBoost预测未来销售数据

本文介绍了一场比赛,目标是根据历史销售数据预测未来销售额。数据集包括每日销售历史,需要预测测试集中每个商店的月度销售总量。文章详细分析了数据,并探讨了item_id、shop_id、价格和日期等关键特征。接着,文章介绍了如何使用XGBoost进行预测,包括数据处理、模型构建、损失函数选择和结果评估。
摘要由CSDN通过智能技术生成

一、比赛简介

在本次比赛中,您将使用具有挑战性的时间序列数据集,其中包括每日销售数据,该数据集由俄罗斯最大的软件公司之一-1C Company提供。

我们要求您预测下个月每个产品和商店的总销售额。通过解决这一竞争,您将能够应用和增强您的数据科学技能。

系统会为您提供每日历史销售数据。任务是预测测试集在每个商店中出售的产品总数。请注意,商店和产品清单每个月都会略有变化。创建可以处理此类情况的可靠模型是挑战的一部分。

二、数据分析1

数据集简介

  • sales_train.csv-训练集。2013年1月至2015年10月的每日历史数据。
  • test.csv-测试集。您需要预测这些商店和产品在2015年11月的销售额。
  • sample_submission.csv-正确格式的示例提交文件。
  • items.csv-有关项目/产品的补充信息。
  • item_categories.csv- 有关项目类别的补充信息。
  • shop.csv-有关商店的补充信息。

属性简介

  • ID- 代表测试集中的(商店,商品)元组的ID
  • shop_id-商店的唯一标识符
  • item_id-产品的唯一标识符
  • item_category_id-项目类别的唯一标识符
  • item_cnt_day-销售的产品数量。您正在预测该指标的每月金额
  • item_price-商品的当前价格
  • 日期 -格式为dd / mm / yyyy的日期
  • date_block_num-连续的月份号,为方便起见。2013年1月为0,2013年2月为1,...,2015年10月为33
  • item_name- 项目名称
  • shop_name-商店名称
  • item_category_name-项目类别名称
%matplotlib inline
 import pandas as pd
 import numpy as np
 import matplotlib.pyplot as plt
 import seaborn as sns

利用pandas分析数据,可以发现没用空值和缺失值等

sale_train = pd.read_csv('data/data45414/sales_train.csv')
 ​
 print("----------前五行数据----------")
 print(sale_train.head(5))
 print("-----------数据信息-----------")
 print(sale_train.info())
 print("-----------数据类型-----------")
 print(sale_train.dtypes)
 print("----------缺失值-----------")
 print(sale_train.isnull().sum())
 print("----------空值-----------")
 print(sale_train.isna().sum())
 print("----------数据集大小----------")
 print(sale_train.shape)
 ----------前五行数据----------
          date  date_block_num  shop_id  item_id  item_price  item_cnt_day
 0  02.01.2013               0       59    22154      999.00           1.0
 1  03.01.2013               0       25     2552      899.00           1.0
 2  05.01.2013               0       25     2552      899.00          -1.0
 3  06.01.2013               0       25     2554     1709.05           1.0
 4  15.01.2013               0       25     2555     1099.00           1.0
 -----------数据信息-----------
 <class 'pandas.core.frame.DataFrame'>
 RangeIndex: 2935849 entries, 0 to 2935848
 Data columns (total 6 columns):
 date              object
 date_block_num    int64
 shop_id           int64
 item_id           int64
 item_price        float64
 item_cnt_day      float64
 dtypes: float64(2), int64(3), object(1)
 memory usage: 134.4+ MB
 None
 -----------数据类型-----------
 date               object
 date_block_num      int64
 shop_id             int64
 item_id             int64
 item_price        float64
 item_cnt_day      float64
 dtype: object
 ----------缺失值-----------
 date              0
 date_block_num    0
 shop_id           0
 item_id           0
 item_price        0
 item_cnt_day      0
 dtype: int64
 ----------空值-----------
 date              0
 date_block_num    0
 shop_id           0
 item_id           0
 item_price        0
 item_cnt_day      0
 dtype: int64
 ----------数据集大小----------
 (2935849, 6)

我们可以发现存在之重复值,但是只有6行,因此是否进行处理对整体的数据并无太大影响

print('重复数量:', len(sale_train[sale_train.duplicated()]))
 重复数量: 6

接下来可以对数据类型进行修改,减小数据集的大小

def downcast_dtypes(df):
     float_cols = [c for c in df if df[c].dtype == "float64"]    # 取得类型为float64的类别
     int_cols = [c for c in df if df[c].dtype in ["int64", "int32"]]    # 取得类型为int64和32的类别
     df[float_cols] = df[float_cols].astype(np.float32)
     df[int_cols] = df[int_cols].astype(np.int16)
     return df
 ​
 sale_train = downcast_dtypes(sale_train)
 print(sale_train.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2935849 entries, 0 to 2935848
Data columns (total 6 columns):
date object
date_block_num int16
shop_id int16
item_id int16
item_price float32
item_cnt_day float32
dtypes: float32(2), int16(3), object(1)
memory usage: 61.6+ MB
None

根据item_id查看数据,并画图

sales_by_item_id = sale_train.pivot_table(index=['item_id'],values=['item_cnt_day'], 
                                         columns='date_block_num', aggfunc=np.sum, fill_value=0).reset_index()    # item_id为第一列标签,date_block_num为行标签,对同一个item_id的item_cnt_day求和,并且空值填充为0,最后重置索引
 # print(sales_by_item_id.head(5))
 sales_by_item_id.columns = sales_by_item_id.columns.droplevel().map(str)    # 去掉字符索引
 # print(sales_by_item_id.head(5))
 sales_by_item_id = sales_by_item_id.reset_index(drop=True).rename_axis(None, axis=1)    # 去掉字符索引
 # print(sales_by_item_id.head(5))
 sales_by_item_id.columns.values[0] = 'item_id'    # 填充字符标志
 ​
item_id 0 1 2 3 4 5 6 7 8 ... 24 25 26 27 28 29 30 31 32
0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0
2 2 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0
3 3 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0
4 4 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0
33
0 0
1 0
2 0
3 0
4 0
[5 rows x 35 columns]
print(sales_by_item_id.head(5))
 print(sales_by_item_id.sum()[1:])
 sales_by_item_id.sum()[1:].plot(legend=True, label="Monthly sum")    # 各月份所有货物总和
 print(sales_by_item_id.mean()[1:])
 sales_by_item_id.mean()[1:].plot(legend=True, label="Monthly mean")    # 月平均
0 131479
1 128090
2 147142
3 107190
4 106970
5 125381
6 116966
7 125291
8 133332
9 127541
10 130009
11 183342
12 116899
13 109687
14 115297
15 96556
16 97790
17 97429
18 91280
19 102721
20 99208
21 107422
22 117845
23 168755
24 110971
25 84198
26 82014
27 77827
28 72295
29 64114
30 63187
31 66079
32 72843
33 71056
dtype: int64

417f00f2377ee652bdb5d9a5e4d0bb79.png
0 6.029211
1 5.873802
2 6.747466
3 4.915394
4 4.905306
5 5.749576
6 5.363691
7 5.745449
8 6.114184
9 5.848627
10 5.961801
11 8.407484
12 5.360618
13 5.029899
14 5.287156
15 4.427753
16 4.484340
17 4.467786
18 4.185812
19 4.710460
20 4.549365
21 4.926033
22 5.403999
23 7.738570
24 5.088779
25 3.861054
26 3.760902
27 3.568900
28 3.315220
29 2.940065
30 2.897556
31 3.030174
32 3.340349
33 3.258403
dtype: float64

36ca0d077bac3fe58f52669aaade1154.png

查看有多少货物在6个月内无销量

outdated_items = sales_by_item_id[sales_by_item_id.loc[:,'27':].sum(axis=1)==0]
 print('过时:', len(outdated_items))

过时: 12391

查看测试集中过时货物占多少

test = pd.read_csv('data/data45414/test.csv')
 print('测试集中的过时货物:', len(test[test['item_id'].isin(outdated_items['item_id'])]))

测试集中的过时货物: 6888

查看销售量和销售价格中的异常值

plt.figure(figsize=(10,4))
 plt.xlim(-100, 3000)
 sns.boxplot(x=sale_train['item_cnt_day'])
 print('Sale volume outliers:',sale_train['item_id'][sale_train['item_cnt_day']>500].unique())
 ​
 plt.figure(figsize=(10,4))
 plt.xlim(sale_train['item_price'].min(), sale_train['item_price'].max())
 sns.boxplot(x=sale_train['item_price'])
 print('Item price outliers:',sale_train['item_id'][sale_train['item_price']>50000].unique())
Sale volume outliers: [ 8057 20949 9242 19437 3731 11373 9249 9248]
Item price outliers: [11365 6066 13199]

e168ba7e38ffdfca5c7f0b1c3d09d5d2.png

898e336b69199b52cc041eeefff23721.png

可能的item_id特征:

  • 滞后性
  • 销售日期
  • 上月销售量
  • 打折日期
  • 相关的数据

根据shop_id查看数据

根据商店分类数据,可能存在新店有高峰值,6个月无销售量的店可能关门了

sales_by_shop_id = sale_train.pivot_table(index=['shop_id'],values=['item_cnt_day'], 
                                         columns='date_block_num', aggfunc=np.sum, fill_value=0).reset_index()
 sales_by_shop_id.columns = sales_by_shop_id.columns.droplevel().map(str)
 sales_by_shop_id = sales_by_shop_id.reset_index(drop=True).rename_axis(None, axis=1)
 sales_by_shop_id.columns.values[0] = 'shop_id'
 ​
 for i in range(6,34):
     print('Not exists in month',i,sales_by_shop_id['shop_id'][sales_by_shop_id.loc[:,'0':str(i)].sum(axis=1)==0].unique())
 ​
 for i in range(6,28):
     print('Shop is outdated for month',i,sales_by_shop_id['shop_id'][sales_by_shop_id.loc[:,str(i):].sum(axis=1)==0].unique())
Not exists in month 6 [ 9 11 20 33 34 36 39 40 48 49]
Not exists in month 7 [ 9 11 20 33 34 36 39 40 48 49]
Not exists in month 8 [ 9 11 20 33 34 36 39 40 48 49]
Not exists in month 9 [11 20 33 34 36 39 40 48 49]
Not exists in month 10 [11 20 33 34 36 39 40 48 49]
Not exists in month 11 [11 20 33 34 36 39 40 48]
Not exists in month 12 [11 20 33 34 36 39 40 48]
Not exists in month 13 [11 20 33 34 36 39 40 48]
Not exists in month 14 [11 20 33 34 36 48]
Not exists in month 15 [11 20 33 34 36]
Not exists in month 16 [11 20 33 34 36]
Not exists in month 17 [11 20 33 34 36]
Not exists in month 18 [11 20 33 36]
Not exists in month 19 [11 20 36]
Not exists in month 20 [11 20 36]
Not exists in month 21 [11 36]
Not exists in month 22 [11 36]
Not exists in month 23 [11 36]
Not exists in month 24
  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值