Ежедневные заметки для изучения, изучения и понимания структуры ПРИЧИННОГО ВЫВОДА. [после Causal Inference and Discovery in Python, написанного Александром Молаком]
День 3
Регрессия и причинная интерпретация
Когда вы видите простое уравнение регрессии, такое как Y = AX + B, что вы неявно думаете? Разве вы не думаете таким образом? Если значение X изменить на одну единицу, значение Y изменится на A. И, честно говоря, такая интерпретация сбивает людей с толку, думая, что каким-то образом X вызывает изменение Y. Однако это не всегда так. .
Регрессия — это просто попытка количественно оценить уровень связи между переменными. Даже если вы привыкли регрессировать Y на X, в зависимости от ситуации вы можете захотеть регрессировать X на Y. И изменение расположения переменных в уравнении регрессии слева направо не показывает наличие причинно-следственной связи между зависимые переменные и независимая переменная.
К сожалению, без знания правильной SCM (структурированной причинно-следственной модели), которая отражает процесс генерации данных, сложно применить причинно-следственную интерпретацию к данным наблюдений, даже если вы получите все статистически значимые коэффициенты. Единственный случай, когда вы можете уверенно построить причинно-следственную связь с помощью регрессии, при отсутствии знаний о SCM, — это когда вы проводите правильно спланированный рандомизированный эксперимент.
День 4
Графические модели
Графы состоят из двух частей — узлов (вершин) и ребер (связей). В зависимости от того, известна ли причинно-следственная связь между узлами или нет, у вас могут быть НАПРАВЛЕННЫЕ или неориентированные графы. В зависимости от того, являются ли причинно-следственные связи между узлами круговыми или нет, вы можете иметь циклические или аЦИКЛИЧЕСКИЕ графы.
Хорошо, это круто. Но как мы можем преобразовать живописный график в какой-либо числовой формат? Вот тут и приходит на помощь МАТРИЦА СМЕЖНОСТИ. Это довольно интересный способ зафиксировать взаимосвязь между двумя узлами. Я думаю, что лучший способ показать, как интерпретировать матрицу смежности, — это использовать простой пример.
import graphviz import networkx as nx graph = graphviz.Digraph(format='png') nodes = ['0', '1', '2','3'] edges = ['01', '02', '13'] [graph.node(n) for n in nodes] graph.edges(edges) graph.render(f'img/ch_04_graph_adj_01') graph #For your reference, the adjacency matrix looks like this: # [0 1 1 0 # 0 0 0 1 # 0 0 0 0 # 0 0 0 0]
У вас есть 4 узла с именами 0,1,2,3. Таким образом, ваша матрица смежности будет 4 на 4. Интересно, что индексы матрицы расскажут вам о направлении воздействия от какого узла к какому узлу. Например, у вас есть 3 ребра (связи) от 0 до 1, от 0 до 2, от 1 до 2. Таким образом, значение индекса вашей матрицы (0,1), (0,2) и (1,2) будет 1, в то время как значения всех остальных компонентов равны нулю.
Одной из важных терминов, которую следует здесь продолжить, является DAG. Расшифровывается как НАПРАВЛЕННЫЙ И АЦИКЛИЧЕСКИЙ ГРАФ. И похоже, что большая часть исследования причинно-следственных связей будет иметь дело со случаями DAG, которые показывают, что дочерний узел СЛУШАЕТ родительский узел. Что это значит? Это означает, что если мы изменим настройку родительской ноты, мы также будем наблюдать изменение дочерней ноды. Опять же, это происходит, когда мы намеренно меняем значение родительского узла, а не просто наблюдаем за изменением значения родительского узла. Помните, возможно, что изменение одной переменной выглядит так, как будто оно вызывает изменение другой переменной, когда существует просто корреляционная или ассоциативная связь даже при отсутствии причинно-следственной связи.
День 5
Цепи, вилки, коллайдеры и d-разделение
Начнем с понимания того, что означает независимость между двумя переменными X и Y. Автор дает четкое определение. Проще говоря, узнав что-то новое об X, мы не изменим нашего мнения об Y и других настороженных окружающих. (стр.72)
Все в порядке. Основываясь на этой информации, давайте представим, какие отношения могут быть между направленными ациклическими графами трех переменных: цепочки, вилки и коллайдеры.
‹Цепи›
Интересная вещь о цепном графике: если мы оставляем B постоянным или контролируем B, не имеет значения, насколько изменится значение A, C не будет затронут. Это означает, что А и С независимы при заданном В.
import graphviz import networkx as nx graph = graphviz.Digraph(format='png') nodes = ['A', 'B', 'C'] edges = ['AB','BC'] [graph.node(n) for n in nodes] graph.edges(edges) graph
‹Вилки›
Интересная вещь о форк-графе: если мы не считаем B постоянным или если мы не контролируем B, A и C являются зависимыми. Да, они не связаны напрямую, но знание об изменении A поможет нам предсказать изменение C, поэтому они не являются независимыми. Однако, если мы считаем B постоянным, A и C независимы. Другими словами, A и C УСЛОВНО независимы при данном B.
Что ж, мы приходим к такому же выводу между цепями и вилками.
import graphviz import networkx as nx graph = graphviz.Digraph(format='png') nodes = ['A', 'B', 'C'] edges = ['BA','BC'] [graph.node(n) for n in nodes] graph.edges(edges) graph
‹Коллайдеры›
Интересная вещь о коллайдере — если мы не контролируем B, A и C безусловно независимы. Однако, как только мы контролируем B, A и C должны работать вместе, чтобы соответствовать фиксированному значению B. Таким образом, A и C условно зависимы при заданном B.
Мне нравится пример автора. Думайте о B как о стакане, а A и C — о количестве воды, которое вы можете налить в стакан B. Если мы ограничим размер стакана B, и мы должны наполнить стакан B, не переполняя его, нам нужно сделать сумма A + C = B. Итак, пока B фиксировано и вы знаете значение A, автоматически определяется значение C, что означает, что A и C зависят друг от друга при заданном B.
import graphviz import networkx as nx graph = graphviz.Digraph(format='png') nodes = ['A', 'B', 'C'] edges = ['AB','CB'] [graph.node(n) for n in nodes] graph.edges(edges) graph.render(f'img/ch_04_graph_adj_01') graph
‹d-разделение›
Что это за знаменитое d-разделение? Это означает, что два набора узлов или два узла разделены d, когда все пути между ними заблокированы (p98). Затем…. когда мы можем преградить путь? Мы только что узнали об этом, не так ли?
- Когда есть коллайдер, не трогайте среднюю переменную. Оставьте путь в покое. Тогда путь d-разделен.
- Когда есть вилка или цепочка, контролируйте эту переменную посередине. Тогда путь d-разделен.
Хорошо. Это все на сегодня.
Спасибо, что были со мной и увидимся в следующий раз.