一.分析背景与目的
1.1背景与数据限制
本数据集为某电商app中的用户行为,本分析案例通过:时间-用户-商品-行为四个维度来分析用户的数量,粘性和购买转化率。本案例使用的数据集为9天内(11月25日-12月3日的数据)的数据。商品名称数据经脱敏,行为数据只有4种,分别是访问商品详情页-加入收藏-加入购物车-购买。
1.2分析指标
1)流量指标:
访问数:当日的商品详情页访问数
日用户数:当日访问的用户数(去重后)
活跃用户数:当日产生超过2次行为数据的用户数
交易用户数:当日有购买行为数据的用户数(去重后)
2)用户属性指标:
活跃用户比例:日活跃用户/日用户数
交易用户比例:日交易用户数/日用户数
用户日均行为数:日访问数/日用户数
用户活跃天数:统计周期内,用户有多少天活跃
3)转化指标:
购买转化率:各类型用户购买转化率
4)用户价值指标(RFM模型):
R:用户最近的一次购买时间
F:用户最近一段时间的购买频率
M:用户最近一段时间的购买金额
1.3 分析用户行为的目的
1)监控周期内是否业务发生数据异常;
2)对用户转化路径进行分类,将用户导向高转化路径,挖掘业务增长点;
3)分析商品数据,增强商品推荐导流成功率;
4)对用户类型进行分类,针对不同用户实现不同的运营策略。
二.数据集理解
user_id: int类型,用户id
item_id: int类型,商品id
category_id: int类型,商品大类id
behaviour_type:用户行为,分成四类:
1)pv:商品详情页pv,等价于点击
2)buy:商品购买
3)fav:商品收藏
4)cart:商品加入购物车
timestamp:行为发生时的时间戳
三.数据清洗
操作:去除有缺失值的行,去除重复值,将timestamp转化成datetime,并筛选出11月25日至12月3日的数据。
结论:数据及较为干净,被筛掉的数据约有5k+。
四.数据分析
4.1基本指标分析
4.1.1应用流量
4.1.2应用用户属性
4.1.3用户活跃天数分布
4.1.4小结
1)应用的日均用户较为稳定,曲线从12月2日起大幅上升,推测原因双12系列活动的预热开始;
2)日均活跃用户比例:79%,日均购买用户比例:19%,推测均为是标准差较小的正态分布,后续可以以该比例作为期望值监控业务是否正常进行;
3)12月2至3日用户数上升了32.3%,活跃比例和购买比例分别下降了3.2%和6.7%,说明双12系列活动只提高了用户的“量”,并没有提高被引流的用户的“质”。
4)超过90%的用户9天内活跃超过2天。
4.2用户行为路径分析
根据用户是否发生4种行为的其中一种,将“用户-商品id”分为15个路径。
4.2.1用户行为路径
4.2.2购买转化率
4.2.3小结
1)用户路径总体特征
绝大部分的用户只访问了商品详情页,但没有收藏、加购、购买;同一件商品,用户的收藏行为和加购行为并没有特别大的联系;对有购买意愿的商品,选择加购的人会比选择收藏的人要多;
收藏fav行为的转化率为 3.82%;
加入购物车cart行为的转化率为 7.17%;
购买buy行为的转化率为2.51%。
2)用户路径占比分析
转化排名TOP4:
①pv-fav-cart(14.94%)
②py-unfav-cart(9.96%)
③py-fav-uncart(8.01%)
④unpy-fav-cart(5.28%)
有收藏和加购行为的用户购买转化率远大于其他用户;
只有收藏和只有购买的用户转化率不相上下。
3)用户路径占比分析
占比排名TOP4:
①pv-unfav-uncart(48.98%)
②pv-unfav-cart(13.48%)
③pv-fav-uncart(4.71%)
④unpv-unfav-cart(4.03%)
大多数用户都是访问了商品后直接购买,由于包含了大量单纯浏览商品的用户,此路径的转化率只有1.39%;
通过购物车购买的用户数量为通过收藏购买的用户的3倍。
4.3用户行为时间分析
4.3.1用户活跃时间
4.3.2购买行为时间分布
4.3.3小结
1)19:00-22:00是访问高峰期,符合人们的工作休息节律。每小时购买数和每小时访问用户曲线趋势基本吻合。20:00-0:00是使用高峰期,用PV/UV大幅度上涨,是平常时段的1.45倍;
2)从购买行为时间分布图上看,收藏且有购物意愿的用户,超过95%会在3天内购买,加入购物车且有购物意愿的用户,超过92%会在5天内购买。用户在刚收藏商品或加入购物车后会有一波购买高峰,在加入购物车约20小时后会有另外一波购买小高峰。
4.4用户行为商品分析
4.4.1 商品大类交易数占比
数据集中商品名称经过脱敏,故只有id
4.4.2商品大类购买行为
分析产生购买行为的数据中,一件商品的购买要经过多少个行为,大部分购买行为平均只会产生20次以的,对于划分开的不同用户行为的商品大类,实施不同的运营策略。
A区(右上区域):购买数大,行为数大,推测该区域商品是快消或高频物品,且品牌选择多,如服装、日用品、零食等;
B区(左上区域):购买数大,行为数少,推测该区域商品是高频、明星产品,品牌不多用户选择少,或者是有头部品牌,又或者是品牌建立了一定的依赖度;
C区(左下区域):购买数相对小,行为数相对小,品类特性需进一步分析;
D区(右下区域):购买数小,行为数多,推测该区域商品低频/贵重,用户决策谨慎,如手机、电视机等高金额非消耗品。
4.4.3 商品关联性分析
提取数据集中各商品大类/商品出现在同一个订单中的次数,次数越大,两种商品大类/商品的关联性越高。
分析小结:
1)总订单数为:178673,商品种类大于1的订单数为12165,商品大类关联性TOP1只有417次,约占3.4%;商品大类的关联性强于单个商品之间的关联性;
2)总体来说由购买行为计算的商品关联性不低,有一定的分类和推荐价值,但在推荐前需先分析高关联性产品是否已存在关联推荐,需把关联性高但非系统关联推荐的商品信息提取出来。
4.5 用户价值分析
RFM模型是衡量客户价值和客户创利能力的重要工具和手段:
· R(Recency)最近一次消费时间:表示用户最近一次消费距离现在的时间。消费时间越近的客户价值越大。1年前消费过的用户肯定没有1周前消费过的用户价值大。
· F(Frequency)消费频率:消费频率是指用户在统计周期内购买商品的次数,经常购买的用户也就是熟客,价值肯定比偶尔来一次的客户价值大。
· M(Monetary)消费金额:消费金额是指用户在统计周期内消费的总金额,体现了消费者为企业创利的多少,自然是消费越多的用户价值越大
由于本数据集没有M维度,故只用R维度和F维度对用户进行打分评级。
五.总结
5.1 分析总结
1)该应用正常情况下日均用户访问数据、用户行为数、活跃用户与付费用户比例稳定,超90%在9天内活跃天数超过2天,后续看继续用各指标的平均值来作为监控业务的期望值;
2)大多数购买的用户在访问商品详情页后直接购买;有收藏和加购行为的用户购买转化率远大于其他用户;通过购物车购买的用户是通过收藏购买的用户数的3倍。
3)19:00-22:00是用户访问高峰期,20:00-0:00是用户活跃高峰期,收藏且有购物意愿的用户,超过95%会在3天内购买,加入购物车且有购物意愿的用户,超过92%会在5天内购买。用户在刚收藏商品或加入购物车后会有一波购买高峰,在加入购物车约20小时后会有另外一波购买小高峰。
4)商品大类的关联性强于单个商品之间的关联性,后续可提高商品大类关联性推荐比重,降低单个商品关联性推荐比重。
5.2业务增长建议
5.2.1提升用户粘性
1)营销活动、运营手段等建议在19:00-0:00展开,配合用户访问和活跃高峰期;
2)考虑为A区(购买量大、品牌繁多)、D区(决策过程长)的商品建立专区,并适当增加科普推送,辅助用户决策,提升沉浸度;
3)对于B区(决策过程短)的商品,应着重提升购买效率,如搜索结果有限显示/提示曾经买过的商品品牌或店铺、在购买过的订单中设置和突出搜索功能;
4)高价值用户,建立优质用户社交社区/生态,发放特别福利;重点保持用户,最近没有购买,启动召回机制,发送消息慰问,店铺活动提醒,上新提醒等;重点发展用户,购买频率低,需要挖掘顾客特征,作出应对手段;重点挽留用户,最近一次购买时间较远,购买率低,需制造机会点让用户有更多机会体验/深入使用产品,增强粘性。
5.2.2 提升交易成功率:
1)双12活动带来的用户增长,并没有维持到日常水平的购买转化率,建议AB TEST用户需求/定向模型,提升购买转化率;
2)在用户加购后提示用户将商品收藏,在用户收藏商品后提示用户加购,或针对以上2个时间点加入运营手段激励用户进行操作,增加多条购买路径,提高购买转化率;
3)在用户浏览页面时间超过一定时长后,提醒用户将商品加购;
4)在用户收藏商品3天、加购商品20小时、加购商品5天时提示用户购买或开展相应促销运营手段;
5)对于关联性高的商品,优先向相关用户展示/打包促销。
# -*- coding:utf-8 -*-
import pandas as pd
import numpy as np
import datetime
import matplotlib.pyplot as plt
import seaborn as sns
#解决matplotlib的中文乱码问题
plt.rcParams['font.sans-serif']='SimHei'
plt.rcParams['axes.unicode_minus']=False
#1.1.数据读取,文件大小问题,只读取1000W行
row_data=pd.read_csv(r'D:\UserBehavior.csv',names=['user_id','item_id','category_id','behaviour_type','timestamp'],iterator=True)
data1=row_data.get_chunk(10000000)
#2.数据集清洗
#2.1.查看有无缺失值
a=data1.isnull().sum(1)
if a.sum()==0:
print('本数据集无缺失')
else:
print(a[a>0])
#2.2查看有无重复值
b=data1.duplicated()
if b.sum()==0:
print('本数据集无重复值')
else:
data1.drop_duplicates(inplace=True)
#2.3将时间戳转化为日期,+8hour转化成北京时间,过滤出11-25到12-3的数据
data1['time']=pd.to_datetime(data1['timestamp'],unit='s')+datetime.timedelta(hours=8)
data1=data1[(data1.time>'2017-11-25')&(data1.time<'2017-12-4')]
#3.数据分析
#3.1.用户侧核心指标
#将date从time里面提取出来
data1=data1.assign(date=data1['time'].map(lambda x:x.strftime('%Y-%m-%d')))
#3.1.1核心指标数量
#日均用户数
df_uvpd=data1[['user_id','date']].groupby('date')['user_id'].nunique()
df_uvpd.name='uv'
#日均活跃用户数
df_aupd=data1[['user_id','date','behaviour_type']].groupby(['date','user_id']).size()
df_aupd=df_aupd[df_aupd>2]
df_aupd=df_aupd.groupby(level=0).size()
df_aupd.name='active_user'
#日均交易用户数
df_bupd=data1[data1['behaviour_type']=='buy']
df_bupd=df_bupd.groupby('date')['user_id'].nunique()
df_bupd.name='buy_user'
#三个指标拼接
df311=pd.concat([df_uvpd,df_aupd,df_bupd],axis=1)
#3.1.2核心指标比例
#日行为数
df_pvpd=data1['user_id'].groupby(data1['date']).size()
df_pvpd.name='pv'
#三个指标计算
df312=df311.assign(pv_per_user=df_pvpd/df311['uv'],active_user_rate=df311['active_user']/df311['uv'],buy_user_rate=df311['buy_user']/df311['uv'])
#3.1.3用户活跃天数
df_user_active_days=data1[['user_id','date','behaviour_type']].groupby(['date','user_id']).size()
df_user_active_days=df_user_active_days[df_user_active_days>2]
df_user_active_days=df_user_active_days.reset_index()
df_user_active_days=df_user_active_days.groupby('user_id')['date'].nunique().value_counts()
#3.2.用户行为路径分析
df32=data1[['user_id','item_id','behaviour_type']].drop_duplicates()
df32=df32.assign(type_num=data1['behaviour_type'].map({'pv':1,'fav':2,'cart':4,'buy':8}))
df32=df32.groupby(['user_id','item_id']).sum()
df32=df32.assign(action=df32['type_num'].map({
1:'pv-unfav-uncart-unbuy',
2:'unpv-fav-uncart-unbuy',
3:'pv-fav-uncart-unbuy',
4:'unpv-unfav-cart-unbuy',
5:'pv-unfav-cart-unbuy',
6:'unpv-fav-cart-unbuy',
7:'pv-fav-cart-unbuy',
8:'unpv-unfav-uncart-buy',
9:'pv-unfav-uncart-buy',
10:'unpv-fav-uncart-buy',
11:'pv-fav-uncart-buy',
12:'unpv-unfav-cart-buy',
13:'pv-unfav-cart-buy',
14:'unpv-fav-cart-buy',
15:'pv-fav-cart-buy'
}),
isbuy=df32['type_num'].map({1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:1,9:1,10:1,11:1,12:1,13:1,14:1,15:1}),
action_type=df32['type_num'].map({
1:'YNN',
2:'NYN',
3:'YYN',
4:'NNY',
5:'YNY',
6:'NYY',
7:'YYY',
8:'NNN',
9:'YNN',
10:'NYN',
11:'YYN',
12:'NNY',
13:'YNY',
14:'NYY',
15:'YYY'
}))
df321=df32.groupby('action').size()
#计算各路径的转化率
#计算每个路径的总人数
user_count=df32.groupby('action_type').size()
user_count.name='user_count'
user_count=user_count.reset_index()
#计算每个路径订购的人数
buyer_count=df32.groupby(['action_type','isbuy']).size()
buyer_count.name='buyer_count'
buyer_count=buyer_count.reset_index()
buyer_count=buyer_count[buyer_count['isbuy']==1]
#连接总人数和已订购的人数,并计算转化率
df322=pd.merge(user_count,buyer_count,on='action_type')
df322['CVR']=df322['buyer_count']/df322['user_count']
#计算各路径占比
#计算已订购路径的总人数
buyer_count_total=df322['buyer_count'].sum(axis=0)
#计算出各路径人数占比
df322['mix']=df322['buyer_count']/buyer_count_total
#3.3用户行为时间分析
#3.3.1.计算每小时pv,uv,购买数
df33=data1.assign(hour=data1['time'].dt.hour)
#计算每小时pv
df33_pv=df33.groupby('hour').size()
df33_pv.name='pv'
#计算每小时uv
df33_uv=df33.groupby('hour')['user_id'].nunique()
df33_uv.name='uv'
#计算每小时交易数
df33_buy=df33[df33['behaviour_type']=='buy']
df33_buy=df33_buy.groupby('hour').size()
df33_buy.name='buy'
#拼接结果
df331=pd.concat([df33_pv,df33_uv,df33_buy],axis=1)
#3.3.2.计算fav-buy和cast-buy
#将3种行为抽取并连接
user_buy=data1[data1['behaviour_type']=='buy']
user_fav=data1[data1['behaviour_type']=='fav']
user_cart=data1[data1['behaviour_type']=='cart']
fav_buy=pd.merge(user_fav,user_buy,on=['user_id','item_id'],how='inner',suffixes=('_fav','_buy'))
cart_buy=pd.merge(user_cart,user_buy,on=['user_id','item_id'],how='inner',suffixes=('_cart','_buy'))
#计算fav_buy时间间隔
df332_fav_buy=(fav_buy['time_buy']-fav_buy['time_fav']).map(lambda x:x.days*24+x.seconds/3600)
df332_fav_buy=df332_fav_buy[df332_fav_buy>0]
df332_fav_buy=pd.DataFrame(df332_fav_buy,columns=['value'])
df332_fav_buy['item']='fav_buy'
#计算cart_buy时间间隔
df332_cart_buy=(cart_buy['time_buy']-cart_buy['time_cart']).map(lambda x:x.days*24+x.seconds/3600)
df332_cart_buy=df332_cart_buy[df332_cart_buy>0]
df332_cart_buy=pd.DataFrame(df332_cart_buy,columns=['value'])
df332_cart_buy['item']='cart_buy'
#拼接并弄成小提琴图
df332=pd.concat([df332_fav_buy,df332_cart_buy],ignore_index=True)
#3.4商品分类分析
df34=data1[data1['behaviour_type']=='buy']
#3.4.1.计算每个商品大类的交易数量并排名
df341=df34.groupby('category_id').size()
df341.name='category_count'
df341=df341.reset_index()
df341.sort_values(by='category_count',inplace=True,ascending=False)
#3.4.2.计算商品大类的购买数和平均行为数的关系
df342=df34[['user_id','category_id']].drop_duplicates()
df342=pd.merge(df342,data1,on=['user_id','category_id'],how='inner')
df342=df342.groupby('category_id').size()
df342.name='behaviour_num'
df342=df342.reset_index()
df342=pd.merge(df342,df341,on='category_id',how='inner')
df342=df342.assign(avg_behaviour=df342['behaviour_num']/df342['category_count'])
#3.4.3.计算商品大类/个体之间的关联
#计算总订单数及每个订购有多少商品
df_order_count=df34.groupby(['user_id','timestamp']).size()
#筛选出商品个数超过1个的订单
df_order_moreone=df_order_count[df_order_count>1]
df_order_moreone=df_order_moreone.reset_index()
#3.4.3.1为每个订购补充商品大类,并自连接,去除重复的行
df3431=pd.merge(df_order_moreone[['user_id','timestamp']],data1[['user_id','timestamp','category_id']],on=['user_id','timestamp'],how='inner')
df3431=pd.merge(df3431,df3431,on=['user_id','timestamp'])
df3431=df3431[df3431['category_id_x']>df3431['category_id_y']]
#以商品大类组合groupby,算出关联性最高的TOP50
df3431=df3431.groupby(['category_id_x','category_id_y']).size()
df3431.name='cc_count'
df3431=df3431.reset_index().sort_values(by='cc_count',ascending=False)[:50]
#3.4.3.2为每个订购补充商品个体,并自连接,去除重复的行
df3432=pd.merge(df_order_moreone[['user_id','timestamp']],data1[['user_id','timestamp','item_id']],on=['user_id','timestamp'],how='inner')
df3432=pd.merge(df3432,df3432,on=['user_id','timestamp'])
df3432=df3432[df3432['item_id_x']>df3432['item_id_y']]
#以商品个体id组合groupby,算出关联性最高的TOP50
df3432=df3432.groupby(['item_id_x','item_id_y']).size()
df3432.name='ii_count'
df3432=df3432.reset_index().sort_values(by='ii_count',ascending=False)[:50]
#3.5 RFM模型用户分层
#过滤出有buy行为的用户
buyer=data1[data1['behaviour_type']=='buy']
#计算每次购买的时间差
buyer_R=buyer.assign(delta=(datetime.datetime(2017,12,4,0,0,0)-buyer['time']).map(lambda x:x.days*24+x.seconds/3600))
#保留每个用户最新的购买时间
buyer_R.sort_values(by=['user_id','delta'],inplace=True)
buyer_R.drop_duplicates('user_id',keep='first',inplace=True)
#为用户进行R评级
def delta_change(x):
if x>0 and x<=24:
return 5
elif x>24 and x<=72:
return 4
elif x>72 and x<=120:
return 3
elif x>120 and x<=168:
return 2
elif x>168 and x<=216:
return 1
else:
print('有异常,异常user_id为:%d'%(buyer_R['user_id']))
buyer_R=buyer_R.assign(R_score=buyer_R['delta'].map(delta_change))
#计算用户购买了多少次东西
buyer_F=buyer.groupby('user_id')[['item_id']].count()
buyer_F=buyer_F.reset_index()
#为用户进行R评级
def freq_change(x):
if x>=31:
return 5
elif x>20 and x<=30:
return 4
elif x>10 and x<=20:
return 3
elif x>1 and x<=10:
return 2
elif x==1:
return 1
else:
print('有异常,异常user_id为:%d'%(buyer_F['user_id']))
buyer_F=buyer_F.assign(F_score=buyer_F['item_id'].map(freq_change))
#计算R和F的平均分
R_avg=buyer_R['R_score'].mean(axis=0)
F_avg=buyer_F['F_score'].mean(axis=0)
#将2个评分联合并为用户评级
def R_level(x,avg=R_avg):
if x>=avg:
return '高'
else:
return '低'
def F_level(x,avg=F_avg):
if x>=avg:
return '高'
else:
return '低'
user_level=pd.merge(buyer_F,buyer_R,on='user_id')
user_level['level_R']=user_level['R_score'].map(R_level)
user_level['level_F']=user_level['F_score'].map(F_level)
user_level=user_level.groupby(['level_R','level_F']).size()