- 一、项目背景
- 1、分析背景
- 2、数据来源
- 3、数据理解
- 二、明确问题&搭建分析框架
- 1、提出问题
- 2、分析框架
- 三、数据处理
- 1、导入相关包及数据
- 2、数据清洗
- (1)缺失值处理
- (2)重复值处理
- (3)去除异常值
- (4)时间维度拆解,增添新列
- 四、流量类指标分析
- 1、流量类绝对指标
- 2、流量类相对指标
- 五、用户类指标分析
- 1、用户购买次数
- (1)用户购买次数(9天内)描述统计
- (2)用户购买次数分布
- 2、复购率
- (1)9天内复购率
- (2) 单日复购率
- (3)回购率
- (4)留存率
- 六、用户行为分析
- 1、时间分布分析
- (1)日期维度
- (2)小时维度
- 2、用户行为路径分析
- (1)用户行为漏斗分析
- (2)用户行为路径分布
- 七、用户价值分析
- 八、用户购买商品分析
- 1、商品大类购买次数分析
- (1)商品大类购买次数描述统计
- (2)最热销的20种商品大类
- 2、商品购买次数分析
- (1)商品购买次数描述统计
- (2)最热销的20种商品
- 3、商品转化率分布
- 九、总结
- 1、背景
- 2、任务
- 3、行动
- 4、结果
电子商务的迅速发展和移动互联网的普及,使得越来越多的人选择方便快捷的网上购物,淘宝作为国内最大的电商交易平台之一,拥有巨大的流量优势。
在淘宝APP上,商品的搜索、分类导航、个性化推荐和广告等通过让用户在短时间内了解到更多可能需要或者喜欢的商品而促进购买,同时可以通过数据埋点,收集和分析用户的数据,实现更精细化的运营。
本文基于数据集的特点,利用python对淘宝APP的用户行为数据进行分析,得出可能存在的业务问题,并提出推荐的解决策略。
数据集来源于阿里云天池的官方数据集: User Behavior Data from Taobao for Recommendation.
数据集中包含了2017年11月25日至2017年12月3日之间,约一百万随机用户的所有行为 (行为包括点击、购买、加购、收藏),共有1亿多条记录,数据集的每一行表示一条用户行为,由用户ID、商品 ID、商品类目ID、行为类型和时间戳组成,并以逗号分隔。关于数据集中每一列的详细描述如下:
| 列名称 | 说明 |
|---|---|
| 用户ID:user_id | 整数类型,序列化后的用户id |
| 商品 ID:item_id | 整数类型,序列化后的商品ID |
| 商品类目ID:category_id | 整数类型,序列化后的商品所属类目ID |
| 行为类型:behavior | 字符串,枚举类型,包括(“pv”,“buy”,“cart”,“fav”) |
| 时间戳:timestamp | 行为发生时的时间戳 |
行为类型说明:
| 行为类型 | 说明 |
|---|---|
| pv | 商品详情页pv,等价于点击 |
| fav | 收藏商品 |
| cart | 将商品加入购物车 |
| buy | 商品购买 |
(1)数据集只涵盖了9天的用户行为,时间较为短;
(2)数据集内容只包括了:用户ID、商品 ID、商品类目ID、行为类型和时间戳,有很大的局限性,有分析价值的是行为、商品ID、时间、商品类目ID这四个维度。
(3)数据集有1亿多条记录,数据量过大,本文随机抽取其中10%的数据作为代表分析,后续文中所表述的数据都是基于这10%的数据中在2017年11月25号~2017年12月03号共9天的行为数据,而不是所有的用户行为数据。
根据AARRR模型,在用户生命周期各环节的电商数据指标包括:
- 用户获取(Acquisition):渠道曝光量、渠道转化率、日应用下载、日新增用户数DNU(Daily New User)、获客成本CAC
- 用户激活(Activation):日活跃用户数DAU、日活跃率、周活跃率等
- 用户留存(Retention):次日留存率、3日留存率、7日留存率、30日留存率等
- 获得收益(Revenue):客单价、用户购买率、平均用户收入ARPU(average revenue per user)、平均付费用户收入(average revenue per paying user)、生命周期价值LTV(Life Time Value)、复购率
- 推荐传播(Referral):转发率、转化率、K因子
本数据集中只包含用户行为数据时间、用户ID、商品ID、商品类目ID、行为类型(点击、收藏、加购、购买),因此,可以分析的指标: - 用户获取阶段:点击量(浏览量PV)
- 用户激活阶段:日活跃用户数、周活跃用户数
- 用户留存阶段:次日留存率、2日留存率、3日留存率、7日留存率
- 获得收益阶段:复购率、回购率(复购率是一个时间窗口的多次消费行为,回购率是两个时间窗口内的消费行为)
- 推荐传播阶段:无
基于本数据集的内容特征,本次分析将从以下几个方面进行:
(1)基于AARRR模型对相关指标进行统计分析,了解淘宝APP的运营情况。
(2)用户行为时间分布分析,找到用户的活跃时间规律,进而进行针对化的活动营销。
(3)用户行为路径分析,找到可以提升转转化率的环节
(4)利用RFM理论,找出核心付费用户群体,并分析核心用户群体的用户行为分布(每天的行为统计分析)。
(5)商品的购买分布分析。
import time import copy import pandas as pd import numpy as np from matplotlib import pyplot as plt import pyecharts.options as opts from pyecharts.charts import Funnel
分析在jupyter notebook中进行,可视化主要使用matplotlib完成,为了方便显示,进行matplolib有关参数设置:
%matplotlib inline
plt.rcParams["font.sans-serif"]=["SimHei"] #用来正常显示中文标签
plt.rcParams["axes.unicode_minus"] = False #用来正常显示负号
plt.style.use("ggplot")
导入原始数据:
dt = pd.read_csv('./UserBehavior/UserBehavior.csv',
names=['user_id', 'item_id', 'category_id', 'behavior_type', 'timestamp'])
print('原始数据shape',dt.shape)
原始数据shape (100150807, 5)
原始数据集中一共包含100150807条数据,由于个人计算机限制,仅从中抽取10%的数据进行处理分析。
抽取10%的数据:
dt = dt.sample(frac=0.1) dt.info()
采样的数据shape: (10015081, 5)
数据shape为(10015081,5),各字段数据类型符合要求,采样的数据集大458.5M。
dt.isnull().sum()
结果显示数据没有缺失值,比较完整干净。
结果显示数据集中1条重复记录,因此,删除这条重复的数据。
根据源数据集介绍,可知道数据的日期应在2017年11月25日至2017年12月3日之间,故根据这条规则对数据进行异常处理。
# 保留时间在2017-11-25 00:00:00至2017-12-4 00:00:00之间的数据,合计9天
dt = dt[(dt['timestamp'] >= 1511539200) & (dt['timestamp'] < 1512316800)]
print('时间段筛选后数据shape:',dt.shape)
# 按时间升序排列
dt = dt.sort_values(['timestamp','user_id']).reset_index(drop=True)
输出结果: (10009697, 5),说明原数据集中包含了不在2017年11月25日~2017年12月3日区间的用户行为记录。
(4)时间维度拆解,增添新列时间戳保持原数据形式,新添加日期-时间列、日期列、小时列。
date_times = []
dates = []
hours = []
for t in dt['timestamp']:
date_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(t))
date_times.append(date_time)
date_ = time.strftime('%Y-%m-%d',time.localtime(t))
dates.append(date_)
hour = time.strftime('%H',time.localtime(t))
hours.append(hour)
dt['datetime'] = date_times
dt['date'] = dates
dt['hour'] = hours
dt.head()
四、流量类指标分析
1、流量类绝对指标
根据数据集内容,本次分析的流量类绝对指标主要包括以下4项:
- 每日PV(Page View):当天淘宝APP页面的浏览量或者点击量;
- 每日UV(Unique Visitor):当天进入淘宝APP的用户数量(需要去重);
- 每日活跃用户数DAU:在这里定义当天在淘宝APP上产生3次及以上行为数据的用户数量(需要去重);
- 每日支付用户数:当天在淘宝APP上产生购买行为(buy)的用户数量(需要去重)。
# 每日pv
daily_pv = dt[dt["behavior_type"]=="pv"][["user_id","date"]].groupby("date").count()
daily_pv.rename(columns={"user_id":"pv"},inplace=True)
# 每日uv
daily_uv = dt[["user_id","date"]].groupby("date").nunique()#按照date分组,统计每组中不同userid的个数
daily_uv = daily_uv.drop("date",axis=1)
daily_uv = daily_uv.rename(columns={"user_id":"uv"})
# 每日活跃用户:当天用户行为超过2次,则视为活跃
daily_active = dt[["user_id","behavior_type","date"]].groupby(["date","user_id"]).count()
dau = daily_active[daily_active["behavior_type"]>2]#筛选出行为数大于2的数据:日期|用户id|行为数
dau = dau.count(level=0)#根据日期,计数用户id
dau.rename(columns={"behavior_type":"dau"},inplace=True)
# 每日支付用户
dbu = dt[dt["behavior_type"]=="buy"]#筛选出支付的数据
dbu = dbu[["user_id","date","behavior_type"]].groupby(["date","user_id"]).count()#计数每天每个用户的支付行为数
dbu = dbu.count(level=0)#根据日期,计数用户id
dbu.rename(columns={"behavior_type":"dbu"},inplace=True)
# 合并数据
df_flow = daily_pv.join([daily_uv,dau,dbu])
df_flow
计算提升百分比:
使用matplolib绘制折线图:
plt.figure(figsize=(10,4),dpi=200) # 设置图的尺寸大小(10,4),200像素
plt.subplot(111,facecolor="#F0F0F0")#第一行,第一列,索引值
plt.xlabel("日期",fontsize=10)
plt.ylabel("单位/万",fontsize=10)
plt.xticks(fontsize=10)
plt.yticks(fontsize=10)
plt.title("流量类绝对指标",fontsize=14)
plt.grid(axis="x")
plt.plot(df_flow["pv"]/10000,linewidth = '2',marker="o",color="#00868B",label="pv")
plt.plot(df_flow["uv"]/10000,linewidth = '2',marker="o",color="#ff5338",label="uv")
plt.plot(df_flow["dau"]/10000,linewidth="2",marker="o",color="#fe8c00",label="活跃用户")
plt.plot(df_flow["dbu"]/10000,linewidth="2",marker="o",color="#595959",label="支付用户")
plt.legend(loc="best",fontsize=8)
每天的点击数量比其他数据高出两倍左右,排除pv后,其他数据折线图如下:
流量类绝对指标分析:
(1)日PV、日UV、日活跃用户数量和日支付用户数量均呈现了上升趋势,且都在12月2日、3日有了大幅度的提升,日PV提升了32.0%、日UV提升了31.8%、日活跃数量提升了30.6%、日支付用户数量提升了20.3%(数据由后两天均值除以前7天均值得出)。
(2)上述指标都在12月2日~ 3日有了大幅度提升,2017年12月2日~ 3日虽然是周末,但是结合上个周末11月25日~ 6日的流量分析,可以排除周末原因;由于12月2日~3日距离双12较近,推测较大可能的原因是双12系列促销活动预热所带来的流量增加。
流量指标可以反映出APP整体的运营情况,而流量的相对指标可以返应出整体更深层次的运营情况,根据上述流量指标,对应的流量相对指标包括以下几项:
- 每日人均PV:即人均浏览量,每日pv/每日uv;
- 每日活跃用户比例:每日活跃用户数量/每日uv;
- 每日支付用户比例:每日支付用户数量/每日uv;
- 跳失率:指在统计时间内,只浏览点击一次的用户数量/uv;本文选取的统计时间周期是一天。
# 每日人均pv df_flow["pv/uv"] = df_flow["pv"]/df_flow["uv"] # 每日活跃用户比例 df_flow["active_rate"] = df_flow["dau"]/df_flow["uv"] # 每日支付用户比例 df_flow["buy_rate"] = df_flow["dbu"]/df_flow["uv"] df_flow
绘图:
计算提升率得:
跳失率统计如下:
(1) 当统计时间为1天时,即每一天APP的跳失率:
'''每一天APP的跳失率'''
df = df[["date","user_id","behavior_type"]]
# 给不同的行为赋值
df = df.assign(behavior_num = df["behavior_type"].map({"pv":1,"fav":2,"cart":4,"buy":8}))
# 以下是计算APP每一天的跳失率
# 根据date,user_id分组,对不同behavior_num求和
df1= df.groupby(["date","user_id"]).sum()
# 筛选出和为1的用户,这部分用户就是当天只有1次pv的用户
daily_loss = df1[df1["behavior_num"]==1].count(level=0)
daily_loss.rename(columns={"behavior_num":"user_lose"},inplace=True)
# 计算APP每天的跳失率
daily_loss = daily_uv.join(daily_loss)
daily_loss["lose_rate"] = daily_loss["user_lose"]/daily_loss["uv"]
daily_loss
每天APP跳失率折线图如下:
'''每天APP跳失率折线图'''
plt.figure(figsize=(10,2),dpi=200) # 设置图的尺寸大小
plt.subplot(111,facecolor="#F0F0F0")
plt.xlabel("日期",fontsize=10)
plt.xticks(fontsize=10)
plt.yticks(fontsize=10)
plt.ylim(0,0.4)
plt.title("每日跳失率",fontsize=12)
plt.grid(axis="x")
plt.plot(daily_loss["lose_rate"],linewidth = '2',marker="o",color="#ff5338")
流量类相对指标分析:
(1)每日人均浏览量波动较平缓,其平均水平为2.3次,即每一位用户每一天平均浏览了2次页面左右。
(2)日活跃用户比例和日支付用户比例稳定在34.4%和4.9%左右。
(3)12月2至3日这两天的浏览量、用户数、活跃用户数均有所上升,但活跃比例和支付比例分别下降了0.9%和8.7%(数据由后两天均值除以前7天均值得出),说明由于活动吸引而来的用户,支付比例并没有比平时的用户高,促销活动带来的流量转化率拉低了整体的支付转化率,建议在活动引流时要更加精准。
(4)活动开始前(即前7天),APP每天的跳失率在37.7%左右,活动开始后(12月2日~3日),APP每天的跳失率上升至38.2%,比活动前提升了1.3%,也说明了活动引流时的精准度要低于活动前。
这9天内,一共有165578名用户有购买行为,平均每人购买1.2次左右,绝大部分用户只购买了1次,用户中也存在购买很多次的小部分用户,购买次数最多的达到了21次。
'''用户购买次数分布'''
plt.figure(figsize=(10,4),dpi=200)
plt.subplot(111,facecolor="#F0F0F0")
plt.title("用户购买次数分布",fontsize=12)
plt.xlabel("购买次数",fontsize=10)
plt.ylabel("用户数",fontsize=10)
plt.hist(df_buy_times["times"],bins=20,color="#6462cc")
plt.xticks(fontsize=10)
plt.yticks(fontsize=10)
绝大部分的用户在这期间购买的次数在5次以内,以下为购买5次以内用户的分布:
'''购买5次以内的用户分布'''
plt.figure(figsize=(10,4),dpi=200)
plt.subplot(111,facecolor="#F0F0F0")
plt.title("用户购买次数分布",fontsize=12)
plt.xlabel("购买次数",fontsize=10)
plt.ylabel("用户数",fontsize=10)
plt.hist(df_buy_times[df_buy_times["times"]<=5]["times"],bins=5,align='mid',color="#6462cc")
plt.xticks(fontsize=10)
plt.yticks(fontsize=10)
随着购买次数的增加,人数也在不断下降,符合消费行为的行业规律;在这9天内,有83%的用户购买次数在平均值以下,高频次(>5)消费的用户占比极小,为0.1%,可以暂时认定为极忠诚用户重点关注。
'''单日复购率'''
# 根据日期、用户ID分组计数
df_rebuy_1 = df_buy.groupby(["date","user_id"]).count()
# 统计每一天购买的用户数量
buy_user_total = df_rebuy_1.count(level=0)
buy_user_total.rename(columns={"behavior_type":"total"},inplace=True)
# 统计有复购的用户数量
repurchase_user = df_rebuy_1[df_rebuy_1["behavior_type"]>=2].count(level=0)
repurchase_user.rename(columns={"behavior_type":"repur_amount"},inplace=True)
# 计算复购率
df_repur_rate = buy_user_total.join(repurchase_user)
df_repur_rate["repur_rate"] = df_repur_rate["repur_amount"]/df_repur_rate["total"]
# 绘制复购率折线图
plt.figure(figsize=(10,3),dpi=200) # 设置图的尺寸大小
plt.subplot(111,facecolor="#F0F0F0")
plt.xlabel("日期",fontsize=10)
plt.xticks(fontsize=10)
plt.yticks(fontsize=10)
plt.ylim(0,0.10)
plt.title("单日复购率",fontsize=12)
plt.grid(axis="x")
plt.plot(df_repur_rate.index,df_repur_rate["repur_rate"])
分析:
(1)根据《精益数据分析》一书中给出的参考:当90天内重复购买率达到30%以上时,电商模式处于忠诚度模式,而淘宝APP在9天内的复购率为17.2%,因此不能说明现在淘宝是否处于电商的忠诚度模式。当处于忠诚度模式时,应该将经营的重心放在客户的忠诚度上,即鼓励忠诚的回头客更加频繁的消费。
(2)每一天用户的复购率在0.06%左右波动,在12月开始时,有小幅度的下降,推测双12活动前夕,用户在抑制消费,在等待更多优惠活动的开展;当然,数据的正常与否还需要通过对比去年相同时间段的数据才能做出判定。
'''回购率'''
# 后续涉及时间加减,将数据集date字段转化为时间格式,
df["date"] = pd.to_datetime(df["date"])
# 将时间划分为3个时间窗口,每3天一个时间窗口
# 新增一列,将同一个时间窗口的日期,设置为日期最大的一天
for m, n in zip(range(1, 10), df.date.unique()):#将1~9分别对应9个日期
if m % 3 == 0:
df.loc[((df.date + np.timedelta64(0,"D"))<= n) & ((df.date + np.timedelta64(2,"D") >= n)), 'date1'] = n
# 按时间窗口分组
df_buy_back = df[df.behavior_type == 'buy'].groupby('date1').user_id.unique()
# 定义空列表,记录对应的时间窗口以及回购率
days = []
back_buy_rates = []
# 计算回购率
for i in range(0,len(df_buy_back.index)-1):
users = df_buy_back.values[i].tolist() # 获取一个时间窗口的用户ID
count=0
for user in users:
if user in df_buy_back.values[i+1].tolist(): # 如果用户在下个时间窗口也消费了,count计1
count += 1
# 计算回购率 ,并记录
buy_back_rate = count/len(users)
back_buy_rates.append(buy_back_rate)
# 记录对应的时间窗口信息
days.append(df_buy_back.index.tolist()[i])
# 生成Dataframe输出
back_buy_rate = pd.Dataframe({'date': days, 'buy_back_rate': back_buy_rates})
back_buy_rate
11月25日 ~ 11月27日,即第一个时间窗口的用户回购率为10.07%,第二个时间窗口11月28日 ~ 11月30日,用户的回购率为10.23%, 比第一个时间窗口有小幅度提升,说明用户忠诚度在增加。
留存率是指用户在某段时间内开始使用应用,经过一段时间后,仍然继续使用该应用的用户占当时新增用户的比例。由于数据集只有9天的数据,无法确认用户是否为新增用户。因此本文将在9天内第一次登陆的用户当做新用户,模拟分析淘宝APP的留存率。
'''留存率'''
# 定义计算留存率函数,n为对应多少天留存
def nday_retention_rate(df, n):
# 创建空集合,记录用户ID;创建空列表,记录对应的日期以及留存率
users2 = set()
days = []
nday_retentions = []
# 筛选出可计算的日期
dates = df.date.unique()[:-n]
# 循环遍历每一天
for date in dates:
# 记录前一天的用户ID
users1 = copy.deepcopy(users2)#deepcopy,这样对users1操作不会改变users2
ids = df[df.date == date].user_id.unique().tolist()#取出每一天的用户id(去重)
for i in ids:
users2.add(i) # 记录当天的用户ID
users = users2 - users1 # 两集合相减,得到当天的新增用户ID
# n天之后使用APP的用户ID列表
nday_users = df[df.date == date + np.timedelta64(n,'D')].user_id.unique()
counts = 0
# 遍历n天之后的用户ID,如果用户ID在当天也消费了,count计1
for nday_user in nday_users:
if nday_user in users:
counts += 1
# 计算留存率,并记录对应日期和留存率
nday_retention_rate = counts / len(users)#某日新增用户数在n天后还在的用户数/某日新增用户数
nday_retentions.append(nday_retention_rate)
days.append(date)#单日留存率记录
# 创建对应的数据框
df_retention_rate = pd.Dataframe({'日期': days, '第{}日留存率'.format(n): nday_retentions})
return df_retention_rate
# 调用函数,计算次日、第2日、第3日、第7日留存
retention_rate1 = nday_retention_rate(df,1)
retention_rate2 = nday_retention_rate(df,2)
retention_rate3 = nday_retention_rate(df,3)
retention_rate7 = nday_retention_rate(df,7)
# 合并
retention_rate = pd.merge(retention_rate1,retention_rate2,how="left",on="日期")
retention_rate = pd.merge(retention_rate,retention_rate3,how="left",on="日期")
retention_rate =pd.merge(retention_rate,retention_rate7,how="left",on="日期")
retention_rate
临近活动时间的留存率明显上升。
本数据集中,用户的行为主要包括了浏览点击(pv)、收藏(fav)、加购物车(cart)和购买支付(buy)。接下来分别以日和小时为单位分析用户购买行为,分析用户在不同时间尺度下的行为规律。
1、时间分布分析 (1)日期维度dt_pv = df[df['behavior_type']=='pv'][['user_id','date']].groupby(['date']).count()
dt_pv.rename(columns={"user_id":"浏览数"},inplace=True)
dt_fav = df[df['behavior_type']=='fav'][['user_id','date']].groupby(['date']).count()
dt_fav.rename(columns={"user_id":"收藏数"},inplace=True)
dt_cart = df[df['behavior_type']=='cart'][['user_id','date']].groupby(['date']).count()
dt_cart.rename(columns={"user_id":"加购数"},inplace=True)
dt_buy = df[df['behavior_type']=='buy'][['user_id','date']].groupby(['date']).count()
dt_buy.rename(columns={"user_id":"购买数"},inplace=True)
dt_sta_date = dt_pv.join([dt_fav,dt_cart,dt_buy])
dt_sta_date
折线图:
分析:
收藏次数、加购次数和支付次数和页面浏览次数的上升趋势一致,都在12月2日~3日出现了大幅度的提升,收藏次数提升了32.2%,加购次数提升了38.3%,支付次数提升了19.7%。
dt_pv = df[df['behavior_type']=='pv'][['user_id','hour']].groupby(['hour']).count()
dt_pv.rename(columns={"user_id":"浏览数"},inplace=True)
dt_fav = df[df['behavior_type']=='fav'][['user_id','hour']].groupby(['hour']).count()
dt_fav.rename(columns={"user_id":"收藏数"},inplace=True)
dt_cart = df[df['behavior_type']=='cart'][['user_id','hour']].groupby(['hour']).count()
dt_cart.rename(columns={"user_id":"加购数"},inplace=True)
dt_buy = df[df['behavior_type']=='buy'][['user_id','hour']].groupby(['hour']).count()
dt_buy.rename(columns={"user_id":"购买数"},inplace=True)
dt_sta_hour = dt_pv.join([dt_fav,dt_cart,dt_buy])
dt_sta_hour
分析:19点~23点是用户活跃的高峰期,23点 ~ 凌晨4点,用户的活跃程度逐渐下降,直至一天中的最低值;5点 ~ 10点用户活跃程度开始上升;10点 ~ 18点这段时间,是一个相对平稳的状态,因为这段时间大致为工作时间;可以看出来,大部分用户的活跃时间符合人类的生物钟,因此,建议可以参考用户的活跃时间段,对应采取一些促销活动。
如果有条件,可以进一步分析不同时间段活跃的主要用户群特征,再针对主要活跃用户群特征,在不同时间段,主推不同商品。
①跳失率
统计时间为9天时,有72537人只浏览过一个页面就离开了APP,占总访问量的0.81%,表明淘宝拥有足够的吸引力让用户停留。
②漏斗分析
淘宝APP的收藏功能主要是帮助用户收藏自己喜欢但不立即购买的商品,而购物车主要还是方便用户批量购买商品,但也有类似收藏商品的功能,两者都用于提升用户购物体验,都属于浏览和购买阶段之间确定购买意向的用户行为,因此,将二者算作一个阶段,分析pv-fav+cart-buy的转化,转化周期设定为9天。
为了方便后续分析,本次分析将通过对用户行为类型进行赋值的方式,对各行为路径的用户人数进行统计,再进一步统计漏斗模型各阶段的用户数。
a. 用户行为赋值
df1 = df.assign(type_num=dt['behavior_type'].map({'pv': 1, 'fav': 2, 'cart': 4, 'buy': 8}))
# 聚合求和,每一个路径都有不同的值
df1_gb = df1[['user_id', 'item_id', 'type_num']].groupby(['user_id', 'item_id']).sum()#统计每个用户对每个商品的行为有哪几种
#用户id,商品id,行为类型组合值(数字)
print(df1_gb.head())
# 划分各路径dataframe:buy购买了的商品的用户
#每个用户对于每个购买的商品,一共可能存在8种可能路径:
buy = df1_gb[df1_gb['type_num'] == 8]#直接购买
pv_buy = df1_gb[df1_gb['type_num'] == 9]#浏览+购买
fav_buy = df1_gb[df1_gb['type_num'] == 10]#收藏+购买
pv_fav_buy = df1_gb[df1_gb['type_num'] == 11]#浏览+收藏+购买
cart_buy = df1_gb[df1_gb['type_num'] == 12]#加购+购买
pv_cart_buy = df1_gb[df1_gb['type_num'] == 13]#浏览+加购+购买
fav_cart_buy = df1_gb[df1_gb['type_num'] == 14]#收藏+加购+购买
pv_fav_cart_buy = df1_gb[df1_gb['type_num'] == 15]#浏览+收藏+加购+购买
# 每个用户对于每个没有购买的商品,一共可能存在7种可能路径:
no_behavior = df1_gb[df1_gb['type_num'] == 0]#没有任何行为的用户,数据集中不存在行为为空的数据,所以每个用户对商品的行为数至少有1.
pv = df1_gb[df1_gb['type_num'] == 1]#仅浏览的用户
fav = df1_gb[df1_gb['type_num'] == 2]#仅收藏的用户
pv_fav = df1_gb[df1_gb['type_num'] == 3]#浏览+收藏未购买的用户
cart = df1_gb[df1_gb['type_num'] == 4]#仅加购的用户
pv_cart = df1_gb[df1_gb['type_num'] == 5]#浏览+加购未购买的用户
fav_cart = df1_gb[df1_gb['type_num'] == 6]#收藏+加购未购买的用户
pv_fav_cart = df1_gb[df1_gb['type_num'] == 7]#浏览+收藏+加购未购买的用户
print('buy:', buy.shape[0], ';pv_buy:',pv_buy.shape[0])
print('fav_buy:', fav_buy.shape[0], ';pv_fav_buy:', pv_fav_buy.shape[0])
print('cart_buy:', cart_buy.shape[0], ';pv_cart_buy:', pv_cart_buy.shape[0])
print('fav_cart_buy:', fav_cart_buy.shape[0], ';pv_fav_cart_buy:', pv_fav_cart_buy.shape[0])
print('--------------')
print('no_behavior:', no_behavior.shape[0], ';pv:',pv.shape[0])
print('fav:', fav.shape[0], ';pv_fav:',pv_fav.shape[0])
print('cart:', cart.shape[0], ';pv_cart:',pv_cart.shape[0])
print('fav_cart:', fav_cart.shape[0], ';pv_fav_cart:', pv_fav_cart.shape[0])
b. 各行为路径的用户数统计:
behavior_routes = ['buy','pv_buy','fav_buy','pv_fav_buy','cart_buy','pv_cart_buy','fav_cart_buy','pv_fav_cart_buy',
'pv','fav','pv_fav','cart','pv_cart','fav_cart','pv_fav_cart']
users = [buy.shape[0],pv_buy.shape[0],fav_buy.shape[0],pv_fav_buy.shape[0],cart_buy.shape[0],pv_cart_buy.shape[0],fav_cart_buy.shape[0],
pv_fav_cart_buy.shape[0],pv.shape[0],fav.shape[0],pv_fav.shape[0],cart.shape[0],pv_cart.shape[0],fav_cart.shape[0],pv_fav_cart.shape[0]]
dt_b = pd.Dataframe()
dt_b['behavior_routes'] = pd.Series(behavior_routes)
dt_b['users'] = pd.Series(users)
dt_b
c. 漏斗模型各阶段用户数计算:
pv = dt_b[dt_b['behavior_routes'].str.contains('pv')]['users'].sum()
fav = dt_b[dt_b['behavior_routes'].str.contains('fav')]['users'].sum()
cart = dt_b[dt_b['behavior_routes'].str.contains('cart')]['users'].sum()
buy = dt_b[dt_b['behavior_routes'].str.contains('buy')]['users'].sum()
behavior_type = ['pv','fav+cart','buy']
users = [pv,fav+cart,buy]
dt_funnel = pd.Dataframe()
dt_funnel['behavior_type'] = pd.Series(behavior_type)
dt_funnel['users'] = pd.Series(users)
dt_funnel
d. 转化率计算:
# 单一环节转化率 d = dt_funnel temp1 = np.array(d['users'][1:]) temp2 = np.array(d['users'][0:-1]) single_convs = temp1 / temp2 single_convs = list(single_convs) single_convs.insert(0,1) single_convs = [round(x,4) for x in single_convs] # 利用round函数将转化率保留四位小数 d['各环节转化率'] = single_convs # 计算总体转化率 temp3 = np.array(d['users']) temp4 = np.array(d['users'][0]) total_convs = (temp3 / temp4).tolist() total_convs = [round(x,4) for x in total_convs] d['整体转化率'] = total_convs d
e. 绘制漏斗图:
x_data = d['behavior_type']
y_data = d['整体转化率']
# 绘制漏斗图
data = [[x_data[i], round(y_data[i]*100,2)] for i in range(len(x_data))]
funnel = Funnel(init_opts=opts.InitOpts(width="800px", height="400px",renderer= "svg"))
funnel.add(series_name="用户行为转化漏斗图",
data_pair=data,
gap=2,
tooltip_opts=opts.TooltipOpts(is_show=True,trigger="item", formatter="{a}
{b} : {c}%"),
label_opts=opts.LabelOpts(is_show=True, position="outside",formatter="{b} {c}%"),
itemstyle_opts=opts.ItemStyleOpts(border_color="#fff", border_width=1),
)
# 设置标题和图例
funnel.set_global_opts(title_opts=opts.TitleOpts(title="用户行为转化漏斗图",pos_left="center"),
legend_opts=opts.LegendOpts(pos_left=0,pos_bottom="50%",orient="vertical",item_height=12)
)
funnel.render_notebook()
可以看到从浏览到有购买意向有9.74%的转化率,当然有一部分用户是直接购买而未通过收藏和加入购物车,但也说明大多数用户浏览页面次数较多,而使用购物车和收藏功能较少,而购买次数占使用购物车和收藏功能的23.92%,说明从浏览到进行收藏和加入购物车的阶段是指标提升的重点环节。
由于数据集时间范围的限制,暂时无法知道这9天各环节的转化率是否正常,需要与历史数据对比才能作出最终的判断。
以用户浏览作为前提,一共有8条用户行为路径。
a. 统计各行为路径的用户数量:
b. 绘图
由于pv路径人数比其他路径高出太多,因此,此处不不加入pv分析。
计算比例:
分析:
1、在这9天中,除去pv外,占比最高3条路径分别是:浏览—加购物、浏览—购买和浏览—收藏,在这7条路径用户数中分别占了49.55%、28.61%、20.57%,总占比98.73%,其他用户路径占比比较小,相差不大。
2、这7条路径的用户在9天内,支付购买的用户占比为29.62%,使用购物车功能用户占比50.57%,使用收藏功能的用户占比21.07%(数据由对应包含行为的路径累加得到)。
3、使用收藏功能并且支付购买了的用户占比0.25%,这9天内,收藏功能的支付转化率为1.19%(0.25%/21.07%);没有使用收藏功能的支付转化率为37.22%(29.38%/78.93%),通常来讲,收藏功能在一定程度上可以反映用户的购买意向,而在这里的分析表明收藏功能却并没有提高用户的支付转化率,原因可能是由于数据集的9天时间限制,加上双十二活动前夕用户会有抑制消费的心理,造成了经收藏-购买路径的用户人数较少,而浏览-收藏和收藏-加购的用户人数更多。
4、使用购物车并且支付购买了的用户占比7.65%,购物车功能的支付转化率为15.12%(7.65%/50.58%),没有使用购物车功能的用户支付转化率为59.44%(29.38%/49.43%),同样,购物车似乎也没有提高用户的支付转化率,但浏览-加购路径的用户数占比最大,且相比于收藏功能来说支付转化率更高。
综上,虽然从短期来看使用收藏和支付功能的用户支付转化率不高,但使用这两个功能的用户占比极大,因此,建议最大限度地优化收藏和加购物车功能,提高用户的支付转化率;此外还可以对在收藏夹和购物车有商品的用户提设置提醒功能,如:商品加入购物车3天后还没购买,可以及时提醒用户;或者购物车里的商品有优惠信息了及时提醒用户。
基于RFM理论找出有价值的用户,首先统计出用户购买商品的最大值和最小值,由于数据源中没有相关的金额数据,因此通过 R 和 F 的数据对客户价值进行打分。其中R表示最近购买时间,用户数据的时间范围为九天,所以最近购买时间的区间为0-9,将其分为3档,3天内为2,大于3而小于6为1,大于6而小于等于9为0。
# 以2017-12-03为最大日期,找到最近与最久远购买的用户的id
df['time_buy'] = pd.to_datetime(df['date'])
df['datetime']= pd.to_datetime(df['datetime'],errors='coerce')
# 最近一次购买的时间与12-03之间的时间差
dt_buy = df[df['behavior_type']=='buy']
dt_buy = dt_buy[['user_id','datetime']].sort_values('datetime', ascending=False).groupby('user_id', as_index=False).first()
s = pd.to_datetime('2017-12-04 00:00:00')
dt_buy['diff_time'] = s - dt_buy["datetime"]
# 时间格式转化,单位为小时
dt_buy['diff_time'] = dt_buy['diff_time'].map(lambda x : x.days * 24 +x.seconds/3600)
dt_buy.head()
R分数:
R = []
for i in range(0,len(dt_buy['diff_time'])):
h = dt_buy['diff_time'][i]/24
if h<3:
r = 2
elif (h>=3) & (h<6):
r = 1
else:
r = 0
i = i+1
R.append(r)
dt_buy['R'] = R
dt_buy
F分数:
# F-消费次数
# 统计每个用户的消费次数
dt_buy_sta = df[df['behavior_type']=='buy'][['user_id','behavior_type']].groupby('user_id').count()
dt_buy_sta.rename(columns={'behavior_type':'buy_times'},inplace=True)
# dt_buy_sta.sort_values('buy_times',ascending=False,inplace=True)
dt_buy_sta.reset_index(inplace=True)
dt_buy_sta
# 付费用户中消费次数从低到高为1-21次,
# 将其分为3档,1-7,8-14,15-21分别对应评分0到2
F = []
for i in range(0,len(dt_buy_sta['buy_times'])):
h = dt_buy_sta['buy_times'][i]
if h<=7:
f = 0
elif (h>7) & (h<=14):
f = 1
else:
f = 2
i = i+1
F.append(f)
dt_buy_sta['F'] = F
dt_buy_sta.sort_values('user_id',inplace=True)
dt_buy_sta
合并R和F评分:
RF = pd.merge(dt_buy,dt_buy_sta,on='user_id')
RF = RF[['user_id','R','F']]
RF['R+F'] = RF['R']+ RF['F']
RF.sort_values('R+F',ascending=False,inplace=True)
RF.reset_index(drop=True)
可以看到,1003412、702034的RF评分最高,为4,是体系中的最有价值用户,需要重点关注,并且活动投放时需谨慎对待,不要引起用户反感;对于R值为2而F值较低的用户,用户粘性不强而消费时间间隔较短,运营活动可以重点针对这部分用户,提高用户使用产品的频率,可以通过拼团打折、积分兑换等活动唤起用户注意力。
在这9天的用户行为数据中,一共有8280种商品大类,用户购买了其中的4993种,占比60.3%;一共有176万种商品,有购买记录的只有13.2万种商品,占比仅为7.5%。接下来分析用户比较喜欢购买的商品大类以及商品。
1、商品大类购买次数分析 (1)商品大类购买次数描述统计
在这9天中,平均每一种商品大类被购买了40.5次,但超过50%的商品大类只被购买了6次以内,整体明显呈现右偏,说明存在着一部分相对热销的商品大类提高了平均水平。接下来找出最热销的20种商品大类。
# 排序,热销的TOP20
df_cat_top20= df_buy.sort_values(by="buy_times",ascending=False).head(20)
df_cat_top20["percent"] = (df_cat_top20.buy_times)/df_cat_top20.buy_times.sum()*100
# 绘制饼图
plt.figure(figsize=(10,5),dpi=120)
plt.pie(df_cat_top20["percent"],labels=df_cat_top20.index,autopct='%1.1f%%',pctdistance=0.8,radius=1.2,startangle=70,labeldistance=1.0)
plt.legend(loc="upper right",fontsize=8,bbox_to_anchor=(1.4,0.9),borderaxespad=0.3)
plt.title("热销TOP20商品大类交易占比",pad=10,fontsize=12)
在这9天中,热销TOP20的商品大类购买次数占总体商品大类购买次数的20.3%,而被购买的商品一共有4993种,因此这TOP20的商品是值得额外关注的商品大类。
在这9天中,平均每一种商品被购买了1.5次,但超过75%的商品只被购买了1次,购买次数最多的商品有137次。筛选被购买次数大于100的商品,结果显示只有1种商品的购买次数为137次,购买次数超过50次的商品也只有10种,即实际上并没有出现购买数量非常集中的商品,说明这9天内,商品售卖还是主要依靠长尾商品的累积效应,而非爆款商品的带动。
df_item_top20= df_buy_item.sort_values(by="buy_times",ascending=False).head(20)
# 添加在热销TOP20购买总数的占比
df_item_top20["percent"] = (df_item_top20.buy_times)/df_item_top20.buy_times.sum()*100
# 绘制饼图
plt.figure(figsize=(10,5),dpi=120)
plt.pie(df_item_top20["percent"],labels=df_item_top20.index,autopct='%1.1f%%',pctdistance=0.8,radius=1.2,startangle=70,labeldistance=1.0)
plt.legend(loc="upper right",fontsize=8,bbox_to_anchor=(1.4,0.9),borderaxespad=0.3)
plt.title("热销TOP20商品购买占比",pad=10,fontsize=12)
在这9天中,热销TOP20的商品购买次数占总体商品购买次数的0.54%,占比较低,再次说明了这9天中没有爆款商品的带动。
# 筛选用户浏览的记录
df_pv =df[df["behavior_type"]=="pv"]
# 对商品进行分组统计,并统计浏览过商品的用户数量
df_pv_item = df_pv[["user_id","item_id"]].groupby("item_id").nunique()
df_pv_item = df_pv_item.rename(columns={"user_id":"pv_user_amount"})
df_pv_item = df_pv_item.drop("item_id",axis=1)
# 筛选用户购买的记录信息
df_buy = df[df["behavior_type"]=="buy"]
# 对商品进行分组统计,并统计购买过商品的用户数量
df_buy_item = df_buy[["user_id","item_id"]].groupby("item_id").nunique()
df_buy_item = df_buy_item.rename(columns={"user_id":"buy_user_amount"})
df_buy_item = df_buy_item.drop("item_id",axis=1)
# 联结两个表,并计算商品的购买转化率
df_item = pd.merge(df_buy_item,df_pv_item,left_index=True,right_index=True,how="inner")
df_item["con_rate"] = df_item["buy_user_amount"]/df_item["pv_user_amount"]
# 排除购买人数大于浏览人数的商品
df_item = df_item[df_item["con_rate"]<=1]
# 绘制直方图
plt.figure(figsize=(10,4),dpi=200)
plt.subplot(111,facecolor="#F0F0F0")
plt.title("商品转化率分布",fontsize=12)
plt.xlabel("商品转化率",fontsize=10)
plt.ylabel("商品数",fontsize=10)
plt.hist(df_item["con_rate"],bins=10)
plt.xticks(ticks=np.arange(0,1.1,0.1),fontsize=10)
plt.yticks(fontsize=10)
# 转化率在90%以上并且用户数量大于1的商品数量
df = df_item[(df_item["con_rate"]>=0.9) & (df_item["con_rate"]<=1.0) & (df_item["buy_user_amount"]>1)].sort_values("buy_user_amount",ascending=False)
df.shape[0]
分析:
① 在9天内,商品的转化率分布出现了两个集中区域,77%的商品转化率在50%以下,12.8%的商品转化率在90%以上,但高转化率的商品中有95.2%只有1个用户购买了,因此这部分商品目前还不能划分为高转化率商品,因为流量基数过小。建议后续可以关注这部分商品随着流量的增大,转化率的变化情况。
②低转化率的商品购买用户数量规模也不大,但是由于UV大,所以整体呈现较低的转化率,对于这部分商品,建议对应的商家做好流量流失分析,提高用户从点击进入商品详情页再到最终购买的体验,从而促进转化率。
数据集来源于阿里天池,涵盖淘宝APP从2017年11月25日到2017年12月3日共1亿多条用户行为数据,由于计算机内存有限,只从中随机抽取了10%的数据进行分析。
2、任务基于AARRR模型和RFM模型,梳理各阶段的常用指标,结合数据集筛选出可以分析的指标,最后结合相关案例学习经验整理出分析的整个框架。
基于本数据集的内容特征,本次分析将从以下几个方面进行:
(1)基于AARRR模型对相关流量类指标和用户类指标进行统计分析,了解淘宝APP的运营情况。
(2)用户行为时间分布分析,找到用户的活跃时间规律,进而进行针对化的活动营销。
(3)用户行为路径分析,找到可以提升转化率的环节
(4)利用RFM理论,找出核心付费用户群体。
(5)商品的购买分布分析。
(1)数据清洗,包括对缺失值、重复值、异常值的处理以及时间维度拆解。
(2)流量类指标分析,包括对日PV、日UV、日活、日支付用户数、每日人均PV、每日活跃用户比例、每日支付用户比例、跳失率的计算与可视化。
(3)用户类指标分析,包括9天内的用户购买次数描述统计/用户购买次数分布、9天内复购率/单日复购率、回购率、留存率。
(4)用户行为时间分析,包括日期维度与小时维度下点击、收藏、添加购物车、支付次数的统计与可视化分析。
(5)用户行为路径分析,包括用户行为漏斗分析、用户行为路径分布。
(6)基于RFM分析评估用户价值。
(7)用户购买商品分析。包括对商品大类和具体商品的购买次数描述统计和热销商品分析、商品转化率分布分析。
本文分析了淘宝APP用户行为数据记录,根据数据集内容的特征,主要从流量指标、用户类指标、用户行为以及用户购买商品四大方面进行入手分析,以下为本次分析的一些结论和建议。
1、在流量类指标中分析发现,虽然双12活动的预热给淘宝APP带来了访客量的大幅上涨,但是日活跃用户和日支付用户的比例都有一定幅度的下降,而跳失率也有小幅度上涨,整体的用户质量在下降,说明活动引流精准度不够。因此,建议结合历史数据以及业务目标分析,是否需要完善和加强个性化推荐功能。
2、用户类指标分析主要分析了用户购买次数、复购率、回购率以及留存率,通过仅9天数据的复购率分析无法判断淘宝是否处于电商的忠诚度模式,数据的正常与否还需要通过对比去年相同时间段的数据才能做出判定,当淘宝是否处于电商的忠诚度模式时,应该将经营的重心放在客户的忠诚度上,即鼓励忠诚的回头客更加频繁的消费。其他指标可以用来衡量对比这9天中用户的整体运营情况,如果有较大幅度上涨或者下跌,需要进一步深入拆解分析。
3、在用户行为分析中发现:
(1)用户使用APP有一定的时间规律,一周中,用户在周末的活跃度比较高,而一天中,19点~23点是用户活跃的高峰期,因此建议进行重要的营销活动时不要错过这些时间点,这样可以触及更多的活跃用户,活动效果会比较好。
(2)使用收藏和购物车的用户群占比很高,建议可以通过AB测试,让用户更加便捷地使用收藏和加购物车功能,提升用户的支付转化率。
4、在商品分析上,9天内,热销TOP20的商品大类购买次数占总体商品大类购买次数的20.3%,属于值得额外关注的商品大类。但绝大部分的商品只被购买了1次,没有出现热销“爆款“,商品的转化率也出现了两个集中区域,对于处在低转化率、高曝光率的商品建议优化展示效果以及提高用户的购买体验,进而提高转化率;对于高转化率、低曝光率的商品建议优化曝光渠道,积极引流。同时淘宝APP可以向高转化率、高曝光率的商品倾斜一定的资源,形成一个良性循环,但是也要加强监管作弊行为。



