数据说明
包含如下字段:
字段 | 字段说明 |
---|---|
user_id | 用户标识 |
order_dt | 日期标识 |
order_products | 用户购买商品数量 |
order_amount | 用户消费金额 |
数据来源
https://pan.baidu.com/s/1pL2qo1H 密码g6vv
一、了解数据
1. 加载模块
import numpy as np
import pandas as pd
import datetime
import pyecharts.options as opts
2. 读取数据
columns=['user_id','order_dt','order_products','order_amount']
user=pd.read_csv('/Users/apple/Desktop/数据分析/数据分析项目/数据集/CDNOW_master.txt',names=columns,sep='\s+')
user.head()
![](https://img.haomeiwen.com/i9682599/39aab420afb31220.jpg)
3. 查看数据类型和数据结构
user.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 69659 entries, 0 to 69658
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 user_id 69659 non-null int64
1 order_dt 69659 non-null int64
2 order_products 69659 non-null int64
3 order_amount 69659 non-null float64
dtypes: float64(1), int64(3)
memory usage: 2.1 MB
user.describe()
![](https://img.haomeiwen.com/i9682599/9e0df31d6210f8b6.jpg)
- 用户平均每笔订单购买2.4个商品,标准差在2.3,波动性不大。
- 中位数在2个商品,75分位数在3个商品,说明绝大部分订单的购买量都不多。
- 购买金额的情况差不多,大部分订单都集中在小额
二、数据处理
1. 查看是否有缺失值
user.isnull().sum()
user_id 0
order_dt 0
order_products 0
order_amount 0
dtype: int64
没有缺失值,数据很干净
2. 数据类型转换
user['order_date']=pd.to_datetime(user.order_dt,format='%Y%m%d')
user['order_month']=user['order_date'].values.astype('datetime64[M]')
user.head()
![](https://img.haomeiwen.com/i9682599/fd7b3d679041ab98.jpg)
三、月度消费数据分析
1. 每个月的CD销量统计
from pyecharts.charts import Line
monthly_sales=user.groupby('order_month')['order_products'].sum()
monthly_sales_line=(Line(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(monthly_sales.index.astype('str').tolist())
.add_yaxis(
'',
monthly_sales.values.tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
title_opts=opts.TitleOpts(title="CD月度销量趋势")
)
)
monthly_sales_line.render_notebook()
![](https://img.haomeiwen.com/i9682599/9c9c5e0b8264b3c4.jpg)
前几个月(1、2、3月)的销量是高峰期,每月销量在20000-26000之间,而从4月份开始急速下降,到后期销量趋势平稳在5000左右上下波动
2. 每个月的CD销售额统计
monthly_amount=user.groupby('order_month')['order_amount'].sum()
monthly_amount_line=(Line(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(monthly_amount.index.astype('str').tolist())
.add_yaxis(
'',
monthly_amount.values.tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
title_opts=opts.TitleOpts(title="CD月度销售额趋势")
)
)
monthly_amount_line.render_notebook()
![](https://img.haomeiwen.com/i9682599/859653c5c74e60aa.jpg)
销售金额一样呈现早期居多,后期平稳下降的趋势
3. 每个月的CD消费人数统计
# 由于一个客户单月可能多次购买,所以需要进行去重
monthly_buy=user.drop_duplicates(['user_id','order_month']).groupby('order_month')['user_id'].count()
monthly_buy_line=(Line(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(monthly_buy.index.astype('str').tolist())
.add_yaxis(
'',
monthly_buy.values.tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
title_opts=opts.TitleOpts(title="CD月度消费人数趋势")
)
)
monthly_buy_line.render_notebook()
![](https://img.haomeiwen.com/i9682599/843cbb03a7a1c093.jpg)
月度消费人数趋势一样呈现早期居多,后期平稳下降的趋势,但与销量和销售金额不一致的是,其高峰是在2月份,与销量、销售额的3月份高峰有些许差异
4. 销售额与销量的散点图
from pyecharts.charts import Scatter
cd_scatter=(Scatter(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(user['order_amount'])
.add_yaxis(
'',
user['order_products'],
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(name='销售额'),
yaxis_opts=opts.AxisOpts(name='销量')
)
)
cd_scatter.render_notebook()
![](https://img.haomeiwen.com/i9682599/f23704423a0d6d5c.jpg)
订单消费金额和订单商品量呈规律性,订单的极值较少,消费金额超出1000元的只有几个,没有很大的波动性
四、用户个体消费数据分析
1. 用户消费金额与消费次数的散点图
# 计算每个用户的消费金额与消费次数总和
a=user.groupby('user_id').sum()
user_scatter=(Scatter(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(a['order_amount'].values)
.add_yaxis(
'',
a['order_products'].values.tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(name='消费金额'),
yaxis_opts=opts.AxisOpts(name='消费次数')
)
)
user_scatter.render_notebook()
![](https://img.haomeiwen.com/i9682599/845c922ad5386de2.jpg)
用户的消费金额和消费次数规律性更强,金额和次数的关系呈线性,大部分数据集中在【消费金额为0-3000元、消费次数为0-200】的区间
2. 用户消费金额的分布图
from pyecharts.charts import Bar
# 将用户消费金额划分20个区间,分别计算每个区间的消费次数
amount_cut=pd.cut(user.groupby('user_id')['order_amount'].sum(),20,right=False).value_counts()
amount_cut_bar=(Bar(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(amount_cut.index.astype('str').tolist())
.add_yaxis(
'',
amount_cut.values.tolist(),
label_opts=opts.LabelOpts(is_show=True),
)
.set_global_opts(
title_opts=opts.TitleOpts(title='用户消费金额分布图')
)
)
amount_cut_bar.render_notebook()
![](https://img.haomeiwen.com/i9682599/da36b125d0e76986.jpg)
从上图直方图可知,大部分用户的消费能力绝集中在很低的消费档次,即【0-700元】这个区间,高消费用户只有零星几个
3. 用户累计消费金额的占比
# 按用户分组求和后,按消费金额升序排序,计算总的累计消费金额占比
b=user.groupby('user_id',as_index=False).sum().sort_values('order_amount').apply(lambda x: x.cumsum()/x.sum())
# 统计不同比例的累计消费金额的累计消费人数
user_cumsum=b.groupby('order_amount')['user_id'].count().cumsum()
user_cumsum_line=(Line(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(user_cumsum.values.tolist())
.add_yaxis(
'',
user_cumsum.index.tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(
name='用户累计消费人数',
min_=0,
max_=24000,
interval=2000,
name_gap=3
),
yaxis_opts=opts.AxisOpts(
name='用户累计消费金额占比',
min_=0,
max_=1,
interval=0.1,
splitline_opts=opts.SplitLineOpts(is_show=True)
)
)
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False),
markline_opts=opts.MarkLineOpts(
data=[
opts.MarkLineItem(x=len(user_cumsum)*0.8, name="80%"),
opts.MarkLineItem(y=0.8,name='80%')
])
)
)
user_cumsum_line.render_notebook()
![](https://img.haomeiwen.com/i9682599/889fa01d4b49f087.jpg)
由图可知,80%的用户仅贡献了30%的消费金额,而剩下的20%用户贡献了70%的消费金额,符合二八定律
4. 累计销量的占比
# 按用户分组计算后,按销量升序排序,计算总的累计销量占比
c=user.groupby('user_id',as_index=False).count().sort_values('order_dt').apply(lambda x: x.cumsum()/x.sum())
# 根据不同的销量比例,计算其对应的累计消费人数
user_counts=c.groupby('order_dt')['user_id'].count().cumsum()
user_counts_line=(Line(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(user_counts.values.tolist())
.add_yaxis(
'',
user_counts.index.tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(
name='用户累计消费人数',
min_=0,
max_=24000,
interval=2000,
name_gap=3
),
yaxis_opts=opts.AxisOpts(
name='销量的占比',
min_=0,
max_=1,
interval=0.1,
splitline_opts=opts.SplitLineOpts(is_show=True)
)
)
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False),
markline_opts=opts.MarkLineOpts(
data=[
opts.MarkLineItem(x=len(user_cumsum)*0.8, name="80%"),
opts.MarkLineItem(y=0.8,name='80%')
])
)
)
user_counts_line.render_notebook()
![](https://img.haomeiwen.com/i9682599/c433aa46b9b9b11c.jpg)
由图可知,80%的用户贡献了40%的销量,而剩下的20%用户贡献了60%的消费金额
五、用户消费行为分析
1. 用户生命周期分析
用户的第一次消费时间与最后一次消费时间
# 用户的第一次消费时间
user_first_time=user.groupby('user_id')['order_month'].min()
print(user_first_time.value_counts())
# 用户的最后一次消费时间
user_last_time=user.groupby('user_id')['order_month'].max()
print(user_last_time.value_counts())
1997-02-01 8476
1997-01-01 7846
1997-03-01 7248
Name: order_month, dtype: int64
1997-02-01 4912
1997-03-01 4478
1997-01-01 4192
1998-06-01 1506
1998-05-01 1042
1998-03-01 993
1998-04-01 769
1997-04-01 677
1997-12-01 620
1997-11-01 609
1998-02-01 550
1998-01-01 514
1997-06-01 499
1997-07-01 493
1997-05-01 480
1997-10-01 455
1997-09-01 397
1997-08-01 384
Name: order_month, dtype: int64
所有用户的第一次消费时间和最后一次消费时间,都集中在前三个月,由此猜测数据集有可能只是选择了某个时间段消费的用户在18个月内的消费行为。
所有的用户生命周期分布
# 用户生命周期:这里定义第一次消费至最后一次消费为整个用户生命
# 统计出用户第一次消费和最后一次消费的时间,相减,得出每一位用户的生命周期
user_life=((user_last_time-user_first_time)/np.timedelta64(1,'D')).reset_index().groupby('order_month',as_index=False).count()
# 用户生命周期分布
user_life_bar=(Bar(init_opts=opts.InitOpts(width='1000px',height='500px'))
.add_xaxis(user_life['order_month'].tolist())
.add_yaxis(
'',
user_life['user_id'].tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
yaxis_opts=opts.AxisOpts(
min_=0,
max_=14000,
interval=2000
),
title_opts=opts.TitleOpts(title='用户生命周期分布图')
)
)
user_life_bar.render_notebook()
![](https://img.haomeiwen.com/i9682599/6a5aca32be62bebf.jpg)
大部分用户只消费了一次,所有生命周期的大头都集中在了0天
老客户的生命周期分布
life_time=((user_last_time-user_first_time)/np.timedelta64(1,'D')).reset_index()
# 生命周期天数大于0天的即为消费两次以上的老客
active_life=life_time[life_time.order_month>0].groupby('order_month',as_index=False).count()
active_life_bar=(Bar(init_opts=opts.InitOpts(width='1000px',height='500px'))
.add_xaxis(active_life['order_month'].tolist())
.add_yaxis(
'',
active_life['user_id'].tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
title_opts=opts.TitleOpts(title='老客生命周期分布图')
)
)
active_life_bar.render_notebook()
![](https://img.haomeiwen.com/i9682599/f70c20f2eedba54a.jpg)
少部分用户集中在60天~300天,属于普通型的生命周期。高质量用户的生命周期,集中在一年365天以后,这已经属于忠诚用户了
2. 复购率和回购率
复购率
# 数据透视表(各月各个用户的消费次数)
pivoted_counts=user.pivot_table(index='user_id',columns='order_month',values='order_dt',aggfunc='count').fillna(0)
pivoted_counts.columns=user.order_month.sort_values().astype('str').unique()
# 复购率(各月消费两次以上的用户数在总消费用户数中的占比)
# 消费两次及以上记为1,消费一次记为0,没有消费记为NaN
pivoted_counts_f=pivoted_counts.applymap(lambda x : 1 if x>1 else np.NaN if x==0 else 0)
# 计算复购率
f_rate=pivoted_counts_f.sum()/pivoted_counts_f.count()
# 复购率月度趋势图
f_rate_line=(Line(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(f_rate.index.tolist())
.add_yaxis(
'',
np.around(f_rate.values*100).tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
yaxis_opts=opts.AxisOpts(
name='复购率',
axislabel_opts=opts.LabelOpts(formatter="{value} %")
),
title_opts=opts.TitleOpts(title="复购率月度趋势图")
)
)
f_rate_line.render_notebook()
![](https://img.haomeiwen.com/i9682599/7914db3e716d1acc.jpg)
图上可以看出复购率在早期,因为大量新用户加入的关系,新客的复购率并不高,比如1月新客们的复购率只有11%左右。而在后期,复购率比较稳定,在20%到25%之间波动
回购率
# 数据透视表(各月各个用户的消费金额)
pivoted_amount=user.pivot_table(index='user_id',columns='order_month',values='order_amount',aggfunc='sum').fillna(0)
pivoted_amount.columns=user.order_month.sort_values().astype('str').unique()
# 回购率(当月消费的用户,在下一个月仍旧消费的用户占当月消费用户总数的占比)
# 先判断当月是否有消费,有消费记为1,没有消费记为0
pivoted_purchase=pivoted_amount.applymap(lambda x : 1 if x>0 else 0)
# 再判断,当月消费且下月也有消费记为1,当月消费但下月没有消费记为0,当月没有消费记为NaN
def purchase_return(data):
status=[];
for i in range(17):# 循环前17个月
if data[i]==1:
if data[i+1]==1:# 当月有消费且下月有消费
status.append(1)
if data[i+1]==0:# 当月有消费但下月无消费
status.append(0)
else:
status.append(np.NaN)# 当月无消费
status.append(np.NaN)# 最后一个月没有回购率
return pd.Series(status,index=pivoted_amount.columns)
pivoted_purchase_return=pivoted_purchase.apply(purchase_return,axis=1)
# 计算回购率
h_rate=pivoted_purchase_return.sum()/pivoted_purchase_return.count()
h_rate
# 回购率月度趋势图
h_rate_line=(Line(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(h_rate.index.tolist())
.add_yaxis(
'',
np.around(h_rate.values*100).tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
yaxis_opts=opts.AxisOpts(
name='回购率',
axislabel_opts=opts.LabelOpts(formatter="{value} %")
),
title_opts=opts.TitleOpts(title="回购率月度趋势图")
)
)
h_rate_line.render_notebook()
![](https://img.haomeiwen.com/i9682599/02cc9ba1b64a8f6d.jpg)
用户的回购率高于复购率,除了前期的新客,后期一直在30%上下波动,但波动性也较强。新用户的回购率在15%左右,和老客差异不大
将回购率和复购率综合分析,可以看出,新客的整体质量低于老客,老客的回购率表现较好,复购率稍次
3. 用户留存分析
用户后续消费分析
# 将用户消费行为与用户第一次消费合并
user_purchase=user[['user_id','order_products','order_amount','order_date']]
order_date_min=user_purchase.groupby('user_id')['order_date'].min()
user_purchase_retention=pd.merge(left=user_purchase,right=order_date_min.reset_index(),how='inner',on='user_id',suffixes=('','_min'))
# 用户每一次消费距第一次消费的时间差值,并转换成时间
user_purchase_retention['order_date_diff']=user_purchase_retention.order_date-user_purchase_retention.order_date_min
user_purchase_retention['date_diff']=user_purchase_retention.order_date_diff.apply(lambda x : x/np.timedelta64(1,'D'))
user_purchase_retention.head()
![](https://img.haomeiwen.com/i9682599/386a72eee1e8aa4d.jpg)
# 将时间差值分成8个区间,代表用户当前消费时间距第一次消费属于哪个时间段呢
bin=[0,3,7,15,30,60,90,180,365]
user_purchase_retention['date_diff_bin']=pd.cut(user_purchase_retention.date_diff,bins=bin)
user_purchase_retention.head()
![](https://img.haomeiwen.com/i9682599/30932f905c5f2bd9.jpg)
# 数据透视:获得的结果是用户在第一次消费之后,在后续各时间段内的消费总额
pivoted_retention=user_purchase_retention.pivot_table(index='user_id',columns='date_diff_bin',values='order_amount',aggfunc=sum)
# 判断是否有消费,有消费记为1,没有消费记为0
pivoted_retention_trans=pivoted_retention.fillna(0).applymap(lambda x :1 if x>0 else 0)
# 用户后续消费分布图
pivoted_retention_rate=pivoted_retention_trans.sum()/pivoted_retention_trans.index.max()
pivoted_retention_bar=(Bar(init_opts=opts.InitOpts(width='1000px',height='500px'))
.add_xaxis(pivoted_retention_rate.index.astype('str').tolist())
.add_yaxis(
'',
np.round(pivoted_retention_rate.values*100).tolist()
)
.set_global_opts(
yaxis_opts=opts.AxisOpts(
axislabel_opts=opts.LabelOpts(formatter="{value} %")
),
title_opts=opts.TitleOpts(title='用户后续消费分布图')
)
)
pivoted_retention_bar.render_notebook()
![](https://img.haomeiwen.com/i9682599/4f185641acef9de5.jpg)
- 只有3%的用户在第一次消费的次日至3天内有过消费,4%的用户在3~7天内有过消费。有20%的用户在第一次消费后的三个月到半年之间有过购买,26%的用户在半年后至1年内有过购买。
- 从运营角度看,商家在用户拉新的同时,还应该注重用户忠诚度的培养,在一定时间内召回用户购买,防止用户流失
用户消费间隔分析
# 计算每位用户的两次消费间隔
def diff(group):
d=group.date_diff-group.date_diff.shift(-1)
return d
last_diff=user_purchase_retention.groupby('user_id').apply(diff)
last_diff.mean()
-68.97376814424265
求出用户的平均消费间隔时间是68天。想要召回用户,在60天左右就应该实施用户召回策略
# 用户消费间隔分布图
last_diff_cut=pd.cut(last_diff.values,bins=20,right=False).value_counts()
last_diff_bar=(Bar(init_opts=opts.InitOpts(width='1000px',height='500px'))
.add_xaxis(last_diff_cut.index.astype('str').tolist())
.add_yaxis(
'',
last_diff_cut.values.tolist(),
category_gap='0%'
)
.set_global_opts(
title_opts=opts.TitleOpts(title='用户消费间隔分布图')
)
)
last_diff_bar.render_notebook()
![](https://img.haomeiwen.com/i9682599/c18064fbd74ac369.jpg)
- 典型的长尾分布,大部分用户的消费间隔确实比较短,在【0-26天】这个区间。
- 不妨将时间召回点设为消费后立即赠送优惠券,消费后30天内调查用户使用情况并提示优惠券到期,消费后60天短信推送做进一步的召回策略
4. 用户分层
# 以月为时间窗口对用户消费进行分层
def active_status(data):
status=[]
for i in range(18):
# 本月没有消费
if data[i]==0:
if len(status)==0:# 第一月没有消费就是潜在客户
status.append('unreg')
else:
if status[i-1]=='unreg':
status.append('unreg')# 如果上月为潜在客户,本月没有消费还是潜在客户
else:
status.append('unactive')# 如果上月不是潜在客户代表之前有消费过,所以本月没有消费为不活跃客户
# 本月有消费
else:
if len(status)==0:
status.append('new')# 第一月有消费就是新客
else:
if status[i-1]=='unactive':
status.append('return')# 如果上月为不活跃客户,本月有消费是回流客户
elif status[i-1]=='unreg':
status.append('new')# 如果上月为潜在客户,本月有消费为新客
else:
status.append('active')# 如果上月既不是不活跃客户,也不是潜在客户,本月有消费为活跃用户
return pd.Series(status,index=pivoted_purchase.columns)
pivoted_purchase_status=pivoted_purchase.apply(active_status,axis=1)
pivoted_purchase_status.head()
![](https://img.haomeiwen.com/i9682599/3fe1f436deacb449.jpg)
用户分层面积图
# 换算成不同分层每月的统计量
purchase_status_counts=pivoted_purchase_status.replace('unreg',np.NaN).apply(lambda x : pd.value_counts(x))
purchase_status_counts
![](https://img.haomeiwen.com/i9682599/e844458f136a5ece.jpg)
# 用户分层面积图
purchase_status_counts=purchase_status_counts.fillna(0)
purchase_status_line=(Line(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(purchase_status_counts.columns.tolist())
.add_yaxis(
'新客',
purchase_status_counts.loc['new'].values.tolist(),
areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
'活跃客户',
purchase_status_counts.loc['active'].values.tolist(),
areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
'不活跃客户',
purchase_status_counts.loc['unactive'].values.tolist(),
areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
'回流客户',
purchase_status_counts.loc['return'].values.tolist(),
areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(
title_opts=opts.TitleOpts(title="用户分层面积图")
)
)
purchase_status_line.render_notebook()
![](https://img.haomeiwen.com/i9682599/b4623d3f998c99fa.jpg)
- 因为是前三个月部分用户的后续消费行为数据,所以从97年4月开始就没有新客
- 可以发现不活跃客户占据面积最大,活跃客户与回流客户占据面积不相上下,代表这前3个月的新客后续还是有大部分的用户流失了
回流用户占比分析
# 用户各个分层占比
purchase_status_rate=purchase_status_counts.apply(lambda x : x/x.sum(),axis=1)
# 回流用户占比
return_rate=purchase_status_rate.loc['return']
return_rate_line=(Line(init_opts=opts.InitOpts(width='1000px',height='500px'))
.add_xaxis(return_rate.index.tolist())
.add_yaxis(
'',
(return_rate.values*100).tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
yaxis_opts=opts.AxisOpts(
axislabel_opts=opts.LabelOpts(formatter="{value} %")
),
title_opts=opts.TitleOpts(title='回流用户占比趋势图')
)
)
return_rate_line.render_notebook()
![](https://img.haomeiwen.com/i9682599/bf8d9c806f2d97c9.jpg)
用户回流占比在大约在5%~8%,从整体来看,后续有下降趋势
活跃用户占比分析
# 活跃用户占比
active_rate=purchase_status_rate.loc['active']
active_rate_line=(Line(init_opts=opts.InitOpts(width='1000px',height='500px'))
.add_xaxis(active_rate.index.tolist())
.add_yaxis(
'',
(active_rate.values*100).tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
yaxis_opts=opts.AxisOpts(
axislabel_opts=opts.LabelOpts(formatter="{value} %")
),
title_opts=opts.TitleOpts(title='活跃用户占比趋势图')
)
)
active_rate_line.render_notebook()
![](https://img.haomeiwen.com/i9682599/2f44a01e89c05536.jpg)
活跃用户的下降趋势更明显,占比在3%~5%间。这里用户活跃可以看作连续消费用户,质量在一定程度上高于回流用户,所以商家除了进行用户召回策略,还需要精心维护活跃用户保持持续的消费才是根本
5. RFM用户分群分析
# 计算R、F、M值
# R:是指用户最近一次消费距离现在多长时间了,以天数为单位
# F:是指用户一段时间内消费了多少次(消费次数按用户ID分组计数)
# M:是指用户一段时间内的消费金额(求和)
group=user.groupby('user_id')
rfm=pd.DataFrame()
rfm['M']=group.sum()['order_amount']
rfm['F']=group.count()['order_dt']
rfm['R']=-(group.max()['order_date']-user['order_date'].max())/np.timedelta64(1,'D')
rfm.head()
![](https://img.haomeiwen.com/i9682599/0e13f83c46407b6e.jpg)
RFM散点图
# R与M的散点图
rm_scatter=(Scatter(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(rfm['M'])
.add_yaxis(
'最后一次消费距今天数',
rfm['R'].values.tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(name='消费金额'),
)
)
rm_scatter.render_notebook()
![](https://img.haomeiwen.com/i9682599/56c97d4bed5ea524.jpg)
可以看出大部分的用户消费金额都不高,大部分处于在【0-3000元】这个区间,最后一次消费距今天数分布比较规律
# F与M的散点图
fm_scatter=(Scatter(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(rfm['M'])
.add_yaxis(
'消费频次',
rfm['F'].values.tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(name='消费金额'),
)
)
fm_scatter.render_notebook()
![](https://img.haomeiwen.com/i9682599/2595a66a04908e31.jpg)
消费频次大部分处于在【0-50次】这个区间,和消费金额之间略微呈现线性关系
# R与F的散点图
rf_scatter=(Scatter(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(rfm['R'])
.add_yaxis(
'消费频次',
rfm['F'].values.tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(
name='最后一次消费距今天数',
name_location='middle',
name_gap=30
)
)
)
rf_scatter.render_notebook()
![](https://img.haomeiwen.com/i9682599/4074b79998b8852f.jpg)
最后一次消费距今天数分布还是一样很规律,大部分用户消费频次大概在【0-50次】这个区间,消费频次较高的用户一般都在【0-100天】这个区间,也就是代表这部分客户属于忠诚客户了,而距今天数越往后消费频次越少,还是有不少的客户流失并且不再消费
rfm用户分群
# R、F、M分为5个区间,分别打1-5分
# R:用户最近一次消费距离现在的天数越短,分值越大
# F:用户消费次数越大,分值越大
# M:用户消费金额越大,分值越大
rfm['r_cut']=rfm.R.apply(lambda x : 5 if x<=(rfm.R.max()*0.2) else 4 if x<=(rfm.R.max()*0.4) else 3 if x<=(rfm.R.max()*0.6) else 2 if x<=(rfm.R.max()*0.8) else 1)
rfm['f_cut']=rfm.F.apply(lambda x : 1 if x<=(rfm.F.max()*0.2) else 2 if x<=(rfm.F.max()*0.4) else 3 if x<=(rfm.F.max()*0.6) else 4 if x<=(rfm.F.max()*0.8) else 5)
rfm['m_cut']=rfm.M.apply(lambda x : 1 if x<=(rfm.M.max()*0.2) else 2 if x<=(rfm.M.max()*0.4) else 3 if x<=(rfm.M.max()*0.6) else 4 if x<=(rfm.M.max()*0.8) else 5)
rfm.head()
![](https://img.haomeiwen.com/i9682599/0b97cc3e1f706220.jpg)
# 每个指标与其平均值对比,判断高低
rfm['R_value']=rfm['r_cut'].apply(lambda x : '高' if x>rfm.r_cut.mean() else '低')
rfm['F_value']=rfm['f_cut'].apply(lambda x : '高' if x>rfm.f_cut.mean() else '低')
rfm['M_value']=rfm['m_cut'].apply(lambda x : '高' if x>rfm.m_cut.mean() else '低')
# 分为8个用户分群
def rfm_func(rfm):
status=[]
y=rfm.R_value+rfm.F_value+rfm.M_value
for x in y:
if x=='高高高':
status.append('重要价值用户')
elif x=='高高低':
status.append('一般价值用户')
elif x=='高低高':
status.append('重要发展用户')
elif x=='高低低':
status.append('一般发展用户')
elif x=='低高高':
status.append('重要保持用户')
elif x=='低高低':
status.append('一般保持用户')
elif x=='低低高':
status.append('重要挽留用户')
elif x=='低低低':
status.append('一般挽留用户')
return status
rfm['label']=rfm_func(rfm)
rfm.head()
![](https://img.haomeiwen.com/i9682599/6f1aaf295da07eb5.jpg)
# rfm分布图
rfm_bar=(Bar(init_opts=opts.InitOpts(width="1000px",height="500px"))
.add_xaxis(rfm['label'].value_counts().index.tolist())
.add_yaxis(
'',
rfm['label'].value_counts().values.tolist(),
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(name='rfm用户分群'),
yaxis_opts=opts.AxisOpts(name='用户个数')
)
)
rfm_bar.render_notebook()
![](https://img.haomeiwen.com/i9682599/6406913f80930c5c.jpg)
可以发现大部分的用户都处于【一般挽留用户】和【一般发展用户】,高价值的用户比较少
网友评论