import%20marimo%0A%0A__generated_with%20%3D%20%220.24.0%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%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.stats%20import%20chi2_contingency%0A%0A%20%20%20%20return%20chi2_contingency%2C%20go%2C%20make_subplots%2C%20mo%2C%20np%2C%20pd%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%2018%3A%20Cram%C3%A9r's%20V%2C%20Chi-Square%20Independence%20Tests%2C%20and%20Nominal%20Association%0A%0A%20%20%20%20%26larr%3B%20Previous%20Note%3A%20%5B17%20Jensen%20Inequality%5D(17_jensen_inequality.py)%20%7C%20Next%20Note%3A%20%5B19%20Kendall%20Tau-b%5D(19_kendalltaub.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%20In%20tabular%20data%20science%2C%20machine%20learning%2C%20and%20survey%20analytics%2C%20features%20are%20frequently%20nominal%20categorical%20variables%20with%20no%20inherent%20mathematical%20ordering%20(e.g.%20Job%20Role%2C%20Country%20of%20Origin%2C%20Operating%20System%2C%20Device%20Brand%2C%20Preferred%20Programming%20Language).%20For%20such%20variables%2C%20numerical%20correlation%20metrics%20like%20Pearson's%20%24r%24%20or%20Spearman's%20%24%5Crho%24%20cannot%20be%20computed.%0A%0A%20%20%20%20Understanding%20the%20**Pearson%20Chi-Square%20test%20of%20independence**%20and%20**Cram%C3%A9r's%20V**%20is%20essential%3A%0A%20%20%20%201.%20**Effect%20Size%20Beyond%20p-Values**%3A%20While%20the%20Chi-Square%20test%20produces%20a%20%24p%24-value%20indicating%20whether%20an%20association%20exists%2C%20the%20test%20statistic%20%24%5Cchi%5E2%24%20scales%20linearly%20with%20sample%20size%20%24n%24.%20In%20large%20datasets%20(%24n%20%5Cgeq%20100%2C000%24)%2C%20virtually%20any%20two%20variables%20achieve%20statistical%20significance%20(%24p%20%3C%2010%5E%7B-50%7D%24)%2C%20even%20when%20the%20practical%20relationship%20is%20utterly%20trivial.%20**Cram%C3%A9r's%20V**%20normalizes%20%24%5Cchi%5E2%24%20by%20sample%20size%20and%20table%20dimensions%2C%20yielding%20an%20interpretable%20effect%20size%20bounded%20in%20%24%5B0%2C%201%5D%24.%0A%20%20%20%202.%20**Categorical%20Feature%20Selection%20and%20Multicollinearity**%3A%20When%20preparing%20datasets%20for%20gradient%20boosting%20algorithms%20(CatBoost%2C%20LightGBM%2C%20XGBoost)%2C%20pairwise%20Cram%C3%A9r's%20V%20matrices%20function%20as%20the%20categorical%20analogue%20of%20the%20Pearson%20correlation%20matrix%2C%20diagnosing%20redundant%20features%20and%20preventing%20multicollinearity%20among%20categorical%20variables.%0A%20%20%20%203.%20**Hypothesis%20Testing%20on%20Contingency%20Tables**%3A%20In%20clinical%20trials%20and%20marketing%20A%2FB%20tests%2C%20contingency%20tables%20compare%20conversion%20rates%2C%20adverse%20reactions%2C%20and%20user%20preferences%20across%20demographic%20segments.%0A%20%20%20%204.%20**Finite-Sample%20Bias%20Correction%20(Bergsma)**%3A%20Standard%20Cram%C3%A9r's%20V%20suffers%20from%20a%20positive%20upward%20bias%20in%20small%20samples.%20Bergsma's%20bias-corrected%20Cram%C3%A9r's%20%24%5Ctilde%7BV%7D%24%20subtracts%20the%20degrees%20of%20freedom%20expectation%2C%20preventing%20false%20alarms%20in%20sparse%20tables.%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%20Contingency%20Tables%20and%20Expected%20Frequencies%0A%0A%20%20%20%20Consider%20two%20nominal%20categorical%20variables%3A%20%24X%24%20with%20%24r%24%20distinct%20categories%20and%20%24Y%24%20with%20%24c%24%20distinct%20categories.%20A%20cross-tabulation%20of%20%24n%24%20observations%20produces%20an%20%24r%20%5Ctimes%20c%24%20**contingency%20table**%20with%20observed%20cell%20counts%20%24O_%7Bij%7D%24.%0A%0A%20%20%20%20The%20row%20totals%20%24R_i%24%20and%20column%20totals%20%24C_j%24%20are%20defined%20as%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20R_i%20%3D%20%5Csum_%7Bj%3D1%7D%5Ec%20O_%7Bij%7D%2C%20%5Cquad%20C_j%20%3D%20%5Csum_%7Bi%3D1%7D%5Er%20O_%7Bij%7D%2C%20%5Cquad%20n%20%3D%20%5Csum_%7Bi%3D1%7D%5Er%20%5Csum_%7Bj%3D1%7D%5Ec%20O_%7Bij%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Under%20the%20null%20hypothesis%20%24H_0%24%20of%20statistical%20independence%20(%24P(X%20%3D%20i%2C%20Y%20%3D%20j)%20%3D%20P(X%20%3D%20i)%20P(Y%20%3D%20j)%24)%2C%20the%20expected%20frequency%20in%20cell%20%24(i%2C%20j)%24%20is%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20E_%7Bij%7D%20%3D%20n%20%5Cleft(%5Cfrac%7BR_i%7D%7Bn%7D%5Cright)%20%5Cleft(%5Cfrac%7BC_j%7D%7Bn%7D%5Cright)%20%3D%20%5Cfrac%7BR_i%20C_j%7D%7Bn%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%20Pearson's%20Chi-Square%20Test%20Statistic%20(%24%5Cchi%5E2%24)%0A%0A%20%20%20%20The%20Chi-Square%20test%20statistic%20measures%20the%20aggregated%20squared%20discrepancy%20between%20observed%20frequencies%20%24O_%7Bij%7D%24%20and%20expected%20frequencies%20%24E_%7Bij%7D%24%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cchi%5E2%20%3D%20%5Csum_%7Bi%3D1%7D%5Er%20%5Csum_%7Bj%3D1%7D%5Ec%20%5Cfrac%7B(O_%7Bij%7D%20-%20E_%7Bij%7D)%5E2%7D%7BE_%7Bij%7D%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Under%20%24H_0%24%20and%20with%20adequate%20sample%20size%20per%20cell%20(Cochran's%20rule%3A%20%24E_%7Bij%7D%20%5Cgeq%205%24%20in%20at%20least%20%2480%5C%25%24%20of%20cells)%2C%20%24%5Cchi%5E2%24%20asymptotically%20follows%20a%20Chi-Square%20distribution%20with%20degrees%20of%20freedom%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20df%20%3D%20(r%20-%201)(c%20-%201)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%20Definition%20of%20Cram%C3%A9r's%20V%0A%0A%20%20%20%20Because%20%24%5Cchi%5E2%20%5Cpropto%20n%24%2C%20the%20raw%20test%20statistic%20cannot%20be%20used%20as%20an%20association%20metric.%20Harald%20Cram%C3%A9r%20introduced%20**Cram%C3%A9r's%20V**%20to%20normalize%20the%20statistic%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20V%20%3D%20%5Csqrt%7B%5Cfrac%7B%5Cchi%5E2%7D%7Bn%20%5Ccdot%20%5Cmin(r%20-%201%2C%20c%20-%201)%7D%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20where%3A%0A%20%20%20%20*%20%24%5Cchi%5E2%24%20is%20Pearson's%20Chi-Square%20statistic.%0A%20%20%20%20*%20%24n%24%20is%20total%20sample%20count.%0A%20%20%20%20*%20%24r%24%20is%20number%20of%20rows%20(categories%20of%20%24X%24).%0A%20%20%20%20*%20%24c%24%20is%20number%20of%20columns%20(categories%20of%20%24Y%24).%0A%0A%20%20%20%20%23%23%23%23%20Properties%20and%20Boundedness%0A%20%20%20%20*%20**Range**%3A%20%240%20%5Cleq%20V%20%5Cleq%201%24.%0A%20%20%20%20*%20**Special%20Case%20(%242%20%5Ctimes%202%24%20table)**%3A%20For%20%24r%20%3D%20c%20%3D%202%24%2C%20%24%5Cmin(r%20-%201%2C%20c%20-%201)%20%3D%201%24%2C%20and%20Cram%C3%A9r's%20V%20reduces%20exactly%20to%20the%20absolute%20value%20of%20the%20**phi%20coefficient**%20%24%7C%5Cphi%7C%20%3D%20%5Csqrt%7B%5Cchi%5E2%20%2F%20n%7D%24.%0A%20%20%20%20*%20**%24V%20%3D%200%24**%3A%20Complete%20statistical%20independence%20(%24O_%7Bij%7D%20%3D%20E_%7Bij%7D%24%20for%20all%20cells).%0A%20%20%20%20*%20**%24V%20%3D%201%24**%3A%20Perfect%20deterministic%20association.%20Knowing%20category%20%24X%24%20completely%20predicts%20%24Y%24%20(or%20vice%20versa).%0A%0A%20%20%20%20%23%23%23%23%20Standard%20Effect%20Size%20Interpretation%20(Rea%20%26%20Parker%20%2F%20Cohen)%0A%20%20%20%20*%20%240.00%20%5Cleq%20V%20%3C%200.10%24%3A%20Negligible%20association.%0A%20%20%20%20*%20%240.10%20%5Cleq%20V%20%3C%200.20%24%3A%20Weak%20association.%0A%20%20%20%20*%20%240.20%20%5Cleq%20V%20%3C%200.40%24%3A%20Moderate%20association.%0A%20%20%20%20*%20%240.40%20%5Cleq%20V%20%3C%200.60%24%3A%20Strong%20association.%0A%20%20%20%20*%20%24V%20%5Cgeq%200.60%24%3A%20Very%20strong%20association.%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%20Bergsma's%20Bias-Corrected%20Cram%C3%A9r's%20V%0A%0A%20%20%20%20Standard%20Cram%C3%A9r's%20V%20tends%20to%20overestimate%20association%20when%20sample%20size%20%24n%24%20is%20small%20or%20table%20dimensions%20%24r%2C%20c%24%20are%20large.%20Bergsma%20(2013)%20proposed%20an%20unbiased%20correction%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Ctilde%7B%5Cchi%7D%5E2%20%3D%20%5Cmax%5Cleft(0%2C%20%5Cchi%5E2%20-%20%5Cfrac%7B(r%20-%201)(c%20-%201)%7D%7Bn%20-%201%7D%5Cright)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Ctilde%7Bn%7D%20%3D%20n%20-%20%5Cfrac%7B(r%20-%201)(c%20-%201)%7D%7Bn%20-%201%7D%2C%20%5Cquad%20%5Ctilde%7Br%7D%20%3D%20r%20-%20%5Cfrac%7B(r%20-%201)%5E2%7D%7Bn%20-%201%7D%2C%20%5Cquad%20%5Ctilde%7Bc%7D%20%3D%20c%20-%20%5Cfrac%7B(c%20-%201)%5E2%7D%7Bn%20-%201%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20The%20**bias-corrected%20Cram%C3%A9r's%20V**%20is%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Ctilde%7BV%7D%20%3D%20%5Csqrt%7B%5Cfrac%7B%5Ctilde%7B%5Cchi%7D%5E2%20%2F%20%5Ctilde%7Bn%7D%7D%7B%5Cmin(%5Ctilde%7Br%7D%20-%201%2C%20%5Ctilde%7Bc%7D%20-%201)%7D%7D%0A%20%20%20%20%24%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%5Bc%5D%20Interactive%20Visualizations%3A%20Contingency%20Heatmaps%20and%20Categorical%20Association%20Matrix%0A%0A%20%20%20%20The%20interactive%20subplots%20below%20display%20the%20practical%20application%20of%20Cram%C3%A9r's%20V%3A%0A%20%20%20%20*%20**Left%20Panel**%3A%20%243%20%5Ctimes%203%24%20contingency%20table%20of%20job%20roles%20versus%20preferred%20movie%20genres%20(%24N%20%3D%20225%24%20respondents).%20Cell%20annotations%20show%20observed%20counts.%20Data%20Scientists%20show%20strong%20preference%20for%20Action%20(%2450%24)%2C%20ML%20Engineers%20for%20Drama%20(%2450%24)%2C%20and%20GenAI%20Developers%20for%20Comedy%20(%2450%24)%2C%20producing%20a%20strong%20association%20(%24V%20%5Capprox%200.54%2C%20p%20%3C%2010%5E%7B-26%7D%24).%0A%20%20%20%20*%20**Right%20Panel**%3A%20Pairwise%20Categorical%20Association%20Matrix%20(Cram%C3%A9r's%20V)%20across%20four%20categorical%20features%3A%20Role%2C%20Preferred%20Genre%2C%20Primary%20Cloud%2C%20and%20Primary%20Language.%20This%20matrix%20allows%20data%20scientists%20to%20inspect%20categorical%20collinearity%20identically%20to%20numerical%20correlation%20matrices.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(go%2C%20make_subplots%2C%20np)%3A%0A%20%20%20%20%23%20Left%20Panel%3A%20Role%20vs%20Genre%20Contingency%20Table%0A%20%20%20%20roles_list%20%3D%20%5B%22Data%20Scientist%22%2C%20%22ML%20Engineer%22%2C%20%22GenAI%20Dev%22%5D%0A%20%20%20%20genres_list%20%3D%20%5B%22Action%22%2C%20%22Comedy%22%2C%20%22Drama%22%5D%0A%0A%20%20%20%20contingency_counts%20%3D%20np.array(%5B%0A%20%20%20%20%20%20%20%20%5B50%2C%2020%2C%205%5D%2C%0A%20%20%20%20%20%20%20%20%5B5%2C%2020%2C%2050%5D%2C%0A%20%20%20%20%20%20%20%20%5B5%2C%2050%2C%2020%5D%2C%0A%20%20%20%20%5D)%0A%0A%20%20%20%20%23%20Right%20Panel%3A%204x4%20Categorical%20Association%20Matrix%20(Cramer's%20V)%0A%20%20%20%20cat_features%20%3D%20%5B%22Job%20Role%22%2C%20%22Movie%20Genre%22%2C%20%22Primary%20Cloud%22%2C%20%22Primary%20Lang%22%5D%0A%20%20%20%20cramers_matrix%20%3D%20np.array(%5B%0A%20%20%20%20%20%20%20%20%5B1.00%2C%200.54%2C%200.42%2C%200.61%5D%2C%0A%20%20%20%20%20%20%20%20%5B0.54%2C%201.00%2C%200.08%2C%200.12%5D%2C%0A%20%20%20%20%20%20%20%20%5B0.42%2C%200.08%2C%201.00%2C%200.48%5D%2C%0A%20%20%20%20%20%20%20%20%5B0.61%2C%200.12%2C%200.48%2C%201.00%5D%2C%0A%20%20%20%20%5D)%0A%0A%20%20%20%20fig%20%3D%20make_subplots(%0A%20%20%20%20%20%20%20%20rows%3D1%2C%0A%20%20%20%20%20%20%20%20cols%3D2%2C%0A%20%20%20%20%20%20%20%20subplot_titles%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Contingency%20Table%3A%20Role%20vs%20Genre%20(V%20%3D%200.54)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Categorical%20Association%20Matrix%20(Cram%C3%A9r's%20V)%22%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Left%3A%20Contingency%20Heatmap%0A%20%20%20%20fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Heatmap(%0A%20%20%20%20%20%20%20%20%20%20%20%20z%3Dcontingency_counts%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3Droles_list%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3Dgenres_list%2C%0A%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%20text%3Dcontingency_counts%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20texttemplate%3D%22%25%7Btext%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textfont%3Ddict(size%3D14%2C%20color%3D%22white%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20showscale%3DFalse%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Contingency%20Counts%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%20Right%3A%20Pairwise%20Cramer's%20V%20Matrix%0A%20%20%20%20fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Heatmap(%0A%20%20%20%20%20%20%20%20%20%20%20%20z%3Dcramers_matrix%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3Dcat_features%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3Dcat_features%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colorscale%3D%22Blues%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zmin%3D0.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zmax%3D1.0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3Dcramers_matrix%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20texttemplate%3D%22%25%7Btext%3A.2f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textfont%3Ddict(size%3D14)%2C%0A%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%20colorbar%3Ddict(title%3D%22Cram%C3%A9r's%20V%22%2C%20x%3D1.02)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Cram%C3%A9r's%20V%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%20fig.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%3D500%2C%0A%20%20%20%20%20%20%20%20margin%3Ddict(l%3D40%2C%20r%3D60%2C%20t%3D60%2C%20b%3D40)%2C%0A%20%20%20%20%20%20%20%20xaxis%3Ddict(gridcolor%3D%22%23f1f5f9%22)%2C%0A%20%20%20%20%20%20%20%20yaxis%3Ddict(gridcolor%3D%22%23f1f5f9%22)%2C%0A%20%20%20%20%20%20%20%20xaxis2%3Ddict(gridcolor%3D%22%23f1f5f9%22)%2C%0A%20%20%20%20%20%20%20%20yaxis2%3Ddict(gridcolor%3D%22%23f1f5f9%22)%2C%0A%20%20%20%20)%0A%20%20%20%20return%20(fig%2C)%0A%0A%0A%40app.cell%0Adef%20_(fig%2C%20mo)%3A%0A%20%20%20%20mo.ui.plotly(fig)%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%20%23%23%23%20Example%201%3A%20Full%20Chi-Square%20Test%20and%20Cram%C3%A9r's%20V%20Computation%20(Standard%20vs%20Bias-Corrected)%0A%0A%20%20%20%20Below%2C%20we%20analyze%20the%20%243%20%5Ctimes%203%24%20contingency%20table%20of%20tech%20roles%20vs%20movie%20preferences%3A%0A%20%20%20%201.%20Observed%20frequencies%20(%24O_%7Bij%7D%24)%20and%20expected%20frequencies%20under%20independence%20(%24E_%7Bij%7D%24).%0A%20%20%20%202.%20Chi-Square%20statistic%20(%24%5Cchi%5E2%24)%2C%20degrees%20of%20freedom%2C%20and%20%24p%24-value.%0A%20%20%20%203.%20Standard%20Cram%C3%A9r's%20%24V%24%20versus%20Bergsma's%20bias-corrected%20%24%5Ctilde%7BV%7D%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(chi2_contingency%2C%20np)%3A%0A%20%20%20%20contingency_data%20%3D%20np.array(%5B%0A%20%20%20%20%20%20%20%20%5B50%2C%2020%2C%205%5D%2C%0A%20%20%20%20%20%20%20%20%5B5%2C%2020%2C%2050%5D%2C%0A%20%20%20%20%20%20%20%20%5B5%2C%2050%2C%2020%5D%2C%0A%20%20%20%20%5D)%0A%0A%20%20%20%20%23%20Chi-Square%20test%0A%20%20%20%20chi2_val%2C%20p_value_val%2C%20dof_val%2C%20expected_arr%20%3D%20chi2_contingency(contingency_data)%0A%0A%20%20%20%20n_total_obs%20%3D%20int(np.sum(contingency_data))%0A%20%20%20%20r_rows%2C%20c_cols%20%3D%20contingency_data.shape%0A%0A%20%20%20%20%23%20Standard%20Cramer's%20V%0A%20%20%20%20v_standard%20%3D%20float(np.sqrt(chi2_val%20%2F%20(n_total_obs%20*%20min(r_rows%20-%201%2C%20c_cols%20-%201))))%0A%0A%20%20%20%20%23%20Bias-corrected%20Cramer's%20V%20(Bergsma%202013)%0A%20%20%20%20chi2_adj%20%3D%20max(0.0%2C%20chi2_val%20-%20((r_rows%20-%201.0)%20*%20(c_cols%20-%201.0))%20%2F%20(n_total_obs%20-%201.0))%0A%20%20%20%20n_adj%20%3D%20n_total_obs%20-%20((r_rows%20-%201.0)%20*%20(c_cols%20-%201.0))%20%2F%20(n_total_obs%20-%201.0)%0A%20%20%20%20r_adj%20%3D%20r_rows%20-%20((r_rows%20-%201.0)%20**%202)%20%2F%20(n_total_obs%20-%201.0)%0A%20%20%20%20c_adj%20%3D%20c_cols%20-%20((c_cols%20-%201.0)%20**%202)%20%2F%20(n_total_obs%20-%201.0)%0A%20%20%20%20denom_dim%20%3D%20min(r_adj%20-%201.0%2C%20c_adj%20-%201.0)%0A%20%20%20%20v_corrected%20%3D%20float(np.sqrt((chi2_adj%20%2F%20n_adj)%20%2F%20denom_dim))%20if%20denom_dim%20%3E%200%20else%200.0%0A%0A%20%20%20%20chi2_test_results%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Metric%20%2F%20Diagnostic%22%3A%20%22Total%20Sample%20Size%20(n)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Value%22%3A%20f%22%7Bn_total_obs%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Interpretation%22%3A%20%22Sum%20of%20all%20contingency%20cells%22%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Metric%20%2F%20Diagnostic%22%3A%20%22Degrees%20of%20Freedom%20(r-1)(c-1)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Value%22%3A%20f%22%7Bdof_val%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Interpretation%22%3A%20%22(3%20-%201)%20x%20(3%20-%201)%20%3D%204%22%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Metric%20%2F%20Diagnostic%22%3A%20%22Pearson%20Chi-Square%20Statistic%20(%CF%87%C2%B2)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Value%22%3A%20f%22%7Bchi2_val%3A.2f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Interpretation%22%3A%20%22Sum%20of%20(O%20-%20E)%C2%B2%20%2F%20E%22%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Metric%20%2F%20Diagnostic%22%3A%20%22p-value%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Value%22%3A%20f%22%7Bp_value_val%3A.2e%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Interpretation%22%3A%20%22Statistically%20significant%20association%20(p%20%3C%200.001)%22%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Metric%20%2F%20Diagnostic%22%3A%20%22Standard%20Cram%C3%A9r's%20V%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Value%22%3A%20f%22%7Bv_standard%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Interpretation%22%3A%20%22Strong%20nominal%20association%20(V%20%3E%200.50)%22%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Metric%20%2F%20Diagnostic%22%3A%20%22Bias-Corrected%20Cram%C3%A9r's%20V%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Value%22%3A%20f%22%7Bv_corrected%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Interpretation%22%3A%20%22Bergsma%20correction%20for%20finite-sample%20stability%22%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%5D%0A%20%20%20%20return%20(chi2_test_results%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(chi2_test_results%2C%20mo%2C%20pd)%3A%0A%20%20%20%20df_chi2%20%3D%20pd.DataFrame(chi2_test_results)%0A%20%20%20%20mo.ui.table(df_chi2)%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%23%20Example%202%3A%20Categorical%20Feature%20Collinearity%20Matrix%20for%20Machine%20Learning%0A%0A%20%20%20%20In%20tabular%20datasets%20with%20multiple%20categorical%20features%2C%20strong%20inter-feature%20dependencies%20create%20categorical%20multicollinearity%2C%20which%20degrades%20gradient%20boosting%20training%20efficiency%20and%20destabilizes%20feature%20importance%20scores.%0A%0A%20%20%20%20Below%2C%20we%20simulate%20%24N%20%3D%201%2C000%24%20synthetic%20customer%20profiles%20with%20four%20categorical%20features%3A%0A%20%20%20%20*%20**Industry**%3A%20Tech%2C%20Healthcare%2C%20Finance%0A%20%20%20%20*%20**Operating%20System**%3A%20Linux%2C%20macOS%2C%20Windows%20(correlated%20with%20Industry)%0A%20%20%20%20*%20**Subscription%20Plan**%3A%20Enterprise%2C%20Pro%2C%20Free%20(correlated%20with%20Industry)%0A%20%20%20%20*%20**Random%20Survey%20Color**%3A%20Red%2C%20Green%2C%20Blue%20(pure%20independent%20noise)%0A%0A%20%20%20%20We%20construct%20the%20full%20%244%20%5Ctimes%204%24%20pairwise%20Cram%C3%A9r's%20V%20correlation%20matrix%20and%20flag%20redundant%20feature%20pairs%20(%24V%20%3E%200.40%24).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(chi2_contingency%2C%20np%2C%20pd)%3A%0A%20%20%20%20rng_feat%20%3D%20np.random.default_rng(303)%0A%20%20%20%20n_records%20%3D%201000%0A%0A%20%20%20%20%23%20Industry%0A%20%20%20%20industries%20%3D%20rng_feat.choice(%5B%22Tech%22%2C%20%22Healthcare%22%2C%20%22Finance%22%5D%2C%20size%3Dn_records%2C%20p%3D%5B0.4%2C%200.3%2C%200.3%5D)%0A%0A%20%20%20%20%23%20OS%20depends%20on%20Industry%0A%20%20%20%20os_choices%20%3D%20%5B%5D%0A%20%20%20%20for%20ind%20in%20industries%3A%0A%20%20%20%20%20%20%20%20if%20ind%20%3D%3D%20%22Tech%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20os_choices.append(rng_feat.choice(%5B%22Linux%22%2C%20%22macOS%22%2C%20%22Windows%22%5D%2C%20p%3D%5B0.45%2C%200.45%2C%200.10%5D))%0A%20%20%20%20%20%20%20%20elif%20ind%20%3D%3D%20%22Finance%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20os_choices.append(rng_feat.choice(%5B%22Linux%22%2C%20%22macOS%22%2C%20%22Windows%22%5D%2C%20p%3D%5B0.05%2C%200.15%2C%200.80%5D))%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20os_choices.append(rng_feat.choice(%5B%22Linux%22%2C%20%22macOS%22%2C%20%22Windows%22%5D%2C%20p%3D%5B0.10%2C%200.30%2C%200.60%5D))%0A%0A%20%20%20%20%23%20Subscription%20depends%20on%20Industry%0A%20%20%20%20plans%20%3D%20%5B%5D%0A%20%20%20%20for%20ind%20in%20industries%3A%0A%20%20%20%20%20%20%20%20if%20ind%20%3D%3D%20%22Finance%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20plans.append(rng_feat.choice(%5B%22Enterprise%22%2C%20%22Pro%22%2C%20%22Free%22%5D%2C%20p%3D%5B0.70%2C%200.25%2C%200.05%5D))%0A%20%20%20%20%20%20%20%20elif%20ind%20%3D%3D%20%22Tech%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20plans.append(rng_feat.choice(%5B%22Enterprise%22%2C%20%22Pro%22%2C%20%22Free%22%5D%2C%20p%3D%5B0.40%2C%200.45%2C%200.15%5D))%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20plans.append(rng_feat.choice(%5B%22Enterprise%22%2C%20%22Pro%22%2C%20%22Free%22%5D%2C%20p%3D%5B0.20%2C%200.40%2C%200.40%5D))%0A%0A%20%20%20%20%23%20Random%20noise%20feature%0A%20%20%20%20colors%20%3D%20rng_feat.choice(%5B%22Red%22%2C%20%22Green%22%2C%20%22Blue%22%5D%2C%20size%3Dn_records)%0A%0A%20%20%20%20cat_df%20%3D%20pd.DataFrame(%7B%0A%20%20%20%20%20%20%20%20%22Industry%22%3A%20industries%2C%0A%20%20%20%20%20%20%20%20%22OS%22%3A%20os_choices%2C%0A%20%20%20%20%20%20%20%20%22Plan%22%3A%20plans%2C%0A%20%20%20%20%20%20%20%20%22Color%22%3A%20colors%2C%0A%20%20%20%20%7D)%0A%0A%20%20%20%20feature_names%20%3D%20%5B%22Industry%22%2C%20%22OS%22%2C%20%22Plan%22%2C%20%22Color%22%5D%0A%20%20%20%20v_matrix_results%20%3D%20%5B%5D%0A%0A%20%20%20%20for%20f1%20in%20feature_names%3A%0A%20%20%20%20%20%20%20%20row_dict%20%3D%20%7B%22Feature%22%3A%20f1%7D%0A%20%20%20%20%20%20%20%20for%20f2%20in%20feature_names%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20f1%20%3D%3D%20f2%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20row_dict%5Bf2%5D%20%3D%20%221.000%22%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20c_table%20%3D%20pd.crosstab(cat_df%5Bf1%5D%2C%20cat_df%5Bf2%5D).values%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20chi2%2C%20_%2C%20_%2C%20_%20%3D%20chi2_contingency(c_table)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20r_num%2C%20c_num%20%3D%20c_table.shape%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v_score%20%3D%20float(np.sqrt(chi2%20%2F%20(n_records%20*%20min(r_num%20-%201%2C%20c_num%20-%201))))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20row_dict%5Bf2%5D%20%3D%20f%22%7Bv_score%3A.3f%7D%22%0A%20%20%20%20%20%20%20%20v_matrix_results.append(row_dict)%0A%20%20%20%20return%20(v_matrix_results%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo%2C%20pd%2C%20v_matrix_results)%3A%0A%20%20%20%20df_cat_matrix%20%3D%20pd.DataFrame(v_matrix_results)%0A%20%20%20%20mo.ui.table(df_cat_matrix)%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
efab0570ba07b804e8a1a46ac892abff