Модуль 2. Difference-in-Differences (DiD)

TL;DR

Сравниваем изменение outcome в treatment-группе с изменением в контрольной. Работает, если без treatment группы двигались бы параллельно. Оценивает ATT.

Фундаментальная интуиция

Главная проблема любой оценки эффекта — мы не знаем, что произошло бы с treated-группой, если бы она не получила treatment. DiD решает это за счёт контрольной группы: предполагается, что без treatment treated развивался бы так же, как control. Тогда фактическое отклонение treated от этой траектории — и есть эффект.

Отсюда название: difference-in-differences — берём разность «до/после» для treated, затем вычитаем разность «до/после» для control. Разность контрольной группы убирает все внешние шоки, не связанные с treatment: если рынок в целом рос или падал, это движение отразится в обеих группах и сократится при вычитании.

DiD оценивает ATT — Average Treatment Effect on the Treated: средний каузальный эффект именно для тех, кто получил treatment. Это не средний эффект по всей популяции. Если treated и control — принципиально разные юниты, экстраполировать ATT на всю популяцию нельзя.

Ключевое ограничение: допущение о параллельных трендах (parallel trends) невозможно доказать — его можно только не опровергнуть по pre-period данным. Если в pre-period тренды были параллельны, это аргумент в пользу допущения, но не его доказательство.

Когда применять

DiD подходит, когда есть натуральный эксперимент: изменение политики, запуск продукта или внешний шок, затронувший одни юниты, но не другие. Необходимы данные до и после события.

Что мы оцениваем

ATT (Average Treatment Effect on the Treated) — средний каузальный эффект для тех, кто получил treatment. Формально: δ = E[Y(1) − Y(0) | D=1], где Y(1) — outcome при treatment, Y(0) — контрфактический outcome без treatment. Y(0) для treated-группы ненаблюдаем — его заменяет траектория контрольной группы.

DiD не оценивает ATE (средний эффект по всей популяции). Если treated и control — разные типы юнитов (крупные города vs малые, premium-сегмент vs mass-market), ATT нельзя распространить на всю популяцию.

Что нужно для идентификации

Пять допущений. Первые два критичны и нарушаются чаще всего:

  1. Parallel trends: без treatment обе группы двигались бы одинаково. Это не доказуемо — только не отвергаемо по pre-period данным. Всё остальное — теоретический аргумент.
  2. No anticipation: treated-группа не меняет поведение до формальной даты treatment. Нарушается, если объявление за N дней до вступления в силу уже запускает реакцию.
  3. No spillover: treatment не влияет на control. В платформах часто нарушается: изменение комиссии в одной категории перетягивает продавцов из другой.
  4. Stable composition: состав групп не меняется из-за treatment. Если treatment заставляет слабых игроков уйти — оставшиеся treated сильнее среднего.
  5. Common shocks: внешние события затрагивают обе группы одинаково. Иначе DiD впишет шок в «эффект treatment».

Как проверить

ПроверкаЧто смотримКрасный флагЧто делать
Pre-trendsEvent study: коэффициенты для k < 0Значимые коэффициенты до treatmentMatching+DiD, SCM, или отказ
AnticipationКоэфф. за 1–2 периода до treatmentРеакция до treatment dateСдвинуть treatment date назад
Placebo outcomeOutcome, не связанный с treatmentЗначимый эффект на placeboПересмотреть дизайн
Placebo treatment dateФиктивная дата в pre-periodЗначимый «эффект»Trends нестабильны → DiD невалиден
SE clusteringУровень кластеризации ≥ уровня treatmentНекластеризованные SE при групповом treatmentКластеризовать; при малом N кластеров — wild bootstrap

Минимальный расчёт

Y_it = α + β₁·Treat_i + β₂·Post_t + δ·(Treat_i × Post_t) + ε_it

δ = (Ȳ_treat_post − Ȳ_treat_pre) − (Ȳ_control_post − Ȳ_control_pre)

Типичные ошибки

  1. Параллельные тренды выглядят хорошо визуально, но нарушаются после treatment по другой причине (confounding shock). Один график — недостаточно.
  2. Anticipation: объявление за N дней до вступления в силу — группа реагирует заранее. Реальная дата treatment раньше формальной.
  3. Compositional change: treatment заставляет часть юнитов «уйти» из группы. Оставшиеся treated — не случайная выборка.
  4. SE без кластеризации → ложная значимость (Bertrand, Duflo, Mullainathan 2004). Групповой treatment всегда требует кластеризации на уровне группы.
  5. Мало кластеров (N < 20) → стандартная кластеризация невалидна, нужен wild cluster bootstrap или randomization inference.
  6. Staggered adoption → TWFE смещён при гетерогенном эффекте (см. раздел ниже).
  7. Нелинейный тренд → визуальная «параллельность» обманчива. Параллельность в pre-period не гарантирует её после treatment.

Что делать дальше

Event Study — полноценный разбор

Event study — регрессия с отдельными коэффициентами δ_k для каждого периода k относительно treatment (k = −4, −3, …, −1, 0, +1, +2, …). Период k = −1 обычно опорный (δ_{−1} = 0).

Y_it = α + Σ_k δ_k · 1{t − t* = k} · Treat_i + γ_t + μ_i + ε_it

Ожидание:
  k < 0: δ_k ≈ 0 (parallel trends подтверждены)
  k ≥ 0: δ_k ≠ 0 (эффект treatment)

ASCII-визуализация (идеальный случай):
  δ_k
   |
 + |                          * * *
   |                        *
   |                      *
 0 |----*---*---*---*---|------------------
   |                    |
 - |                    |
   +----+---+---+---+--+--+---+---+---→ k
       -4  -3  -2  -1  0  +1  +2  +3

Красные флаги event study

ФлагЧто означаетДействие
Pre-trend: δ_{−3}, δ_{−2} значимыParallel trends нарушеныDiD невалиден без коррекции
Монотонный pre-trend (рост/падение)Группы расходились и до treatmentДобавить group-specific trends или отказаться
Эффект в k=0, но не в k≥1Возможно transient shock, не treatmentПроверить устойчивость по длине post-period

При нарушении pre-trends

Staggered DiD — предупреждение

Toy example: DiD вручную

Маркетплейс снижает комиссию для категории «Одежда» с 1 апреля (treated). Категория «Электроника» — контроль. Outcome: средний дневной GMV категории (тыс. руб.).

КатегорияГруппаPre (янв–март, avg)Post (апр–июнь, avg)
ОдеждаTreated10090
ЭлектроникаControl130105
# Step 1: Изменения внутри каждой группы
ΔY_treated = 90 − 100 = −10   (GMV упал)
ΔY_control = 105 − 130 = −25  (GMV упал сильнее)

# Step 2: DiD-оценка
τ̂ = ΔY_treated − ΔY_control = −10 − (−25) = +15

# Step 3: Проверки
# → Pre-trends: были ли тренды параллельны в янв–марте?
# → Spillover: не перетянула ли Одежда продавцов из Электроники?
# → SE: кластеризовать на уровне категории

Интерпретация: общий рыночный спад затронул обе категории. Без снижения комиссии Одежда тоже упала бы на 25 тыс. Снижение комиссии смягчило падение: τ̂ = +15 тыс. — оценённый эффект изменения политики (при выполнении parallel trends).

Упражнения

Задача 1: parallel trends

Финтех-компания запускает кешбэк-программу для premium-сегмента (лимит > 100К руб.) с 1 марта. Контроль — middle-сегмент (лимит 50–100К). Outcome: число транзакций в месяц. Аналитик строит event study и видит значимый pre-trend: δ_{−3} = +8%, δ_{−2} = +6%. Валиден ли DiD?

Решение

DiD невалиден без коррекции. Значимые коэффициенты δ_{−3} и δ_{−2} говорят, что premium-сегмент рос быстрее middle ещё до запуска программы. Их месячный оборот менялся в pre-period не так, как у middle-сегмента. Parallel trends нарушены: оценка DiD впишет часть существующего тренда в «эффект кешбэка». Возможные действия: (1) matching+DiD — подобрать контроль из middle, похожий на premium по pre-period динамике; (2) SCM — построить синтетический premium из доноров; (3) честно признать, что DiD здесь неприменим без дополнительных допущений.

Задача 2: anticipation

Маркетплейс объявил об изменении алгоритма ранжирования 15 февраля; изменение вступило в силу 1 марта. Event study показывает δ_{−2} = +5% (p < 0.05) — значимый рост в феврале. Что это означает и что делать?

Решение

Это anticipation effect: продавцы отреагировали на объявление ещё до технического вступления в силу (оптимизировали листинги, подняли ставки). Формальная treatment date (1 марта) не совпадает с реальной датой изменения поведения. Решение: сдвинуть treatment date на 15 февраля (дату объявления). После сдвига проверить, исчезли ли значимые pre-trend коэффициенты.

Задача 3: SE clustering

Geo-launch: 3 региона получили treatment (новая логистика), 9 регионов — контроль. DiD: δ = +8%, SE = 2%, p = 0.001. SE не кластеризованы. Что не так и как исправить?

Решение

SE должны быть кластеризованы на уровне региона — уровне, на котором назначается treatment. Без кластеризации SE занижены: остатки внутри региона коррелируют (общий региональный шок), а обычные SE считают их независимыми. p = 0.001 ложно мал. При 12 кластерах (3 treated + 9 control) даже кластеризованные SE ненадёжны — мало кластеров. Правильное решение: wild cluster bootstrap или randomization inference (переставлять treatment случайно между регионами, строить эмпирическое распределение δ).