留存率:同期群与分母
留存率按同期群计算:分母是该 cohort 的首日新增用户数,分子是这批用户在第 N 日仍然活跃的人数。新老用户定义、活跃定义与回访口径都要固定下来。cohort 一旦生成就应当冻结——如果补数或规则变更改写了 cohort 集合,历史留存曲线会整体漂移,已经对外披露的数字会跟着变,而前后对比也失去意义。
基本信息
| cohort | 以首次活跃日划分的同期群 |
|---|---|
| 分母 | 首日新增用户数,生成后冻结 |
| 分子 | 第 N 日仍然活跃的用户数 |
| 常用口径 | 次日留存 D1、7 日留存 D7、30 日留存 D30 |
| 统计方式 | 按 cohort 日期分组,逐日计算 |
| 口径要求 | 活跃定义与首日判定规则必须写明 |
典型使用场景
- 产品健康度:看新增用户的长期留存曲线是否走平
- 渠道质量:不同渠道的 D1 与 D7 对比,判断用户质量
- 版本对比:发版前后的留存差异,需控制 cohort 与其他变量
- 召回效果:被召回用户的次留与自然新增次留对比
- 付费产品:付费用户的留存显著高于免费用户,需分层统计
- 流失预警:D30 留存持续下滑时提前介入
次日与 7 日留存
次日与 7 日留存
WITH cohort AS ( -- 首日集合
SELECT user_id, min(dt) AS first_dt
FROM dwd_active_user
GROUP BY user_id
)
SELECT c.first_dt,
count(DISTINCT c.user_id) AS cohort_size,
count(DISTINCT CASE WHEN a.dt = date_add(c.first_dt, 1)
THEN a.user_id END)
/ count(DISTINCT c.user_id) AS d1,
count(DISTINCT CASE WHEN a.dt = date_add(c.first_dt, 7)
THEN a.user_id END)
/ count(DISTINCT c.user_id) AS d7
FROM cohort c
LEFT JOIN dwd_active_user a ON a.user_id = c.user_id
GROUP BY c.first_dt; -- 每个 cohort 一行,便于横向对比常见留存口径
| 口径 | 分子定义 | 注意 |
|---|---|---|
| 次日留存 D1 | 首日后第 1 天活跃 | 最敏感,适合快速判断效果 |
| 7 日留存 D7 | 首日后第 7 天活跃 | 需等 7 天数据齐备才能计算 |
| 滚动留存 | 首日后 7 天内任意一天活跃 | 与固定日留存不可混比 |
| 回访留存 | 按周回访而非连续活跃 | 口径更宽松,数值高于日留存 |
| 付费留存 | 限付费用户 | 分母口径不同,不可与整体对比 |
补数改写 cohort 是留存统计里最隐蔽的问题:如果某个用户昨天没活跃、今天补了昨天的数据,他的首日就变了,原本落在 A cohort 的人跑到了 B cohort,两个 cohort 的分母与分子同时变化,历史曲线被追溯性改写。cohort 集合应在首次生成时固化落表。