import%20marimo%0A%0A__generated_with%20%3D%20%220.24.0%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20plotly.graph_objects%20as%20go%0A%20%20%20%20from%20plotly.subplots%20import%20make_subplots%0A%20%20%20%20from%20scipy%20import%20stats%0A%0A%20%20%20%20return%20go%2C%20make_subplots%2C%20mo%2C%20np%2C%20pd%2C%20stats%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Note%2020%3A%20Spurious%20Correlation%2C%20Confounding%2C%20and%20Partial%20Correlation%0A%0A%20%20%20%20%26larr%3B%20Previous%20Note%3A%20%5B19%20Kendall%20Tau-b%5D(19_kendalltaub.py)%20%7C%20Next%20Note%3A%20%5B21%20Kruskal-Wallis%5D(21_kruskal_wallis.py)%20%26rarr%3B%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%20%5Ba%5D%20Why%20do%20you%20need%20to%20know%20these%20concepts%3F%0A%0A%20%20%20%20The%20fundamental%20tenet%20of%20empirical%20science%20and%20machine%20learning%20is%20that%20**correlation%20does%20not%20imply%20causation**.%20Two%20variables%20%24X%24%20and%20%24Y%24%20may%20exhibit%20a%20statistically%20significant%20correlation%20(%24r%20%3E%200.90%2C%20p%20%3C%2010%5E%7B-15%7D%24)%20despite%20having%20no%20direct%20causal%20link%20whatsoever.%0A%0A%20%20%20%20In%20machine%20learning%2C%20AI%20alignment%2C%20and%20causal%20inference%2C%20failing%20to%20distinguish%20between%20genuine%20association%20and%20spurious%20correlation%20leads%20to%20severe%20vulnerabilities%3A%0A%20%20%20%201.%20**Spurious%20Shortcuts%20in%20Deep%20Learning**%3A%20Computer%20vision%20models%20trained%20to%20detect%20pneumonia%20often%20learn%20to%20identify%20hospital%20ward%20markers%20or%20scanner%20metadata%20rather%20than%20lung%20pathology.%20Language%20models%20trained%20on%20web%20corpora%20associate%20demographic%20tokens%20with%20specific%20professions%20due%20to%20historical%20reporting%20biases.%20When%20deployed%20in%20new%20hospitals%20or%20environments%2C%20these%20models%20suffer%20catastrophic%20generalization%20failure.%0A%20%20%20%202.%20**Confounder%20Bias%20in%20Observational%20Data**%3A%20In%20observational%20studies%20(e.g.%20ad%20spend%20vs%20revenue%2C%20medical%20treatment%20vs%20patient%20recovery%2C%20hours%20studied%20vs%20exam%20scores)%2C%20unobserved%20or%20unmodelled%20third%20variables%20(economic%20conditions%2C%20disease%20severity%2C%20student%20prior%20ability)%20confound%20both%20the%20predictor%20and%20the%20outcome.%0A%20%20%20%203.%20**Simpson's%20Paradox**%3A%20When%20a%20population%20consists%20of%20distinct%20subgroups%2C%20the%20aggregate%20correlation%20across%20the%20pooled%20sample%20can%20point%20in%20the%20exact%20opposite%20direction%20of%20the%20true%20relationship%20within%20every%20single%20subgroup.%20A%20drug%20can%20appear%20harmful%20in%20aggregate%20while%20being%20life-saving%20within%20every%20clinical%20severity%20stratum.%0A%20%20%20%204.%20**Partial%20Correlation%20as%20Orthogonal%20Deconfounding**%3A%20Partial%20correlation%20measures%20the%20linear%20association%20between%20two%20variables%20%24X%24%20and%20%24Y%24%20after%20algebraically%20removing%20the%20linear%20effect%20of%20one%20or%20more%20confounding%20variables%20%24Z%24.%20In%20linear%20models%20and%20Gaussian%20Graphical%20Models%20(GGMs)%2C%20zero%20partial%20correlation%20implies%20conditional%20independence%20(%24X%20%5Cperp%20Y%20%5Cmid%20Z%24).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%20%5Bb%5D%20Concept%20explanation%20with%20their%20role%20in%20ML%2FAI%2FStats%3F%0A%0A%20%20%20%20%23%23%23%201.%20The%20Common%20Cause%20Model%20(Fork%20DAG)%0A%0A%20%20%20%20Consider%20Reichenbach's%20Common%20Cause%20Principle.%20In%20a%20directed%20acyclic%20graph%20(DAG)%2C%20when%20a%20latent%20or%20observed%20variable%20%24Z%24%20exerts%20a%20direct%20causal%20influence%20on%20both%20%24X%24%20and%20%24Y%24%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20X%20%5Cleftarrow%20Z%20%5Crightarrow%20Y%0A%20%20%20%20%24%24%0A%0A%20%20%20%20We%20can%20write%20the%20structural%20equations%20as%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20X%20%3D%20%5Calpha_X%20Z%20%2B%20%5Cepsilon_X%2C%20%5Cquad%20%5Cepsilon_X%20%5Csim%20%5Cmathcal%7BN%7D(0%2C%20%5Csigma_X%5E2)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20%24%24%0A%20%20%20%20Y%20%3D%20%5Calpha_Y%20Z%20%2B%20%5Cepsilon_Y%2C%20%5Cquad%20%5Cepsilon_Y%20%5Csim%20%5Cmathcal%7BN%7D(0%2C%20%5Csigma_Y%5E2)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20where%20the%20disturbance%20terms%20%24%5Cepsilon_X%24%20and%20%24%5Cepsilon_Y%24%20are%20mutually%20independent%20of%20each%20other%20and%20of%20%24Z%24.%0A%0A%20%20%20%20The%20covariance%20between%20%24X%24%20and%20%24Y%24%20expands%20to%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Coperatorname%7BCov%7D(X%2C%20Y)%20%3D%20%5Cmathbb%7BE%7D%5B(X%20-%20%5Cmu_X)(Y%20-%20%5Cmu_Y)%5D%20%3D%20%5Calpha_X%20%5Calpha_Y%20%5Coperatorname%7BVar%7D(Z)%20%2B%20%5Coperatorname%7BCov%7D(%5Cepsilon_X%2C%20%5Cepsilon_Y)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Because%20%24%5Coperatorname%7BCov%7D(%5Cepsilon_X%2C%20%5Cepsilon_Y)%20%3D%200%24%2C%20the%20entire%20covariance%20is%20driven%20exclusively%20by%20the%20variance%20of%20%24Z%24%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Coperatorname%7BCov%7D(X%2C%20Y)%20%3D%20%5Calpha_X%20%5Calpha_Y%20%5Coperatorname%7BVar%7D(Z)%20%5Cneq%200%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Thus%2C%20the%20sample%20correlation%20%24r_%7BXY%7D%24%20can%20be%20arbitrarily%20close%20to%20%24%2B1%24%20or%20%24-1%24%2C%20despite%20there%20being%20zero%20direct%20causal%20transmission%20from%20%24X%24%20to%20%24Y%24.%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%202.%20First-Order%20Partial%20Correlation%0A%0A%20%20%20%20The%20partial%20correlation%20between%20%24X%24%20and%20%24Y%24%20controlling%20for%20a%20single%20confounder%20%24Z%24%2C%20denoted%20%24r_%7BXY%20%5Ccdot%20Z%7D%24%2C%20is%20defined%20algebraically%20in%20terms%20of%20bivariate%20Pearson%20correlations%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20r_%7BXY%20%5Ccdot%20Z%7D%20%3D%20%5Cfrac%7Br_%7BXY%7D%20-%20r_%7BXZ%7D%20r_%7BYZ%7D%7D%7B%5Csqrt%7B(1%20-%20r_%7BXZ%7D%5E2)(1%20-%20r_%7BYZ%7D%5E2)%7D%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20%23%23%23%23%20Orthogonal%20Residual%20Formulation%20(Frisch-Waugh-Lovell%20Theorem)%0A%20%20%20%20Equivalently%2C%20partial%20correlation%20is%20the%20Pearson%20correlation%20between%20the%20residuals%20of%20%24X%24%20and%20%24Y%24%20after%20linearly%20regressing%20each%20onto%20%24Z%24%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Chat%7BX%7D%20%3D%20%5Chat%7B%5Cbeta%7D_%7BXZ%7D%20Z%2C%20%5Cquad%20%5Ctilde%7BX%7D%20%3D%20X%20-%20%5Chat%7BX%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Chat%7BY%7D%20%3D%20%5Chat%7B%5Cbeta%7D_%7BYZ%7D%20Z%2C%20%5Cquad%20%5Ctilde%7BY%7D%20%3D%20Y%20-%20%5Chat%7BY%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20%24%24%0A%20%20%20%20r_%7BXY%20%5Ccdot%20Z%7D%20%3D%20%5Coperatorname%7Bcorr%7D(%5Ctilde%7BX%7D%2C%20%5Ctilde%7BY%7D)%20%3D%20%5Cfrac%7B%5Ctilde%7BX%7D%5E%5Ctop%20%5Ctilde%7BY%7D%7D%7B%5C%7C%5Ctilde%7BX%7D%5C%7C_2%20%5C%7C%5Ctilde%7BY%7D%5C%7C_2%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Geometrically%2C%20%24%5Ctilde%7BX%7D%24%20and%20%24%5Ctilde%7BY%7D%24%20are%20the%20projections%20of%20vectors%20%24X%24%20and%20%24Y%24%20onto%20the%20orthogonal%20complement%20of%20the%20subspace%20spanned%20by%20%24Z%24.%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%203.%20Multivariate%20Partial%20Correlation%20via%20the%20Precision%20Matrix%0A%0A%20%20%20%20For%20a%20random%20vector%20%24%5Cmathbf%7BX%7D%20%3D%20%5BX_1%2C%20X_2%2C%20%5Cdots%2C%20X_p%5D%5E%5Ctop%20%5Csim%20%5Cmathcal%7BN%7D(%5Cboldsymbol%7B%5Cmu%7D%2C%20%5Cboldsymbol%7B%5CSigma%7D)%24%2C%20the%20partial%20correlation%20between%20any%20two%20variables%20%24X_i%24%20and%20%24X_j%24%20controlling%20for%20all%20remaining%20%24p%20-%202%24%20variables%20%24%5Cmathbf%7BX%7D_%7B%5Csetminus%20%5C%7Bi%2C%20j%5C%7D%7D%24%20is%20computed%20from%20the%20**precision%20matrix**%20(inverse%20covariance%20matrix)%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cboldsymbol%7B%5CTheta%7D%20%3D%20%5Cboldsymbol%7B%5CSigma%7D%5E%7B-1%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20%24%24%0A%20%20%20%20r_%7Bij%20%5Ccdot%20%5Ctext%7Brest%7D%7D%20%3D%20-%5Cfrac%7B%5Ctheta_%7Bij%7D%7D%7B%5Csqrt%7B%5Ctheta_%7Bii%7D%20%5Ctheta_%7Bjj%7D%7D%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20In%20Gaussian%20Graphical%20Models%20(GGMs)%2C%20a%20zero%20entry%20%24%5Ctheta_%7Bij%7D%20%3D%200%24%20corresponds%20to%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20r_%7Bij%20%5Ccdot%20%5Ctext%7Brest%7D%7D%20%3D%200%20%5Ciff%20X_i%20%5Cperp%20X_j%20%5Cmid%20%5Cmathbf%7BX%7D_%7B%5Csetminus%20%5C%7Bi%2C%20j%5C%7D%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20This%20establishes%20the%20direct%20edge%20structure%20in%20Markov%20Random%20Fields%20and%20sparse%20graphical%20Lasso%20algorithms.%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%204.%20Hypothesis%20Testing%20and%20Fisher's%20Z-Transformation%0A%0A%20%20%20%20Under%20the%20null%20hypothesis%20%24H_0%3A%20%5Crho_%7BXY%20%5Ccdot%20%5Cmathbf%7BZ%7D%7D%20%3D%200%24%2C%20the%20sample%20partial%20correlation%20test%20statistic%20follows%20a%20Student's%20%24t%24-distribution%20with%20%24n%20-%20k%20-%202%24%20degrees%20of%20freedom%2C%20where%20%24k%24%20is%20the%20number%20of%20conditioned%20variables%20(%24k%20%3D%201%24%20for%20single%20variable%20%24Z%24)%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20t%20%3D%20r_%7BXY%20%5Ccdot%20Z%7D%20%5Csqrt%7B%5Cfrac%7Bn%20-%20k%20-%202%7D%7B1%20-%20r_%7BXY%20%5Ccdot%20Z%7D%5E2%7D%7D%20%5Csim%20t(n%20-%20k%20-%202)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Alternatively%2C%20Fisher's%20hyperbolic%20arctangent%20transformation%20yields%20an%20asymptotic%20standard%20normal%20variable%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20z%20%3D%20%5Coperatorname%7Barctanh%7D(r_%7BXY%20%5Ccdot%20Z%7D)%20%3D%20%5Cfrac%7B1%7D%7B2%7D%20%5Cln%20%5Cleft(%5Cfrac%7B1%20%2B%20r_%7BXY%20%5Ccdot%20Z%7D%7D%7B1%20-%20r_%7BXY%20%5Ccdot%20Z%7D%7D%5Cright)%20%5Csim%20%5Cmathcal%7BN%7D%5Cleft(0%2C%20%5Cfrac%7B1%7D%7Bn%20-%20k%20-%203%7D%5Cright)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%205.%20Simpson's%20Paradox%0A%0A%20%20%20%20Simpson's%20paradox%20arises%20when%20a%20marginal%20trend%20across%20pooled%20data%20reverses%20when%20conditioning%20on%20a%20discrete%20stratifying%20confounder%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cfrac%7B%5Cpartial%20%5Cmathbb%7BE%7D%5BY%20%5Cmid%20X%5D%7D%7B%5Cpartial%20X%7D%20%3E%200%20%5Cquad%20%5Ctext%7Bwhile%7D%20%5Cquad%20%5Cfrac%7B%5Cpartial%20%5Cmathbb%7BE%7D%5BY%20%5Cmid%20X%2C%20Z%20%3D%20z%5D%7D%7B%5Cpartial%20X%7D%20%3C%200%20%5Cquad%20%5Cforall%20z%0A%20%20%20%20%24%24%0A%0A%20%20%20%20This%20occurs%20when%20the%20distribution%20of%20the%20confounder%20%24Z%24%20differs%20substantially%20across%20values%20of%20%24X%24.%20Conditioning%20on%20%24Z%24%20blocks%20the%20backdoor%20path%20%24X%20%5Cleftarrow%20Z%20%5Crightarrow%20Y%24%2C%20isolating%20the%20true%20causal%20effect.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(np%2C%20pd)%3A%0A%20%20%20%20%23%20Data%20Generation%20Cell%3A%20Reproducible%20Confounding%20Experiment%0A%20%20%20%20np.random.seed(42)%0A%20%20%20%20_n%20%3D%2050%0A%0A%20%20%20%20%23%20Latent%20Confounder%20Z%20(e.g.%20Firm%20Scale%20%2F%20User%20Activity%20Index)%0A%20%20%20%20z_latent%20%3D%20np.random.normal(loc%3D10.0%2C%20scale%3D2.5%2C%20size%3D_n)%0A%0A%20%20%20%20%23%20Observed%20Predictor%20X%20and%20Outcome%20Y%20generated%20from%20common%20cause%20Z%20%2B%20independent%20noise%0A%20%20%20%20x_obs%20%3D%2010.0%20*%20z_latent%20%2B%20np.random.normal(loc%3D0.0%2C%20scale%3D8.0%2C%20size%3D_n)%0A%20%20%20%20y_obs%20%3D%2020.0%20*%20z_latent%20%2B%20np.random.normal(loc%3D1.0%2C%20scale%3D8.0%2C%20size%3D_n)%0A%0A%20%20%20%20df_confounded%20%3D%20pd.DataFrame(%7B%22X%22%3A%20np.round(x_obs%2C%202)%2C%20%22Y%22%3A%20np.round(y_obs%2C%202)%2C%20%22Z%22%3A%20np.round(z_latent%2C%202)%7D)%0A%0A%20%20%20%20%23%20Simpson's%20Paradox%20Dataset%20(3%20Demographic%20Cohorts)%0A%20%20%20%20np.random.seed(101)%0A%20%20%20%20_n_group%20%3D%2030%0A%20%20%20%20_groups%20%3D%20%5B%22Group%20A%20(Mild)%22%2C%20%22Group%20B%20(Moderate)%22%2C%20%22Group%20C%20(Severe)%22%5D%0A%20%20%20%20_simpson_records%20%3D%20%5B%5D%0A%0A%20%20%20%20for%20_idx%2C%20_grp%20in%20enumerate(_groups)%3A%0A%20%20%20%20%20%20%20%20_dose_shift%20%3D%20_idx%20*%204.0%0A%20%20%20%20%20%20%20%20_base_health%20%3D%2080.0%20-%20_idx%20*%2025.0%0A%20%20%20%20%20%20%20%20_dosage%20%3D%20np.random.uniform(2.0%2C%208.0%2C%20_n_group)%20%2B%20_dose_shift%0A%20%20%20%20%20%20%20%20%23%20True%20within-group%20causal%20effect%20is%20negative%20(-2.5%20health%20drop%20per%20dose)%0A%20%20%20%20%20%20%20%20_recovery%20%3D%20_base_health%20-%202.5%20*%20_dosage%20%2B%20np.random.normal(0.0%2C%203.0%2C%20_n_group)%0A%20%20%20%20%20%20%20%20for%20_d%2C%20_r%20in%20zip(_dosage%2C%20_recovery)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_simpson_records.append(%7B%22Group%22%3A%20_grp%2C%20%22Dosage%22%3A%20np.round(_d%2C%202)%2C%20%22RecoveryScore%22%3A%20np.round(_r%2C%202)%7D)%0A%0A%20%20%20%20df_simpson%20%3D%20pd.DataFrame(_simpson_records)%0A%20%20%20%20return%20df_confounded%2C%20df_simpson%0A%0A%0A%40app.cell%0Adef%20_(df_confounded%2C%20df_simpson%2C%20go%2C%20make_subplots%2C%20np%2C%20stats)%3A%0A%20%20%20%20%23%20Interactive%20Visualizations%20Cell%3A%0A%20%20%20%20%23%20Subplot%201%3A%20Raw%20Confounded%20Scatter%20(X%20vs%20Y%20color-coded%20by%20continuous%20Z)%0A%20%20%20%20%23%20Subplot%202%3A%20Deconfounded%20Residual%20Scatter%20(Residual%20X%20vs%20Residual%20Y)%0A%20%20%20%20%23%20Subplot%203%3A%20Simpson's%20Paradox%20(Aggregate%20positive%20vs%20Group-level%20negative%20trendlines)%0A%0A%20%20%20%20_fig%20%3D%20make_subplots(%0A%20%20%20%20%20%20%20%20rows%3D1%2C%0A%20%20%20%20%20%20%20%20cols%3D3%2C%0A%20%20%20%20%20%20%20%20subplot_titles%3D(%0A%20%20%20%20%20%20%20%20%20%20%20%20%221.%20Raw%20Confounded%20Scatter%20(Color%20%3D%20Z)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%222.%20Deconfounded%20Residuals%20(Z%20Removed)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%223.%20Simpson's%20Paradox%3A%20Aggregate%20vs%20Groups%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20horizontal_spacing%3D0.08%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_x%20%3D%20df_confounded%5B%22X%22%5D.to_numpy()%0A%20%20%20%20_y%20%3D%20df_confounded%5B%22Y%22%5D.to_numpy()%0A%20%20%20%20_z%20%3D%20df_confounded%5B%22Z%22%5D.to_numpy()%0A%0A%20%20%20%20%23%20Subplot%201%3A%20Confounded%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_x%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_y%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22markers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20size%3D9%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%3D_z%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20colorscale%3D%22Viridis%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20colorbar%3Ddict(title%3D%22Confounder%20Z%22%2C%20x%3D0.28%2C%20len%3D0.7)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showscale%3DTrue%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(width%3D1%2C%20color%3D%22%23333333%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Confounded%20Obs%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20hovertemplate%3D%22X%3A%20%25%7Bx%3A.1f%7D%3Cbr%3EY%3A%20%25%7By%3A.1f%7D%3Cbr%3EZ%3A%20%25%7Bmarker.color%3A.1f%7D%3Cextra%3E%3C%2Fextra%3E%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20col%3D1%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_slope_raw%2C%20_inter_raw%2C%20_%2C%20_%2C%20_%20%3D%20stats.linregress(_x%2C%20_y)%0A%20%20%20%20_line_x%20%3D%20np.linspace(_x.min()%2C%20_x.max()%2C%2050)%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_line_x%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_slope_raw%20*%20_line_x%20%2B%20_inter_raw%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D%22%23ef4444%22%2C%20width%3D2.5%2C%20dash%3D%22solid%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Raw%20Fit%20(Spurious)%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20col%3D1%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Subplot%202%3A%20Residuals%0A%20%20%20%20_slope_xz%2C%20_inter_xz%2C%20_%2C%20_%2C%20_%20%3D%20stats.linregress(_z%2C%20_x)%0A%20%20%20%20_slope_yz%2C%20_inter_yz%2C%20_%2C%20_%2C%20_%20%3D%20stats.linregress(_z%2C%20_y)%0A%20%20%20%20_res_x%20%3D%20_x%20-%20(_slope_xz%20*%20_z%20%2B%20_inter_xz)%0A%20%20%20%20_res_y%20%3D%20_y%20-%20(_slope_yz%20*%20_z%20%2B%20_inter_yz)%0A%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_res_x%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_res_y%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22markers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D9%2C%20color%3D%22%236366f1%22%2C%20line%3Ddict(width%3D1%2C%20color%3D%22%23312e81%22))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Orthogonal%20Residuals%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20hovertemplate%3D%22Res%20X%3A%20%25%7Bx%3A.2f%7D%3Cbr%3ERes%20Y%3A%20%25%7By%3A.2f%7D%3Cextra%3E%3C%2Fextra%3E%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20col%3D2%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_slope_res%2C%20_inter_res%2C%20_%2C%20_%2C%20_%20%3D%20stats.linregress(_res_x%2C%20_res_y)%0A%20%20%20%20_line_rx%20%3D%20np.linspace(_res_x.min()%2C%20_res_x.max()%2C%2050)%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_line_rx%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_slope_res%20*%20_line_rx%20%2B%20_inter_res%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D%22%2310b981%22%2C%20width%3D2.5%2C%20dash%3D%22dash%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Residual%20Fit%20(Near%200)%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20col%3D2%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Subplot%203%3A%20Simpson's%20Paradox%0A%20%20%20%20_group_colors%20%3D%20%7B%22Group%20A%20(Mild)%22%3A%20%22%233b82f6%22%2C%20%22Group%20B%20(Moderate)%22%3A%20%22%2310b981%22%2C%20%22Group%20C%20(Severe)%22%3A%20%22%23f59e0b%22%7D%0A%20%20%20%20for%20_grp%2C%20_col%20in%20_group_colors.items()%3A%0A%20%20%20%20%20%20%20%20_sub%20%3D%20df_simpson%5Bdf_simpson%5B%22Group%22%5D%20%3D%3D%20_grp%5D%0A%20%20%20%20%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3D_sub%5B%22Dosage%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20y%3D_sub%5B%22RecoveryScore%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22markers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D8%2C%20color%3D_col)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%3D_grp%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hovertemplate%3D%22Dosage%3A%20%25%7Bx%3A.1f%7D%3Cbr%3ERecovery%3A%20%25%7By%3A.1f%7D%3Cextra%3E%3C%2Fextra%3E%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20col%3D3%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20_sl%2C%20_it%2C%20_%2C%20_%2C%20_%20%3D%20stats.linregress(_sub%5B%22Dosage%22%5D%2C%20_sub%5B%22RecoveryScore%22%5D)%0A%20%20%20%20%20%20%20%20_lx%20%3D%20np.linspace(_sub%5B%22Dosage%22%5D.min()%2C%20_sub%5B%22Dosage%22%5D.max()%2C%2030)%0A%20%20%20%20%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3D_lx%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20y%3D_sl%20*%20_lx%20%2B%20_it%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D_col%2C%20width%3D2)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20showlegend%3DFalse%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20col%3D3%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%23%20Aggregate%20fit%20for%20Simpson's%20Paradox%0A%20%20%20%20_sl_agg%2C%20_it_agg%2C%20_%2C%20_%2C%20_%20%3D%20stats.linregress(df_simpson%5B%22Dosage%22%5D%2C%20df_simpson%5B%22RecoveryScore%22%5D)%0A%20%20%20%20_lx_agg%20%3D%20np.linspace(df_simpson%5B%22Dosage%22%5D.min()%2C%20df_simpson%5B%22Dosage%22%5D.max()%2C%2050)%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_lx_agg%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_sl_agg%20*%20_lx_agg%20%2B%20_it_agg%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D%22%23dc2626%22%2C%20width%3D3%2C%20dash%3D%22dash%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Aggregate%20Paradox%20Fit%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20col%3D3%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_fig.update_layout(%0A%20%20%20%20%20%20%20%20template%3D%22plotly_white%22%2C%0A%20%20%20%20%20%20%20%20height%3D480%2C%0A%20%20%20%20%20%20%20%20title%3Ddict(%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3D%22Spurious%20Association%2C%20Confounding%20Removal%2C%20and%20Simpson's%20Paradox%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D0.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20xanchor%3D%22center%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20font%3Ddict(size%3D16%2C%20family%3D%22Inter%2C%20system-ui%2C%20sans-serif%22)%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20legend%3Ddict(orientation%3D%22h%22%2C%20yanchor%3D%22bottom%22%2C%20y%3D-0.25%2C%20xanchor%3D%22center%22%2C%20x%3D0.5)%2C%0A%20%20%20%20%20%20%20%20margin%3Ddict(l%3D40%2C%20r%3D40%2C%20t%3D70%2C%20b%3D80)%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_fig.update_xaxes(title_text%3D%22Observed%20X%22%2C%20row%3D1%2C%20col%3D1)%0A%20%20%20%20_fig.update_yaxes(title_text%3D%22Observed%20Y%22%2C%20row%3D1%2C%20col%3D1)%0A%0A%20%20%20%20_fig.update_xaxes(title_text%3D%22Residual%20X%20(e_X%7CZ)%22%2C%20row%3D1%2C%20col%3D2)%0A%20%20%20%20_fig.update_yaxes(title_text%3D%22Residual%20Y%20(e_Y%7CZ)%22%2C%20row%3D1%2C%20col%3D2)%0A%0A%20%20%20%20_fig.update_xaxes(title_text%3D%22Dosage%20Level%22%2C%20row%3D1%2C%20col%3D3)%0A%20%20%20%20_fig.update_yaxes(title_text%3D%22Recovery%20Score%22%2C%20row%3D1%2C%20col%3D3)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%20%5Bd%5D%20Code%20Examples%0A%0A%20%20%20%20We%20demonstrate%20two%20complete%2C%20mathematically%20rigorous%20workflows%3A%0A%20%20%20%201.%20**Deconfounding%20via%20Three%20Equivalent%20Approaches**%3A%0A%20%20%20%20%20%20%20-%20Analytical%20partial%20correlation%20formula%0A%20%20%20%20%20%20%20-%20Frisch-Waugh-Lovell%20linear%20regression%20residual%20projection%0A%20%20%20%20%20%20%20-%20Precision%20matrix%20inversion%20(%24%5Cboldsymbol%7B%5CTheta%7D%20%3D%20%5Cboldsymbol%7B%5CSigma%7D%5E%7B-1%7D%24)%0A%20%20%20%202.%20**Hypothesis%20Testing%20and%20Confounder%20Diagnostic**%3A%0A%20%20%20%20%20%20%20-%20Evaluating%20raw%20correlation%20vs.%20partial%20correlation%0A%20%20%20%20%20%20%20-%20Degrees%20of%20freedom%20adjustment%2C%20%24t%24-statistics%2C%20and%20two-sided%20%24p%24-values%0A%20%20%20%20%20%20%20-%20Simpson's%20paradox%20quantification%20across%20segmented%20cohorts%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_confounded%2C%20np%2C%20pd%2C%20stats)%3A%0A%20%20%20%20%23%20Example%201%3A%20Three%20Distinct%20Mathematical%20Formulations%20of%20Partial%20Correlation%0A%20%20%20%20_x%20%3D%20df_confounded%5B%22X%22%5D.to_numpy()%0A%20%20%20%20_y%20%3D%20df_confounded%5B%22Y%22%5D.to_numpy()%0A%20%20%20%20_z%20%3D%20df_confounded%5B%22Z%22%5D.to_numpy()%0A%20%20%20%20_n%20%3D%20len(_x)%0A%0A%20%20%20%20%23%201.%20Bivariate%20Correlation%20Matrix%0A%20%20%20%20_r_xy%2C%20_p_xy%20%3D%20stats.pearsonr(_x%2C%20_y)%0A%20%20%20%20_r_xz%2C%20_%20%3D%20stats.pearsonr(_x%2C%20_z)%0A%20%20%20%20_r_yz%2C%20_%20%3D%20stats.pearsonr(_y%2C%20_z)%0A%0A%20%20%20%20%23%20Analytical%20Formula%0A%20%20%20%20_r_part_formula%20%3D%20(_r_xy%20-%20_r_xz%20*%20_r_yz)%20%2F%20np.sqrt((1.0%20-%20_r_xz**2)%20*%20(1.0%20-%20_r_yz**2))%0A%0A%20%20%20%20%23%202.%20Frisch-Waugh-Lovell%20Residual%20Regression%0A%20%20%20%20_beta_xz%2C%20_alpha_xz%2C%20_%2C%20_%2C%20_%20%3D%20stats.linregress(_z%2C%20_x)%0A%20%20%20%20_beta_yz%2C%20_alpha_yz%2C%20_%2C%20_%2C%20_%20%3D%20stats.linregress(_z%2C%20_y)%0A%20%20%20%20_res_x%20%3D%20_x%20-%20(_beta_xz%20*%20_z%20%2B%20_alpha_xz)%0A%20%20%20%20_res_y%20%3D%20_y%20-%20(_beta_yz%20*%20_z%20%2B%20_alpha_yz)%0A%20%20%20%20_r_part_fwl%2C%20_%20%3D%20stats.pearsonr(_res_x%2C%20_res_y)%0A%0A%20%20%20%20%23%203.%20Precision%20Matrix%20Inversion%0A%20%20%20%20_data_matrix%20%3D%20np.column_stack(%5B_x%2C%20_y%2C%20_z%5D)%0A%20%20%20%20_cov_matrix%20%3D%20np.cov(_data_matrix%2C%20rowvar%3DFalse)%0A%20%20%20%20_precision%20%3D%20np.linalg.inv(_cov_matrix)%0A%20%20%20%20_r_part_precision%20%3D%20-_precision%5B0%2C%201%5D%20%2F%20np.sqrt(_precision%5B0%2C%200%5D%20*%20_precision%5B1%2C%201%5D)%0A%0A%20%20%20%20%23%20Hypothesis%20Testing%20(t-statistic%20and%20p-value%20for%20k%3D1%20conditioned%20variable)%0A%20%20%20%20_k%20%3D%201%0A%20%20%20%20_df%20%3D%20_n%20-%20_k%20-%202%0A%20%20%20%20_t_stat%20%3D%20_r_part_formula%20*%20np.sqrt(_df%20%2F%20(1.0%20-%20_r_part_formula**2))%0A%20%20%20%20_p_val%20%3D%202.0%20*%20(1.0%20-%20stats.t.cdf(np.abs(_t_stat)%2C%20df%3D_df))%0A%0A%20%20%20%20_comparison_table%20%3D%20pd.DataFrame(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Method%20%2F%20Metric%22%3A%20%22Raw%20Pearson%20Correlation%20r(X%2C%20Y)%22%2C%20%22Estimated%20Value%22%3A%20f%22%7B_r_xy%3A.4f%7D%22%2C%20%22P-Value%22%3A%20f%22%7B_p_xy%3A.2e%7D%22%2C%20%22Interpretation%22%3A%20%22Spurious%20high%20correlation%20caused%20by%20Z%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Method%20%2F%20Metric%22%3A%20%22Analytical%20Formula%20r(XY.Z)%22%2C%20%22Estimated%20Value%22%3A%20f%22%7B_r_part_formula%3A.4f%7D%22%2C%20%22P-Value%22%3A%20f%22%7B_p_val%3A.4f%7D%22%2C%20%22Interpretation%22%3A%20%22True%20conditional%20association%20after%20removing%20Z%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Method%20%2F%20Metric%22%3A%20%22Frisch-Waugh-Lovell%20Residuals%22%2C%20%22Estimated%20Value%22%3A%20f%22%7B_r_part_fwl%3A.4f%7D%22%2C%20%22P-Value%22%3A%20f%22%7B_p_val%3A.4f%7D%22%2C%20%22Interpretation%22%3A%20%22Pearson%20correlation%20of%20orthogonal%20residuals%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Method%20%2F%20Metric%22%3A%20%22Precision%20Matrix%20(Theta_01)%22%2C%20%22Estimated%20Value%22%3A%20f%22%7B_r_part_precision%3A.4f%7D%22%2C%20%22P-Value%22%3A%20f%22%7B_p_val%3A.4f%7D%22%2C%20%22Interpretation%22%3A%20%22Normalized%20off-diagonal%20precision%20entry%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Method%20%2F%20Metric%22%3A%20%22Degrees%20of%20Freedom%20(n%20-%20k%20-%202)%22%2C%20%22Estimated%20Value%22%3A%20str(_df)%2C%20%22P-Value%22%3A%20%22-%22%2C%20%22Interpretation%22%3A%20%22Adjusted%20for%20conditioning%20on%201%20variable%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Method%20%2F%20Metric%22%3A%20%22Student's%20t-Statistic%22%2C%20%22Estimated%20Value%22%3A%20f%22%7B_t_stat%3A.4f%7D%22%2C%20%22P-Value%22%3A%20f%22%7B_p_val%3A.4f%7D%22%2C%20%22Interpretation%22%3A%20%22Fail%20to%20reject%20H0%3A%20true%20association%20is%20~%200%22%7D%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_simpson%2C%20pd%2C%20stats)%3A%0A%20%20%20%20%23%20Example%202%3A%20Simpson's%20Paradox%20Quantification%0A%20%20%20%20%23%20Demonstrate%20aggregate%20slope%20vs%20subgroup%20slopes%0A%20%20%20%20_groups%20%3D%20df_simpson%5B%22Group%22%5D.unique()%0A%20%20%20%20_simpson_metrics%20%3D%20%5B%5D%0A%0A%20%20%20%20%23%20Aggregate%20metric%0A%20%20%20%20_agg_slope%2C%20_%2C%20_agg_r%2C%20_agg_p%2C%20_%20%3D%20stats.linregress(df_simpson%5B%22Dosage%22%5D%2C%20df_simpson%5B%22RecoveryScore%22%5D)%0A%20%20%20%20_simpson_metrics.append(%7B%0A%20%20%20%20%20%20%20%20%22Stratum%22%3A%20%22Pooled%20Sample%20(Aggregate)%22%2C%0A%20%20%20%20%20%20%20%20%22Sample%20Size%20(n)%22%3A%20len(df_simpson)%2C%0A%20%20%20%20%20%20%20%20%22Slope%20(Beta)%22%3A%20f%22%7B_agg_slope%3A%2B.3f%7D%22%2C%0A%20%20%20%20%20%20%20%20%22Pearson%20r%22%3A%20f%22%7B_agg_r%3A%2B.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%22p-Value%22%3A%20f%22%7B_agg_p%3A.2e%7D%22%2C%0A%20%20%20%20%20%20%20%20%22Diagnosis%22%3A%20%22Misleading%20Positive%20Trend%20(Confounded)%22%2C%0A%20%20%20%20%7D)%0A%0A%20%20%20%20%23%20Within%20each%20subgroup%0A%20%20%20%20for%20_grp%20in%20_groups%3A%0A%20%20%20%20%20%20%20%20_sub%20%3D%20df_simpson%5Bdf_simpson%5B%22Group%22%5D%20%3D%3D%20_grp%5D%0A%20%20%20%20%20%20%20%20_sl%2C%20_%2C%20_r%2C%20_p%2C%20_%20%3D%20stats.linregress(_sub%5B%22Dosage%22%5D%2C%20_sub%5B%22RecoveryScore%22%5D)%0A%20%20%20%20%20%20%20%20_simpson_metrics.append(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Stratum%22%3A%20_grp%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Sample%20Size%20(n)%22%3A%20len(_sub)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Slope%20(Beta)%22%3A%20f%22%7B_sl%3A%2B.3f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Pearson%20r%22%3A%20f%22%7B_r%3A%2B.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22p-Value%22%3A%20f%22%7B_p%3A.2e%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Diagnosis%22%3A%20%22True%20Causal%20Negative%20Slope%22%2C%0A%20%20%20%20%20%20%20%20%7D)%0A%0A%20%20%20%20_df_simpson_summary%20%3D%20pd.DataFrame(_simpson_metrics)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
45fa22cfb8de3f455dc65679386dced2