合作机构:阿里云 / 腾讯云 / 亚马逊云 / DreamHost / NameSilo / INWX / GODADDY / 百度统计
根据CNNIC的统计数据显示,中国互联网用户已达10.79亿人,互联网普及率达到79.4%。互联网虽然仍然在快速增长,但是用户规模逐渐饱和,互联网事实上已经进入了存量用户时代,整体的流量竞争也越来越激烈,用户的留存的重要性也越来越高于拉新。因此,如何识别忠实用户,了解目标用户群的留存表现?如何分析用户流失情况,优化产品?如何分析目标用户是否完成了期望的行为等等就是我们数据分析的重要课题,而留存分析模型就是我们解决这些问题的重要工具。
留存分析模型主要用于分析触发了起始事件的用户在后续时间周期内触发了后续事件(即回访事件)的比率,该模型可以较好的反映出用户的忠实度或者说是用户的粘性。对于留存分析模型有几个重要的概念要了解:
留存分析一般需要指定起始事件和回访事件,但起始事件和回访事件可以相同,也可以不同:
1、起始事件、回访事件可以选择相同事件,这种可以很直观地看出触发事件的忠实用户量。
例如:在签到过程中,起始事件为签到成功,回访事件也是签到成功,在一段时间内,连续触发该事件的用户数量即可为忠实用户量。
2、起始事件、回访事件可以选不同事件,这种就是比较正常流程下的用户留存数据。
例如:在某个活动中,从下单到成功支付的场景内,起始事件为下单,回访事件为支付成功,这种在一段时间内,触发这两个事件的同一用户为指定流程下的用户留存数据。
留存率作为一个产品的核心指标之一,我们提升产品力,改善使用体验,分析目标用户很大程度上也是为了提升这个指标。比如,我们可以通过计算N日的留存率,来评估某个迭代是否是正向的。如图1所示,某应用优化了首页布局,推出了新版本A,就可以联同旧版本B,分别计算每日的用户留存率,它一般会组成一个衰减的留存曲线。曲线衰减的越慢,说明我们的留存率越高,也就能体现我们首页的修改是有正向的效果的。当然有时留存的提升可能只有百分之零点几,但是在一个很大的用户基数的前提下,也可能产生一些质变的效果。我们也可以将特定的人群圈定为用户组,针对不同的用户组进行留存分析,挖掘更加忠实的用户群体。
图1 新版本A与旧版本B的留存对比
了解了上面的关于留存模型的基本概念,我们看一下如何创建一个留存。
起始事件:打开浏览器。
回访事件:退出浏览器。
设置一个留存天数为3天。
这里的时间区间概念是指,你需要查看的日期区间,例如选择时间区间为2023-01-06~2023-01-08,则是只计算2023-01-06到2023-01-08这3天,每天的当日留存,第1日留存,第2日留存,第3日留存。
起始用户数 = 计算日期触发起始事件用户数。
用户留存数表(即表1)表示起始事件为“打开浏览器”、回访事件为“退出浏览器”时,对应2023-01-06~2023-01-09每天的近3天的留存用户数据。
表1 用户留存数表
用户留存率表(即表2)表示 起始事件为“打开浏览器”、回访事件为“退出浏览器”时,对应2023-01-06~2023-01-08每天的近3天的留存用户占比数据。
表2 用户留存率表
以表1中2023-01-06日的数据为例,1月6日起始用户数1000:是指触发起始事件“打开浏览器”的用户数;当日留存用户数900:是指在触发起始事件用户中当日又触发回访事件为“退出浏览器“的用户人数;
第1日留存用户数500:是指1月7日触发回访事件且与1月6日中触发起始事件的交集用户数;第2日留存用户数300:是指1月8日触发回访事件且与1月6日中触发起始事件的交集用户数300,以此类推到第3日,此时计算出来的2023-01-06这一天的3天的留存数据!
图2:触发起始事件、回访事件对应3日内的留存用户趋势图
图3 留存分析模型hive架构图
整体架构主要分为配置、计算、存储、展示四阶段。
1. 配置
此阶段主要是工程端的后台服务实现。用户在平台按照自身需求设置起始事件及回访事件、过滤条件、用户群筛选、维度筛选等配置。后台服务收到配置请求后,依据留存分析类型选择不同任务组装器进行sql任务的组装。
2. 计算
平台根据接收到的查询方式,选择离线查询Spark引擎进行分析计算。离线计算结果同步到MySQL。
3. 存储
离线结果集持久化到MySQL数据库中,可通过后台服务展示给用户。
4. 展示
离线结果根据图表配置ID查询MySQL结果表数据进行展示,即时查询通过配置后直接查询展示结果。
离线通用执行hive任务SQL
离线留存hive执行SQL
select
'起始留存计算日期' as origin_day,
a.day as day,
datediff('起始留存计算日期', a.day) as diff,
count(distinct (a.uid)) as user,
count(distinct (case when b.uid is not null then b.uid end)) as retention
FROM
(
SELECT
day,
uid
FROM
abcd.test
WHERE
day >= if('起始时间' >= date_sub('起始留存计算日期', '留存天数'),'起始时间',date_sub('起始留存计算日期', '留存天数'))
AND day <= if('结束时间' <= '起始留存计算日期','结束时间','起始留存计算日期')
AND event_id = '起始事件')
) a
LEFT JOIN (
SELECT
s.uid
FROM
abcd.test s
WHERE
s.day = '起始留存计算日期'
AND s.event_id = '回访事件'
GROUP BY
s.uid
) b ON
a.uid = b.uid
WHERE
day >= if('起始时间' >= date_sub('起始留存计算日期', '留存天数'),'起始时间',date_sub('起始留存计算日期', '留存天数'))
AND day <= if('结束时间' <= '起始留存计算日期','结束时间','起始留存计算日期')
GROUP BY a.day
TOP