Полное объяснение предварительной корректировки причинно-следственного вывода с примерами, включая весь исходный код 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) путем моделирования следующего:

  1. Путешествие в прошлое и выступление и вмешательство, которое заставляет всех курить.
  2. Проделайте тот же трюк с путешествием во времени еще раз и на этот раз заставьте всех сдаться.
  3. Вычесть второй результат из первого.

Выраженный математически с помощью оператора «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.