理想世界里,每次产品变更都该跑一次随机对照实验。现实更乱。有时候你不能随机 — 功能已经全量上线,法律约束不让留 holdout,或者样本太小没有统计功效。
碰到这些场景,我用准实验方法。下面是我的 playbook。
观测数据的问题
根本难题是混杂(confounding)。采用新功能的用户和不采用的本就不同。可能更活跃、更懂技术、或者是在某次营销活动里涌入的。简单对比”用 vs. 不用”,对于功能真实影响而言什么都说明不了。
我见过团队反复犯这个错 — 欢呼一个”功能成功”,其实只是选择偏差。
方法一:双重差分(DiD)
当一个功能在不同时间铺到不同群体(比如按地区或平台),DiD 能很好用。关键假设是平行趋势 — 处理组和对照组在无干预的情况下会一起动。
永远去画那些 pre-trend。如果不平行,DiD 会给你误导性结论 — 正如上面的滑块所示,即使小幅违反也会让朴素对比产生有意义的偏差。
# 简化的 DiD 估计
import statsmodels.formula.api as smf
model = smf.ols("outcome ~ treated * post + C(group) + C(time)", data=df)
results = model.fit()
# treated:post 的系数即为处理效应
方法二:合成控制
当你只有一个处理单位,但有很多潜在的对照,合成控制用对照的加权组合造一个”合成”的处理对象。我在地理实验里大量用这个 — 它比简单对比更能处理真实市场的脏乱。
方法三:断点回归(RD)
如果处理是按某个阈值分配的(例如 engagement score 高于 X 的用户才拿到功能),RD 利用阈值处的不连续。阈值上下的用户几乎相同,形成局部随机化。
这个方法我觉得被低估了。很多产品功能都有天然的阈值,却没人想到去挖。
什么时候用哪个
| 方法 | 最适合 | 关键假设 |
|---|---|---|
| DiD | 分时段上线 | 平行趋势 |
| 合成控制 | 单一处理单位 | 干预前拟合 |
| RD | 阈值分配 | 阈值处连续性 |
你的场景适合哪个?
回答下面几个问题,我给你指一个方向。
Which causal method fits your situation?
Answer a few questions — I'll recommend one from my working playbook.
结语
没有哪个方法完美。最好的做法是组合多种方法,看它们是否讲出一致的故事。当它们背离,往往就是最有意思的学习点 — 通常说明你对底层动态的理解缺了一块。