Полное объяснение предварительной корректировки причинно-следственного вывода с примерами, включая весь исходный код Python.
Цель
К концу этой статьи вы поймете магию предварительной корректировки причинно-следственного вывода, которая может рассчитать влияние события на результат, даже если есть другие факторы, влияющие на оба, которые не измерены или даже неизвестны, и у вас будет полный доступ к весь код Python.
Я обыскал Интернет и множество книг, пытаясь найти полностью работающий пример формулы входа в Python, и я ничего не понял, поэтому, если нет источников, которые я пропустил, то, что вы собираетесь прочитать, действительно уникальный …
Введение
В недавней статье я исследовал силу формулы корректировки бэкдора для расчета истинного влияния события на результат, даже если есть наблюдаемые факторы, которые «смешивают» оба…
Цель состояла в том, чтобы установить истинное влияние приема препарата на показатели выздоровления пациентов, и волшебство формулы корректировки черного хода восстановило этот эффект, даже несмотря на то, что «мужской» скрывал этот результат, потому что -
- Доля мужчин, принимавших наркотик, выше, чем женщин.
- У мужчин скорость выздоровления была выше, чем у женщин
В этом примере «мужской» является «вмешивающимся фактором», но значения для «мужского» были включены в данные наблюдения, а затем была применена формула черного хода, чтобы доказать, что испытание препарата оказало положительное влияние.
Но что, если «конфаундер» нельзя было измерить и он не был включен в данные?
Пример из реального мира
В 1950-х годах бушевала статистическая война между учеными, твердо верившими в то, что курение вызывает респираторные заболевания, и табачными компаниями, которым удалось представить «доказательства» обратного.
Суть этих доказательств заключалась в предположении табачных компаний о том, что генетический фактор несет ответственность как за то, что курильщики начинают курить, так и за вероятность развития респираторных заболеваний. Это была удобная гипотеза для табачных компаний, потому что ее было почти невозможно проверить.
Вот предложение о причинно-следственных связях между вовлеченными факторами…
Решение причинного вывода
Если это единственные данные, которые у вас есть, т. е. простой обходной путь от ненаблюдаемого искажающего фактора к событию и результату, то ничего нельзя сделать; истинный эффект не может быть восстановлен.
Однако есть и другие «шаблоны», в которых эффект может быть восстановлен, включая входные критерии и инструментальные переменные. В этой статье будет полностью объяснен первый из этих шаблонов.
Чтобы удовлетворить критерию входной двери, между событием и результатом должен быть посредник, и в примере с курением это может выглядеть так:
то есть курение вызывает смолу, а смола вызывает респираторное заболевание, а не прямую причинную связь.
Когда эта модель существует, влияние события (курения) на результат (респираторное заболевание) можно выделить и восстановить независимо от влияния ненаблюдаемого фактора, используя «Формулу коррекции перед входной дверью», предложенную Джудеей Перл в «The Книга почему» и «Причинно-следственный вывод в статистике».
Исключение влияния ненаблюдаемого искажающего фактора кажется волшебством, и последствия действительно поразительны, но если вы будете следовать шагам, описанным в оставшейся части этой статьи, вы сможете добавить эту удивительную технику в свой набор инструментов для обработки и анализа данных всего несколькими строками Python. код!
Начиная
Первое, что нам нужно, это некоторые тестовые данные. Я создал синтетический набор данных, используя свой класс BinaryDataGenerator
. Если вам нужен полный исходный код, перейдите к этой статье —
Краткий анализ данных выглядит следующим образом:
- В выборке было 800 человек.
- 50% выборки были курильщиками (400/800).
- 95% курильщиков имели отложения смолы (380/400)
- 5% некурящих имели отложения смолы (20/400)
- У 15% курильщиков смол были респираторные заболевания (47/380)
- У 10% курильщиков без смол были респираторные заболевания (2/20)
- У 95% курильщиков смолы были респираторные заболевания (19/20)
- 90% некурящих без смол имели респираторные заболевания (342/380)
Первая попытка: использование библиотеки Pgmpy
В своей статье о критериях бэкдора я начал с демонстрации простого решения с использованием pgmpy
.
Учитывая, как легко было применить критерии бэкдора в этом примере, должно быть очень просто применить таким же образом критерии бэкдора. Вот код, который должен это сделать…
Ожидаемый результат — 4,5% (подробнее об этом позже!), но pgmpy
вылетает с ValueError: Maximum Likelihood Estimator works only for models with all observed variables. Found latent variables: set()
.
После долгих исследований, а также поднятия вопроса с разработчиками, я пришел к выводу, что pgmpy
не работает при применении оператора «сделать» (т. е. вмешиваться), когда есть ненаблюдаемый мешающий фактор, и что pgmpy
не может применить переднюю настройку. формула.
Это даже хуже, так как библиотека DoWhy
не работает и в этом случае.
DoWhy
может иметь дело с ненаблюдаемыми искажающими факторами при расчете «среднего эффекта лечения» (ATE), но когда оператор «выполнить» применяется для имитации вмешательства, он терпит неудачу так же, как pgmpy
.
ATE применяется к непрерывным переменным, поэтому мы можем задать DoWhy
вопрос типа "Если выбросы двуокиси углерода увеличатся на 100 миллионов тонн, каков причинный эффект повышения глобальной температуры?" и DoWhy
даст результат.
Однако при применении вмешательства «выполнить» к дискретным бинарным данным, например «Какова вероятность респираторного заболевания, учитывая, что все в выборке курят?» ни pgmpy
, ни DoWhy
не могут выполнять расчеты, если присутствует ненаблюдаемый источник помех, и на сегодняшний день я не нашел других библиотек, которые могли бы это сделать.
Моя статья о бэкдоре перешла от реализации pgmpy
, чтобы предоставить пример математики, чтобы показать, что pgmpy
делал за кулисами. В этой статье требуется понимание математики заранее, чтобы мы могли построить собственную реализацию формулы предварительной настройки в Python...
Вторая попытка: сделать это вручную
Цель состоит в том, чтобы рассчитать средний причинный эффект (ACE) путем моделирования следующего:
- Путешествие в прошлое и выступление и вмешательство, которое заставляет всех курить.
- Проделайте тот же трюк с путешествием во времени еще раз и на этот раз заставьте всех сдаться.
- Вычесть второй результат из первого.
Выраженный математически с помощью оператора «do», этот удивительный подвиг выглядит так:
А поскольку мы знаем, что в данных есть ненаблюдаемый мешающий фактор и прямой путь, нам нужно заменить каждую часть формулы ACE формулой корректировки переднего входа, предложенной Джудеей Перл…
Давайте начнем с левой части формулы ACE, заменим ею формулу корректировки входной двери и используем переменные, присутствующие в наших данных, вместо x, y и z. Чтобы все было чисто и аккуратно, будут использоваться следующие сокращения: S = курение, R = дыхание, T = смола…
t может принимать значения {0, 1}, а s может принимать значения {0, 1}, поэтому теперь нам нужно расширить следующим образом...
… а внутренние члены ∑𝑠 можно расширить следующим образом …
Теперь это должно быть простым вопросом замены условных вероятностей из данных. В следующем разделе будет предоставлена функция Python для вычисления любой условной вероятности на основе данных, а пока вот необходимые значения…
Подстановка этих условных вероятностей дает …
So …
… и если вы снова пересчитаете все вышеперечисленные шаги для 𝑃(𝑅=1∣𝑑𝑜(𝑆=0)) ответ будет …
Таким образом, общий средний причинно-следственный эффект (ACE) равен …
Было приложено много усилий, чтобы вычислить средний причинно-следственный эффект вручную! К счастью, теперь, когда работа формулы предварительной корректировки полностью понята, относительно легко преобразовать все это в Python, чтобы все это можно было полностью автоматизировать для любого набора данных, где функции представляют собой дискретные значения…
Третья попытка: повторно используемая функция Python
Третья попытка включает в себя создание повторно используемой функции Python, которая реализует математику из предыдущего раздела для любой простой DAG и любого DataFrame
, чтобы математику можно было отложить в сторону, как только она будет понята.
Реализация этой функции потребует использования условных вероятностей, и потребуется простая функция Python для вычисления этих вероятностей из любого DataFrame
.
Я опустил детали функции calc_cond_prob
за пределы этой статьи, чтобы сосредоточить внимание на регулировке передней двери, но вы можете прочитать полное объяснение и загрузить исходный код из этой статьи…
После того, как вы загрузили calc_cond_prob
, его можно использовать для простого расчета условных вероятностей из любого DataFrame
следующим образом...
𝑝(𝑟𝑒𝑠𝑝𝑖𝑟𝑎𝑡𝑜𝑟𝑦=0∣𝑠𝑚𝑜𝑘𝑖𝑛𝑔=0,𝑡𝑎𝑟=0)=0.1
… или, альтернативно, outcome / result
и events
могут быть указаны явно следующим образом...
𝑝(𝑟𝑒𝑠𝑝𝑖𝑟𝑎𝑡𝑜𝑟𝑦=0∣𝑠𝑚𝑜𝑘𝑖𝑛𝑔=0,𝑡𝑎𝑟=0)=0.1
В предыдущем разделе объяснялась математика, стоящая за формулой регулировки входной двери Пирлея, и приводился полностью рабочий пример.
Учитывая эти строительные блоки (и функцию calc_cod_prob
), можно разработать функцию Python, которая будет вычислять формулу front_door_adjustment для anny DataFrame
, которая содержит следующие функции:
- Х — лечение
- Y — результат
- З — посредник
Вот полный исходный код для регулировки передней двери…
… и функция может быть вызвана вот так …
Заключение
Начнем со слона в комнате: если бы курение увеличивало среднюю вероятность респираторных заболеваний всего на 4,5%, это не убедило бы многих курильщиков бросить курить.
Однако мы увидели, что индивидуальная вероятность респираторных заболеваний при курении
Причина, по которой средний причинно-следственный эффект настолько низок, заключается в том, что наши фиктивные табачные компании провернули подлую уловку, составив колоду, убедившись, что в выборку попало множество некурящих с респираторными заболеваниями, в попытке скрыть правду, то есть то, что курение вредит здоровью. вызывает респираторные заболевания.
Но даже с этим шумом в данных, и даже если мы примем маловероятную гипотезу о том, что существует неизмеримый генетический фактор, который смешивает как событие, так и результат, волшебство формулы предварительной корректировки все же выявило положительную причинно-следственную связь между курением. и респираторные заболевания!
Этот удивительный результат не похож ни на что, что я обнаружил в других методах науки о данных, и он отвечает на самые распространенные вопросы, которые всегда задают клиенты моих прогнозов машинного обучения, т. Е. -
- Почему это происходит?
- Что я должен сделать, чтобы изменить результат и улучшить ситуацию?
Эти типы «почему?» Вопросы превращают знания, способности и понимание, необходимые для предварительной корректировки, чтобы рассчитать эффект «вмешательств», бесценным дополнением к набору инструментов для обработки и анализа данных.
К сожалению, доступные в настоящее время библиотеки, в том числе pgmpy
и DoWhy
, не работают при применении оператора "do" к дискретным наборам данных, включающим ненаблюдаемый конфаундер и входной путь.
Это огромный пробел в функциональности этих библиотек, и после долгих поисков решения Python с рабочим примером как в Интернете, так и в книгах я ничего не смог найти.
Если только я не просмотрел некоторые примеры, которые делают эту статью уникальной, и я хотел бы иметь возможность прочитать ее, когда меня начала очаровывать регулировка передней двери, вместо того, чтобы проводить все эти исследования самостоятельно.
Это было очень весело, и я очень надеюсь, что вам понравится результат!
Бонусный раздел
Итак, сказав, что pgmpy
не работает в этом сценарии, и зайдя так далеко в своем учебном путешествии, я решил написать версию формулы настройки входной двери на Python, чтобы исправить это упущение.
Просто отмечу, что я решил реорганизовать формулу, чтобы сделать реализацию Python немного более лаконичной, изменив это…
в это..
… что математически эквивалентно и равнозначно утверждению —
4 x 3 x 1 x 2 x 2 = 4 x 1x 2 x 2 x 3
Примечание: см. «Причинно-следственный вывод в статистике» Перла, Глимура и Джуэлла, стр. 68 (3.15) и стр. 69 (3.16) для полного объяснения этой эквивалентности.
Вернемся к решению. Первым шагом является создание причинно-следственной модели с использованием pgmpy
классов. Обратите внимание: ненаблюдаемый мешающий объект должен быть удален из списка edges
, так как именно он вызывает сбой метода BayesianNetwork.fit()
с ValueError
...
После того, как настройка завершена, формулу входной двери можно реализовать на Python следующим образом…
И просто чтобы доказать, что это работает, вычисление дает точно такие же результаты, что и ручное вычисление, и более ранняя функция Python, которая работает непосредственно с DataFrame
...
Подключайтесь и будьте на связи…
Если вам понравилась эта статья, вы можете получить неограниченный доступ к тысячам других, став участником Medium всего за 5 долларов в месяц, нажав на мою реферальную ссылку (я получу часть сборов, если вы зарегистрируетесь по этой ссылке без каких-либо дополнительных затрат). стоимость для вас).
… или подключиться через …
Подписка на бесплатную электронную почту всякий раз, когда я публикую новую историю.
Беглый взгляд на мои предыдущие статьи.
Загружаю мою бесплатную систему принятия стратегических решений на основе данных.
Посещение моего сайта по науке о данных — The Data Blog.