Regression discontinuity простыми словами
created_at имеет тип timestamp. Какой тип данных вернёт DATE_TRUNC('day', created_at)?Содержание:
Зачем это знать
Бонусная программа включается при балле ≥ 70. Те, у кого 69, ничего не получают, у 71 — получают. Пользователи почти одинаковые, а воздействие разное. Это натурный эксперимент — regression discontinuity (RDD).
В банковской, страховой, финтех-аналитике RDD встречается постоянно: пороги для кредитов, тарифов, предложений. Знание RDD — мощный инструмент для middle+.
Короткое объяснение
RDD измеряет эффект воздействия, которое применяется к объекту на основе его балла (running variable) относительно порога (cutoff).
Сравниваем объекты «чуть выше» и «чуть ниже» порога → они почти одинаковы во всём, кроме самого воздействия.
Пример
Кредитный бонус даётся клиентам с баллом ≥ 700.
- Балл 699: бонуса нет → LTV = $200
- Балл 701: бонус есть → LTV = $280
Разница $80 — эффект бонуса, если допущения RDD выполнены.
Sharp vs Fuzzy
Sharp RDD
Воздействие применяется всегда и только при балле ≥ порога.
Все 701+ получают бонус, никто ниже.
Fuzzy RDD
Вероятность получить воздействие растёт на пороге, но не на 100%.
Например, 80% клиентов с баллом ≥ 700 выбирают бонус, 20% — нет.
Требует подхода с инструментальными переменными (instrumental variables).
Допущения метода
Непрерывность (continuity)
Все остальные факторы (кроме воздействия) — непрерывные функции running variable около порога.
Другими словами: без порога LTV(балл) был бы гладкой функцией.
Отсутствие манипуляций
Объекты не могут точно управлять своим баллом, чтобы попасть в/выше порога.
Если клиенты могут «подкрутить» балл до 701 — RDD сломан.
В формуле
Y = α + β × Treatment + f(score) + εГде f(score) — гладкая функция балла (полином или kernel), а β — эффект воздействия.
Визуально
График: по X — running variable, по Y — исход.
- До порога: гладкий тренд
- На пороге: скачок (разрыв)
- После порога: гладкий тренд
Размер скачка = эффект.
В Python
import statsmodels.api as sm
import numpy as np
# Берём окно (bandwidth 30) вокруг порога
data_near = data[abs(data['score'] - 700) < 30]
data_near['treatment'] = (data_near['score'] >= 700).astype(int)
data_near['score_centered'] = data_near['score'] - 700
# Линейная регрессия с взаимодействием
X = sm.add_constant(data_near[['treatment', 'score_centered']])
X['interact'] = X['treatment'] * X['score_centered']
model = sm.OLS(data_near['outcome'], X).fit()
# коэффициент при treatment = эффектИли специальный пакет:
import rdrobust
rdrobust.rdplot(y=data['y'], x=data['score'], c=700)Bandwidth (ширина окна)
Ключевое решение: как близко к порогу смотреть.
- Слишком широко: смещение (объекты слишком разные)
- Слишком узко: дисперсия (мало данных)
Оптимум — через кросс-валидацию или формулы optimal bandwidth (Imbens-Kalyanaraman).
Когда использовать
- Есть чёткий порог в процессе
- Running variable непрерывная
- Около порога достаточно данных
Классические кейсы
- Кредитные ограничения
- Минимальный балл (поступление в вузы)
- Возрастные пороги (пенсия, алкогольное совершеннолетие)
- Политика (результаты выборов с близким исходом)
Подводные камни
Манипуляции
Если объекты могут подкрутить балл — нужен тест McCrary на плотность около порога. Если плотность скачет → манипуляция.
Чувствительность к bandwidth
Результат может сильно зависеть от выбранного окна. Нужны проверки устойчивости (robustness checks).
Несколько порогов
Если в процессе несколько порогов — всё усложняется.
На собесе
«Что такое RDD?» Метод измерения эффекта воздействия на основе порога running variable.
«Sharp vs fuzzy?» Sharp — 100% воздействия выше порога, fuzzy — вероятность.
«Допущения?» Непрерывность и отсутствие манипуляций.
«Когда использовать?» Когда есть чёткий порог и нельзя провести A/B.
Частые ошибки
Игнорировать манипуляции
Тест McCrary обязателен.
Слишком широкое окно
Сравниваются объекты, не похожие друг на друга.
Неверная функциональная форма
Если f(score) на самом деле кубическая, а вы подогнали линейную — получите смещение.
Связанные темы
FAQ
В A/B есть?
Нет. RDD — когда A/B нельзя сделать.
Сложно?
Концепция проста, но детали (bandwidth, polynomial order) требуют care.
Внешняя валидность?
Эффект на границе порога может отличаться от среднего эффекта по всей популяции.