Этот пост представляет собой краткое введение в причинно-следственный вывод с практическим примером, взятым из книги Причинно-следственный вывод для храбрых и правдивых. Обратите внимание, что я просто взял примеры из книги и реализовал их в CausalPy, чтобы придать им немного байесовского колорита. Оригинал статьи, в которой исследовался вопрос, можно найти здесь.

Причинный вывод - это процесс оценки причинного эффекта на основе данных наблюдений. В этом контексте у нас обычно есть лечение (например, медицинское вмешательство), которое применяется к какой-то группе/индивидуму. Затем мы можем наблюдать метрику/меру этого индивидуума до и после лечения. Значение после обработки также называют результатом.

Фундаментальная проблема заключается в том, что для любого конкретного человека мы можем наблюдать только один результат. Другой остается для нас скрытым. Это так называемый контрфактический (т.е. противодействующий факту). Например, мы можем либо лечить пациента, либо нет, но результат мы получаем только при одной из настроек. Другой результат — это тот, который мы не наблюдаем, поэтому он известен как потенциальный результат. Однако мы можем оценить потенциальный эффект, если у нас есть контрольная группа, которая не подвергается лечению, но очень похожа на группу, получающую лечение. Мы должны убедиться, что нет никакой разницы между группами предварительной обработки.

Синтетический контроль

Во многих ситуациях нет контрольной группы, с которой мы могли бы сравнить пролеченных субъектов. Представьте, например, что мы показываем рекламу определенному проценту наших пользователей. До и после показа рекламы (т.е. лечения) мы записываем трафик на наш сайт. Следуя определению причинно-следственной связи, нам нужно знать, что произошло бы, если бы пользователи не увидели эту рекламу. Это часто возможно в случае рекламы, где мы можем показать процент пользователей и оставить остальных в качестве нашей контрольной группы. В следующем примере это невозможно.

В этом примере мы хотим узнать, как политика, ограничивающая курение, повлияла на продажи сигарет в Калифорнии. Обратите внимание, что в данном случае естественной контрольной группы нет (у нас нет второй Калифорнии в мире). Это создает проблему, поскольку может быть трудно проверить, действительно ли политика повлияла на продажи или они все равно уменьшились бы.

Именно здесь на сцену выходит Synthetic Control. Идея заключается в следующем: поскольку у нас нет естественной контрольной группы, мы попытаемся создать группу, максимально похожую на нашу экспериментальную группу. В нашем случае мы можем использовать другие штаты США, аналогичные предварительной обработке Калифорнии. Таким образом, мы можем построить «синтетическую Калифорнию» из смеси других американских штатов.

import causalpy as cp
import pandas as pd

cigar = (pd.read_csv("data/smoking.csv")
         .drop(columns=["lnincome","beer", "age15to24", "california", "after_treatment"]))

Выше мы импортируем пакет Python CausalPy, загружаем данные и удаляем некоторые столбцы, которые нам не нужны. Мы получаем данные за 31 год из 39 разных штатов. Вмешательство (начало полиса) произошло в 1989 году. Калифорния является штатом № 1. 3. Прежде чем мы сможем передать данные в CausalPy, нам нужно выполнить некоторую переформовку/предварительную обработку. Самое главное, данные должны быть в широком, а не в длинном формате.

piv = cigar.pivot(index="year", columns="state", values="cigsale")
treatment_time = 1989
unit = "s3"

piv.columns = ["s" + str(i) for i in list(piv.columns)]

piv = piv.rename(columns={unit: "actual"})

Во-первых, мы повернем данные так, чтобы у нас был один столбец для каждого штата и одна строка за год. Мы также переименуем столбцы, причины чего будут ясны позже.

formula = "actual ~ 0 + " + " ".join(list(piv.columns.drop("actual")))

Мы составляем формулу, которая говорит, что мы хотим объяснить «фактические» переменные (то есть продажи сигарет в Калифорнии) продажами сигарет в других странах. Обратите внимание, что нам пришлось переименовать столбцы, поскольку мы не можем использовать здесь целые числа. Первый 0 просто означает, что мы не хотим включать в модель перехват.

result = cp.pymc_experiments.SyntheticControl(
    piv,
    treatment_time,
    formula=formula,
    model=cp.pymc_models.WeightedSumFitter(
        sample_kwargs={"target_accept": 0.95}
    ),
)

Приведенный выше код создает модель и соответствует ей. Это довольно просто, если у нас есть чистые данные. Нам просто нужно передать данные в CausalPy вместе со временем лечения и нашей формулой. Формула описывает, как мы хотим построить синтетическую контрольную группу (т. е. какие переменные). Помимо использования SyntheticControl в качестве типа нашего эксперимента, мы сообщаем CausalPy, что хотим использовать WeightedSumFitter в качестве нашей модели. Как только мы запустим этот код, CausalPy запустит алгоритм Монте-Карло с цепочкой Маркова (MCMC), который выполняет логический вывод, извлекая выборки из апостериорного распределения. Обратите внимание, что здесь мы не будем вдаваться в подробности байесовского вывода, но есть хорошие вводные статьи, которые интуитивно объясняют концепцию.

Это первичная цифра, которую мы получаем после подгонки модели. Сначала мы должны убедиться, что у нас есть хорошая модель, которая может построить хорошую синтетическую группу. Это тот случай, когда мы достигаем R2 ~ 82%. Затем CausalPy показывает нам на первом участке оранжевым цветом то место, где Калифорния была бы без вмешательства. Черные точки показывают фактические наблюдения. Два других подграфика показывают (кумулятивную) разницу между синтетическим контролем и экспериментальной группой. Обратите внимание, что мы также получаем достоверные интервалы, связанные с причинным эффектом.

Мы также можем посмотреть на коэффициенты WeightedSumFitter. Это еще раз показывает, что синтетическая Калифорния представляет собой комбинацию других штатов. В данном случае s8 и s4 составляют большую часть синтетической калифорнии.

Заключение

Причинно-следственный вывод — область статистики, которую часто упускают из виду. Однако он становится все более популярным, поскольку позволяет нам выйти за рамки простой ассоциации и корреляции и ответить на вопросы типа «что, если». Ответы на вопросы такого типа необходимы для фактического принятия решений, основанных на данных.