Модуль 3. Regression Discontinuity Design (RDD)

TL;DR

Если treatment назначается по порогу running variable, юниты рядом с порогом фактически рандомизированы. Оцениваем локальный эффект (LATE) в окрестности cutoff.

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

What you estimate

LATE (Local Average Treatment Effect) — эффект для юнитов в окрестности порога. Не экстраполируется на всю выборку. Fuzzy RDD оценивает LATE для compliers (тех, чей treatment status меняется из-за порога).

Assumptions

  1. Continuity: E[Y(0)|X=x] и E[Y(1)|X=x] непрерывны в окрестности cutoff
  2. No manipulation: субъекты не могут точно контролировать running variable вокруг порога
  3. Local randomization: у порога assignment фактически случайный
  4. Relevance (fuzzy): порог создаёт значимый скачок в P(D=1)

Sharp vs Fuzzy

ТипПравилоОценка
SharpD = 1 если X ≥ c, иначе D = 0lim(x→c⁺) E[Y|X] − lim(x→c⁻) E[Y|X]
FuzzyP(D=1) скачкообразно растёт при X = cРазрыв в Y / разрыв в D (= IV с порогом как Z)

Diagnostics

ПроверкаЧто смотримКрасный флагЧто делать
McCrary densityПлотность X у cutoffСкачок / bunching у порогаManipulation → RDD невалиден
Баланс ковариатСредние ковариат слева и справа от cЗначимый разрывДобавить ковариаты в регрессию / пересмотреть
Bandwidth robustnessРезультат при h/2, h, 2hЗнак/значимость меняютсяРезультат нестабилен, нужна осторожность
Placebo cutoffsФиктивные пороги (c−50, c+50)Значимый "эффект"Проблема в спецификации, не в treatment
Polynomial orderЛинейный vs квадратичный fitРезультат сильно зависит от степениИспользовать local linear (рекомендуется)

Minimal estimator

# Sharp RDD — local linear regression в окне [c−h, c+h]:
Y_i = α + τ·D_i + β·(X_i − c) + γ·D_i·(X_i − c) + ε_i

# D_i = 1{X_i ≥ c}, τ = LATE

# Fuzzy RDD — IV/2SLS:
# First stage:  D_i = π₀ + π₁·Z_i + ... (Z_i = 1{X_i ≥ c})
# Second stage: Y_i = α + τ·D̂_i + ...

Pitfalls

What to do next

Toy example: sharp RDD

Кредит одобряется при score ≥ 650. Оцениваем эффект одобрения на расходы.

IDScore (X)Одобрен (D)Расходы (Y)
16400520
26450535
36480540
46490545
56501610
66511620
76551630
86601650
# Step 1: Средние рядом с порогом (±5 баллов)
Ȳ_left  = mean(520, 535, 540, 545) = 535.0  (score 640–649)
Ȳ_right = mean(610, 620, 630, 650) = 627.5  (score 650–660)

# Step 2: Наивная оценка разрыва
τ̂ = Ȳ_right − Ȳ_left = 627.5 − 535.0 = 92.5

# Step 3: Проверить — нет ли bunching у 650?
# Проверить — ковариаты (доход, возраст) скачут у порога?

Ожидаемый результат: τ̂ ≈ 92.5 (локальный эффект кредита на расходы у порога 650).

Упражнения

Задача 1: выбор метода

Q: Компания даёт бесплатную доставку заказам от 3000₽. Нужно оценить, как бесплатная доставка влияет на повторные покупки. Какой метод?

A: RDD с порогом 3000₽ (running variable = сумма заказа). Но: покупатели могут манипулировать суммой (добавить товар до 3000₽) → нужен McCrary test. Если bunching сильный — RDD невалиден, рассмотреть donut RDD или DiD по времени введения policy.

Задача 2: диагностика

Q: RDD по скорингу: порог 700. McCrary test показывает, что плотность заявок при score 698–702 в 3 раза выше, чем при 690–695. Что это означает?

A: Bunching у порога = manipulation. Скорее всего, менеджеры или алгоритм "подтягивают" score до 700. Юниты у порога не случайны → RDD невалиден. Можно попробовать donut RDD (исключить ±5 от порога) или искать другой дизайн.

Задача 3: интерпретация

Q: RDD оценивает τ̂ = +15% retention у порога score = 500. Менеджер спрашивает: "Значит, если мы уберём порог и дадим treatment всем, retention вырастет на 15%?" Что ответить?

A: Нет. RDD оценивает локальный эффект для юнитов у порога 500. Юниты с score 300 или 800 могут реагировать совершенно иначе. Экстраполяция на всю выборку невалидна. Для оценки глобального эффекта нужен другой дизайн (A/B или DiD).