* shap_frames.do * * Table 4 of "Which H2O frame should you use to explain your model?" * * Mean absolute SHAP value by predictor and frame, over 6 replications. clear all set more off capture program drop makedata program define makedata args n seed clear set seed `seed' set obs `n' gen double x1 = runiform(-3,3) gen double x2 = rnormal() gen double x3 = 0.9*x2 + sqrt(1-0.9^2)*rnormal() gen double x4 = runiform(-2,2) gen byte g = runiform()<0.5 gen double x5 = runiform() gen byte x6 = runiform()<0.5 gen double y = 4*sin(1.5*x1) + 2*x2 + 3*x4*(2*g-1) + rnormal(0,1.5) end h2o init h2o init //number of simulations local nsim 6 tempfile res postfile pf int rep str2 frame str2 vname double mabs int nrows using `res' forvalues r = 1/`nsim' { makedata 4000 `=20260901 + `r'' quietly _h2oframe put, into(c`r') quietly _h2oframe split c`r', into(ct`r' cv`r' cs`r') split(0.6 0.2 0.2) rseed(19) quietly _h2oframe change ct`r' quietly h2oml gbregress y x1 x2 x3 x4 g x5 x6, /// ntrees(500) maxdepth(12) minobsleaf(1) lrate(0.1) h2orseed(19) foreach fr in ct cs { quietly h2omlgraph shapsummary, frame(`fr'`r') samples(700) rseed(19) /// savedata(_ss, replace) nodraw preserve quietly use _ss, clear local N = _N local tag = cond("`fr'"=="ct","tr","te") foreach v in x1 x2 x3 x4 g x5 x6 { quietly gen double _a = abs(`v') quietly summarize _a, meanonly post pf (`r') ("`tag'") ("`v'") (r(mean)) (`N') quietly drop _a } restore } di "rep `r' done" } postclose pf use `res', clear save shapres, replace di _n "=== mean |SHAP| by feature and frame (`nsim' reps) ===" table vname frame, statistic(mean mabs) nformat(%8.4f) di _n "rows used:" table frame, statistic(mean nrows) di _n "=== paired within-rep: train vs test ===" keep rep frame vname mabs reshape wide mabs, i(rep vname) j(frame) string gen double ratio = mabstr/mabste gen double gap = mabstr - mabste di " feat ratio(tr/te) gap reps tr>te" levelsof vname, local(vs) foreach v in `vs' { quietly summarize ratio if vname=="`v'", meanonly local rr = r(mean) quietly summarize gap if vname=="`v'", meanonly local gg = r(mean) quietly count if vname=="`v'" & gap>0 local w = r(N) quietly count if vname=="`v'" di " `v' " %10.3f `rr' " " %10.4f `gg' " `w'/" r(N) } di "----shap_frames.do successful----"