3025 字
约 10 分钟
13
S16-A18 · 度量口径之争:同一个数为什么两种说法
2024-12-31
2026-11-09

两个团队报的日活差了三成。一方说 42 万,一方说 31 万,会上从"谁的数据有问题"吵到"谁在美化管理层预期",两小时过去两个数都没变。散会后各自回去查:两边 SQL 都没写错,库里也没丢数,差的只是四个默认值——按登录事件还是任意行为事件去重、自然日还是 UTC 切日、含不含测试账号。

这类争执很有规律:默认假设是"对方算错了",而事实是"对方用了另一套默认值"。把默认值摆上桌,多数争议很快收敛,剩下的才真正涉及结论。


1. 口径分歧的四个层次

一个指标从原始事件走到报出的数字,要过四道闸口。每道闸口都有一组"不写下来就各自填"的默认值。

层次 争论的内容 常见默认值(各团队不同) 差异量级
取数范围 算谁的 全部账号 / 排除测试与内部 / 排除已注销 大,常见两位数百分比差
时间边界 算哪一段 自然日 / 滚动 24 小时 / 事件时间的时区 中,边界附近 1–3%
去重规则 一人算几次 按 user_id / 按设备 ID / 按会话 中大,跨端用户是主要来源
异常剔除 剔除什么 刷单、批量脚本、爬虫、补数、回灌 视业务,恶意流量大时可达数成

前两个层次最容易吵也最容易解决,因为它们能直接写成 SQL 条件;后两个难,涉及"什么算一个人""什么算一次真实行为",而定义问题没有唯一解。经验判据:差异超过 10% 先怀疑取数范围与去重规则,差异在 1–3% 先看时间边界与提交延迟。


2. 分歧不是算错:默认值、伪问题与真问题

把"两边数不一样"等同于"有一边错了",是这类会议最贵的假设。成因大致分布:

成因 频率 表现 处理方式
默认值不同 最常见 差异稳定、可重复、比率接近常数 对齐默认值,不改代码
实现 bug 较少 差异随机跳变、只影响某个维度 查实现,属工程问题
数据缺失/延迟 常见于实时口径 差异随一天中的时刻变化 区分"最终值"与"当前值"
上游数据源不同 常见 差异在特定人群上放大 确认事实源归属

判断顺序固定为:先问默认值,再看时间点,最后查实现。反过来做,两边会各花两天翻 SQL,最后发现谁都没写错。定位可以脚本化:

-- 口径 A:任意行为事件去重(含测试租户)
SELECT COUNT(DISTINCT user_id) FROM dwd_user_event_di
WHERE dt = '2026-03-01';
-- 口径 B:仅登录事件去重(已排除测试租户)
SELECT COUNT(DISTINCT user_id) FROM dwd_login_di
WHERE dt = '2026-03-01' AND tenant_type <> 'internal';
-- 逐层加条件对齐,观察差额在哪一步被吃掉

反向陷阱:差异稳定不等于口径不同。比值长期是 1.30,也可能是某一边采集始终漏掉某个客户端版本——那是稳定的实现缺陷,不是口径选择。

"哪个口径对"是伪问题:同一个指标在回答不同问题时,本来就该有不同的口径。

这个数要回答什么 合理口径 常被混用的口径
服务容量够不够 峰值时段在线会话数 日活(平滑掉了峰值)
产品是否被持续使用 周内多次活跃用户 日活(含一次性回访)
收入对账 财务确认口径的付费用户 埋点口径的支付点击

真问题是"这个数要回答什么,因此必须包含什么、排除什么"。说清楚之后口径是推导出来的,不需要投票。同一个名字被两个问题共用,是口径之争的结构性根源:"活跃用户"在产品、运营、财务、基础设施四个语境下是四个集合,却都写成 dau。


3. 合格口径的四项与变更留痕

口径不是一句话,是一个四元组。缺任何一项,它都会在某个时间点被重新解读。

metric: dau
version: 3
range:                              ─── 取数范围:谁在里面
  entity: 登录态用户
  include: [web, ios, android]
  exclude: [internal_tenant, qa_seed, deleted_account]
  fact_source: dwd_user_event_di    ─── 唯一事实源,禁止多源并行
time:                               ─── 时间边界:算哪一段
  window: natural_day
  timezone: Asia/Shanghai
  event_time: client_ts
dedupe:                             ─── 去重规则:一人算几次
  key: user_id
  cross_device: true
  anonymous: excluded
filter:                             ─── 异常剔除:什么不算
  bot_rule: rules/bot_v7.yaml
  backfill_policy: restate_7d
缺项 会被怎么误读 典型后果
缺范围 有人用全量、有人用清洗后 长期差 5–30% 且无人知道为什么
缺时间 有人按 UTC、有人按本地 跨日指标在月初月末对不上
缺去重 一人多端被算多次 移动端扩张期指标虚高
缺剔除 刷量与爬虫进入统计 指标被污染后无法回溯清洗

口径必然要改:业务变了、采集变了、作弊手段变了。问题在于改完之后历史曲线还能不能连起来。

处理方式 做法 代价 适用
重算历史 用新口径回刷全量 成本高、需要旧数据仍在 变更小、数据保留完整
双轨并行 新旧口径同时产出 N 期 一段时间内两套数并存 变更大、需要可比较
断点标注 曲线上打标,不做重算 历史不再可比 旧数据已不可回刷
硬切不标注 直接换 曲线出现台阶 任何情况下都不推荐

硬切在曲线上留下台阶,三个月后没人记得原因,于是被当成"那次改版提升了 20%"写进复盘。所以变更必须落一条可查记录:

INSERT INTO metric_definition_change
  (metric, version, effective_date, change_type, reason, owner, restated)
VALUES
  ('dau', 3, '2026-03-01', 'dedupe_key',
   'user_id 打通多端,改用账号去重', 'data-platform', false);
-- 回看某区间实际生效的版本,用于解释曲线台阶
SELECT date, version FROM metric_definition_version_range
WHERE metric = 'dau' AND date BETWEEN '2026-01-01' AND '2026-06-30';

4. 收口、裁定与字典的失效

同一指标在多系统各有一套实现,是口径分歧的第二种形态:不在会上出现,而在看板里并排显示。收口顺序:定义唯一 → 实现唯一 → 展示可复用,分别靠口径字典、事实表层、指标服务,而不是每个看板自己写 SQL。

收口方式 强度 成本 失效方式
口径字典(文档) 弱 低 无人读、无人改、与实现脱节
统一事实表层 中强 中 表结构僵化,新问题绕开它
指标服务/语义层 强 高 成为瓶颈,例外需求外溢
财务口径裁定 最强 低 只覆盖进入钱的那部分指标

"以财务口径为准"有效,是因为它依赖后果的唯一性而非技术权威——对账不平要有人担责。裁定有效的前提是存在承担后果的角色;研发内部指标没有这种角色,照搬只会把争执换个人。

口径字典的成本随条目数非线性上升,主要不是要写,而是读的人必须在决策前想起来读。它最常见的失效不是无人维护,而是字典定义与看板实现长期不一致且无人察觉——直到争议再次爆发。低成本做法是让字典从代码生成:

$ make metric-dict
  metric-defs/*.yaml → site/docs/metrics/*.md
  check: 每条必须有 owner / fact_source / dedupe.key
$ grep -L 'fact_source' metric-defs/*.yaml    ─── 缺项直接失败

争议解决后留一份可引用的裁定记录,否则半年后同样的问题会再吵一次:

dispute: dau_definition
date: 2026-03-08
participants: [data-platform, growth, finance]
question: 日活按登录事件还是任意行为事件
decision: 采用任意行为事件去重口径,v3 生效
scope: 内部看板与增长分析;对外披露仍用财务口径
cost: 历史曲线在 2026-03-01 出现断点,不回刷
owner: data-platform

5. 排错:五种口径争议的现场

现象 最可能的层次 第一步动作
两个数长期差固定比例 取数范围 拉出两边的排除条件逐条比对
差异随时间波动、月初最大 时间边界 确认时区与提交延迟,对齐"最终值"
差异只在移动端出现 去重规则 检查是否按设备 ID 去重
指标在促销期间异常高 异常剔除 检查刷单与批量脚本规则是否生效
曲线在某日出现台阶 口径变更 查断点表,确认是否硬切未标注

排错最该避免"先改个条件跑一遍看能否对上"。这种试错产出第三个数,把争议从两方变三方。


6. 边界与度量

口径管理本身也要被度量,否则它会膨胀成一份没人用的文档集。

度量 含义 观测方式
口径条目数 字典规模 与看板指标数比,比值过高说明过度细化
断点次数 一段时间内的口径变更次数 半年超过若干次说明上游不稳
口径争议数 单位时间内发生的对比争执 会议记录/工单计数
跨系统不一致率 同名指标在不同系统不同值的比例 定期抽样比对
边界场景 结论
一次性分析 口径写进分析脚本注释即可,不必入字典
单人使用的临时指标 不需要正式口径,但不要对外引用
指标不进入任何决策 口径管理的收益接近零
指标进入对外披露或结算 口径管理是必需项,且必须有人担责

判定线:当一个数会被比较、被跨团队引用或带来后果时,口径管理才值得投入。其余情况把时间花在把分析做对更划算。


自测

  1. 两个团队报的同一指标差三成,你按什么顺序排查四个层次,为什么这个顺序能省时间?
  2. "哪个口径对"为什么是伪问题?换成什么问题之后争议才会真正收敛?
  3. 一个口径缺少"异常剔除"这一项,会在什么业务阶段先出问题?
  4. 口径硬切不标注,三个月后最可能被误读成什么?
  5. "以财务口径为准"为什么有效?这种裁定在研发内部指标上为什么常常失效?
  6. 口径字典最常见的失效方式是什么?用代码生成能解决其中哪一部分?
S16-A18 · 度量口径之争:同一个数为什么两种说法
https://www.clxhxhhr.top/posts/6324/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。