<jupyter_start><jupyter_text>Causal Inference In Statistics - A Primer        2.3 Colliders        <NAME>        www.data4sci.com            @bgoncalves, @data4sci<jupyter_code>from collections import Counter
from pprint import pprint

import pandas as pd
import numpy as np

import matplotlib
import matplotlib.pyplot as plt 
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

from CausalModel import CausalModel

import watermark

%load_ext watermark
%matplotlib inline<jupyter_output><empty_output><jupyter_text>We start by print out the versions of the libraries we're using for future reference<jupyter_code>%watermark -n -v -m -g -iv<jupyter_output>json       2.0.9
numpy      1.18.1
watermark  2.0.2
matplotlib 3.1.3
pandas     1.0.1
autopep8   1.5
Sat Sep 12 2020 

CPython 3.7.3
IPython 6.2.1

compiler   : Clang 4.0.1 (tags/RELEASE_401/final)
system     : Darwin
release    : 19.6.0
machine    : x86_64
processor  : i386
CPU cores  : 8
interpreter: 64bit
Git hash   : b7e1acd9fcd43d710e34c26c6375c4bc440268e9<jupyter_text>Load default figure style<jupyter_code>plt.style.use('./d4sci.mplstyle')
colors = plt.rcParams['axes.prop_cycle'].by_key()['color']<jupyter_output><empty_output><jupyter_text>Colliders<jupyter_code>G = CausalModel()
G.add_causation('Ux', 'X')
G.add_causation('Uy', 'Y')
G.add_causation('Uz', 'Z')
G.add_causation('X', 'Z')
G.add_causation('Y', 'Z')

G.pos = {'X': (-1, 0), 'Y': (1, 0), 'Z':(0, -1), 'Ux':(-1, 1), 'Uy':(1, 1), 'Uz': (0, 0)}
fig, ax = plt.subplots(1, figsize=(2.2, 2.2))
G.plot(ax=ax)
G.save_model('dags/Primer.Fig.2.3.dot')<jupyter_output><empty_output><jupyter_text>Conditioning<jupyter_code>fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.linspace(1, 10, 100)
Y = np.linspace(1, 10, 100)
X, Y = np.meshgrid(X, Y)
Z = X+Y
Z10 = Z*0+10

# Workaround for how matploltib works in 3D. We plot both sides of the surface separately.
X2 = np.linspace(1, 10, 100)
Y2 = np.linspace(1, 10, 100)
X2, Y2 = np.meshgrid(X2, Y2)
Z102 = Z*0+10

X2[Z<=10] = np.nan
Y2[Z<=10] = np.nan
Z102[Z<=10] = np.nan

ax.plot_surface(X2, Y2, Z102, cmap=cm.coolwarm, antialiased=False)
ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, antialiased=False)

X3 = np.linspace(1, 10, 100)
Y3 = np.linspace(1, 10, 100)
X3, Y3 = np.meshgrid(X3, Y3)
Z103 = Z*0+10

X3[Z>10] = np.nan
Y3[Z>10] = np.nan
Z103[Z>10] = np.nan
ax.plot_surface(X3, Y3, Z103, cmap=cm.coolwarm, antialiased=False)

ax.set_xlabel('X', labelpad=20)
ax.set_ylabel('Y', labelpad=20)
ax.set_zlabel('Z', labelpad=10)

ax.text(0, 0, 11, r'$Z\equiv 10$')
ax.text(8, 10, 20, r'$Z=X+Y$')<jupyter_output><empty_output><jupyter_text>Monty Hall<jupyter_code>Monty = pd.DataFrame({'Car':   ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C'], 
                      'Choice':['A', 'A', 'B', 'C', 'A', 'B', 'B', 'C', 'A', 'B', 'C', 'C'],
                      'Monty': ['B', 'C', 'C', 'B', 'C', 'A', 'C', 'A', 'B', 'A', 'A', 'B'],
                      'P': np.array([.5, .5, 1, 1, 1, .5, .5, 1, 1, 1, .5, .5])/9})
Monty
Unconditional = Monty[['Car', 'Choice', 'P']].groupby(['Car', 'Choice']).sum().reset_index()
Unconditional['P'] = Unconditional.groupby(['Car']).apply(lambda x:x['P']/x['P'].sum()).values
Unconditional.set_index('Car')
Conditional = Monty[['Monty', 'Car', 'Choice', 'P']].groupby('Monty').apply(lambda x:x[['Car', 'Choice', 'P']]
    .groupby(['Car', 'Choice']).sum()).reset_index()
Conditional['P'] = Conditional.groupby(['Monty', 'Car']).apply(lambda x:x['P']/x['P'].sum()).values
Conditional.set_index(['Monty', 'Car'])
Monty['Win'] = (Monty['Choice'] == Monty['Car'])
Monty[['Win', 'P']].groupby('Win').sum()
Choice_win = Monty[['Choice', 'Win', 'P']].groupby(['Choice', 'Win'], as_index=False).sum()
Choice_win['P'] = Choice_win.groupby('Choice').apply(lambda x:x['P']/x['P'].sum()).values
Choice_win
Change_win = pd.concat([Monty, Monty], ignore_index=True)
Change_win['P']/=2
Change_win['Change']=False
Change_win['Change'].iloc[12:]=True
Change_win['Win'].iloc[12:] = ~Change_win['Win'].iloc[12:] 
Change_win
Change_win = Change_win[['Choice', 'Change', 'Win', 'P']].groupby(['Choice', 'Change', 'Win'], as_index=False).sum()
Change_win['P'] = Change_win.groupby(['Choice', 'Change']).apply(lambda x:x['P']/x['P'].sum()).values
Change_win
pd.pivot_table(Change_win[Change_win['Win']==True], index='Choice', columns='Change', values='P')[[1, 0]]
G = CausalModel()
G.add_causation('X', 'R')
G.add_causation('R', 'S')
G.add_causation('S', 'T')
G.add_causation('U', 'T')
G.add_causation('V', 'U')
G.add_causation('V', 'Y')


G.pos = {'X': (0, 0), 'R': (1, 0), 'S':(2, 0), 'T':(3, 0), 'U':(4, 0), 'V': (5, 0), 'Y': (6, 0)}
fig, ax = plt.subplots(1, figsize=(8, 1))
G.plot(ax=ax)
G.save_model('dags/Primer.Fig.2.5.dot')
G2 = CausalModel()
G2.add_causation('X', 'R')
G2.add_causation('R', 'S')
G2.add_causation('S', 'T')
G2.add_causation('U', 'T')
G2.add_causation('V', 'U')
G2.add_causation('V', 'Y')
G2.add_causation('T', 'P')

G2.pos = {'X': (0, 0), 'R': (1, 0), 'S':(2, 0), 'T':(3, 0), 'U':(4, 0), 'V': (5, 0), 'Y': (6, 0), 'P': (3, -1)}
fig, ax = plt.subplots(1, figsize=(8, 2.2))
G2.plot(ax=ax)
G2.save_model('dags/Primer.Fig.2.6.dot')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.23872832369942196, 'fraction_numerical': 0.05606936416184971, 'mean_word_length': 5.14319526627219, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '290709', 'license': 'MIT', 'n_tokens_mistral': 2488, 'n_tokens_neox': 2332, 'n_words': 458, 'path': '2.3 - Colliders.ipynb', 'repo_name': 'snowdj/Causality-1', 'size': '5199'}