分析目标
本次分析的目标以用户和消费产品为主,意在构建用户画像。找出热门销售产品,为下一次促销做准备。
数据获取
数据来源于kaggle的Black Friday数据集,数据特征如下:
- 客户ID
- 产品ID
- 性别
- 年龄段
- 客户职业
- 所在城市类别
- 在当前城市生活年份
- 婚姻状况
- 购买产品所属类别1
- 购买产品所属类别2
- 购买产品所属类别3
- 消费额(美元)
数据导入
导入相关包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# 中文设置
plt.rcParams['font.sans-serif'] = ['SimHei']
# 坐标轴正常显示负数
plt.rcParams['axes.unicode_minus'] = False
# 使用R语言的绘图风格
plt.style.use('ggplot')
df = pd.read_csv('black_friday.csv')
df.head()
首先查看数据整体情况,检查是否存在缺失值。
df.info()
RangeIndex: 550068 entries, 0 to 550067
Data columns (total 12 columns):
User_ID 550068 non-null int64
Product_ID 550068 non-null object
Gender 550068 non-null object
Age 550068 non-null object
Occupation 550068 non-null int64
City_Category 550068 non-null object
Stay_In_Current_City_Years 550068 non-null object
Marital_Status 550068 non-null int64
Product_Category_1 550068 non-null int64
Product_Category_2 376430 non-null float64
Product_Category_3 166821 non-null float64
Purchase 550068 non-null int64
dtypes: float64(2), int64(5), object(5)
memory usage: 50.4+ MB
Product_Category_2和Product_Category_3都存在大量的缺失值。
print('Product_Category_2 缺失值占比:', df.Product_Category_2.isna().sum()/len(df))
print('Product_Category_3 缺失值占比:', df.Product_Category_3.isna().sum()/len(df))
Product_Category_2 缺失值占比: 0.3156664266963357
Product_Category_3 缺失值占比: 0.6967265865311197
品类2缺失数据166986条,缺失数据占比达31%,品类3缺失数据373299条,缺失数据占比达69%,品类数据缺失过于严重,即使进行填充,也会产生极大的误差,因此分析时忽略品类2、品类3的数据。
删除品类2和品类3的数据。
df = df.dropna(axis=1)
df.head()
构建用户画像
性别对消费的影响
genderPurchase = df.pivot_table(index=['User_ID', 'Gender'], values='Purchase', aggfunc='sum').reset_index()
genderCount = genderPurchase.groupby('Gender').size().reset_index(name='peoNum')
genderCount['Percentage'] = genderCount.peoNum / genderCount.peoNum.sum()
genderCount
女性消费者人数为1666人,占所有消费者的28.3%;男性消费者人数为4225人,占所有消费者的71.7%,是女性消费者的2.5倍。消费者以男性为主体。
groupedGender = (df.groupby('Gender').Purchase.sum() / 100000000).round(2).reset_index()
groupedGender['Percentage'] = groupedGender.Purchase / groupedGender.Purchase.sum()
groupedGender
女性消费总额为11.86亿元,占总销售额的23.3%;男性消费总额为39.10亿元,占总销售额的76.7%,
是女性消费总量的3.3倍。
plt.figure(figsize=(10, 5))
plt.bar(groupedGender.Gender, groupedGender.Purchase)
plt.title('性别-消费总额对比')
plt.xlabel('性别')
plt.ylabel('消费总额/亿元')
plt.pie(groupedGender.Purchase,labels=groupedGender.Gender,autopct='%.1f%%')
plt.title('黑色星期五\n男vs女消费占比')
男性消费者数量是女性消费者的2.5倍,但消费总额却是女性消费总额的3.3倍。原因推测为男性购买商品的客单价比女性的要高。
年龄对消费的影响
agePurchase = (df.groupby('Age').Purchase.sum() / 100000000).round(3).reset_index()
agePurchase
消费主力为18-25、26-35、36-45三个年龄段,三者总额占比近8成。其中26-35年龄段为主力中的主力,需要重点维护。18-25和36-45两个年龄段应想办法进行突破,刺激这两个群体消费,扩大盘口。
plt.figure(figsize=(10, 5))
plt.bar(agePurchase.Age, agePurchase.Purchase)
plt.title('不同年龄段消费贡献')
plt.xlabel('年龄段')
plt.ylabel('消费总额/亿元')
text = agePurchase.Purchase
for i in range(len(text)):
plt.text(i, text[i]+0.3, str(text[i]), ha='center', va='bottom', fontsize=10)
plt.figure(figsize=(10, 5))
plt.pie(agePurchase.Purchase, labels=agePurchase.Age, autopct='%.1f%%')
plt.title('黑色星期五\n不同年龄段消费占比')
饼图能较为直观的看出各年龄段的消费占比,其中18-45岁区间内的消费者需要重点维护。
城市对消费的影响
cityPurchase = (df.groupby('City_Category').Purchase.sum() / 100000000).round(3).reset_index()
cityPurchase
plt.figure(figsize=(10, 5))
plt.bar(cityPurchase.City_Category, cityPurchase.Purchase)
plt.title('不同城市消费贡献')
plt.xlabel('城市')
plt.ylabel('消费总额/亿元')
text = cityPurchase.Purchase
for i in range(len(text)):
plt.text(i, text[i]+0.3, str(text[i]), ha='center', va='bottom', fontsize=10)
plt.figure(figsize=(10, 5))
plt.pie(cityPurchase.Purchase, labels=cityPurchase.City_Category, autopct='%.1f%%')
plt.title('黑色星期五\n不同城市消费占比')
B城市消费总额为21.155亿元占比41.5%,排名第一;C城市消费总额16.638亿元占比32.7%排第二;A城市消费总额13.165亿元占比25.8%排最后。
职业对消费的影响
occupationPurchase = (df.groupby('Occupation').Purchase.sum() / 10000000).round(2).reset_index()
occupationPurchase.head()
plt.figure(figsize=(10, 5))
plt.bar(occupationPurchase.Occupation, occupationPurchase.Purchase)
plt.title('不同职业消费贡献')
plt.xlabel('职业')
plt.ylabel('消费总额/亿元')
text = occupationPurchase.Purchase
for i in range(len(text)):
plt.text(i, text[i]+0.3, str(text[i]), ha='center', va='bottom', fontsize=10)
occupationPurchase.sort_values(by='Purchase', ascending=False).head()
排名前五的职业为4,0,7,1,17,前五名消费总额占比为:
occupationPurchase.sort_values(by='Purchase', ascending=False).head().Purchase.sum() / occupationPurchase.Purchase.sum()
0.5253355836407881
结合图形可知,消费能力最强的5中职业分别是职业4、职业0、职业7、职业1、职业17,职业4、职业0是所有职业中消费能力最强的,应当重点关注。
婚姻状况对消费的影响
maritalPurchase = (df.groupby('Marital_Status').Purchase.sum() / 10000000).round(2).reset_index()
maritalPurchase.Marital_Status[0] = '未婚'
maritalPurchase.Marital_Status[1] = '已婚'
maritalPurchase
plt.figure(figsize=(10, 5))
plt.pie(maritalPurchase.Purchase,labels=maritalPurchase.Marital_Status,autopct='%.1f%%')
plt.title('黑色星期五\n已婚vs未婚消费总额占比')
未婚人群总消费占比比已婚人群高接近20%
城市生活年份对消费的影响
scyPurchase = (df.groupby('Stay_In_Current_City_Years').Purchase.sum()/100000000).round(2).reset_index()
scyPurchase
plt.figure(figsize=(10, 5))
plt.bar(scyPurchase.Stay_In_Current_City_Years, scyPurchase.Purchase)
plt.title('城市生活年份对消费的影响')
plt.xlabel('年份')
plt.ylabel('消费总额/亿元')
text = list(scyPurchase.Purchase)
for i in range(len(scyPurchase)):
plt.text(i, text[i]+0.2, str(text[i]), ha='center', va='bottom', fontsize=10)
plt.figure(figsize=(10, 5))
plt.pie(scyPurchase.Purchase, labels=scyPurchase.Stay_In_Current_City_Years, autopct='%.1f%%')
plt.title('黑色星期五\n城市生活年份消费总额占比')
在当前城市中生活一年左右的人消费力最强,其次是在当前城市生活2、3年的。
商品分析
热销品、滞销品分析
热销品前五:
df.Product_Category_1.astype(str)
productPurchase = df.pivot_table(index=['Product_ID', 'Product_Category_1'], values='Purchase', aggfunc='sum').reset_index()
productPurchase.groupby('Product_ID').Purchase.sum().reset_index().sort_values(by='Purchase', ascending=False).head()
滞销品前五:
productPurchase.groupby('Product_ID').Purchase.sum().reset_index().sort_values(by='Purchase', ascending=False).tail()
热销品类前五:
productPurchase.groupby('Product_Category_1').Purchase.sum().reset_index().sort_values(by='Purchase', ascending=False).head()
滞销品类前五:
productPurchase.groupby('Product_Category_1').Purchase.sum().reset_index().sort_values(by='Purchase', ascending=False).tail()
热销品前五依次为P00025442、P00110742、P00255842、P00059442、P00184942,这几款产品销售额在2500000左右,应该作为下次大促主推产品。P00309042、P00091742这两个商品严重滞销,应考虑清仓甩货或者重新包装上架。热销品类前五分别为1、5、8、6、2,其中1类产品的销售额是排名第二名的5类产品的两倍,应重点关注。
销售量分析
purchaseCount = df[['Product_ID', 'Purchase']].groupby('Product_ID').Purchase.count().reset_index().sort_values(by='Purchase', ascending=False)[:10]
purchaseCount
plt.figure(figsize=(10, 5))
plt.bar(purchaseCount.Product_ID, purchaseCount.Purchase)
plt.xlabel('产品ID')
plt.ylabel('销量')
text = list(purchaseCount.Purchase)
for i in range(len(purchaseCount)):
plt.text(x[i], text[i]+0.5, str(text[i]), ha='center', va='bottom', fontsize=10)
plt.title('销量前十商品')
产品销量前3分别是:P00265242、P00110742、P00112142,应当予以重点关注,P00265242产品销量虽然高但是没有进入销售额前10名,说明销售单价较低,可考虑下一次大促作为引流爆款。
总体营收指标分析
客单价
pct = df.groupby('User_ID').Purchase.sum().reset_index()
(pct.Purchase.sum() / pct.User_ID.count()).round(2)
865016.59
客单价为865016.59美元。由于缺乏订单ID和销售数量等特征,件单价和连带率无法计算。
用户累计销售金额占比
userCumsum = df.groupby('User_ID').sum().sort_values(by='Purchase', ascending=False).apply(lambda x:x.cumsum()/x.sum()).reset_index()
userCumsum[['User_ID', 'Purchase']].head()
plt.figure(figsize=(10, 5))
userCumsum.Purchase.plot()
plt.title("用户累计消费占比")
plt.ylabel('消费占比')
plt.xlabel('排序索引')
userCumsum.loc[userCumsum.Purchase>0.8,['User_ID', 'Purchase']][:5]
经过查询得知索引为2520的顾客累计消费金额为80%,可以导出这批顾客的id,作为重点对象精心维护。
总结
- 用户画像
男性消费者
26-35岁
B城市
职业0、4、7
未婚
当前所在城市生活1-2年
畅销产品P00025442、P0011074销售额在2500000左右,应该作为下次大促主推盈利型产品。
P00309042、P00091742严重滞销,应该调整战略选择清仓放弃或重新‘包装’畅销类目前5名为1、5、8、6、2,1类产品是第二名的2倍,应该重点关注并给予一定的资源倾斜,这几大类产品应该作为重点保障品类,备足货源,合理安排库存并对库存进行实时预警。
P00265242产品销量虽然排名第一但是没有进入销售额前10名,说明销售单价较低,可考虑作为下一次大促时的引流爆款
A、B城市消费能力较强,C城市与之相比有较大的上升空间,下次大促不妨对C城市适当倾斜一定资源,测试其消费上升空间
对于累计消费额占比达80%的这批头部客户,需要精心维护;优惠券之类的促销手段可以适当向已婚人士倾斜