经营一所魔法学院,开学季是你最忙碌也是最兴奋的时候。一批批新生拖着行李箱涌进校门,你问自己的第一个问题不是“今天来了多少人”,而是“这一批孩子,到下个学期还能留下几个”?于是你给每个入学季建一份“班级档案”:九月班、十月班、十一月班……每份档案记录同一个班从第 1 天到第 30 天每天来上课的人数。你渐渐发现,有些班第一天很热闹,第二周就冷清了一半;有些班看起来人不多,却一直有学生坐在教室里自习。这种“跟着同一批人,看他们随时间留下的比例”的观察方法,就是 Cohort Analysis——用户队列分析。 在 AI 公司里,用户就是学生,产品就是校园。Cohort 分析帮你把“今天涨了多少用户”这种表面热闹,变成“这批用户到底有没有留下来”的深层答案。它能告诉你:是哪次改版让用户更愿意回来?是哪个渠道带来的用户质量更高?流失发生在第几天?下面,就让我们从“怎么建立班级档案”开始,一步步进入队列分析的世界。
掌握 Cohort Analysis 是增长工程师和用户运营的基本功——它能让你从“今天来了多少人”的平面视角,升级为“同一群人跟住了多久”的立体视角,用数据驱动留存和增长决策。
可视化演示
动态演示Cohort Analysi的核心机制,通过输入/处理/存储/输出四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
Cohort Analysi:Coho Cohort分析定义与队列划分 留存曲线解读与分析方法 核心机制可视化 Cohort Analysi整体架构与关键组件
队列定义与特征
你是一所“魔法学院”的校长。每年九月一号,都会有一批新生提着行李箱走进校门。你不可能把三年入学的学生搅在一起管,因为你真正想知道的是:这批九月入学的孩子,一年后还有多少人留在学校?于是,你轻轻在他们名单上盖了一个章:“2024 九月班”。这个“九月班”,就是 Cohort——一群在同一时间起点上,共享同一段旅程的用户群体。
在互联网产品里,Cohort 通常指在某个时间窗口内完成同一关键动作(如注册、首次购买)的用户群体。因为他们的起点相同,后续的行为变化就可以被公平地追踪和比较。Cohort 有三大属性:共同的时间锚点(什么时候进来的)、共同的边界条件(通过什么渠道进来的)、以及对未来行为的独立观察(只看这一群人,不看全局混杂数据)。
技术上,一个 Cohort 可以看作是从全量用户集合中过滤出一个子集。被选中的用户必须满足注册时间落在窗口内,这就是最基础的定义式:
回到魔法学院,“2024 九月班”的名单一旦定下就不再改变。你既不会中途把表现好的插班生塞进这个班,也不会因为有人退学就把他的名字从名单上划掉。这正是 Cohort 分析的诚实之处——名单固定,观察才公正。
- 队列符号$C_{[t_0,t_1]}$ 表示在时间窗口 $[t_0, t_1]$ 内形成的队列,$t_0$ 是窗口起点,$t_1$ 是终点。
- 遍历用户空间$u \in U$ 表示遍历产品全量用户集合中的每一个用户。
- 注册时间筛�选$T(u)$ 是用户 $u$ 的注册时间,条件 $t_0 \le T(u) \le t_1$ 把窗口外的用户排除掉。
- 整体含义满足条件的用户全部进入队列,构成一个同期群,之后观察它时名单不再变动。
队列划分维度
同样是“新生班”,你可以按“入学月份”分成九月班、十月班;也可以按“住校/走读”来分,看看哪种学生更能融入学校生活;甚至能按“是否参加过暑期先修营”来分,检验先修营到底有没有用。每一种分法,都在回答一个不同的问题。
Cohort 的划分维度通常有两类。第一类是基于时间的维度:按注册日、注册周、注册月分组,适合观察自然的新增和留存周期;第二类是基于行为的维度:按是否首次购买、是否完成新手引导、是否使用过核心功能分组,适合评估功能上线和运营动作的效果。实践中还可以叠加渠道来源,形成多维度队列。
不管用哪种维度,底层都是一个“分组映射”:把散落的用户,精确地放进各自的抽屉里。用数学的语言说,就是定义一个映射函数 $g$,让每个用户都落到唯一的组:
分班的方式决定了你看到的世界。拿“是否参加先修营”来分班,你能看清产品教育的价值;拿“入学月份”来分班,你能看清季节和节日对招生的影响。选择维度,就是在选择你要回答的问题。
- 分组函数定义$g(u)$ 是作用于每个用户的映射函数,输出是用户所属队列的标签。
- 时间窗口桶$\mathrm{Window}(T(u))$ 把注册时间 $T(u)$ 落入某个时间桶(如第几周、第几月)。
- 行为特征标签$\mathrm{BehaviorKey}(u)$ 根据用户是否完成关键行为(如首购、激活)打上行为标签。
- 组合成组标识两个返回值构成一个二元组,同时按时间和行为切开用户群,得到更精细的队列。
留存曲线解读
开学一个月后,你在每间教室门口蹲点,数一数“九月班”今天来了多少人。第二天、第七天、第三十天……一路记下来,你得到一串数字:100、82、63、42……把这串数字连成线,就是九月班的“坚持上课曲线”。曲线掉得越快,说明你对学生的吸引力流失得越快。
这串“坚持上课曲线”就是留存曲线(Retention Curve)。横轴是相对激活日期的天数,纵轴是留存率——第 N 天还有多大比例的用户在活跃。留存曲线几乎是所有增长团队的第一张图,因为它直接反映产品是否创造了用户愿意反复回来的价值。
留存率的计算很简单,但很容易算错。关键是分子分母的选取:分子是“该 Cohort 中第 N 天仍活跃的用户数”,分母是“该 Cohort 的总人数”,注意是同一群人:
你慢慢学会了看曲线的形状:开头两周陡降是常态,说明绝大多数产品都无法留住全部用户;但如果曲线在某个平台期站稳,比如维持在 30% 以上,说明有一批忠实的学生,哪怕课程再难,也会天天来报到。
- 初始总人数$N_0$ 是队列建立时的全部用户数,即第 0 天的活跃人数。
- 第 d 天活跃数$N_d$ 是该队列中第 $d$ 天(相对注册日)仍活跃的用户数。
- 计算比率$N_d$ 除以 $N_0$ 得到“存活比例”,再乘以 100 转为百分比。
- 曲线解读$R(1)$ 到 $R(7)$ 的斜率越陡,说明用户在前几天流失越严重,要优先排查激活体验。
同期群对比
你翻开三份记录:三月班的曲线、四月班、五月班。四月开始,你给新生都发了“学霸导航手册”;五月又加了“每周导师面对面”。对比三条曲线,你惊喜地发现,五月班第七天留存比三月班整整高了 15 个百分点——手册和导师的组合拳,确实留住了更多孩子。
这就是同期群对比:把不同时间窗口(或不同维度)的 Cohort 留存曲线叠放在一起。由于每个 Cohort 的起点都是各自的“第 0 天”,它们之间的差异不再来自季节或市场大环境,而主要来自产品、内容和渠道的变化。因此,同期群对比是“剥离大环境噪声”最朴素也最有力的武器。
产品改版、活动补贴、渠道投放都可能改变留存。通过新旧 Cohort 的逐天留存差,可以量化这些干预的效果:
从此你不再只看“这个月活跃人数涨了没有”,而是追问“是哪一班的学生更愿意留下”。五月的班比三月班强,不是季节的功劳,而是你扎扎实实的改进被看见、被验证了。
- 新旧队列表示$R_{\mathrm{new}}(d)$ 和 $R_{\mathrm{old}}(d)$ 分别是新批次与旧批次在第 $d$ 天的留存率。
- 逐天作差用新队列的留存率减去旧队列,得到每天的留存差异 $\Delta R(d)$。
- 正负含义$\Delta R(d) > 0$ 表示新队列留存更优,产品改进或新渠道策略有效。
- 稳定性判断若连续多天 $\Delta R(d)$ 都为正,说明改善不是偶发波动,而是结构性提升。
数据可视化
当记录堆满了一整个抽屉,校长你再看曲线就比较吃力了。于是你铺开一张巨大的彩格毯:每一行是一个班级,每一列是开学后的第几天;格子颜色越深,说明当天坚持上课的人占比越高。你一眼扫过去,就能看出每个班在第几天“掉色”,也能看出哪个班整体颜色最深。
这张“彩格毯”就是留存热力图(Retention Heatmap),也是 Cohort 分析最经典的可视化形式。同行是不同 Cohort,同列是相对时间,格子的颜色深浅映射留存率的高低。相比叠加曲线,热力图能同时呈现几十个 Cohort 的全局模式,特别适合发现“结构性”的异常。
把留存率数值映射为颜色,本质上是归一化加映射的过程:
热力图让“看不见的流失”变成了“看得见的色块”。你可能第二天就对团队说:“你看,春季班的第三周整列颜色都变浅了,我们的春季大促结束后,用户明显流失了。” 数据说服力,来自直观的视觉冲击。
- 原始数值$r$ 是某个格子中的留存率,$r_{\min}$ 和 $r_{\max}$ 是整个热力图的最小、最大留存率。
- 归一化映射$\frac{r - r_{\min}}{r_{\max} - r_{\min}}$ 把所有数值压缩到 0 到 1 之间。
- 颜色映射函数$\mathrm{colormap}(\cdot)$ 把 0~1 的归一化值转换为具体颜色(如浅色到深色)。
- 可视化直觉深色代表高留存、浅色代表低留存,某一行突然变浅就是该批次的流失拐点。
业务洞察应用
校长终于不是只看热闹了。你发现九月班第二周流失严重,于是安排了“班主任电话回访”;发现十月班第一天就掉了一大截,于是优化了入学流程。你每做一次调整,就用下一个班来验证效果。Cohort 分析不再只是观察工具,它成了你经营学校的驾驶舱。
在 AI 公司增长团队中,Cohort 分析贯穿用户生命周期的始终:拉新阶段用它评估渠道质量,激活阶段用它验证新手引导,留存阶段用它发现流失拐点,召回阶段用它圈定最值得挽回的人群。它把抽象的“用户体验”翻译成一组可以追踪的存活指标。
当某个策略上线时,我们最关心的是它是否真的提升了留存。最简单也最严格的评估方式,是拿同一维度下、策略前后两组 Cohort 的留存率做差分:
你合上考勤本,心里已经有了下一学年的计划:九月继续用新导航手册,十月把导师面谈提前到第二周,十一月的班会记录留给更长期的同学会。每一笔改进,都写在 Cohort 这本“班级日记”里。
- 改版前基线$R_{\mathrm{before}}(7)$ 是旧 Cohort 注册后第 7 天的留存率,作为对照组基线。
- 改版后结果$R_{\mathrm{after}}(7)$ 是新 Cohort 在第 7 天的留存率,代表策略生效后的表现。
- 差分归因两数相减得到 $\Delta R_{\mathrm{att}}$,即激活或增长策略带来的留存改善幅度。
- 决策依据若 $\Delta R_{\mathrm{att}}$ 显著为正,策略有效;若接近零或为负,需要回滚或迭代。
AI 应用场景
产品改版的归因评估
阶段:增长实验分析
解决的问题:新版用户引导流程上线后,团队直觉上觉得“用户更活跃了”,但看总 DAU 无法区分是拉新的功劳还是留存的提升。传统方式容易把“新用户带来的增量”误当成“留存变好”。用 Cohort 对比改版前后注册的两批用户,可以把“拉新效应”和“留存款”完全分开。
具体案例:某 AI 笔记应用在 5 月更新了手势引导。增长团队以周为单位拆分 Cohort,对比 4 月和 5 月批次注册用户的 D7 留存,发现从 31% 提升到 39%。由此确认引导优化有效,同时把 D7 留存提升纳入产品团队的季度 OKR。
拉新渠道质量对比
阶段:渠道策略
解决的问题:市场部同时投放了抖音达人种草和应用商店搜索,新用户数量差不多,但哪个渠道带来的用户更愿意留下来?只看首日激活量会误导预算分配。按渠道来源划分 Cohort,对比各渠道用户的 D30 留存,就能识别真正的高价值渠道。
具体案例:某 AI 绘画 App 对比两个渠道的 Cohort:搜索渠道 D30 留存 41%,而达人种草渠道只有 22%。团队把预算向搜索品牌词倾斜后,整体三个月留存率提升了 6 个百分点。
召回与流失预警
阶段:用户运营
解决的问题:通过 Cohort 曲线发现某些批次的用户在第 3 周留存骤降,说明产品体验在特定时间点出了问题。传统做法等用户流失后才发优惠券,而 Cohort 分析能提前识别“高危批次”,在流失拐点前进行干预。
具体案例:某 AI 阅读产品发现 6 月班 D14 留存比 5 月班低 12 个百分点,复盘发现是算法推荐改版导致内容流质量下降。团队立即回滚并给受影响用户推送补偿权益,该批次 D21 留存恢复到原来的水平。
Python 演示
# -*- coding: utf-8 -*-"""Cohort Analysis demo: simulate user activation data,build retention matrix by registration date."""import randomfrom collections import defaultdict def generate_act_data(cohort_size=300, days=30): """Generate users with act day and active day list.""" data = {} for uid in range(cohort_size): act_day = random.randint(0, days - 1) active_days = [] p = 0.8 d = act_day while d < days: active_days.append(d) # 用户当天活跃 d += 1 if random.random() >= p: break # 流失, 停止活跃 p *= 0.85 # 留存概率逐日衰减 data[uid] = {"act": act_day, "active_days": active_days} return data def build_retention_matrix(data, days=30): """Group by activation day, compute retention rate per offset day.""" cohorts = defaultdict(lambda: {"n0": 0, "active": defaultdict(int)}) for uid, rec in data.items(): c = rec["act"] cohorts[c]["n0"] += 1 for d in rec["active_days"]: offset = d - c # 相对激活日的天数 if 0 <= offset < days: cohorts[c]["active"][offset] += 1 matrix = [] for c in sorted(cohorts): n0 = cohorts[c]["n0"] row = [0] * days for offset, cnt in cohorts[c]["active"].items(): row[offset] = round(cnt / n0 * 100) # 转为留存率百分比 matrix.append({"cohort_day": c, "retention": row}) return matrix def print_heatmap(matrix, show_days=14): """Print text heatmap, col(day) x row(cohort).""" header = "cohort | " + " ".join("D%2d" % i for i in range(show_days)) print(header) for row in matrix: cells = " ".join("%3d" % v for v in row["retention"][:show_days]) print("%6d | %s" % (row["cohort_day"], cells)) if __name__ == "__main__": random.seed(42) data = generate_act_data(300, 30) matrix = build_retention_matrix(data, 30) print_heatmap(matrix, 14)
p *= 0.85模拟用户“每天想坚持的概率”会逐日打折,越老的用户越容易流失。cohorts[c]["n0"] += 1给某个激活日队列的总人数加一,相当于在学籍簿上盖一个“九月班”的章。offset = d - c把具体日期换算成“加入后的第几天”,这正是 Cohort 分析中相对时间的核心。row[offset] = round(cnt / n0 * 100)用活跃人数除以队列总人数得到留存率,分子分母必须是同一批人。for c in sorted(cohorts)按激活日从早到晚排列队列,让热力图的每一行顺序读起来像日历。
常见误区
误区我把所有新注册用户当成一个整体看留存,反正都是“新用户”,分那么细多麻烦。
正解不同时间注册的用户,所处的产品版本、渠道、市场环境完全不同。把三月和五月注册的用户混在一起,就像把“开学第一天”和“期末最后一天”的学生考勤加总,掩盖了真实的趋势变化。Cohort 的价值恰恰在于“分而治之”。
为何常见:看总体留存最简单,不用建复杂的队列分组,但代价是丢失了变化的时间和原因。
误区留存率从 40% 涨到了 45%,产品肯定变好了,可以庆祝了。
正解没有参照物的留存率没有意义。45% 可能是淡季里所有产品都在下滑,只是你的下滑少一点;也可能是老用户自然流失后的波动。必须与历史同期 Cohort、不同渠道 Cohort 对比,才能判断 45% 到底是好是坏。
为何常见:绝对数字容易理解且便于汇报,但分析需要的是“差值”和“变化方向”,单点值会掩盖结构性问题。
误区D30 留存是硬指标,前面的折损无所谓,只要最后留下来的人多就行。
正解多数产品的流失高度集中在前 7 天。D1 到 D7 的曲线斜率才是激活体验的镜子,如果首日留存只有 50%,D30 再高也高不到哪去。先解决“第一周为什么走人”,再谈长期留存。
为何常见:D30 是管理层爱看的“大数字”,但它来得太晚,等看到结果时问题已发生一个月。
误区每个月 1 号到月底注册的用户就是一个 Cohort,因为报表都是按月出的。
正解Cohort 周期应基于用户的生命周期事件(注册、首购、首次使用核心功能),而不是自然月。以自然月分组会把“月初注册用户”和“月末注册用户”混在一起,他们的成熟度和行为完全不同,比较起来不公正。
为何常见:自然月与财务和汇报周期同步,数据最好取,但分析场景需要的是用户自己的时间轴。
误区昨天新功能上线,今天就有 50 个用户注册,D1 留存只有 30%,功能肯定失败了。
正解小样本的留存率波动极大。50 个人里少来 5 个人,留存率就掉 10 个百分点。正确的做法是等样本量足够(通常至少数百),或使用更长的时间窗口聚合,再对比显著性和置信区间。
为何常见:新功能上线后急于评估、想快速汇报,导致在统计噪声里做决策。
面试题
Q1. Cohort 分析的核心目的是什么?
- A.统计每日活跃人数
- B.追踪同群用户的留存变化← 正确答案
- C.预测流失的具体时间
- D.计算用户的消费金额
答案:B。Cohort 分析的本质是把同一时间窗口内的用户圈成一群,追踪他们随时间的留存变化,就像跟着同班同学看谁坚持到了毕业。A 是整体活跃统计,C 是流失预测模型,D 是用户价值分析,都不是 Cohort 的核心定位。
Q2. 以下哪个最适合作为 Cohort 的分组维度?
- A.用户注册时间← 正确答案
- B.用户昵称首字母
- C.用户设备颜色
- D.用户星座习惯
答案:A。注册时间决定了用户处于产品生命周期的哪个阶段,是最经典的 Cohort 维度。昵称、设备颜色、星座与用户行为没有因果关联,分组后也无法形成可解释的留存差异。
Q3. 按注册时间划分的 Cohort,第 7 天留存率如何计算?
- A.当天活跃总数除以第 7 天新注册数
- B.该队列第 7 天仍活跃人数除以队列总人数← 正确答案
- C.第 7 天新增用户数除以当日总活跃数
- D.队列总人数除以第 7 天活跃人数
答案:B。确切口径是“第 7 天仍活跃的用户数 ÷ 该 Cohort 初始总人数”。分子分母必须是同一批人,就像统计九月班出勤率只能用九月班花名册上的人。A 引入当天新用户,C 引入新增用户,D 把除法倒过来,都违背了“同一群人”的原则。
Q4. 留存曲线衰减越慢说明什么?
- A.用户量越大
- B.产品黏性越强← 正确答案
- C.拉新成本越低
- D.注册时间越集中
答案:B。留存曲线衰减慢,意味着用户在一段时间后仍然频繁回访,说明产品提供了持续的价值,黏性强,好比学生放学后还愿意留在教室自习。用户量、拉新成本、注册集中度都与曲线斜率没有直接关系。
Q5. 同期群对比可以用于哪些场景?
- A.评估改版前后留存变化← 正确答案
- B.对比不同渠道用户质量← 正确答案
- C.判断服务器响应速度
- D.验证优化策略是否有效← 正确答案
答案:ABD。同期群对比的核心是“不同批次间的留存差异”。改版前后对比能归因产品变化,渠道对比能识别优质用户来源,策略验证能衡量优化效果。服务器响应速度属于工程技术指标,不属于 Cohort 分析范畴。
Q6. 关于留存热力图,颜色越深通常表示?
- A.表示留存率越高← 正确答案
- B.表示用户年龄越大
- C.表示注册时间越久
- D.表示活跃天数越少
答案:A。热力图通过颜色深浅编码留存率数值,深色代表该行该列的留存率更高,就像彩格毯上颜色最深的班级坚持上课的人最多。它与用户年龄、注册时间长度无关,只映射当格的留存率。
Q7. 下列哪些属于常见的 Cohort 分析误区?
- A.把所有新用户混成一组← 正确答案
- B.只看绝对留存率不看趋势← 正确答案
- C.样本过小就草率下结论← 正确答案
- D.按用户昵称分组分析
答案:ABC。混组会掩盖批次差异,绝对留存率缺少参照物,小样本结论充满噪声,这些都是真实工作中高频踩坑的误区。按昵称分组几乎不会出现在实际工作中,不属于“常见”误区,选它反而是把不合理做法当成了普遍现象。
Q8. 某 Cohort 的 D1 留存 80%、D7 留存 45%、D30 留存 30%,这说明什么?
- A.流失主要发生在次周之后
- B.流失集中在首日到第七天之间← 正确答案
- C.该队列用户增长非常迅速
- D.产品最近一次更新彻底失败
答案:B。从 D1 的 80% 降到 D7 的 45%,7 天内流失了 35 个百分点,是流失最剧烈的阶段;D7 到 D30 只再降 15 个百分点。所以首周是最大流失窗口,B 正确。A 说反了,C 与留存无关,D 无法从单条曲线推断。
Q9. 一个合理的 Cohort 分析流程包括哪些步骤?
- A.定义队列的分组维度← 正确答案
- B.计算各期限留存率← 正确答案
- C.删除留存差的分组数据
- D.生成可视化并对比解读← 正确答案
答案:ABD。合理的流程是“定义维度 → 计算留存 → 可视化对比 → 输出洞察”四步闭环。C 选项删除留存差的分组数据属于数据造假,会让分析结果失真,在任何规范流程中都不可接受。
Q10. 在移动应用分析中,Cohort 通常按什么时间单位划分?
- A.按小时划分
- B.按天/周/月划分← 正确答案
- C.按毫秒划分
- D.不按时间划分
答案:B。Cohort 的时间粒度取决于产品使用周期:工具类产品按周/月分组,社交或游戏类产品按天分组,电商可按活动周期分组。毫秒粒度没有业务含义,完全不按时间划分则无法形成同期群。