<jupyter_start><jupyter_text>Collider Bias<jupyter_code>%%R
g = dagitty("dag{ T -> C <- B }")
plot(g)
#collider bias
num_samples = 1000000
talent = np.random.normal(size=num_samples)
beauty = np.random.normal(size=num_samples)
congeniality = talent + beauty + np.random.normal(size=num_samples) #congeniality
cond_talent = np.where(talent > 0, 1, 0)
cond_beauty = np.where(beauty > 0, 1, 0)
data = {"talent": talent, "beauty": beauty, "congeniality": congeniality, "cond_talent": cond_talent, "cond_beauty": cond_beauty}

print(smf.ols("talent ~ beauty", data).fit().summary())
print(smf.ols("talent ~ beauty + congeniality", data).fit().summary())
print(smf.ols("cond_talent ~ cond_beauty", data).fit().summary())<jupyter_output><empty_output><jupyter_text>We can also use package Dagitty to illustrate collider bias, also known as M-bias.<jupyter_code>%%R
print(adjustmentSets( g, "T", "B" ))

## empty set -- we should not condition on the additional
## variable C.
## Generate data where C = .5T + .5B

d <- simulateSEM( g, .5 )
data = rpy2.robjects.r["d"]
print(smf.ols("T ~ B", data).fit().summary()) # includes 0
print(smf.ols("T ~ B + C", data).fit().summary()) # does not include 0<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1737704918032787, 'fraction_numerical': 0.01557377049180328, 'mean_word_length': 5.859550561797753, 'pattern_counts': {'":': 5, '<': 11, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '32631', 'license': 'MIT', 'n_tokens_mistral': 483, 'n_tokens_neox': 459, 'n_words': 105, 'path': 'CM2/colliderbias-hollywood.ipynb', 'repo_name': 'CausalAIBook/MetricsMLNotebooks', 'size': '1220'}