跳到主要内容

双重差分法及平行趋势检验

一、直观理解:处理组的变化,减去对照组同期的变化​

双重差分(Difference-in-Differences, DID)利用时间与处理状态两个维度:

  • 处理组:政策实施前、后;
  • 对照组:同一时期前、后。

第一重差分:处理组后−前,去掉个体固定水平;
第二重差分:再减去对照组的后−前,去掉共同时间趋势。

DID=(Yˉ1,post−Yˉ1,pre)−(Yˉ0,post−Yˉ0,pre)\mathrm{DID}=\big(\bar Y_{1,post}-\bar Y_{1,pre}\big)-\big(\bar Y_{0,post}-\bar Y_{0,pre}\big)

若无政策时两组本会平行演变(平行趋势),则 DID 识别处理组平均处理效应 ATT。

经典 2×2 表:

前后
处理组AABB
对照组CCDD

DID=(B−A)−(D−C)\mathrm{DID}=(B-A)-(D-C)。

二、适用场景与优缺点​

类型说明
适用场景政策/冲击有明确时点;存在未受处理的对照;可获得前后面板或重复截面;需要应对不随时间混杂。
核心优点直觉强;能控制个体固定差异与共同冲击;事件研究可检验动态与前置趋势;应用极广。
局限与缺点平行趋势不可直接验证(仅可部分检验);处理时点交错时双向 FE 可能有偏;溢出使对照被污染;构成变化(重复截面)需小心。

三、核心原理与识别​

1. 回归写法(2×2)​

Yit=α+γTreati+λPostt+δ(Treati×Postt)+εitY_{it}=\alpha+\gamma\mathrm{Treat}_i+\lambda\mathrm{Post}_t+\delta(\mathrm{Treat}_i\times\mathrm{Post}_t)+\varepsilon_{it}

δ\delta 即 DID 估计量。面板中等价常用:

Yit=ai+λt+δDit+xitTβ+εitY_{it}=a_i+\lambda_t+\delta D_{it}+x_{it}^\mathsf{T}\beta+\varepsilon_{it}

其中 DitD_{it} 为处理状态(个体×时间)。

2. 平行趋势(PT)​

无处理时,E[Yt(0)∣Treat=1]E[Y_t(0)\mid \mathrm{Treat}=1] 与对照组应平行。
事件研究:

Yit=ai+λt+∑k≠−1δk1{Kit=k}+εitY_{it}=a_i+\lambda_t+\sum_{k\neq -1}\delta_k \mathbf{1}\{K_{it}=k\}+\varepsilon_{it}

KitK_{it} 为相对处理时点。看 k<0k<0 的 δk\delta_k 是否接近 0(前置趋势)。不显著不等于证明 PT,但是必要的支持证据。

3. 交错 DID 警告​

多期、多组在不同时间处理时,TWFE 的 δ\delta 可能是异质性效应的负权重平均。应考虑 Callaway–Sant’Anna、Sun–Abraham、插补估计量等。建模赛至少应:事件研究 + 分组时效性稳健。

四、关键决策​

1. 对照是否干净​

有无溢出、预期效应、政策前抢跑。

2. 固定效应与控制变量​

个体与时间 FE 是基线;控制变量应是时变且非中介。

3. 聚类 SE​

通常在处理分配层级聚类(如地区)。

4. 安慰剂​

假政策时点、从未处理样本、替代结果。

五、MATLAB 示例​

rng(24);
% 平衡面板:40 个个体 × 10 期;后 20 个为处理组,第 6 期起处理
N = 40; T = 10;
id = repelem((1:N)', T);
t = repmat((1:T)', N, 1);
treat = id > 20;
post = t >= 6;
D = treat & post;

a = repelem(randn(N,1), T);
lam = repmat(0.3*((1:T)'-1), N, 1); % 共同趋势
% 平行趋势 + ATT=2
Y = 1 + a + lam + 2*D + 0.7*randn(N*T,1);

% DID 回归:Treat, Post, Treat*Post
Tr = double(treat); Po = double(post); TP = double(D);
mdl = fitlm([Tr Po TP], Y);
fprintf("DID delta = %.3f\n", mdl.Coefficients.Estimate(4));

% 双向 FE:y ~ D + id FE + time FE
tbl = table(categorical(id), categorical(t), double(D), Y, ...
'VariableNames', {'id','time','D','Y'});
mdl_fe = fitlm(tbl, "Y ~ D + id + time");
fprintf("TWFE delta = %.3f\n", mdl_fe.Coefficients.Estimate("D"));

% 事件研究:相对时点 k=t-6,基期 k=-1
k = t - 6;
levels = setdiff(unique(k)', -1);
Xev = zeros(N*T, numel(levels));
for j = 1:numel(levels)
Xev(:,j) = treat & (k == levels(j));
end
% 去个体与时间均值后回归(简单 within)
Yw = Y; Xw = Xev;
for i = 1:N
idx = id==i;
Yw(idx) = Y(idx) - mean(Y(idx));
Xw(idx,:) = Xev(idx,:) - mean(Xev(idx,:),1);
end
for tt = 1:T
idx = t==tt;
Yw(idx) = Yw(idx) - mean(Yw(idx));
Xw(idx,:) = Xw(idx,:) - mean(Xw(idx,:),1);
end
b_ev = Xw\Yw;
figure;
stem(levels, b_ev, "filled"); yline(0); xline(-0.5, "--");
xlabel("相对处理时点 k"); ylabel("\delta_k"); title("事件研究(示意)"); grid on;

% 平行趋势粗检:政策前处理组与对照组均值路径
figure; hold on;
for g = 0:1
mu = zeros(T,1);
for tt = 1:T
mu(tt) = mean(Y(t==tt & treat==g));
end
plot(1:T, mu, "-o", "LineWidth", 1.5);
end
xline(5.5, "--"); legend("对照","处理"); xlabel("t"); ylabel("Y");
title("组均值路径"); grid on;

六、如何解释结果​

  1. 制度背景:谁在何时被处理;
  2. 估计方程与 FE 结构;
  3. δ^\hat\delta、聚类 SE、ATT 含义;
  4. 事件研究图与政策前系数;
  5. 安慰剂与稳健性;
  6. 是否存在交错处理及应对;
  7. 外推范围。

七、常见误区​

1. 把“政策前不显著”写成“已证明平行趋势”​

只能说“未发现明显前置差异”。

2. 对照也被间接影响​

溢出低估/高估效应。

3. 用后置结果当控制变量​

坏控制。

4. 交错 DID 仍只报一个 TWFE 系数且不做事件研究​

可能严重误导。

5. SE 不聚类​

过度显著。

八、小结​

DID 的核心是:

在平行趋势下,用处理组的前后变化减去对照组的前后变化,识别处理效应。

它是政策评估最重要的工具之一。平行趋势的事件研究、干净对照、聚类推断与交错处理稳健性,决定了 DID 结论能否从“回归星号”升级为可信因果证据。