Lantide Data
返回博客
数据分析实践

转化率为什么每个人算得不一样?先对齐分母、事件与时间窗

漏斗转化率没有唯一公式;使用者或事件粒度、cohort 或日历时间窗、事件顺序与取消规则不同,答案就会不同。本文附可复用 Plan 模板与最大流失检查方式。

转化率不同,常不是谁算错,而是分母、事件粒度、时间窗与事件顺序不同。同一句「六月付款转化率」,可能是在算六月建单 cohort 最终付款,或六月内所有建单与付款事件的比值。先把 unit、stage、window、order 与取消/退款规则写成契约,再比较数字。

一个公式,至少藏了五个决策

最简单的转化率是:

conversion rate = 完成目标的人数(或事件数) ÷ 进入起点的人数(或事件数)

问题都在括号里。以「建单 → 付款」为例,先回答:

  1. Unit:一位 user、一张 order,还是一次 event?
  2. Stage:建单与付款分别由哪个栏位/事件定义?
  3. Window:固定日历区间,还是每个起点后 N 天?
  4. Order:付款一定要发生在建单之后吗?重复事件取第一次还是任一次?
  5. Eligibility:测试帐号、取消、退款、重建单如何处理?

只要任一项不同,两个「转化率」都可能各自正确,却不能直接对比。

User-based 与 event-based:先确定分母单位

假设同一位使用者六月建立三张订单,其中一张付款:

  • User-based:只要这位使用者至少付款一次,就是 1 位转化 user;分母也是 unique users。
  • Order-based:1 张付款订单 ÷ 3 张建立订单 = 33.3%。
  • Event-based:若付款重试产生两笔成功事件,直接拿 events 相除甚至可能得到 2 ÷ 3。

User-based 适合回答「有多少人完成旅程」;order-based 适合回答「有多少订单成交」;event-based 常用于事件管线健康或操作次数,但必须处理 retry/duplicate。不要在同一公式中用 unique users 当分子、orders 当分母。

最低限度要同时输出 numerator、denominator 与 rate:

付费使用者 420 / 建单使用者 1,000 = 42.0%

单独写「转化率 42%」无法验证分母是否缩水。

Cohort window 与 calendar window 回答不同问题

假设使用者 6 月 30 日建单、7 月 1 日付款:

Calendar window(日历窗)

分母是 6 月内建单,分子也是 6 月内付款。跨月付款不算。它适合描述「六月发生了多少事件」,但月末进站者天生只有很短的转化时间。

Cohort window(cohort 窗)

先选 6 月内建单的 cohort,再观察每位/每单在建单后 7 天是否付款。6 月 30 日建单、7 月 1 日付款会计入。它较适合比较不同起点 cohort 的转化品质,但要等完整观察窗结束;截至 7 月 3 日,6 月 30 日 cohort 尚未成熟。

两者没有谁永远正确。营运日报可能需要 calendar view,产品流程优化常需要 cohort view。名称要直接揭露口径,例如「6 月建单 cohort 的 7 日付款率」,不要都叫「六月转化率」。

事件顺序与 stage 去重,决定漏斗是否成立

事件资料可能乱序、重送或补登。标准有序漏斗通常要求:

first_order_created_at <= first_payment_at
first_payment_at <= first_fulfilled_at

但「first」也需定义:每位使用者第一笔?每张订单第一笔成功?如果使用者取消后重建,是否视为同一旅程?若 payment webhook 重送,应用 payment_id 或业务 key 去重,而不是把 event count 当人数。

建议为每个 stage 建一张诊断表:

Stage Unit key Event/栏位 去重规则 时间栏位
建单 order_id order_created 每单第一笔 created_at
付款 order_id payment_succeeded 每单第一笔成功 paid_at
完成 order_id fulfilled 最早完成 fulfilled_at

这张表能及早暴露「付款表是一对多」或「status 是当前快照、不是事件历史」等差异。

取消、退款与跨日转化怎么处理?

取消

取消前已付款的订单,若问题是「付款流程是否成功」,可以算转化;若问题是「最终成交」,可能排除。不要在没有决策问题时直接选一个。

退款

付款率通常以付款成功事件为分子;net conversion 或 retained revenue 才可能排除退款。可同时报 gross payment rate 与 post-refund rate,避免一个数字承担两种意义。

跨日与时区

事件以 UTC 储存、报表用 Asia/Taipei 截日,应先转时区再决定日期。以半开区间 [start, end) 避免漏掉月底最后一秒后的小数时间;但 cohort 的 observation window 应从每个起点事件计算,而非再套同一个日历月底。

可直接复用的漏斗 Plan 模板

## Decision question
- 我们要用这个漏斗决定什么?比较哪两个期间或族群?

## Population and unit
- Population:纳入哪些帐号/订单?排除测试、内部或机器流量吗?
- Unit key:user_id / order_id / session_id
- Grain:中间表与最终表各一列代表什么?

## Stages
- S1 名称、事件/栏位、时间栏位、去重规则
- S2 名称、事件/栏位、时间栏位、去重规则
- 是否强制顺序?允许跳 stage 吗?

## Time policy
- Cohort 起点:[start, end)
- Observation window:起点后 N 天
- Report timezone:Asia/Taipei
- 未成熟 cohort 如何排除或标示?

## Eligibility and reversal
- 取消、退款、重建、重试、NULL key 的处理

## Outputs
- 每 stage count、step conversion、overall conversion
- numerator / denominator 同时呈现
- 依必要维度分群,不事后任意切割

## Checkpoints
- 每 stage distinct unit 与 row count
- 顺序违反、重复事件、NULL key、未成熟 cohort 数
- 找出最大绝对流失与最大相对流失 stage

## Limitations
- 事件缺漏、追踪变更、无法推论因果之处

最大流失不要只看百分比

对每一段同时报:

absolute drop = stage_n count - stage_n+1 count
step conversion = stage_n+1 count / stage_n count

最大绝对流失指出「少了最多人」;最低 step conversion 指出「比例最弱」。两者可能不是同一段。还要检查 stage count 是否不合理地增加;若漏斗要求严格顺序,增加通常代表去重、JOIN 或 unit 不一致。

Lantide Data 如何让口径在 Execute 前被看见

在 Lantide Data 的 Project Analysis 中,Agent 可先探索 schema 与事件分布,再把 unit、stage、denominator、时间窗与 checkpoints 写进 Plan。PM 或业务 owner 可直接对 Plan 批注,不必先会改 SQL;口径确认后由使用者按 Approve & Execute,Agent 再建立正式 SQL evidence 与 Report。实务流程见 Plan → Execute → Report

SQL-first 的好处是分母与事件顺序不只存在摘要:grain、JOIN、filter 与 aggregation 可在持久 SQL 分页审阅,Report 应同时保留 counts、rates 与 limitations。这个工作流能让争议提早出现,但不会替团队决定「退款算不算」或修复缺漏事件;最终口径仍由对决策负责的人确认。更多做法见 SQL-first 工作流

结语:先替指标取一个不能误解的名字

下次有人问转化率,先不要回单一百分比。用一句完整名称回答:「6 月建单 order cohort、7 日内首笔成功付款、排除测试单但不排除后续退款的转化率」。如果团队无法同意这句话,就代表还没到 Execute 的时候。

参考资料