数据分析工具箱v1.4——留存分析

背景

留存分析(群组分析,cohort analysis)是以一段时间窗内的研究对象,观察其在后续若干个时间窗内有指定行为的比例变化趋势。

留存率是一个与DAU强相关的核心指标,是反映产品生命力的重要风向标,如果留存率高、衰减速度慢,那就说明产品生命力强劲,反之则衰弱。近来在用户增长领域出现一种论调:AARRR已过时,RARRA才是更好的增长模型。也强调了留存率的重要性——如果用户都不留下来,就不会给你机会做运营。

与此同时,留存分析也是一种非常常见的数据分析模型,基本上各个业务线都会研究其特定的用户留存(当然留存分析模型不一定仅限于用户,比如我以前在某自行车公司就研究过自行车的留存,虽然我现在已经忘了当时是在研究啥……),比如:

  • 做了一个运营活动,想看参加活动的用户留存
  • 做了一个AB试验,想对比实验组和对照组的用户留存
  • 产品做了一次改动,想看影响范围下的用户留存
    ……

如果来一个这样的需求,就跑一次数,那就显得有点不够优雅。正是因为它重要,又常见,且模型本质和计算逻辑比较通用,所以可以把数据处理和计算的部分抽象在数据平台上,以便用户能够快速高效地进行留存分析。

本文的目标在于连通底层明细数据,并支持用户在前端上组合筛选条件来自定义群组,然后自动计算群组的日、周、月留存,并在此基础上拟合一个留存率衰减模型,以此来预测群组在任意一天的留存值。整体思路如下:

留存分析数据产品设计逻辑

数据分析方法

留存率计算方法

在数据仓库日常生产调度中,有一种计算留存率的方法,即拿1个分区的基准明细数据不断左关联后续N个时间窗分区的明细数据,以计算重合数,进而计算留存率——这是一种稳妥的数据生产调度方法,却有失灵活。

本文计算的方法如下:
基准表与行为表按id关联,日期不作限制,即同id按日期作笛卡尔积,得到的中间表如下示意——

基准日 用户id 行为日 日期差
2019-09-01 user1 2019-09-02 1
2019-09-01 user1 2019-09-03 2
2019-09-01 user1 2019-09-04 3
2019-09-01 user2 2019-09-02 2
2019-09-01 user3 2019-09-05 4

先去重,然后按基准朱和日期差分组统计行数,得到的中间表如下示意——

基准日 日期差 用户数
2019-09-01 0 1000
2019-09-01 1 500
2019-09-01 2 300
2019-09-02 0 900
2019-09-02 1 400

再作行列转换——

基准日 0 1 2 3 4
2019-09-01 1000 500 300 200 100
2019-09-02 900 400 250 150 90
2019-09-03 1200 600 400 200 100

其中0那一列则是基准值,也是分母,后面各列除以基准值则可得到留存率;例如1列除以0列则是次日留存率,7列除以0列则是7日留存率。向量化计算,则可快速得出每一天的留存率。

周、月留存率计算同理。

留存幂函数拟合

就拿新增活跃举例,一个正常的互联网产品,观察某一天的新增用户,在后续N天的留存率,它总体上一定是以斜率逐步下降的速率在逐步衰减,然后到达平衡——如果把散点图画出来看,很容易看到长得很像幂小于0的函数曲线。

幂函数曲线

于是就可以用幂函数来拟合留存率模型,然后就可以用户预测留存率了。
y = a*x^b

其中y是留存率,x是往后的天数,a是次日留存率(当x=1时,y = a),b是衰减幂。
从这个公式中可以看出:

  1. 次日留存率很重要,它决定了留存衰减曲线的起点和整体高度
  2. 衰减幂b小于0,b越大(越接近0)则衰减越慢,留存越稳定;b越小(绝对值越大),则衰减越快,越容易流失。

在这个公式中,x,y和a在训练集中都是已知的,就只需要拟合b;两边取对数,就能把这个幂函数模型转化成线性模型,然后用线性模型的拟合方法即可,十分简单。

> get_fit_power <- function(x,y){
+   a <- log(x)
+   b <- log(y) - log(y[1])
+   fit <- lm(b~a)
+   return(fit$coefficients[2])
+ }
> 
> # 构造样例数据来验证一下
> x <- 1:100
> y <- rnorm(1)*x^(-0.56234) # 系数怎么取不重要,幂随便瞎写一个
> get_fit_power(x,y)
       a 
-0.56234 

拿完全的幂函数样本数据去拟合,拟合的结果完全吻合样本上的幂,毫无误差,哈哈哈。

有了上述2个数据分析方法,就可以进行数据产品建设了。

数据产品示意

(本文中的示例数据来自于网络上某产品的数据,其中用户id作去隐私处理。)

上传基准明细数据

第一步没有别的,还是上传数据。上传一份用户粒度的新增明细数据,其中日期和用户id必备,其他维度可加可不加,主要用来筛选用。

上传基准明细数据

控件说明

  • 第1个上传框用于上传行为明细数据
  • 第2个日期区间选择器用于选定一段基准日期,即只看这一段日期以内新增的留存率情况
  • 第3个和第4个下拉框只有当2份数据都上传后才能筛选,取值范围为2个表列名的交集(所以2个表的日期和ID必须同名),通过用户筛选,用来告诉用户哪个字段是日期,哪个字段是ID,才能让系统正确地关联计算
  • 第5个是统计周期,有daily(默认)、weeklymonthly3个值可选,分别对应日留存、周留存和月留存
  • 最后一个日期单选器,用于在留存幂函数模型拟合出来以后,指定1天,计算基准日期内的新增在指定天的留存预测值
页面控件

留存率热力图

2份数据都上传后,指定日期字段为day,关联ID为userid,统计周期为daily,则可自动计算并以热图形式可视化出统计周期内每1天的新增在后续的逐日留存率。这是一个标准的下三角形,每一个热块代表着某一个基准日在后续时间窗的留存率,颜色从浅到深表示留存率从小到大,鼠标移到一个热块上,可以显示对应的基准日期、时间窗间隔,以及对应的留存率。

留存率热图

当然你可能觉得这样会逼死密集恐惧症,没有关系,可以缩小要观察的基准日期范围,比如我只想看8月内的留存率——

8月内留存率

当然你可能还是觉得密集,不想看那么多天,没有关系,可以在图上通过缩放截取,只看你关心范围内的留存情况——

热力图截取

同样地,你可以通过切换统计周期,来观察周留存和月留存。

周留存
月留存

通过这几个功能,可以对留存率作全局分析,也可以发现一些异常的现象。比如下图所示,这款产品整体留存率偏低,6月5号这一天的新增用户,在80+天内留存率都很高(约40%+以上的水平),在88天后骤然恢复到正常水平,所以这一天的新增用户是什么情况?是数据出问题了,还是持续活跃了80+天的水军?

留存率异常

留存衰减幂函数模型

留存热力图下方有2部分,左下方是留存幂函数拟合曲线,这个是基于用户所筛选(如果没有选则不筛选)的基准日日期范围内的新增用户的留存率数据作拟合,蓝色的点为实际留存率数值,黑色的虚线为拟合的幂函数模型曲线,图上有拟合的模型结果;右下方是预测留存数,是基于拟合后的幂函数模型,在用户指定的预测留存日期(上方最后一个日期选择器控件筛选结果)预测的数值,比如第1行的结果表示,2019-07-17这1天有999个新增用户,在经过57天之后(即2019-09-12)将会衰减至3.78个。从曲线图中可以看到散点的分布并不是严格符合幂函数模型,所以拟合的模型效果不会很好。

留存衰减幂函数模型

当然,用户切换基准日日期范围后,训练集会变化,拟合的模型结果也会跟着变。比如我这里限定基准日期范围为7月下半月(2019-07-16 - 2019-07-31),来预测这一段时期内的新增用户在8.1号的留存值。

从下面的曲线来看,这次的拟合结果较好。基于新拟合的模型预测结果,可以看到7.30号新增了147个用户,预期2天后能留存15个。

以7月下旬的训练集拟合的留存衰减模型

切片留存分析

我把数据处理放在左侧导航栏,表示着数据处理结果可以适用于任何模型,包括这里的筛选,就意味着任何一个模型不仅能作用于全体数据,还能作用于用户任意自定义的切片。比如我只想观察“来自于渠道3,用brand_2品牌的男性用户”的留存情况,只需在左侧输入筛选条件channel == 'channel_3', brand == 'brand_2', gender == 'male',系统则会自动计算展现这个群组的留存率和留存模型。

切片后的留存分析

总结

本文以留存分析为主题,提供了一种高效的留存率计算逻辑和留存率幂函数拟合方法,并将之产品化——只需要指定2份数据集,即可自动计算出日、周和月留存,并支持自由筛选群体范围、观测周期、以及时间窗长度,同时还能基于留存率数据自动拟合留存率幂函数衰减模型,并基于这个模型预测一段时间的群组在任意1天的留存情况、

不过后续仍有2个问题需要考虑——

  1. 由于这套系统是在单机内存上运行,所以试验用的是小样本量数据。但在一款成熟产品的数据仓库中,用户明细数据可是很庞大的,且关于日期作笛卡尔运算,会很消耗集群计算资源——所以真正在生产环境中,系统的稳定性、计算效率是需要考虑的问题。
  2. 其实留存幂函数衰减模型再往下挖,就应该是DAU预测模型了,不过这个我现在还拿不准,所以这次先不搞。

参考文档

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,475评论 4 372
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,744评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,101评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,732评论 0 221
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,141评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,049评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,188评论 2 320
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,965评论 0 213
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,716评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,867评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,341评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,663评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,376评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,200评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,990评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,179评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,979评论 2 279

推荐阅读更多精彩内容

  • 【河马12月11日打卡】 言语理解:对29 错11 判断推理:对 错 资料分析:对 错 数量关系:对 错 常识判断...
    河马先森阅读 319评论 0 0
  • 如果一个人在第一次面对诱惑时妥协了,事情发生后他/她会说保证不会有下次,但是再下一次再次面对这样的事情的时候,往往...
    年华随流星而逝阅读 141评论 0 1
  • 夢行者 2017.11.21 工作时间占据了大部分,可控就剩早上...
    UP夢行者阅读 191评论 4 0
  • 上周四,去新华书店订购书籍,发现了一套适合儿子的书籍,<培养男孩子的男子汉气质>,正好家里的书和他现在的阶段有点青...
    选定事情999阅读 221评论 0 0
  • 人生苦短,请珍惜眼前的路.
    张一诺de阅读 121评论 0 1