消费品用户行为分析
根据CDNOW的一段用户订单数据进行消费行为分析
CDNow是一家在线音乐零售平台,后被德国波泰尔斯曼娱乐集团公司出资收购,其资产总价值在最辉煌时曾超过10亿美元。下面主要通过分析CDNow网站的用户购买明细来分析该网站的用户消费行为,使运营部门在营销时更加具有针对性,从而节省成本,提升效率。
数据包括cdnow1997年1月1日至1998年6月30日期间内购买CD交易明细。
https://links.jianshu.com/go?to=https%3A%2F%2Fpan.baidu.com%2Fs%2F1_co54-bX9Mz_e_NWV4xtOg
提取码va7h
一、分析框架
1.准备
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
2.读入数据并检查
columns = ['用户ID','订单日期','订购数','订单金额']
dataf = pd.read_table('CDNOW_master.txt',names = columns,sep = '\s+')
dataf.head()
dataf.describe()
dataf.info()
#查看一下数据情况,能读出一些简单的统计分析,如客单价35.89,平均订购数量2.41件
#能看出中位数和平均值差距比较大,可以判断出存在极大值干扰,存在一部分顾客消费金额和数量特别大
用户ID 订单日期 订购数 订单金额
0 1 19970101 1 11.77
1 2 19970112 1 12.00
2 2 19970112 5 77.00
3 3 19970102 2 20.76
4 3 19970330 2 20.76
用户ID 订单日期 订购数 订单金额
count 69659.000000 6.965900e+04 69659.000000 69659.000000
mean 11470.854592 1.997228e+07 2.410040 35.893648
std 6819.904848 3.837735e+03 2.333924 36.281942
min 1.000000 1.997010e+07 1.000000 0.000000
25% 5506.000000 1.997022e+07 1.000000 14.490000
50% 11410.000000 1.997042e+07 2.000000 25.980000
75% 17273.000000 1.997111e+07 3.000000 43.700000
max 23570.000000 1.998063e+07 99.000000 1286.010000
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 69659 entries, 0 to 69658
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 用户ID 69659 non-null int64
1 订单日期 69659 non-null int64
2 订购数 69659 non-null int64
3 订单金额 69659 non-null float64
dtypes: float64(1), int64(3)
memory usage: 2.1 MB
3.数据处理
dataf.drop_duplicates(inplace=True)#去重
dataf.dropna()#去空值行
dataf['order_date'] = pd.to_datetime(dataf['order_date'],format = '%Y%m%d')
dataf['month'] = dataf['order_date'].values.astype('datetime64[M]')
#添加月份列,修改订单日期列格式,方便统计
dataf.head()
用户ID 订单日期 订购数 订单金额 月份
0 1 1997-01-01 1 11.77 1997-01-01
1 2 1997-01-12 1 12.00 1997-01-01
2 2 1997-01-12 5 77.00 1997-01-01
3 3 1997-01-02 2 20.76 1997-01-01
4 3 1997-03-30 2 20.76 1997-03-01
4.用户总体消费趋势分析
plt.figure(figsize=(15,10))#母图大小
plt.subplot(221)#添加子图
dataf.groupby('月份')['订单金额'].sum().plot(fontsize = 24)
plt.title('总销售额',fontsize = 24)
plt.subplot(222)
dataf.groupby('月份')['用户ID'].count().plot(fontsize = 24)
plt.title('消费次数',fontsize = 24)
plt.subplot(223)
dataf.groupby('月份')['订购数'].sum().plot(fontsize = 24)
plt.title('消费数量',fontsize = 24)
plt.subplot(224)
dataf.groupby('月份')['用户ID'].apply(lambda x:x.nunique()).plot(fontsize = 24)
plt.title('用户数量',fontsize = 24)
plt.tight_layout()#调整间距
plt.show()#总体上四张图没有太大分歧,销售额销售量在前三月份暴增,之后陡降,趋于平稳
#用户数量图略有不同,在2,3月份出现小幅度持平,而此时其他数据仍然向好,判断这段时间用户质量比较高
5.用户个体消费分析
用户消费金额分布
group_by_user_id = dataf.groupby('用户ID')
group_by_user_id.sum()
group_by_user_id.sum().describe()
group_by_user_id.sum().plot.scatter(x='订购数',y='订单金额')
group_by_user_id.sum().query('订单金额<800').plot.scatter(x='订购数',y='订单金额')#极值干扰较大,取限制金额作图
plt.show()
#大部分的用户消费集中在100以下
用户购买次数分布
group_by_user_id.sum().query('订购数 < 100').订购数.hist(bins = 40)
plt.show()#高度集中在20次以下
用户消费次数与消费金额分布散点图
group_by_user_id.sum().query('订单金额<2000').plot.scatter(x='订购数',y='订单金额')
plt.show()#可以看到没有太多离散点,数据的集中程度很高,说明cdnow的产品间价格十分接近
#用户的消费次数和总金额成近似正比(y=12.5x)
6.用户消费周期
6.1用户购买周期
circle = group_by_user_id.apply(lambda x:x.订单日期- x.订单日期.shift(1))
circle.describe()
count 46089
mean 68 days 23:22:13.567662566
std 91 days 00:47:33.924168893
min 0 days 00:00:00
25% 10 days 00:00:00
50% 31 days 00:00:00
75% 89 days 00:00:00
max 533 days 00:00:00
Name: 订单日期, dtype: object
plt.hist((circle/np.timedelta64(1,'D')).dropna(),bin=50)
plt.xlabel('消费周期')
plt.ylabel('频数')
plt.title('消费周期分布')
plt.show()。
消费周期可以看出是长尾分布,用户消费周期均值是68天,75%的用户小于89天,对于CD这种耐用品,这个数值可以接受。而且这里看出大部分用户消费周期较短,0~20天出现消费周期分布的极值,可以在用户购买cd的0-20天给予优惠券或活动推送等,强化这种消费周期行为习惯的形成。
6.2用户生命周期
length = group_by_user_id.订单日期.max()-group_by_user_id.订单日期.min()
length.describe()
length = group_by_user_id.订单日期.max()-group_by_user_id.订单日期.min()
plt.hist(length/np.timedelta64(1,'D'),bins = 40)
plt.xlabel ('生命周期')
plt.show()
count 23570
mean 134 days 20:55:36.987696224
std 180 days 13:46:43.039788104
min 0 days 00:00:00
25% 0 days 00:00:00
50% 0 days 00:00:00
75% 294 days 00:00:00
max 544 days 00:00:00
Name: 订单日期, dtype: object
分布图可以看出大部分用户仅仅消费一次,就流失了,这比较符合网络平台购物的特点。
取出仅购买一次的用户,可以观察到用户生命周期分布图显示如下,可见10天(这里用bins=50)内是用户生命周期的高峰,应当在用户购买十天内鼓励用户再次购买,充分利用这十天的消费高峰,形成消费习惯延长其生命周期。
7.用户分层(RFM用户价值模型)
使用RFM模型将用户群体划分为不同的价值分层。
R (Rencency):最近一次购买距今间隔时间。最近消费时间越近的顾客越是好顾客,对提供即时的商品或是服务也最有可能会有反应
F (Frequency):最近一段时间的采购频率。越是经常购买的顾客越是商家的信任者,忠实度越高。
我们可以按消费次数划分顾客的重视程度。比如:1次是新顾客;2-3次是潜力客户;4-5次是成熟客户;更多则是忠实客户群体。把营销演变成推动客户不断地上台阶。
M (Monetary):最近一段时间的销售额。M是指标中最重要的部分,在此项目中,cd产品价格单一,M的划分作用被削弱了。同时此项目是一个很好的帕累托法则案例,即二八法则,20%的用户贡献了80%的销售额。这里用均值为划分标准展示一个2x2x2的用户价值层级的划分。
ts = dataf.pivot_table(values=['订单日期','订购数','订单金额'],index='用户ID',aggfunc={'订单日期':'max','订单金额':'sum','订购数':'sum'})
rfm = ts.rename(columns={'订购数':'F','订单金额':'M'})
rfm['R'] = (ts.订单日期.max()-ts.订单日期) /np.timedelta64(1,'D')
rfm = rfm[['R','F','M']]
rfm_ = (rfm-rfm.mean()).applymap(lambda x :1 if x>0 else 0)
def rfml(row):
d = {'111':'重要价值','011':'重要保持','101':'重要发展','001':'重要挽留','110':'潜力','100':'新客有推广价值','010':'一般维持','000':'流失'}
label =str(row['R'])+str(row['F'])+str(row['M'])
return d[label]
ts['标签'] = rfm_.apply(rfml,axis=1)
ts.groupby('标签').sum()
ts.groupby('标签').count()
订单金额 订购数
标签
一般维持 7181.28 650
新客有推广价值 196971.23 13977
流失 438291.81 29346
潜力 19937.45 1712
重要价值 1592039.62 107789
重要保持 167080.83 11121
重要发展 45785.01 2023
重要挽留 33028.40 1263
订单日期 订单金额 订购数
标签
一般维持 77 77 77
新客有推广价值 3300 3300 3300
流失 14074 14074 14074
潜力 206 206 206
重要价值 4554 4554 4554
重要保持 787 787 787
重要发展 331 331 331
重要挽留 241 241 241
以上为不同层次用户的消费人数,流失状态的消费人数排名第一,有14074人,这部分顾客仅仅消费一次就再没有出现过。重要价值客户数量排名第二,有4554人,与一般挽留用户差距比较大,但累计消费金额最多,业务方可以根据结果对客户分类运营,降低营销成本,提高ROI。
8.按用户活跃程度分层
def active_level(row):
status = []
for x in range(0,18):
if row[x] == 0:
if len(status) ==0:
status.append('未注册')
else:
if status[x-1] =='未注册':
status.append('未注册')
else:
status.append('不活跃')
else:
if len(status) == 0:
status.append('新用户')
elif status[x-1] == '不活跃':
status.append('回归')
elif status[x-1] == '未注册':
status.append('新用户')
else:
status.append('活跃')
return status
level = dataf.pivot_table(values = '订单日期',index='用户ID',columns='月份',aggfunc= 'count').fillna(0)#对用户每月消费情况做透视表
col = dataf['月份'].sort_values().astype('str').unique()#得到月份
level_ = level.apply(lambda x:pd.Series(active_level(x),index=col),axis = 1)#执行
le = level_.replace('未注册', np.NAN).apply(pd.value_counts).T.fillna(0)#排除干扰
labels = le[['活跃','新用户','回归','不活跃']].columns
index = le.reset_index()
plt.figure(figsize=(16,5))#这个图有点长,横坐标有点挤
plt.stackplot(index['index'].astype('str').apply(lambda x:x[:-3]),le['活跃'],le['新用户'],le['回归'],le['不活跃'],labels=labels)#得到堆积图
plt.xlabel('月份')
plt.ylabel('人数')
plt.title('分层用户按月统计')
plt.legend(loc = 'upper left')
plt.show()
9.用户质量分析