名称: 数据验证 描述: 在与利益相关者分享分析前进行质量保证 — 方法论检查、准确性验证和偏见检测。用于审查分析错误、检查生存偏差、验证聚合逻辑或准备可重复性文档。
数据验证技能
交付前质量保证清单、常见数据分析陷阱、结果合理性检查以及可重复性文档标准。
交付前质量保证清单
在将任何分析分享给利益相关者前,运行此清单。
数据质量检查
- [ ] 源验证: 确认使用了哪些表/数据源。它们是否适用于这个问题?
- [ ] 新鲜度: 数据足够新以进行分析。注明“截至”日期。
- [ ] 完整性: 时间序列中没有意外的间隔或缺失段。
- [ ] 空值处理: 检查关键列的空值率。空值已适当处理(排除、插补或标记)。
- [ ] 去重: 确认没有因错误连接或重复源记录导致的重复计数。
- [ ] 过滤器验证: 所有WHERE子句和过滤器都正确。没有意外的排除。
计算检查
- [ ] 聚合逻辑: GROUP BY包括所有非聚合列。聚合级别与分析粒度匹配。
- [ ] 分母正确性: 比率和百分比计算使用正确的分母。分母非零。
- [ ] 日期对齐: 比较使用相同的时间段长度。部分期间已排除或注明。
- [ ] 连接正确性: JOIN类型适当(INNER vs LEFT)。多对多连接未膨胀计数。
- [ ] 指标定义: 指标与利益相关者的定义匹配。任何偏差均已注明。
- [ ] 小计总和: 部分之和等于整体,如预期。如果不符,解释原因(例如重叠)。
合理性检查
- [ ] 幅度: 数字在合理范围内。收入不为负。百分比在0-100%之间。
- [ ] 趋势连续性: 时间序列中没有无法解释的跳跃或下降。
- [ ] 交叉参考: 关键数字与其他已知来源(仪表板、先前报告、财务数据)匹配。
- [ ] 数量级: 总收入在正确的范围内。用户计数与已知数字匹配。
- [ ] 边缘情况: 在边界上会发生什么?空段、零活动期、新实体。
展示检查
- [ ] 图表准确性: 条形图从零开始。轴已标注。跨面板的刻度一致。
- [ ] 数字格式: 适当的精度。一致的货币/百分比格式。在需要的地方使用千位分隔符。
- [ ] 标题清晰度: 标题说明洞察,而不仅仅是指标。日期范围已指定。
- [ ] 警告透明度: 已知限制和假设已明确说明。
- [ ] 可重复性: 他人可以根据提供的文档重现此分析。
常见数据分析陷阱
连接爆炸
问题: 多对多连接默默增加行数,膨胀计数和总和。
如何检测:
-- 检查连接前后的行数
SELECT COUNT(*) FROM table_a; -- 1,000
SELECT COUNT(*) FROM table_a a JOIN table_b b ON a.id = b.a_id; -- 3,500(哦不)
如何预防:
- 连接后总是检查行数
- 如果计数增加,调查连接关系(它真的是1:1或1:多吗?)
- 当通过连接计数实体时,使用
COUNT(DISTINCT a.id)而不是COUNT(*)
生存偏差
问题: 只分析今天存在的实体,忽略那些被删除、流失或失败的实体。
示例:
- 分析“当前用户”的用户行为,忽略了流失用户
- 查看“使用我们产品的公司”,忽略了那些评估后离开的公司
- 研究“成功”结果的特性,而没有“不成功”的结果
如何预防: 在得出结论前,询问“谁不在此数据集中?”
不完全期间比较
问题: 比较部分期间与完整期间。
示例:
- “一月收入为$500K vs. 十二月的$800K” — 但一月尚未结束
- “本周的注册量下降” — 在周三检查,与完整的前一周比较
如何预防: 总是过滤到完整期间,或比较同月同日/相同天数。
分母偏移
问题: 分母在不同期间发生变化,使比率不可比。
示例:
- 转化率提高是因为改变了如何计数“符合条件”的用户
- 流失率变化是因为“活跃”的定义被更新
如何预防: 在所有比较期间使用一致的定义。注明任何定义变化。
平均值的平均值
问题: 平均预计算的平均值在组大小不同时给出错误结果。
示例:
- 组A: 100用户,平均收入$50
- 组B: 10用户,平均收入$200
- 错误: 平均值平均值 = ($50 + $200) / 2 = $125
- 正确: 加权平均值 = (100*$50 + 10*$200) / 110 = $63.64
如何预防: 总是从原始数据聚合。从不平均预聚合的平均值。
时区不匹配
问题: 不同数据源使用不同时区,导致错位。
示例:
- 事件时间戳用UTC vs. 用户界面日期用本地时间
- 每日汇总使用不同的截止时间
如何预防: 在分析前将所有时间戳标准化为单一时区(推荐UTC)。注明使用的时区。
分段中的选择偏差
问题: 分段由正在测量的结果定义,创造循环逻辑。
示例:
- “完成入职的用户有更高的留存率” — 显然,他们自我选择
- “高级用户产生更多收入” — 他们通过产生收入成为高级用户
如何预防: 基于处理前特性定义分段,而不是结果。
结果合理性检查
幅度检查
对于分析中的任何关键数字,验证它通过“嗅觉测试”:
| 指标类型 | 合理性检查 |
|---|---|
| 用户计数 | 这匹配已知MAU/DAU数字吗? |
| 收入 | 这相对于已知ARR在正确的数量级吗? |
| 转化率 | 这在0%和100%之间吗?匹配仪表板数字吗? |
| 增长率 | 50%+ 月增长现实吗,还是有数据问题? |
| 平均值 | 根据已知分布,平均值合理吗? |
| 百分比 | 分段百分比之和约100%吗? |
交叉验证技术
- 用两种不同方式计算相同指标并验证它们匹配
- 抽查个别记录 — 选取一些特定实体并手动追踪其数据
- 与已知基准比较 — 匹配已发布仪表板、财务报告或先前分析
- 反向工程 — 如果总收入为X,每用户收入乘以用户计数大约等于X吗?
- 边界检查 — 当过滤到单日、单用户或单类别时,会发生什么?这些微结果合理吗?
值得调查的红旗
- 任何指标在没有明显原因的情况下周期变化超过50%
- 计数或总和是精确的整数(暗示过滤器或默认值问题)
- 比率正好为0%或100%(可能表明数据不完整)
- 结果完美确认假设(现实通常更混乱)
- 跨时间段或分段的相同值(暗示查询忽略了维度)
可重复性文档标准
分析文档模板
每个非平凡分析应包括:
## 分析: [标题]
### 问题
[正在回答的具体问题]
### 数据源
- 表: [schema.table_name](截至[日期])
- 表: [schema.other_table](截至[日期])
- 文件: [文件名](来源: [来源])
### 定义
- [指标A]: [确切计算方式]
- [分段X]: [确切确定成员资格的方式]
- [时间段]: [开始日期]至[结束日期],[时区]
### 方法论
1. [分析方法步骤1]
2. [分析方法步骤2]
3. [分析方法步骤3]
### 假设和限制
- [假设1及其合理性]
- [限制1及其对结论的潜在影响]
### 关键发现
1. [发现1及支持证据]
2. [发现2及支持证据]
### SQL查询
[所有使用的查询,带注释]
### 警告
- [在基于此采取行动前,读者应知道的事情]
代码文档
对于可能重用的任何代码(SQL, Python):
"""
分析: 月度群组留存
作者: [姓名]
日期: [日期]
数据源: 事件表, 用户表
最后验证: [日期] — 结果匹配仪表板在2%内
目的:
基于首次活动日期计算月度用户留存群组。
假设:
- “活跃”表示每月至少一个事件
- 排除测试/内部账户(user_type != 'internal')
- 全程使用UTC日期
输出:
群组留存矩阵,行是群组月,列是自注册以来的月数。
值是留存率(0-100%)。
"""
分析版本控制
- 将查询和代码保存在版本控制(git)或共享文档系统中
- 注明使用的数据快照日期
- 如果使用更新数据重新运行分析,记录更改内容和原因
- 链接到定期分析的先前版本以进行趋势比较