9.4 安慰剂检验(Placebo Tests)
验证 DID 稳健性的关键方法
本节目标
- 了解安慰剂检验的思想与作用
- 掌握常见的安慰剂方案及适用场景
- 能够用 Python 实现常用安慰剂检验
一、为什么需要安慰剂检验
在 DID 框架下,核心识别假设是“平行趋势”。即便我们做了前趋势检验,也仍需通过“安慰剂检验”进一步验证:如果政策是“假的”(不在真实时间/不在真实组上/换个无关结果变量),那么估计出来的“政策效应”应当接近 0、且不显著。否则说明模型可能把别的因素误当成了政策效应。
常见动机:
- 排除巧合(时点上刚好发生别的事)
- 排除选择性(处理组与对照组差异导致的伪效应)
- 排除模型设定问题(不恰当控制、聚类方式、趋势设定等)
二、常见安慰剂检验方法(推荐优先级)
假政策时间(Placebo Time)
- 做法:把“政策实施时间”往前/往后平移若干期,再估计 DID。
- 期望:系数应接近 0(不显著)。
- 适用:时间维度较长,且没有密集干预的情形。
假对照组(Placebo Group)
- 做法:把未受影响、且与处理组相似的一些单位,随机当作“处理组”。
- 期望:DID 系数分布以 0 为中心。
- 适用:横截面样本较多时。
Leave-one-out 稳健性(排除单个处理单位/地区)
- 做法:每次剔除一个处理单位,重复估计。
- 期望:结果不被单一单位驱动。
随机化推断(Randomization Inference, 置换检验)
- 做法:保持时间结构,随机打散处理分配,重复 B 次,形成“虚拟效应”分布。
- 期望:真实效应位于置换分布的尾部(得到近似 p 值)。
安慰剂结果变量(Placebo Outcome)
- 做法:选择一个“理论上不受政策影响”的结果变量运行 DID。
- 期望:估计系数≈0。
三、Python 简易实现模板
为了便于快速上手,以下给出可复制的“安慰剂检验”最小化代码模板(与 9.3 的风格一致,UTF-8 编码)。
python
import numpy as np
import pandas as pd
import statsmodels.formula.api as smf
# df: 包含列 y, treated(0/1), time(整数), post(0/1), id
def did_once(df):
"""标准 DID 回归(实体/时间固定效应的最简形式,可按需扩展)"""
model = smf.ols('y ~ treated*post + C(id) + C(time)', data=df).fit(cov_type='cluster', cov_kwds={'groups': df['id']})
return model.params.get('treated:post', np.nan)
def placebo_time(df, shift=2):
"""把政策时点平移 shift 期,重新构造 post 并估计 DID"""
df2 = df.copy()
true_cut = df2.loc[df2['post']==1, 'time'].min() # 真实时点
fake_cut = true_cut + shift
df2['post'] = (df2['time'] >= fake_cut).astype(int)
return did_once(df2)
def placebo_group(df, n_draw=200, seed=42):
"""随机把同规模的对照单位当成“处理组”,重复 n_draw 次,返回伪效应分布"""
rng = np.random.default_rng(seed)
ids = df['id'].unique()
treated_ids = df[df['treated']==1]['id'].unique()
k = len(treated_ids)
fake_ate = []
for _ in range(n_draw):
fake_treated = set(rng.choice(ids, size=k, replace=False))
df2 = df.copy()
df2['treated'] = df2['id'].isin(fake_treated).astype(int)
fake_ate.append(did_once(df2))
return pd.Series(fake_ate, name='placebo_group_ate')使用建议:先跑一次真实 DID,记录 ATE;再运行 placebo_time / placebo_group,绘制分布并标出真实 ATE 所在位置。
四、结果解读与注意事项
- Placebo Time:在一系列“假时点”附近,系数应围绕 0 波动;若显著,警惕时序性混淆。
- Placebo Group:伪效应分布应以 0 为中心,真实 ATE 应落在分布尾部。
- Leave-one-out:若剔除任一单位结果都稳定,说明不是由“某个特殊单位”驱动。
- 置换检验:可报告置换 p 值作为稳健性证据。
- 安慰剂结果:明确解释为何该结果“不应受政策影响”。
技术细节:
- 聚类标准误:面板数据常对实体聚类(或双向聚类)。
- 多期/错位处理:建议采用事件研究(见 9.3)或近年的多期 DID 估计器。
本节小结
- 安慰剂检验是对 DID 识别假设的“反事实压力测试”。
- 常用方法:假时点、假对照组、Leave-one-out、置换检验、安慰剂结果。
- 重点是“接近 0、且不显著”的基准期待;一旦显著,要回到识别与设定层面查因。
- 报告时建议配合:图(分布/事件研究)、表(ATE 与 p 值)与文字解释。
上一节: 9.3 平行趋势假设 | 下一节: 9.5 经典案例和 Python 实现