项目介绍:
黑色星期五是美国感恩节后一天,圣诞节前的一次大采购活动,当天一般美国商场会推出大量的打折优惠、促销活动, 由于美国的商场一般以红笔记录赤字,以黑笔记录盈利,而感恩节后的这个星期五人们疯狂的抢购使得商场利润大增,因此被商家们称作黑色星期五。 商家期望通过以这一天开始的圣诞大采购为这一年获得最多的盈利。
分析目的:
本次的分析数据来自于Kaggle提供的某电商黑色星期五的销售记录, 将围绕产品和用户两大方面展开叙述,为电商平台制定策略提供分析及建议。
本文分析的主要框架
1.整体消费的情况
2.用户画像分析(探究最优价值的用户类型:性别、年龄、职业、婚姻)
3.城市业绩分析(城市分布 、居住年限分布)
3.产品分析(探究最优价值的产品) 细化分析:产品销售额Top 10产品、产品销售额Top10 产品类别
4.最大贡献用户价值分析: 客单价、价值Top10用户清单、价值Top10用户情况
5.结论以及建议
0.数据集观察
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 #用来显示正常负号
import seaborn as sns
df=pd.read_csv("BlackFriday.csv")
df.info()
原始数据中共有12个字段,每个字段共537577行,字段解释如下:
User_ID: 用户ID
Product_ID: 产品ID
Gender: 性别
Age: 年龄
Occupation: 职业
City_Category: 城市(A,B,C)
Stay_In_Current_City_Years: 居住时长
Marital_Status: 婚姻状况
Product_Category_1 产品类别1,是一级分类
Product_Category_2 产品类别2,是二级分类
Product_Category_3 产品类别3,是三级分类
Purchase: 金额(美元)
(df.shape[0]-df.count())/df.shape[0]
其中产品类别2和3是有欠缺的
Product_Category_2将近欠缺了31%的数据
Product_Category_3将近欠缺了69%的数据
print(df["Product_Category_2"].unique())
print("-"*30)
print(df["Product_Category_3"].unique())
Product_Category_2、Product_Category_3存在NaN值
1.我们先来看下整体的消费情况
2.我们一起从用户的角度上来考虑下问题
(1)性别方面
df_gender_purchase=df.groupby("Gender").agg({"Purchase":"sum"}).reset_index().rename(columns={"Purchase":"Purchase_amout"})
df_gender_purchase["gender_purchase_prop"]=df_gender_purchase.apply(lambda x:x[1]/df["Purchase"].sum(),axis=1) #金额占比
def Gender_user_count(x):
if x[0] == "F":
return(df.loc[df["Gender"]=="F"].drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count())
if x[0] == "M":
return(df.loc[df["Gender"]=="M"].drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count())
df_gender_purchase["gender_user_count"]=df_gender_purchase.apply(lambda x:Gender_user_count(x),axis=1)
df_gender_purchase["gender_customer_price"]=df_gender_purchase.apply(lambda x:x[1]/x[3],axis=1)
df_gender_purchase["gender_user_prop"]=df_gender_purchase.apply(lambda x:x[3]/df.drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count(),axis=1)
df_gender_purchase
男性用户及消费金额远超女性,男性用户占整体的71.7%,是女性的2.5倍,男性消费金额占整体76.7%,是女性的3.3倍。
显然 有男性用户更多参与本次活动,且客单价高于女性,所以产品应倾向男性及针对男性的产品价格较高进行推销。
(2)年龄方面
df_age_purchase=df.groupby("Age").agg({"Purchase":"sum"}).reset_index().rename(columns={"Purchase":"Purchase_amout"})
df_age_purchase["age_purchase_prop"]=df_age_purchase.apply(lambda x:x[1]/df["Purchase"].sum(),axis=1)
def Age_user_count(x):
for i in df["Age"].drop_duplicates():
if x[0] == i:
return(df.loc[df["Age"]==i].drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count())
df_age_purchase["Age_user_count"]=df_age_purchase.apply(lambda x : Age_user_count(x),axis=1)
df_age_purchase["Age_Purchase_count"]=df_age_purchase.apply(lambda x: x[1]/x[3],axis=1)
df_age_purchase["Age_user_prop"]=df_age_purchase.apply(lambda x : x[3]/df.drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count(),axis=1)
df_age_purchase
购买消费金额的年龄段在18-45岁的居多,占整体78%,其中26-35岁人群的消费金额占40%
用户个数在18-45岁的占73%,其中26-35岁的个数占整体35%;
18-45岁的用户群体客单价在84万以上,消费极大。
无论是消费金额还是消费次数,18-45岁群体占主力,重点推销产品的对象是该用户群体。
(3)婚姻方面
df_Marital_purchase=df.groupby("Marital_Status").agg({"Purchase":"sum"}).reset_index().rename(columns={"Purchase":"Purchase_amount"})
df_Marital_purchase["Marital_Purchase_Prop"]=df_Marital_purchase.apply(lambda x:x[1]/df["Purchase"].sum(),axis =1)
def Marital_user_count(x):
if x[0] == 0:
return (df.loc[df["Marital_Status"]==0].drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count())
if x[0] == 1:
return (df.loc[df["Marital_Status"]==1].drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count())
df_Marital_purchase["Marital_user_count"]=df_Marital_purchase.apply(lambda x :Marital_user_count(x),axis=1)
df_Marital_purchase["Marital_Purchase_count"]=df_Marital_purchase.apply(lambda x:x[1]/x[3],axis=1)
df_Marital_purchase["Marital_user_prop"]=df_Marital_purchase.apply(lambda x:x[3]/df.drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count(),axis=1)
df_Marital_purchase
不结婚的人群在消费金额及消费次数上是已婚人群的1.5倍左右;
(4)接下来我们合并性别和婚姻状态这两个字段分析不同年龄段的销售额情况
df["Gender_MaritalStatus"]=df[["Gender","Marital_Status"]].apply(lambda x:str(x[0])+"_"+str(x[1]),axis=1)
df_Gender_MaritalStatus_purchase = df.groupby(["Gender_MaritalStatus","Age"]).agg({"Purchase":"sum"}).reset_index().rename(columns={"Purchase":"Purchase_amount"})
df_Gender_MaritalStatus_purchase
def Gender_MaritalStatus_user_count(x):
for i in df["Gender_MaritalStatus"].drop_duplicates():
for j in df["Age"].drop_duplicates():
if x[0]==i and x[1]==j:
return (df.loc[(df["Gender_MaritalStatus"]==i) & (df["Age"]==j)].drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count())
df_Gender_MaritalStatus_purchase["Gender_MaritalStatus_user_count"]=df_Gender_MaritalStatus_purchase.apply(lambda x:Gender_MaritalStatus_user_count(x),axis=1) #消费人次
df_Gender_MaritalStatus_purchase["Gender_MaritalStatus_user_price"]=df_Gender_MaritalStatus_purchase.apply(lambda x:x[2]/x[3],axis=1) #客单价
df_Gender_MaritalStatus_purchase["Gender_MaritalStatus_user_prop"]=df_Gender_MaritalStatus_purchase.apply(lambda x:x[3]/df.drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count(),axis=1) #消费人次占比
df_Gender_MaritalStatus_purchase["Gender_MaritalStatus_purchase_prop"]=df_Gender_MaritalStatus_purchase.apply(lambda x:x[2]/df["Purchase"].sum(),axis=1) #消费金额占比
df_Gender_MaritalStatus_purchase
sns.barplot(x="Age",y="Gender_MaritalStatus_user_count",hue="Gender_MaritalStatus",data=df_Gender_MaritalStatus_purchase)
26-35岁年龄段,未婚男性的消费人次最多,
18-45岁年龄段,均是未婚男性消费人次高于其他类人群
说明产品重点推售对象应该为18-45岁,未婚男性
sns.barplot(x="Age",y="Purchase_amount",hue="Gender_MaritalStatus",data=df_Gender_MaritalStatus_purchase)
消费金额
在18-45岁期间,男性未婚消费金额远超其他类人群,其中26-35岁的男性未婚消费金额最高
sns.barplot(x="Age",y="Gender_MaritalStatus_user_price",hue="Gender_MaritalStatus",data=df_Gender_MaritalStatus_purchase)
客单价
从客单价角度观察,男性客单价均高于女性
在26-45岁,男性婚否对消费金额产生的差异不大
18-25岁,男性未婚的客单价高于男性已婚
(5)我们再来考虑不同职位的下的人购买情况
df_Occupation_purchase=df.groupby("Occupation").agg({"Purchase":"sum"}).reset_index().rename(columns={"Purchase":"Purchase_amount"})
df_Occupation_purchase["Occupation_purchase_prop"]=df_Occupation_purchase.apply(lambda x:x[1]/df["Purchase"].sum(),axis=1)
def Occupation_user_count(x):
for i in df["Occupation"].drop_duplicates():
if x[0]==i:
return (df.loc[df["Occupation"]==i].drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count())
df_Occupation_purchase["Occupation_user_count"]=df_Occupation_purchase.apply(lambda x:Occupation_user_count(x),axis=1)
df_Occupation_purchase["Occupation_customer_price"]=df_Occupation_purchase.apply(lambda x:x[1]/x[3],axis=1)
df_Occupation_purchase["Occupation_user_prop"]=df_Occupation_purchase.apply(lambda x:x[3]/df.drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count(),axis=1)
df_Occupation_purchase.sort_values("Occupation_user_count",ascending=False)
4、0、7、1职业的人群合计占总人数的40%,是重点关注对象
df_Occupation_purchase["Occupation_user_prop"].plot.pie()
3.我们一起从城市贡献的角度上来考虑
df_City_Category_purchase=df.groupby("City_Category").agg({"Purchase":"sum"}).reset_index().rename(columns={"Purchase":"Purchase_amount"})
df_City_Category_purchase=df.groupby("City_Category").agg({"Purchase":"sum"}).reset_index().rename(columns={"Purchase":"Purchase_amount"})
df_City_Category_purchase["Purchase_prop"]=df_City_Category_purchase.apply(lambda x:x[1]/df["Purchase"].sum(),axis=1)
def City_Category_user_count(x):
for i in df["City_Category"].drop_duplicates():
if x[0] == i :
return (df.loc[df["City_Category"]==i].drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count())
df_City_Category_purchase["City_Category_user_count"]=df_City_Category_purchase.apply(lambda x:City_Category_user_count(x),axis=1)
df_City_Category_purchase["City_Category_customer_price"]=df_City_Category_purchase.apply(lambda x:x[1]/x[3],axis=1)
df_City_Category_purchase["City_Category_user_prop"]=df_City_Category_purchase.apply(lambda x:x[3]/df.drop_duplicates(subset=["User_ID"],keep="first")["User_ID"].count(),axis=1)
df_City_Category_purchase
B城市的消费人次占29%,但消费金额占41.5%,而C城市的消费人次占53%,但消费金额占32.6%。
A和B城市的客单价是C城市的两倍以上。
AB城市的产品价格可以进行提高,C城市的产品价格可进行调低,在C城市以提高销售量为主的推售策略,AB城市以提高销售额为主的推售策略。
4.品相方面来考虑
(1)销量Top10的产品
df_count10 = df.groupby("Product_ID").agg({"User_ID":"count","Purchase":"sum"}).rename(columns={"Purchase":"Purchase_amount","User_ID":"User_count"}).reset_index()
df_Purchase_amount10=df_count10.sort_values("Purchase_amount",ascending=False)[["Product_ID","Purchase_amount"]].head(10)
df_Purchase_amount10
(2)销售金额Top10 产品
df_User_count10=df_count10.sort_values("User_count",ascending=False)[["Product_ID","User_count"]].head(10)
df_User_count10
(3)有哪些产品在销量和销量金额都是在Top10中的
pd.merge(df_Purchase_amount10,df_User_count10,how="inner")
df_amount=df.groupby("Product_Category_1").agg({"User_ID":"count","Purchase":"sum"}).rename(columns={"Purchase":"Purchase_amount","User_ID":"User_count"}).reset_index().sort_values(by=["Purchase_amount"],ascending=False)
df_amount["Category_Prop"]=df_amount.apply(lambda x:x[2]/df["Purchase"].sum(),axis=1)
df_amount
df_amount.plot.bar(x="Product_Category_1",y="Category_Prop")
产品类型1中的1号产品消费金额占整个类型的37.5%,
5、8号产品紧跟其后,在17%左右,其余的产品竞争力不强
5、总结
1、用户角度
结论汇总:
- 年龄26-35岁,职业编号为“4、0、7”,“1”的未婚男性消费人群属于高消费人群,该平台的超级忠实用户
后续改进:
对高价值用户重点关注,进行更精细化的营销,后续为这些用户提供更多高价值的消费品;
-
针对其他用户,主要引导用户点击购买,多推荐一些热销产品;
2、商品角度
结论汇总:
- 一级产品分类的5/1/8销量、销售额都是排在前3的,这三类产品贡献了72%的销售量
- 销量排名最低的三个商品种类是17、 12 、 13,合计占比3%不到
- 即在在Top10销售额中的产品和在Top10销售量的产品,可利用爆款商品陈列位置为其他产品引流。
后续改进:
可以在最受用户欢迎的商品top10的商品和其他一些相关的商品做一些捆绑销售,带动其他商品的销量;在一级商品分类为5、1、8的商品页面推荐一些其他的商品,引导用户去点击购买;
-
具体再分析下销量排名最低的三个商品种类是什么原因造成的,如果商品种类16、11、12是一些已经淘汰过时的商品或者被一些该商品的替代品占领了市场,可以考虑是否要下架,减少相关渠道的广告等;
3、城市角度:
结论汇总:
- B城市的消费人次占29%,但消费金额占41.5%,而C城市的消费人次占53%,但消费金额占32.6%。
- A和B城市的客单价是C城市的两倍以上。
后续改进:
- 畅销第一级别类目依次是5、8、1,仓库管理需按畅销商品名单、分类,安排库存,对于消费旺盛B城市提前备货,节省调度;同时监控库存,防止断货。