用户行为分析可以让产品更加详细、清楚地了解用户的行为习惯,从而找出网站、app、推广渠道等产品存在的问题,有助于产品发掘高转化率页面,让产品的营销更加精准、有效,提高业务转化率。本文选取阿里天池项目中的淘宝App用户行为数据利用Python进行数据分析。
常用用户分析模型:
常用用户行为分析方法:
本次分析的用户行为数据来自于阿里巴巴天池平台:
[User Behavior Data on Taobao App]: https://tianchi.aliyun.com/dataset/dataDetail?dataId=46
对淘宝的用户行为数据做探索性分析,找出问题然后做具体分析。
#导入数据
import pandas as pd
data = pd.read_csv('data/tianchi_mobile_recommend_train_user.csv')
#查看数据字段类型
data.info()
"""
user_id int64
item_id int64
behavior_type int64
user_geohash object
item_category int64
time object
"""
user_geohash地理位置字段,由于做了加密处理且大多数为空无法利用分析,所以剔除。
#删除地理位置字段
data=data.drop('user_geohash',axis=1)
查看是否存在缺失值:没有缺失值
#查看是否存在缺失值
data.count()
"""
user_id 12256906
item_id 12256906
behavior_type 12256906
item_category 12256906
time 12256906
dtype: int64
"""
将behavior_type字段的1,2,3,4类型分别改为pv,collect,cart,buy。
# 将behavior_type字段的1,2,3,4类型分别改为,pv,collect,cart,buy
data.ix[data['behavior_type']==1,'behavior_type']='pv'
data.ix[data['behavior_type']==2,'behavior_type']='collect'
data.ix[data['behavior_type']==3,'behavior_type']='cart'
data.ix[data['behavior_type']==4,'behavior_type']='buy'
为了便于时间维度的分析,将time时间字段中的内容分成 time(时间)、date(日期)、week(星期)三个字段。
#将time时间字段中的内容分成 time(时间)、date(日期)、week(星期)三个字段
data['date'] = data.time.apply(lambda x:([i for i in x.split()][0]))
data['time'] = data.time.apply(lambda x:([i for i in x.split()][1]))
#转换时间格式
data['date']=pd.to_datetime(data['date'])
data['time']=data['time'].astype(int)
data['week'] = [i.weekday() for i in data['date']]
(1)用户一个月的pv和uv
#一个月的用户pv和uv
data.groupby(['behavior_type'])['user_id'].count()
"""
behavior_type
buy 120205
cart 343564
collect 242556
pv 11550581
Name: user_id, dtype: int64
"""
data.groupby(['user_id']).count().shape
#(10000, 6)
总pv:11550581;uv:10000。
(2)一个月内,每天的pv、uv
#每日的访问量和uv
data.groupby(['date']).count()
data.groupby('date')['user_id'].nunique()
由图可知,在12月12日(“双十二”)当天,pv和uv数激增,然后又恢复正常状态。说明活动取得了很好的吸引流量的效果。
(1)时间维度分析用户消费行为习惯
#用户四种行为各自的记录
pv_data=data[data['behavior_type']=='pv']
cart_data=data[data['behavior_type']=='cart']
collect_data=data[data['behavior_type']=='collect']
buy_data=data[data['behavior_type']=='buy']
#每个时刻四种行为各自的uv
pv_data.groupby(['time'])['user_id'].nunique()
cart_data.groupby(['time'])['user_id'].nunique()
collect_data.groupby(['time'])['user_id'].nunique()
buy_data.groupby(['time'])['user_id'].nunique()
#每周四种行为各自的uv
buy_data.groupby(['week'])['user_id'].nunique()
cart_data.groupby(['week'])['user_id'].nunique()
collect_data.groupby(['week'])['user_id'].nunique()
buy_data.groupby(['week'])['user_id'].nunique()
由图可知,用户一天中逛淘宝的时间习惯与人的作息工作时间基本一致。一天中9:00-19:00淘宝用户人数较多且活跃人数大概在8100左右,到19:00-22:00之间用户最活跃,这段时间也是购物的黄金时间。22:00点之后用户人数呈下降趋势,直到5:00用户人数逐步上升。因此,利用用户的空闲时间进行营销,比如中午吃饭时间,晚上19:00-22:00,能够提高用户购买率。
由图可知,在周末与平时工作日相比uv数没有太大变化。购买人数在周五明显增多的原因是当天“双十二”做活动,增加了周五的购买人数。
(2)用户行为转化分析
用户行为转化:
用户浏览商品详情页面,可以直接购买,也可以加购物车、收藏购买,用户收藏和加入购物车并没有必然的联系,不存在上下级,所以这里不画单一转化漏斗,而画出pv到成其他三种行为转化率的漏斗图。
#用户发生四种行为每个行为的总数
behavior_funnel=data['behavior_type'].value_counts().reset_index()
behavior_funnel.columns=['用户行为','访问量']
# 求出单一环节转化率:
temp1 = np.array(behavior_funnel['访问量'][1:])
temp2 = np.array(behavior_funnel['访问量'][0:-1])
single_convs = list(temp1 / temp2)
single_convs.insert(0,1)
single_convs = [round(x,4) for x in single_convs]
behavior_funnel['单一环节转化率'] = single_convs
#求出总体转化率
temp3 = np.array(behavior_funnel['访问量'])
temp4= np.ones(len(behavior_funnel['访问量'])) * behavior_funnel['访问量'][0]
total_convs = (temp3 / temp4).tolist()
total_convs = [round(x,4) for x in total_convs]
behavior_funnel['总体转化率'] = total_convs
#画用户行为总体转化漏斗图
import pyecharts.options as opts
from pyecharts.charts import Funnel
attrs = behavior_funnel['用户行为'].tolist()
values = (np.array(behavior_funnel['总体转化率'])* 100).tolist() 586120
d = [[attrs[i], values[i]] for i in range(len(attrs))]
funnel=(
Funnel(init_opts=opts.InitOpts(width="800px", height="600px"))
.add(
series_name="",
data_pair=d,
gap=2,
label_opts=opts.LabelOpts(is_show=True, position="inside",formatter="{c}%"),
itemstyle_opts=opts.ItemStyleOpts(border_color="#fff", border_width=1),
)
.set_global_opts(title_opts=opts.TitleOpts(title="用户行为总体转化漏斗图"))
)
funnel.render_notebook()
由图可知,pv到加购物车、收藏还是购买的转化率都偏低,其中点击转化成购买的转化率仅为1.04%,即平均每96次浏览才会取得1次购买,付费流失较高。采用以下思路进行分析:
由于缺乏商品数据无法具体分析,这里仅考虑网站原因。可能是搜索筛选商品或推荐系统推荐商品不到位,用户找不到自己喜欢的商品,也有可能是首页和商品页面UI设计和描述信息、文案不够好,用户直接退出了。
加购物车和收藏到购买的转化率为20.5%,与pv到购买的转化率相比比较可观,因此,应关注加购物车和收藏的商品,比如发放一些对应商品的优惠券、给用户推送其中降价的商品等策略。
uv转化率:
四种行为各自的uv
pv_data.groupby('user_id').count().count() #10000
cart_data.groupby('user_id').count().count() #8614
collect_data.groupby('user_id').count().count() #6730
buy_data.groupby('user_id').count().count() #8886
由图可知,淘宝一个月有访问记录的独立访客数为10000,uv点击到购买的转化率为88.86%,说明大所述人都愿意付费,对平台的忠诚度较高,有很大的成长空间。
(3)月复购率
月复购率:一个月内购买次数超过一次的用户数与所有购买过的用户数。
这里购买次数本应当按订单量计算,由于缺少订单数据,这里姑且用购买商品数超过3件及以上计算。
pv_data.groupby('user_id').count().count() #访问记录用户数:10000
user_buy=data[data['behavior_type']=='buy'].groupby('user_id').count()
user_buy.count() #有购买记录用户数:8886
user_buy[user_buy['behavior_type'] >=3 ].count() #买次数超过一次的用户数:7475
#月复购率=7475/8886=0.8412108935404006
经过计算,淘宝用户一个月内的复购率很高为84.12%,反应出用户对淘宝的忠诚度较高。
(4)用户购买和不购买的路径分析
购买方式:
#四种行为按商品分组
item_pv = pv_data.groupby('item_id')['behavior_type'].count().reset_index()
item_cart=cart_data.groupby('item_id')['behavior_type'].count().reset_index()
item_collect=collect_data.groupby('item_id')['behavior_type'].count().reset_index()
item_buy=buy_data.groupby('item_id')['behavior_type'].count().reset_index()
# 点击—购买
pd.merge(item_pv,item_buy,on='item_id',how='inner').count() #89786
#点击—加购物车-购买
pv_cart=pd.merge(item_pv,item_cart,on='item_id',how='inner')
pd.merge(pv_cart,item_buy,on='item_id',how='inner').count() #61102
#点击—收藏—购买
pv_collect=pd.merge(item_pv,item_collect,on='item_id',how='inner')
pd.merge(pv_collect,item_buy,on='item_id',how='inner').count() #19869
#点击—加购物车—收藏—购买
pv_cart_collect=pd.merge(pv_cart,item_collect,on='item_id',how='inner')
pd.merge(pv_cart_collect,item_buy,on='item_id',how='inner').count() #13892
不购买方式:
#不购买行为按商品分组
item_nobuy=data[data['behavior_type'].isin(['pv','cart','collect'])].groupby(
'item_id')['behavior_type'].count().reset_index
# 点击—不购买
pd.merge(item_pv,item_nobuy,on='item_id',how='inner').count() #2870604
#点击—加购物车-不购买
pv_cart=pd.merge(item_pv,item_cart,on='item_id',how='inner')
pd.merge(pv_cart,item_nobuy,on='item_id',how='inner').count() #247177
#点击—收藏—不购买
pv_collect=pd.merge(item_pv,item_collect,on='item_id',how='inner')
pd.merge(pv_collect,item_nobuy,on='item_id',how='inner').count() #204117
#点击—加购物车—收藏—不购买
pv_cart_collect=pd.merge(pv_cart,item_collect,on='item_id',how='inner')
pd.merge(pv_cart_collect,item_nobuy,on='item_id',how='inner').count() #38710
由图可知,对于购买路径,用户以浏览商品然后直接购买的路径最多,其次是浏览商品然后加入购物车最后购买的路径,这两种路径是最主要的购买路径。对于不购买路径,用户主要是浏览商品然后直接离开。
data.groupby('item_id').count().shape #商品总数:2876947
item_frequency=buy_data.groupby(['item_id'],as_index=False).count()
item_frequency[item_frequency['behavior_type'] >=2 ].count() #销售两次及以上的商品数:15167
item_frequency.count() #销售的商品数:92753
总共销售的商品有92753个,有77586个商品只销售了一次,15167件商品销售了2次及以上,一次性购买的商品占据了84%,说明电商靠长尾理论累计销售。因此,我们可以尝试将销量较低的商品和销量较高的商品捆绑销售,并且优化商品的展示,将畅销类的商品和非畅销品展示在一起,提升商品被购买的几率。
#pv前10的商品
pv_item=pv_data.groupby('item_id').count().sort_values(by="user_id" , ascending=False)[:10]
#购买量前10的商品
buy_item=buy_data.groupby('item_id').count().sort_values(by="user_id" , ascending=False)[:10]
#pv前10和购买量前10中都有的商品
pv_item_list=list(pv_item.index)
buy_item_list=list(buy_item.index)
same_item= list(set(buy_item_list) & set(pv_item_list))
same_item #pv前10和购买量前10中都有的商品只有一个:[14087919]
由图可知,淘宝用户购买量前十的商品是核心产品,要重点推送这些热销商品。特别的,pv前十的商品与购买量前10重合的商品只有一件,说明用户花了很长时间去寻找想要的商品,推荐系统推荐放在首页资源位高位置的商品与用户想要购买的商品不匹配,因此需要优化推荐系统。
RFM模型:通过计算最近一次购买时间R(Recency)、购买频率F(Frequency)、购买金额M(Monetary)得出RFM得分。
此数据集仅为一个月用户行为记录,由于没有订单记录,这里R和F都是以购买的商品记录计算,而且也没有购买金额的记录,因此只计算RF。将RF2个维度分别做2个区间的离散化,分成4个群体。
R | F | 用户类别 | rfm_group |
---|---|---|---|
高 | 高 | 价值用户 | 22 |
高 | 低 | 发展用户 | 21 |
低 | 高 | 保持用户 | 12 |
低 | 低 | 挽留用户 | 11 |
#拿到用户的购买记录
rfm_data=buy_data.ix[:,['user_id','item_id','date']]
#拿到一个月的最大日期
rfm_data['max_data']=rfm_data['date'].max()
#计算购买商品距离月底的时间间隔
rfm_data['date_interval']=rfm_data['max_data']-rfm_data['date']
#转换日期间隔为数字
rfm_data['date_interval']=rfm_data['date_interval'].apply(lambda x: x.days)
# 按用户做汇总
rfm_gb = rfm_data.groupby(['user_id'],as_index=False).agg(
{'date_interval': 'min', # 计算最近一次消费时间
'date': 'count'})# 计算购买频率
# 重命名列名
rfm_gb.columns=['user_id','R','F']
rfm_gb.head()
"""
user_id R F
0 4913 2 6
1 6118 1 1
2 7528 5 6
3 7591 5 21
4 12645 4 8
"""
rfm_gb.iloc[:,1:].describe().T
"""
count mean std min 25% 50% 75% max
R 8886.0 5.811839 6.678478 0.0 1.0 4.0 7.0 30.0
F 8886.0 13.527459 19.698786 1.0 4.0 8.0 17.0 809.0
"""
这里R采用中位数(4天)划分,F采用中位数(8次)划分
# 定义区间边界
r_bins = [-1,5,30]
f_bins = [0,13,809]
# rfm 计算
rfm_gb['r_score'] = pd.cut(rfm_gb['R'],r_bins,labels=[i for i in range(len(r_bins)-1,0,-1)])
rfm_gb['f_score'] = pd.cut(rfm_gb['F'],f_bins,labels=[i+1 for i in range(len(f_bins)-1)])
这里除用户行为记录以外没有其他可利用的数据,所以无法预估R和F的权重,根据一般用户的等级首先侧重于实际订单的总金额贡献,其次是最近一次消费时间,最后是频次的情况。因此,采用加权平均人为设置权重,R的权重设为0.6,F的权重设为0.4。
# 计算RFm的得分
# 加权的RFM的值
rfm_gb=rfm_gb.apply(np.int32)
rfm_gb['rfm_score'] = rfm_gb['r_score']*0.6+rfm_gb['f_score']*0.4
#计算rfm的组合
rfm_gb['r_score'] = rfm_gb['r_score'].astype(np.str)
rfm_gb['f_score'] = rfm_gb['f_score'].astype(np.str)
rfm_gb['rfm_group'] = rfm_gb['r_score'].str.cat(rfm_gb['f_score'])
rfm_gb.head()
"""
user_id R F r_score f_score rfm_score rfm_group
0 4913 2 6 2 1 1.6 21
1 6118 1 1 2 1 1.6 21
2 7528 5 6 1 1 1.0 11
3 7591 5 21 1 2 1.4 12
4 12645 4 8 2 1 1.6 21
"""
#按rfm_group统计各个分群的用户数
display_data=rfm_gb.groupby(['rfm_group'],as_index=False)['user_id'].count()
display_data.columns=['rfm_group','number']
display_data['rfm_group']=display_data['rfm_group'].astype(np.int32)
#求出各个分群占总用户的比例
temp1 = np.array(display_data['number'])
temp2= np.ones(len(display_data['number'])) * display_data['number'].sum()
percent= (temp1 / temp2).tolist()
percent = [round(x,4) for x in percent]
display_data['百分比'] = percent
def func(x):
if x==11:
rfm_group='挽留用户'
if x==12:
rfm_group='保持用户'
if x==21:
rfm_group='发展用户'
if x==22:
rfm_group='价值用户'
return rfm_group
display_data['rfm_group']=display_data['rfm_group'].apply(func)
display_data
"""
rfm_group number 百分比
0 挽留用户 2767 0.3114
1 保持用户 1219 0.1372
2 发展用户 1721 0.1937
3 价值用户 3179 0.3578
"""
画出各个分群与购买用户占比的圆环图
from pyecharts import options as opts
from pyecharts.charts import Pie
attrs = display_data['rfm_group'].tolist()
values = (np.array(display_data['百分比'])* 100).tolist()
values = [round(x,2) for x in values]
c = (
Pie()
.add(
"",
[[attrs[i], values[i]] for i in range(len(attrs))],
radius=["40%", "55%"],
label_opts=opts.LabelOpts(
position="outside",
formatter="{b|{b}: } {per|{d}%} ",
background_color="#eee",
border_color="#aaa",
border_width=1,
border_radius=4,
rich={
"b": {"fontSize": 16, "lineHeight": 33},
"per": {
"color": "#eee",
"backgroundColor": "#334455",
"padding": [2, 4],
"borderRadius": 2,
},
},
),
)
.set_global_opts(title_opts=opts.TitleOpts(title="用户价值分析"))
.render("pie_rich_label.html")
)
由图可知,根据RFM模型,共划分为四类客户,分别为 22/价值用户,21/发展用户, 12/保持用户, 11/挽留用户,其中价值用户和挽留用户占比较高。对得到的不同类型的用户,应该采取不同的激励方案:
1、用户逛淘宝习惯与人的作息工作时间基本一致,在用户空闲时间,如:中午吃饭时间,晚上下班到睡觉之前,对用户做一些精准推送、发放优惠劵、营销活动等策略,提升用户购买率。
2、用户购买、不购买的路径大多数都是浏览商品直接购买或者流失。所以应当优化淘宝首页和商品详情页,将用户喜欢的商品展示在最显眼的地方,也就是资源位高的地方。商品详情页的描述信息要尽量详细,文案要打动吸引顾客。而且商品详情页购买到支付的流程尽量简单不用让用户做过多的操作。
3、加购物车和收藏到购买的转化率相比于pv到购买比较可观,应关注加购物车和收藏的商品,比如给用户推送对应商品的优惠券、推送其中降价的商品等策略。后台推荐系统构建用户画像时购物车和收藏中的商品相比于浏览的商品的权重高一些。
4、淘宝活跃用户占比、付费用户占比较高,且uv转化率和月复购率也较高,用户对平台的粘性和忠诚度较高,平台有很大的成长空间。
5、pv到购买的转化率偏低,且浏览量前十商品和购买量前十商品中相同的商品较少,说明用户花了大量的时间选择合适的商品,浏览了众多商品页面之后才筛选到合适的商品收藏或者放进购物车或者直接购买。针对这个可以优化平台的筛选功能,让用户可以更容易找到合适产品。还可以优化推荐系统,优化推荐系统算法,做混合推荐算法的召回,排序时多种模型组合,经过ABTest测试,采用效果最好最稳定的模型进行排序推荐。