某网站用户的消费趋势及行为分析
该数据来源于某网站的消费记录,现针对该数据对用户的消费趋势及消费行为进行分析。
链接:https://pan.baidu.com/s/17I7JN579RZS6zvsJCWHOug 提取码:ydqa
主要内容:
1、导入第三方库及数据、观察数据、修改数据类型
2、用户消费的趋势分析
- 每月的消费总金额及其变化趋势
- 每月的消费次数及其变化趋势
- 每月的消费人数
- 每月用户平均消费金额的趋势
- 每月用户平均消费次数的趋势
3、用户个体消费分析
- 用户消费金额、消费次数的描述统计
- 用户消费金额的分布图
- 用户消费的商品数的分布图
- 用户消费金额和商品数的散点图
4、用户消费行为分析
- 用户第一次消费及最后一次消费
- 用户购买周期(按第一次和最后一次消费)
- 多少客户仅消费了一次
- 用户生命周期描述
- 用户生命周期分布
- 用户分层
- RFM
- 新客户、活跃客户、不活跃客户、回流客户
5、复购率和回购率分析
1、导入第三方库及数据、观察数据、修改数据类型
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
columns=['user_id','order_dt','order_products','order_amount']
df=pd.read_table(r'C:\Users\f\Desktop\shujufenxi\CDNOW_master.txt',names=columns,sep='\s+')
df.head()
image.png
其中各个字段的含义如下:
•user_id:用户id
•order_dt:每笔订单生成的日期
•order_products:每笔订单中所包含的商品数
•order_amount:每笔订单的消费总额
df.describe()
image.png
- 其中用户数有69659,平均每笔订单中有2.4个产品,最少的订单中有1个产品,最多的有99个产品,存在一定的极值干扰; 其中每笔订单的平均消费为35元左右,而最小的消费额为0,最大的则为1286,也存在一定的极值干扰。
df.info()
各字段的数据类型.png
- 从表格的各项属性信息中可以看到,订单日期的格式为数字模式,需对其进行修正
df['order_dt']=pd.to_datetime(df.order_dt,format='%Y%m%d')
df['month']=df.order_dt.values.astype('datetime64[M]')
df.head()
image.png
- 此处将各个月份的不同日期所生成的订单的日期统一归为同一个月份,以便后续进行分析使用
df.info()
image.png
- 现已将订单的日期类型修正为正确的数据类型
2、用户消费的趋势分析
每月的消费总金额及其变化趋势
思路:设置图标格式>>对月份进行分组>>对每个月的消费金额求和>>制图
plt.style.use('ggplot')
df.groupby('month')['order_amount'].sum().plot()
image.png
- 由消费总金额的变化趋势图可以看出,97年前三个月份消费金额逐渐上升并达到高峰,但三月份后出现断崖式下跌,并于随后的连续的月份中呈现出逐渐下降的趋势。可见在三月份可能出现营销方面的危机或者与产品的淡旺季的交替有所相关。
每月的消费次数及其变化趋势
思路:对月份进行分组>>求得每个月进行消费的用户总数>>制图
df.groupby('month').user_id.count().plot()
image.png
- 通过对每月的消费次数的变化趋势的体现来看,也表现出前三个月逐渐攀升至顶峰最后出现断崖式下跌并持续缓慢下降的趋势。说明客户对于该产品的消费意愿在下降,亦有可能是该产品的曝光率突然下跌,导致客户很难再更好的了解到产品信息,从而出现消费次数下跌的情况等等。
每月的消费人数
思路:对月份进行分组>>运用匿名函数对用户id去重并计算个数>>制图
df.groupby('month').user_id.apply(lambda x:len(x.drop_duplicates())).plot.pie(autopct='%.2f%%')
image.png
- 由饼图可知,前三个月的消费人数分别占到了14.17%、17.39%、17.20%,其前三个月的消费人数总合将近等于后续好几个月的消费人数的综合,占比近百分之50,可见后续可能是对顾客的营销力度或吸引力度做的不到位等等。
每月用户平均消费金额的趋势
- 制数据透视表
df.pivot_table(index='month',
values=['order_products','order_amount','user_id'],
aggfunc={'order_products':'sum',
'order_amount':'sum',
'user_id':'count'}).head()
image.png
思路:对‘月份’及‘用户id’进行分组求和>>去掉表中的索引打平>>再按月份进行分组>>对每月的消费金额求平均>>制图
df.groupby(['month','user_id']).sum().reset_index().groupby('month')['order_amount'].mean().plot()
image.png
每月用户平均消费次数的趋势
思路:对‘月份’和‘用户id’进行分组计数>>去除索引打平并将其命名为‘user_c’的表>>在‘user_c’表中添加一列‘count’,让这一列的值等于‘order_products’列的值>>在‘user_c’表中对月份进行分组并对‘count’求平均值>>制图
user_c=df.groupby(['month','user_id']).count().reset_index()
user_c['count']=user_c['order_products']
user_c.loc[:,['month','user_id','count']].groupby('month')['count'].mean().plot()
image.png
- 综合用户每月消费金额的数据透视表、平均消费金额、平均消费次数的图标信息可知。前三个月的用户流量较高,消费的总商品数也较多,自然总体的消费金额也是相对较高,但平均到这么大的用户流量上的时候,平均消费金额及平均消费次数自然也会相对较低,说不定这其中还包含有只消费一次后续都不再消费,而且消费金额较低的用户,这也将大大拉低平均值。但是从平均消费金额及平均消费次数的趋势图上可以看到,随着前三个月的上涨趋势后是区域稳定的震荡阶段,结合数据透视表可以了解到,后续的月份的用户流量及消费总金额较稳定,这其中可能存在忠实用户的贡献也免不了会有老客户的流失的现象。因此,若每个月想争取有更高的消费金额,应积极引流,增大用户流量,加大营销力度,促进用户多消费。
3、用户个体消费分析
用户消费金额、消费次数的描述统计
思路:对用户id进行分组求和
df.groupby('user_id').sum().describe()
image.png
- 由上述表格可知,所有订单的商品总数是23570,而其中每个用户平均消费的商品数是7笔左右,有75%的用户的购买的商品数小于等于7,然而所有用户中购买到的商品数的最小值是1,最大值是1033,中位数3,因此可见会存在一定的极值干扰。
- 同上,每个用户消费金额的数据分析也呈现出如上的形式,也有可能存在一定的极值干扰。
用户消费金额的分布图
思路:对用户id进行分组求和>>对‘order_amount’列中小于1100的值进行制图
df.groupby('user_id').sum().query('order_amount<1100').order_amount.plot.hist(bins=25)
image.png
用户消费的商品数的分布图
思路:对用户id进行分组求和>>对‘order_products’列中小于60的值进行制图
df.groupby('user_id').sum().query('order_products < 60').order_products.plot.hist(bins=35)
image.png
用户消费金额和商品数的散点图
思路:对用户id进行分组>>以‘order_amount’为x轴,以‘order_products’为y轴>>制图
df.groupby('user_id').sum().plot.scatter(x='order_amount',y='order_products')
image.png
- 人为去除异常值
df.groupby('user_id').sum().query('order_amount <4000').plot.scatter(x='order_amount',y='order_products')
image.png
- 由‘用户消费金额的分布图’及‘用户消费商品数的分布图’可以看出,大部分用户消费的金额在范围0-200之间,消费的商品数在0-10之间,除个别大客户的高消费外,吸引、加大一般客户的消费意愿还是至关重要的,大客户可以通过专项服务来维持。最后‘消费金额与商品数的散点图’中可以看出,去除个别异常值之后可知:消费金额和商品数之间还是存在一定的正相关,同时大量的商品数及金额分布集中在一般用户的这个范围内,因此最后商品的营销,用户的引流是促进经营、增加营收的重中之重。
4、用户消费行为分析
用户第一次消费及最后一次消费
思路:以用户id进行分组>>求出每个用户第一次消费的时间>>制图
df.groupby('user_id').order_dt.min().value_counts().plot()
image.png
思路:以用户id进行分组>>求出每个用户最后一次消费的时间>>制图
df.groupby('user_id').max().order_dt.value_counts().plot()
image.png
- 由两图交叉对比分析可知:前三个月的用户流量中,新增的首次消费的用户中有大量的用户只消费了一次,后续的月份中就没有再消费了,因此最后一次消费的表中,前三个月的值比较高;第一次消费的表中,后续几个月虽然新增用户有所增加但最后新增的用户量也在逐渐减少,而最后一次消费的表中,用户量后续几个月虽然不多,但最后也在逐渐增多,此消彼长中大体也可以看出:用户在逐渐流失。
用户购买周期
1)多少客户仅消费了一次
思路:对用户id进行分组>>分别求得用户购买商品第一次和最后一次的消费时间>>求出两次时间都为同一天的用户的总数
user_life=df.groupby('user_id').order_dt.agg(['min','max'])
(user_life.loc[:,'min']==user_life.loc[:,'max']).value_counts()
image.png
- 以上数据表明:仅消费一次的用户所占的比例占到了全部用户的一半左右。
2)用户生命周期描述
(user_life['max']-user_life['min']).describe()
image.png
- 由以上数据表明:用户平均生命周期为134天,而有50%的用户生命周期为0天,中位数为0天,但是却有75%用户生命周期在294天及以下,最大的用户生命周期为544天,可见这其中有大量的客户是只在一天有消费过,后期就没有再消费了,而平均天数是通过忠实客户的生命周期来拉升的。
3)用户生命周期分布
((user_life['max']-user_life['min'])/np.timedelta64(1,'D')).hist(bins=20)
image.png
- 上表印证了生命周期描述的信息,只消费一天的用户占据着特别大的数量
#除去只消费一天的用户数
user_life['a0']=(user_life['max']-user_life['min'])/np.timedelta64(1,'D')
user_life.loc[user_life['a0']>0]['a0'].hist(bins=20)
image.png
用户分层
1)RFM
rfm=df.pivot_table(index='user_id',
values=['order_products','order_amount','order_dt'],
aggfunc={'order_dt':'max',
'order_amount':'sum',
'order_products':'sum'})
rfm['R']=-(rfm.order_dt-rfm.order_dt.max())/np.timedelta64(1,'D')
rfm.rename(columns={'order_products':'F','order_amount':'M'},inplace=True)
def rfm_func(x):
level1=x.apply(lambda x:'1' if x>= 0 else '0')
lable=level1.R+level1.F+level1.M
d={'111':'重要价值客户',
'011':'重要保持客户',
'101':'重要挽留客户',
'001':'重要发展客户',
'110':'一般价值客户',
'010':'一般保持客户',
'100':'一般挽留客户',
'000':'一般发展客户'}
result=d[lable]
return result
rfm['lable']=rfm[['R','F','M']].apply(lambda x:x-x.mean()).apply(rfm_func,axis=1)
rfm.head()
image.png
rfm.groupby('lable').sum()
image.png
- 由表中数据可以看出:‘重要保持客户’的消费金额和消费产品数都是比较多,需要商家去重点维护;而‘一般挽留客户’虽然消费金额及消费产品数都不是很突出,但是其消费间隔时间较长,说明对产品依赖性、或者说是支持度较高;‘重要挽留客户’虽然消费的产品数不多,但却贡献了相对较多的消费金额,对产品的依赖性也不低,可以对其进行维护和发展。
rfm.reset_index().groupby('lable')['user_id'].count().plot.pie(autopct='%.2f%%')
image.png
- 由饼图可知:‘一般挽留客户’占到全部客户数的过半的比例,加之对比RFM表可知,该客户群对产品的支持度高,也贡献了较大一部分的消费金额,可针对其进行适当的营销,促进其消费;‘重要保持客户’占到了全部顾客数的近五分之一,凭借该客户群高消费能力,为保障商店的大部分营收,也应对其重点维护。
2)新客户、活跃客户、不活跃客户、回流客户
pivoted_counts=df.pivot_table(index='user_id',
columns='month',
values='order_dt',
aggfunc='count').fillna(0)
df_purchase=pivoted_counts.applymap(lambda x: 1 if x>0 else 0)
def active_status(data):
status=[]
for i in range(18):
#若本月没有消费
if data[i] ==0:
if len(status) > 0:
if status[i-1] == '未注册':
status.append('未注册')
else:
status.append('不活跃')
else:
status.append('未注册')
#若本月有消费
else:
if len(status) ==0:
status.append('新客户')
else:
if status[i-1] == '不活跃':
status.append('回流')
elif status[i-1] == '未注册':
status.append('新客户')
else:
status.append('活跃')
data.iloc[0:]=status
return data
purchase_stats=df_purchase.apply(active_status,axis=1)
purchase_stats.tail()
image.png
purchase_stats_ct=purchase_stats.replace('unreg',np.NaN).apply(lambda x:pd.value_counts(x))
purchase_stats_ct.T.fillna(0).head()
image.png
purchase_stats_ct.T.fillna(0).plot.area()
image.png
- 由该面积图可知:前三个月的新客户和回流客户暴增的同时不活跃的用户也在逐渐攀升,加之活跃用户上升的较平缓,可见必将会有一大部分用户是单次消费的客户;随后,新用户在三月份出现断崖式下跌,同时活跃用户和回流用户也有所下降,但不活跃用户却趋于平稳,这也必将导致销量的下跌。
5、复购率和回购率分析
1)复购率
purchase_r=pivoted_counts.applymap(lambda x: 1 if x>1 else np.NaN if x==0 else 0)
(purchase_r.sum()/purchase_r.count()).plot(figsize=(10,4))
image.png
- 由图可知:前三个月的复购率逐渐上升,并最终稳定在20%~22%的范围内。
2)回购率
def purchase_back(data):
status=[]
for i in range(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)
data.iloc[0:]=status
return data
purchase_b=df_purchase.apply(purchase_back,axis=1)
(purchase_b.sum()/purchase_b.count()).plot(figsize=(10,4))
image.png
- 由上图可知:回购率在前两个月上升平稳,在三月份时出现大幅度的上升,最终在30%这一百分值的范围出现较大幅度的震荡。