kaggle黑色星期五数据集数据分析

「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战

本文数据集取自于Kaggle网站的“Black Friday”数据集,数据集背景依托于黑色星期五,黑色星期五是西方国家的大采购类似于我国的“双十一”活动,在黑五当天商场都会推出大量的优惠和折扣活动进行圣诞节前最后一次大规模的促销,以期在年关收获最大的盈利。网站为保证提供数据集的运营公司和消费用户的隐私权益不受侵犯,数据集中部分特征进行了“脱敏处理”。某零售有限公司希望了解客户针对不同类别的各种产品的购买行为(特别是购买金额)。提供了黑色星期五当天精选大批量产品的客户群体的购买信息。数据集包含两部分信息客户人口统计信息(年龄,性别,婚姻状况,城市类别,定居时长)和商品详细信息(商品id和商品类别)以及总购买金额。 kaggle数据集:www.kaggle.com/sdolezel/bl…

其各字段具体解释如表 1 1所示:

表 1‑1 数据集字段解释表

字段 含义
User_ID 用户编码
Product_ID 商品编码
Gender 性别(M为男性,F为女性)
Age 年龄(0-17,18-25,26-35,36-45,46-50,51-55,55+,7种)
Occupation 职业(用数字代表具体职业,一共20种职业)
City_Category 城市分类(分为三类城市:ABC)
Stay_in_Current_City_Years 在目前城市的居住的年数(0,1,2,3,4+,5种)
Marital_Status 婚姻状态(0为未婚,1为已婚)
Product_Category_1 产品分类为1(服饰,20种,用1-20表示)
Product_Category_2 产品分类为2(电子产品)
Product_Category_3 产品分类为3(家具用品)
Purchase 购买金额(单位为美元)
# 导入数据
df = pd.read_csv("product_data.csv")
df.head()
复制代码

image.png

基本分析

info了解基本信息

使用info对简单了解数据信息

df.info()
复制代码

image.png info() 可以让我们看到什么?

1.Dtype 数据类型
可以发现User_ID是int,而Product_ID是object类型,这是因为Product_ID含有字母,那么是只含有P这个字母?还是有其他的?我们后续需要去查看和分析.

Gender/Age/City_Category/Stay_In_Current_City_Years 这几个特征也是因为含有字符串所以是object类型,没有什么大问题,我们后续进行结构化处理。

Occupation/Marital_Status 是纯数值变量而且还是分类变量使用int挺合适的。

Product_Category_1/Product_Category_2/Product_Category_3 有意思的是虽然都是产品,但是1号是int其余的都是float。但分类变量是不可能为浮点数的,后续查看数据再决定是否转换数据类型

总结,所有数据的数据类型混乱,有大量非结构化的字符串数据需要转换成对应的数值数据,有部分数据需要转换数据类型。

2.Non-Null 数据缺失\

很直观的可以发现Product_Category_2/Product_Category_3 有缺失,而且Product_Category_3缺失貌似挺严重的。

数据量那么大,删除是肯定不得行的,所以需要思考一些有效填充策略,处理这些缺失值。

import missingno
df.isna().sum()/df.shape[0]
# 条形图 看缺失程度
missingno.bar(df)
复制代码

image.png image.png

# 矩阵图 看缺失分布
missingno.matrix(df)
复制代码

image.png

总结一下所知信息: 包含int64、object、float64三种数据类型
共有537577条交易记录,12个字段
字段Product_Category_2有31%的值缺失,Product_Category_3有69%的值缺失

挖掘字段信息

# 查看消费用户数目和物品数目
print('消费者人数:',df.User_ID.nunique())
print('商品种类:',df.Product_ID.nunique())
# 总消费金额
print('总消费金额 {}'.format(df.Purchase.sum()),"美元")
# 让我看看是谁那么买 选出消费用户TOP10
user_Purchase_top10 = df.groupby('User_ID').Purchase.count().reset_index(name='下单次数')
user_Purchase_top10['总消费额'] = df.groupby('User_ID').Purchase.sum().values
user_Purchase_top10.sort_values('下单次数',ascending=False).head(10)
复制代码

消费者人数: 5891
商品种类: 3623
好家伙消费了50亿美元!
image.png

# 查看商品类别2有多少不同的商品
print(df.Product_Category_2.unique())
print(df.Product_Category_3.unique())
复制代码

[nan, 6., 14., 2., 8., 15., 16., 11., 5., 3., 4., 12., 9.,10., 17., 13., 7., 18.]

[nan, 14., 17., 5., 4., 16., 15., 8., 9., 13., 6., 12., 3.,18., 11., 10.]

Product_Category_2和Product_Category_3均为2-18之间的正整数, 对于nan,可以采用中位数填充。但也可以猜测缺失值的商品并不属于这两个商品种类,因此用0替换缺失值,生成一个新的类别。

# 为了保证原始数据的不动copy一份源数据
# 并且希望得到一张新的表 记录5819位消费者的信息
UserInfo = df.copy()
UserInfo = UserInfo.pivot_table(index = ['User_ID','Gender','Age','Occupation','City_Category','Stay_In_Current_City_Years',\
            'Marital_Status'],values = ['Purchase'],aggfunc = 'sum').reset_index()
UserInfo.nunique()
复制代码

image.png

消费者特征:性别——2种
年龄段——7种
职业——21种
城市——3个
居住年数——5种
婚姻状况——2种\

数据可视化

创建一个函数feature_group(data,group,text),按照消费者特征分类,输出多层饼图

colors = ['salmon','lightskyblue','#FFF68F','palegreen','lightpink','silver','burlywood','plum','rosybrown']
def feature_group(data,group,text):    #data:数据集,group:要分类的字段  
    data['Number'] = 1
    feature_class = data.groupby(group)[['Purchase','Number']].sum().sort_values('Purchase',ascending = False)
    #内圈为消费者人数占比
    plt.pie(x = feature_class.Number,colors = colors,radius = 1.2,
            wedgeprops = {'width':1,'edgecolor':'w'},autopct = '%.f%%',pctdistance = 0.7)    
     #外圈为消费金额占比
    plt.pie(x = feature_class.Purchase,colors = colors,radius = 1.8,
            wedgeprops = {'width':0.6,'edgecolor':'w'},autopct = '%.f%%',pctdistance = 0.85)   
    # 图例
    plt.legend(feature_class.index,bbox_to_anchor = (1.2,1.2),fontsize = 15)
    # 图表名
    plt.title('不同'+text+'对应消费人数和消费金额占比图',y = 1.25,fontsize = 15)
    plt.show()
复制代码

性别

feature_group(UserInfo,'Gender','性别')
复制代码

image.png

malesPurchaserData = df.loc[df['Gender'] == 'M']
malesPurchaseMean = np.mean(malesPurchaserData['Purchase'])
print("男性消费用户人均销售额 = ",malesPurchaseMean)

femalsPurchaserData = df.loc[df['Gender'] == 'F']
femalsPurchaseMean = np.mean(femalsPurchaserData['Purchase'])
print("女性消费用户人均销售额 = ",femalsPurchaseMean)
复制代码

男性消费用户人均销售额 = 9504.771712960679

女性消费用户人均销售额 = 8809.761348593387

男性的消费者人数占比为72%,消费金额占比为77%,均远高于女性,男性的平均消费金额也略高于女性

年龄

feature_group(UserInfo,'Age','年龄')
复制代码

image.png

26-35岁的消费人数占比为35%,消费金额占比为40%,平均消费金额也高于其他年龄段
36-45岁的消费人数占比为20%,消费金额占比为20%,18-25岁的消费人数占比为18%,消费金额占比为18%
18-45岁的青年和中年人消费人数占比为73%,消费金额占比更是高达78%,是本次活动的消费主力

职业

# 职业太多了重新定义个大一点图函数
def feature_group_mul(data,group,text):    #data:数据集,group:要分类的字段  
    data['Number'] = 1
    feature_class = data.groupby(group)[['Purchase','Number']].sum().sort_values('Purchase',ascending = False)
    #内圈为消费者人数占比
    plt.figure(figsize=(10,8))
    plt.pie(x = feature_class.Number,colors = colors,radius = 1.2,
            wedgeprops = {'width':1,'edgecolor':'w'},autopct = '%.f%%',pctdistance = 0.7)    
     #外圈为消费金额占比
    plt.pie(x = feature_class.Purchase,colors = colors,radius = 1.8,
            wedgeprops = {'width':0.6,'edgecolor':'w'},autopct = '%.f%%',pctdistance = 0.85)   
    # 图例
    plt.legend(feature_class.index,bbox_to_anchor = (1.5,1.2),fontsize = 15)
    # 图表名
    plt.title('不同'+text+'对应消费人数和消费金额占比图',y = 1.3,fontsize = 15)

feature_group_mul(UserInfo,'Occupation','职业')
复制代码

image.png

消费人数占比最高的职业是4、0、7,占比分别为13%、12%、11%
消费金额占比最高的职业也是4、0、7,占比分别为13%、12%、11%

feature_group(UserInfo,'City_Category','城市')
复制代码

image.png

消费人数占比最高的城市是C城市,为53%,但C城市的消费金额占比仅为33%
消费金额占比最高的城市是B城市,为42%,B城市的消费人数占比为29%
A、B两城的平均消费金额较高,C城市的平均消费金额则远远低于A、B城市

feature_group(UserInfo,'Stay_In_Current_City_Years','居住年数')
复制代码

image.png

居住1年的消费者数量最多,消费的金额也最多,不同居住年数消费者的平均消费金额相差无几

feature_group(UserInfo,'Marital_Status','婚姻状况')
复制代码

image.png

未婚人士的消费人数、消费金额、平均消费金额都要高于已婚人士,果然没结婚才能尽情的买买买

#针对城市、年龄两个特征进行进一步探索
fig = plt.figure(figsize=(10,5))
width_bar = 0.12
width_add = 0
for c,Age in enumerate(sorted(UserInfo.Age.unique())):
    City_Age = UserInfo[UserInfo.Age == Age].groupby('City_Category').Purchase.sum()\
        .reset_index(name = 'Purchase')
    City_Age['Purchase'] = round(City_Age['Purchase'] / 1000000,1)
    plt.bar(np.arange(UserInfo.City_Category.nunique()) + width_add,City_Age['Purchase'],width = width_bar,\
        color = colors[c],label = Age)
    for x,y in enumerate(City_Age.Purchase):
        plt.text(x + width_add,y + 8,y,ha = 'center')
    width_add += width_bar
plt.title('不同城市、年龄消费金额对比图',y = 1.02,fontsize = 13)
plt.xlabel('城市',fontsize = 12)
plt.ylabel('消费金额(百万美元)',fontsize = 12)
plt.xlim(-0.1,3.2)
plt.ylim(0,900)
plt.xticks(np.arange(UserInfo.City_Category.nunique()) + 0.3,sorted(UserInfo.City_Category.unique()))
plt.tight_layout()
plt.legend()
plt.show()
复制代码

image.png

26-35岁的青年人是消费主力,消费金额高于其他年龄段
18-45岁的青年、中年消费者贡献的消费金额在A、B两城市占比极高,在C城市则要低一些
C城市的1-17岁的未成年消费者和55+的老年消费者贡献的消费金额要高于A、B城市
初步推测C城市为人口流出型城市

#针对城市、婚姻状态两个特征进行进一步探索
fig = plt.figure(figsize=(10,5))
width_bar = 0.12
width_add = 0
for c,M in enumerate(sorted(UserInfo.Marital_Status.unique())):
    City_M = UserInfo[UserInfo.Marital_Status == M].groupby('City_Category').Purchase.sum()\
        .reset_index(name = 'Purchase')
    City_M['Purchase'] = round(City_M['Purchase'] / 1000000,1)
    plt.bar(np.arange(UserInfo.City_Category.nunique()) + width_add,City_M['Purchase'],width = width_bar,\
        color = colors[c],label = M)
    for x,y in enumerate(City_M.Purchase):
        plt.text(x + width_add,y + 8,y,ha = 'center')
    width_add += width_bar
plt.title('不同城市、婚姻状态消费金额对比图',y = 1.02,fontsize = 13)
plt.xlabel('城市',fontsize = 12)
plt.ylabel('消费金额(百万美元)',fontsize = 12)
plt.xlim(-0.1,3.2)
plt.ylim(0,1500)
plt.xticks(np.arange(UserInfo.City_Category.nunique()) + 0.1,sorted(UserInfo.City_Category.unique()))
plt.tight_layout()
plt.legend()
plt.show()
复制代码

image.png

#先来看一看销售额排名前20的商品
Product_Top20 = df.groupby('Product_ID').Purchase.sum().reset_index(name = 'Purchase')
Product_Top20 = Product_Top20.sort_values('Purchase',ascending = False)[:20]
Product_Top20['Purchase'] = round(Product_Top20['Purchase'] / 1000000,1)
fig = plt.figure(figsize=(10,4.5))
plt.bar(range(20),Product_Top20.Purchase,color = colors,width = 0.6)
for x,y in enumerate(Product_Top20.Purchase):
    plt.text(x,y + 0.5,y,ha = 'center')
plt.xticks(range(20),Product_Top20.Product_ID,rotation = -90)
plt.ylim(0,30)
plt.xlabel('产品品类',fontsize = 12)
plt.ylabel('销售额(百万美元)')
plt.title('Top20商品销售额对比图')
plt.tight_layout()
plt.show()
复制代码

image.png

有16个品类的商品销售额突破了20百万美元,最高的是P00025442,为27.5百万美元

#看一看销售额前20%的商品占总销售额的比例
Product_Group = df.groupby('Product_ID').Purchase.sum().sort_values(ascending = False)
Product_Group[:int(df.Product_ID.nunique() * 0.2)].sum() / Product_Group.sum()
复制代码

0.7317218081007266

销售额前20%的商品销售额占比高达73%,基本符合二八法则

#因为Product_Category_2、Product_Category_3缺失值太多,暂不分析,只对Product_Category_1(类别1)进行分析
#分析一下类别1各个类别的销售额
Category_Group = round(df.groupby('Product_Category_1').Purchase.sum().sort_values(ascending = False) /10000000,1)
fig = plt.figure(figsize=(10,4))
plt.bar(range(df.Product_Category_1.nunique()),Category_Group,color = colors,width = 0.6)
for x,y in enumerate(Category_Group):
    plt.text(x,y + 3,y,ha = 'center')
plt.xticks(range(df.Product_Category_1.nunique()),Category_Group.index)
plt.ylim(0,200)
plt.xlabel('类别',fontsize = 12)
plt.ylabel('销售额(百万美元)',fontsize = 12)
plt.title('不同分类销售额对比图',fontsize = 13)
plt.tight_layout()
plt.show()

#条形图不太方便,通过饼图来直观感受占比
plt.figure(figsize=(12,9))
plt.pie(x = Category_Group,colors = colors,radius = 1.5,wedgeprops = {'width':0.6,'edgecolor':'w'},\
            autopct = '%.f%%',pctdistance = 0.8,labels = Category_Group.index)
plt.title('不同分类销售额对比图',y = 1.14,fontsize = 13)
plt.show()
复制代码

image.png

image.png 销售额排名第一的类别是1,是188.3百万美元,占比38%
销售额排名第二、第三的类别是5和8,销售额占比分别是18%,17%
18、9、17、12、13五个类别的商品销售额都小于1百万美元
不同类别的商品销售额悬殊极大

# 箱型图 查看数据分布和异常值
fig = plt.figure(figsize=(14,6))
sns.boxplot(x = 'Product_Category_1',y = 'Purchase',data = df)
plt.tight_layout()
plt.title('不同类别商品销售单价箱线图',fontsize = 14)
plt.show()
复制代码

image.png

销售额最多的类别1、5、8的销售单价都处于中游或较低的位置,证明这3个类别商品的需求量非常高
类别10的销售单价最高,但销售额仅占比2%,其他销售单价较高的类别销售额也普遍不高
类别12、13的销售单价最低,销售额也是最少的,加起来还不足1百万美元

#结合商品类别和消费者性别进行分析,看一看男性和女性消费者的消费偏好
Category_Gender_pvt = pd.pivot_table(df,index = 'Product_Category_1',columns = 'Gender',\
values = 'Purchase',aggfunc = np.sum)
M_Percent = round(Category_Gender_pvt.M / df.groupby('Product_Category_1').Purchase.sum() *100,1)
F_Percent = round(100 - M_Percent,1)
fig = plt.figure(figsize=(12,4.5))
width_bar = 0.35
plt.bar(np.arange(18) - width_bar * 0.5,M_Percent,width = width_bar,color = colors[0],label = 'M')
for x1,y1 in enumerate(M_Percent):
    plt.text(x1 - width_bar * 0.5,y1 + 2,y1,ha = 'center')
plt.bar(np.arange(18) + width_bar * 0.5,F_Percent,width = width_bar,color = colors[1],label = 'F')
for x2,y2 in enumerate(F_Percent):
    plt.text(x2,y2 + 2,y2)
plt.xticks(np.arange(18),Category_Gender_pvt.index)
plt.xlim(-0.8,19)
plt.ylim(0,100)
plt.xlabel('类别',fontsize = 12)
plt.ylabel('百分比(%)',fontsize = 12)
plt.title('各类别男女销售额占比图',fontsize = 14)
plt.legend()
plt.tight_layout()
plt.show()
复制代码

image.png

男性消费比例最高的类别是17、18,分别占比89.6%、88.2%
女性消费比例最高的类别是14、12,分别占比42.8%、40.7%,比例仍低于男性
最热销的类别1、5、8男性的消费额均远高于女性

小结

男性在消费中占据主导地位,青壮年未婚人群购买力较强,可以作为目标市场,单价对销量影响显著,针对不同城市的人口状况可以投放不同的产品,精准投放,以求得利益最大化。

Guess you like

Origin juejin.im/post/7034882878794104862