From ae2860a0ee28cbd4c1ae37efe45673f28e96b68e Mon Sep 17 00:00:00 2001 From: Daniel Rosel Date: Mon, 23 Mar 2026 15:04:46 +0100 Subject: [PATCH] chore: adding the data and figure procssing --- .../final/final_focus_alpha_deltas.csv | 12 + .../final/final_focus_alpha_mode_summary.csv | 23 + .../final/final_focus_headline_summary.json | 27 ++ .../final/final_focus_zone_summary.csv | 3 + .../plots/final_focus_revenue_by_alpha.pdf | Bin 0 -> 17520 bytes .../final/plots/final_focus_revenue_delta.pdf | Bin 0 -> 19800 bytes .../final/plots/final_focus_risk_deltas.pdf | Bin 0 -> 19553 bytes .../final/final_focus_revenue_by_alpha.tex | 1 + .../final/final_focus_revenue_delta.tex | 1 + .../final/final_focus_risk_deltas.tex | 1 + .../figures/results/process_final_sweeps.py | 409 ++++++++++++++++++ 11 files changed, 477 insertions(+) create mode 100644 paper/src/chapters/figures/results/generated/final/final_focus_alpha_deltas.csv create mode 100644 paper/src/chapters/figures/results/generated/final/final_focus_alpha_mode_summary.csv create mode 100644 paper/src/chapters/figures/results/generated/final/final_focus_headline_summary.json create mode 100644 paper/src/chapters/figures/results/generated/final/final_focus_zone_summary.csv create mode 100644 paper/src/chapters/figures/results/generated/final/plots/final_focus_revenue_by_alpha.pdf create mode 100644 paper/src/chapters/figures/results/generated/final/plots/final_focus_revenue_delta.pdf create mode 100644 paper/src/chapters/figures/results/generated/final/plots/final_focus_risk_deltas.pdf create mode 100644 paper/src/chapters/figures/results/includes/final/final_focus_revenue_by_alpha.tex create mode 100644 paper/src/chapters/figures/results/includes/final/final_focus_revenue_delta.tex create mode 100644 paper/src/chapters/figures/results/includes/final/final_focus_risk_deltas.tex create mode 100644 paper/src/chapters/figures/results/process_final_sweeps.py diff --git a/paper/src/chapters/figures/results/generated/final/final_focus_alpha_deltas.csv b/paper/src/chapters/figures/results/generated/final/final_focus_alpha_deltas.csv new file mode 100644 index 0000000..32bbd73 --- /dev/null +++ b/paper/src/chapters/figures/results/generated/final/final_focus_alpha_deltas.csv @@ -0,0 +1,12 @@ +alpha,revenue_delta,revenue_delta_pct,reward_delta,reward_delta_pct,volatility_delta,supra_delta,coi_leakage_delta +0.0,-17982.383542886935,-5.11072862876989,-17145.799161982606,-5.235033672101227,0.001232973729699119,0.0,-0.0030412479577408003 +0.1,-14962.041501283413,-4.410637208586118,-14303.760282736213,-4.531344436782669,0.0011858665298920962,0.0,-0.004133727080174038 +0.2,-16153.416666167905,-4.826514761457546,-15398.621298776357,-4.9418165571901715,0.00200624274016295,0.0,-0.0033201883450373615 +0.3,-17294.9275360335,-5.382423616385397,-16544.91845114401,-5.533399709364953,-0.0011022484400295268,0.0,-0.0029151149203366505 +0.4,-19661.294346174283,-6.250307313590199,-18728.35578200908,-6.3953153560217535,3.582812967113658e-05,0.0,-0.0038123361988749577 +0.5,-16411.03168918495,-5.3630681206030015,-15638.77510066732,-5.4888928630525315,0.00015428950526953644,0.0,-0.00439661338956944 +0.6,-14729.668247641937,-5.069964928178309,-13912.22417824401,-5.148827377884945,-0.002735776807082743,0.0,-0.004310129386364658 +0.7,-21160.81910514756,-7.351404104505076,-20171.762105623755,-7.525169314210056,-0.0008903632602569461,0.0,-0.0026198461183787186 +0.8,-16404.76825612632,-5.9342582959227075,-15645.025250480074,-6.078699946285722,0.0010338614665691137,0.0,-0.002542765270289696 +0.9,-8674.090655496111,-3.2592966246269577,-8371.30734891587,-3.378943339994106,-0.0005579187914590139,0.0,-0.0013720835439427759 +1.0,768.8099906174757,0.2991618705853567,399.7394696234842,0.16706914330070038,0.0014659834822295797,0.0,-0.0007600066499474645 diff --git a/paper/src/chapters/figures/results/generated/final/final_focus_alpha_mode_summary.csv b/paper/src/chapters/figures/results/generated/final/final_focus_alpha_mode_summary.csv new file mode 100644 index 0000000..50051aa --- /dev/null +++ b/paper/src/chapters/figures/results/generated/final/final_focus_alpha_mode_summary.csv @@ -0,0 +1,23 @@ +alpha,mode,runs,revenue_mean,reward_mean,supra_mean,volatility_mean,coi_leakage_mean,coi_level_mean +0.0,baseline,36,351855.57381502265,327520.32242613373,0.0,0.06922494093544151,0.11931704468268205,136.80105514058158 +0.0,defended,35,333873.1902721357,310374.5232641511,0.0,0.07045791466514063,0.11627579672494125,136.81832905386602 +0.1,baseline,32,339226.3020897988,315662.6136522988,0.0,0.06952778671756812,0.11924519238669087,136.47864859317326 +0.1,defended,33,324264.2605885154,301358.8533695626,0.0,0.07071365324746022,0.11511146530651684,136.7200845824852 +0.2,baseline,31,334680.76789409376,311598.399506997,0.0,0.06848006194428993,0.11597869134898402,136.83684469591932 +0.2,defended,35,318527.35122792586,296199.77820822067,0.0,0.07048630468445288,0.11265850300394666,137.2758153292305 +0.3,baseline,30,321322.30327214615,299000.9636054795,0.0,0.07085669473747759,0.11527347603412934,136.4452630715689 +0.3,defended,44,304027.37573611265,282456.0451543355,0.0,0.06975444629744806,0.11235836111379269,136.4704115371568 +0.4,baseline,33,314565.2423109539,292844.914432166,0.0,0.07031811881503117,0.11300307992768284,136.72547178046122 +0.4,defended,38,294903.9479647796,274116.55865015695,0.0,0.0703539469447023,0.10919074372880788,136.75671002806396 +0.5,baseline,33,306000.80625751516,284916.7489847879,0.0,0.06938663916591635,0.11118137138243217,136.9528780620641 +0.5,defended,35,289589.7745683302,269277.9738841206,0.0,0.06954092867118589,0.10678475799286273,136.65018588845163 +0.6,baseline,28,290528.0106727377,270201.7985298805,0.0,0.07139577980623227,0.11081647254398667,135.258395468266 +0.6,defended,41,275798.3424250958,256289.57435163652,0.0,0.06866000299914952,0.10650634315762202,136.3194947785247 +0.7,baseline,40,287847.3119465684,268057.25244656845,0.0,0.07132313199532896,0.10746267580456732,137.0170522633547 +0.7,defended,40,266686.49284142087,247885.4903409447,0.0,0.07043276873507201,0.1048428296861886,136.56834095392904 +0.8,baseline,26,276441.76303208206,257374.52726285128,0.0,0.06945655282263205,0.1063246766773884,136.66765260798618 +0.8,defended,39,260036.99477595574,241729.5020123712,0.0,0.07049041428920116,0.1037819114070987,136.61222667078658 +0.9,baseline,35,266133.8213268301,247749.2667554015,0.0,0.0709569180547784,0.10455882265976374,136.5370653814206 +0.9,defended,39,257459.73067133396,239377.95940648564,0.0,0.07039899926331938,0.10318673911582096,136.7368893225831 +1.0,baseline,35,256987.96076959255,239265.888198164,0.0,0.06888231148034313,0.10369761394735275,136.68691718467974 +1.0,defended,30,257756.77076021003,239665.62766778748,0.0,0.07034829496257271,0.10293760729740528,136.65287739235566 diff --git a/paper/src/chapters/figures/results/generated/final/final_focus_headline_summary.json b/paper/src/chapters/figures/results/generated/final/final_focus_headline_summary.json new file mode 100644 index 0000000..e257560 --- /dev/null +++ b/paper/src/chapters/figures/results/generated/final/final_focus_headline_summary.json @@ -0,0 +1,27 @@ +{ + "bundle": "engine/studies/results/wandb_sweep_bundles/bundle_20260317_093826", + "focus_cohort": "max_alpha_coverage", + "alpha_cells": 11, + "alpha_min": 0.0, + "alpha_max": 1.0, + "mean_revenue_delta_pct": -4.787221975639986, + "mean_reward_delta_pct": -4.91730667541704, + "zone_summary": [ + { + "zone": "high_alpha_0_7_plus", + "alpha_cells": 4, + "revenue_delta_pct_mean": -4.0614492886173466, + "reward_delta_pct_mean": -4.2039358642972955, + "coi_leakage_delta_mean": -0.0018236753956396637, + "volatility_delta_mean": 0.00026289072427068336 + }, + { + "zone": "low_alpha_below_0_7", + "alpha_cells": 7, + "revenue_delta_pct_mean": -5.201949225367208, + "reward_delta_pct_mean": -5.324947138914036, + "coi_leakage_delta_mean": -0.0037041938968711296, + "volatility_delta_mean": 0.00011102505536893832 + } + ] +} diff --git a/paper/src/chapters/figures/results/generated/final/final_focus_zone_summary.csv b/paper/src/chapters/figures/results/generated/final/final_focus_zone_summary.csv new file mode 100644 index 0000000..224a022 --- /dev/null +++ b/paper/src/chapters/figures/results/generated/final/final_focus_zone_summary.csv @@ -0,0 +1,3 @@ +zone,alpha_cells,revenue_delta_pct_mean,reward_delta_pct_mean,coi_leakage_delta_mean,volatility_delta_mean +high_alpha_0_7_plus,4,-4.0614492886173466,-4.2039358642972955,-0.0018236753956396637,0.00026289072427068336 +low_alpha_below_0_7,7,-5.201949225367208,-5.324947138914036,-0.0037041938968711296,0.00011102505536893832 diff --git a/paper/src/chapters/figures/results/generated/final/plots/final_focus_revenue_by_alpha.pdf b/paper/src/chapters/figures/results/generated/final/plots/final_focus_revenue_by_alpha.pdf new file mode 100644 index 0000000000000000000000000000000000000000..343539eb657d0ac16452d3182e9f79695454bfa2 GIT binary patch literal 17520 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 literal 0 HcmV?d00001 diff --git a/paper/src/chapters/figures/results/generated/final/plots/final_focus_risk_deltas.pdf b/paper/src/chapters/figures/results/generated/final/plots/final_focus_risk_deltas.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9bbbf7a32807c783724f020fd95a69bbcf0ffd4c GIT binary patch literal 19553 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 Path: + return Path(__file__).resolve().parents[5] + + +def _default_bundle_dir() -> Path: + base = _project_root() / "engine" / "studies" / "results" / "wandb_sweep_bundles" + bundles = sorted( + [path for path in base.glob("bundle_*") if path.is_dir()], + key=lambda path: path.stat().st_mtime, + reverse=True, + ) + if not bundles: + raise FileNotFoundError(f"No sweep bundle directories found in {base}") + return bundles[0] + + +def _default_output_dir() -> Path: + return Path(__file__).resolve().parent / "generated" / "final" + + +def _default_plot_dir(output_dir: Path) -> Path: + return output_dir / "plots" + + +def _truthy(value: Any) -> bool: + if isinstance(value, bool): + return value + if value is None: + return False + return str(value).strip().lower() in {"1", "true", "yes", "on"} + + +def _mode_of(row: pd.Series) -> str: + mode_hint = str(row.get("study_mode", "")).strip().lower() + if mode_hint in {"baseline", "no_robust"}: + return "baseline" + if mode_hint in {"defended", "robust"}: + return "defended" + if _truthy(row.get("baseline_mode")) or _truthy(row.get("no_robust")): + return "baseline" + return "defended" + + +def _coerce_numeric(frame: pd.DataFrame, columns: list[str]) -> None: + for column in columns: + if column in frame.columns: + frame[column] = pd.to_numeric(frame[column], errors="coerce") + + +def _configure_style() -> None: + plt.rcParams.update( + { + "font.family": "serif", + "font.size": 10, + "axes.titlesize": 10, + "axes.labelsize": 9, + "legend.fontsize": 8, + "xtick.labelsize": 8, + "ytick.labelsize": 8, + "figure.dpi": 220, + "savefig.dpi": 320, + "axes.spines.top": False, + "axes.spines.right": False, + "axes.grid": True, + "grid.alpha": 0.22, + } + ) + + +def _load_runs(bundle_dir: Path) -> pd.DataFrame: + path = bundle_dir / "runs_finished.csv" + if not path.exists(): + raise FileNotFoundError(f"Missing required file: {path}") + frame = pd.read_csv(path) + frame["mode"] = frame.apply(_mode_of, axis=1) + _coerce_numeric( + frame, + [ + "alpha", + "n_products", + "eval_revenue_mean", + "eval_reward_mean", + "eval_supra_share_mean", + "eval_volatility_mean", + "eval_coi_level_mean", + "eval_coi_leakage_mean", + "objective_score", + ], + ) + return frame + + +def _focus_sweep(runs: pd.DataFrame) -> str: + coverage = ( + runs.groupby("sweep_id", as_index=False) + .agg( + n_alpha=("alpha", lambda s: int(pd.Series(s).dropna().nunique())), + max_alpha=("alpha", "max"), + run_count=("run_id", "size"), + ) + .sort_values( + ["n_alpha", "max_alpha", "run_count"], ascending=[False, False, False] + ) + ) + if coverage.empty: + raise ValueError("No sweep rows available in runs_finished.csv") + return str(coverage.iloc[0]["sweep_id"]) + + +def _alpha_mode_summary(runs: pd.DataFrame) -> pd.DataFrame: + return ( + runs.groupby(["alpha", "mode"], as_index=False) + .agg( + runs=("run_id", "size"), + revenue_mean=("eval_revenue_mean", "mean"), + reward_mean=("eval_reward_mean", "mean"), + supra_mean=("eval_supra_share_mean", "mean"), + volatility_mean=("eval_volatility_mean", "mean"), + coi_leakage_mean=("eval_coi_leakage_mean", "mean"), + coi_level_mean=("eval_coi_level_mean", "mean"), + ) + .sort_values(["alpha", "mode"]) + .reset_index(drop=True) + ) + + +def _alpha_deltas(alpha_mode: pd.DataFrame) -> pd.DataFrame: + rows: list[dict[str, float]] = [] + for alpha, group in alpha_mode.groupby("alpha", sort=True): + defended = group[group["mode"] == "defended"] + baseline = group[group["mode"] == "baseline"] + if defended.empty or baseline.empty: + continue + d_rev = float(defended["revenue_mean"].iloc[0]) + b_rev = float(baseline["revenue_mean"].iloc[0]) + d_reward = float(defended["reward_mean"].iloc[0]) + b_reward = float(baseline["reward_mean"].iloc[0]) + d_vol = float(defended["volatility_mean"].iloc[0]) + b_vol = float(baseline["volatility_mean"].iloc[0]) + d_supra = float(defended["supra_mean"].iloc[0]) + b_supra = float(baseline["supra_mean"].iloc[0]) + d_coi_leak = float(defended["coi_leakage_mean"].iloc[0]) + b_coi_leak = float(baseline["coi_leakage_mean"].iloc[0]) + rows.append( + { + "alpha": float(alpha), + "revenue_delta": d_rev - b_rev, + "revenue_delta_pct": 0.0 + if b_rev == 0.0 + else 100.0 * (d_rev - b_rev) / b_rev, + "reward_delta": d_reward - b_reward, + "reward_delta_pct": 0.0 + if b_reward == 0.0 + else 100.0 * (d_reward - b_reward) / b_reward, + "volatility_delta": d_vol - b_vol, + "supra_delta": d_supra - b_supra, + "coi_leakage_delta": d_coi_leak - b_coi_leak, + } + ) + return pd.DataFrame(rows).sort_values("alpha").reset_index(drop=True) + + +def _zone_summary(alpha_deltas: pd.DataFrame) -> pd.DataFrame: + if alpha_deltas.empty: + return pd.DataFrame() + data = alpha_deltas.copy() + data["zone"] = np.where( + data["alpha"] >= 0.7, "high_alpha_0_7_plus", "low_alpha_below_0_7" + ) + return ( + data.groupby("zone", as_index=False) + .agg( + alpha_cells=("alpha", "size"), + revenue_delta_pct_mean=("revenue_delta_pct", "mean"), + reward_delta_pct_mean=("reward_delta_pct", "mean"), + coi_leakage_delta_mean=("coi_leakage_delta", "mean"), + volatility_delta_mean=("volatility_delta", "mean"), + ) + .sort_values("zone") + ) + + +def _save_plot(fig: plt.Figure, path: Path) -> Path: + path.parent.mkdir(parents=True, exist_ok=True) + fig.savefig(path, bbox_inches="tight") + plt.close(fig) + return path + + +def _plot_focus_revenue_by_alpha(alpha_mode: pd.DataFrame, out_path: Path) -> Path: + fig, ax = plt.subplots(figsize=(7.8, 4.8), constrained_layout=True) + for mode, color, label in ( + ("baseline", "#4C72B0", "Baseline"), + ("defended", "#C44E52", "Defended"), + ): + sub = alpha_mode[alpha_mode["mode"] == mode].sort_values("alpha") + if sub.empty: + continue + ax.plot( + sub["alpha"], + sub["revenue_mean"], + marker="o", + linewidth=1.9, + markersize=4, + color=color, + label=label, + ) + ax.axvline(0.7, color="#666666", linewidth=1.0, linestyle="--") + ax.set_xlabel(r"Contamination $\alpha$") + ax.set_ylabel("Mean episode revenue") + ax.set_title("Final Cohort Revenue Curves") + ax.legend(loc="lower left") + return _save_plot(fig, out_path) + + +def _plot_focus_revenue_delta(alpha_deltas: pd.DataFrame, out_path: Path) -> Path: + fig, ax = plt.subplots(figsize=(7.8, 4.8), constrained_layout=True) + x = alpha_deltas["alpha"].to_numpy(dtype=float) + y = alpha_deltas["revenue_delta_pct"].to_numpy(dtype=float) + ax.plot(x, y, marker="o", linewidth=2.0, markersize=4, color="#C44E52") + ax.fill_between(x, y, 0.0, color="#C44E52", alpha=0.12) + ax.axhline(0.0, color="#444444", linewidth=1.0, linestyle="--") + ax.axvline(0.7, color="#666666", linewidth=1.0, linestyle="--") + high = alpha_deltas[alpha_deltas["alpha"] >= 0.7] + if not high.empty: + best = high.reindex( + high["revenue_delta_pct"].abs().sort_values(ascending=False).index + ).iloc[0] + ax.scatter( + [best["alpha"]], + [best["revenue_delta_pct"]], + color="#1f77b4", + s=45, + zorder=3, + ) + ax.annotate( + f"high-alpha peak {best['revenue_delta_pct']:.2f}%", + (float(best["alpha"]), float(best["revenue_delta_pct"])), + textcoords="offset points", + xytext=(6, 6), + fontsize=8, + ) + ax.set_xlabel(r"Contamination $\alpha$") + ax.set_ylabel("Defended minus baseline revenue (%)") + ax.set_title("Revenue Delta by Contamination (Final Cohort)") + return _save_plot(fig, out_path) + + +def _plot_focus_risk_deltas(alpha_deltas: pd.DataFrame, out_path: Path) -> Path: + fig, ax = plt.subplots(figsize=(7.8, 4.8), constrained_layout=True) + x = alpha_deltas["alpha"].to_numpy(dtype=float) + ax.plot( + x, + alpha_deltas["coi_leakage_delta"].to_numpy(dtype=float), + marker="o", + linewidth=1.8, + markersize=4, + color="#55A868", + label="COI leakage delta", + ) + ax.plot( + x, + alpha_deltas["volatility_delta"].to_numpy(dtype=float), + marker="s", + linewidth=1.8, + markersize=3.8, + color="#8172B3", + label="Volatility delta", + ) + ax.axhline(0.0, color="#444444", linewidth=1.0, linestyle="--") + ax.axvline(0.7, color="#666666", linewidth=1.0, linestyle="--") + ax.set_xlabel(r"Contamination $\alpha$") + ax.set_ylabel("Defended minus baseline") + ax.set_title("Leakage and Stability Deltas (Final Cohort)") + ax.legend(loc="lower left") + return _save_plot(fig, out_path) + + +def _write_include(path: Path, figure_rel_path: str, width: str) -> Path: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(f"\\includegraphics[width={width}]{{{figure_rel_path}}}\n") + return path + + +def run(bundle_dir: Path, output_dir: Path, plot_dir: Path) -> list[Path]: + all_runs = _load_runs(bundle_dir) + focus_id = _focus_sweep(all_runs) + focus_runs = all_runs[all_runs["sweep_id"] == focus_id].copy() + alpha_mode = _alpha_mode_summary(focus_runs) + deltas = _alpha_deltas(alpha_mode) + zones = _zone_summary(deltas) + + output_dir.mkdir(parents=True, exist_ok=True) + plot_dir.mkdir(parents=True, exist_ok=True) + + written: list[Path] = [] + alpha_mode_path = output_dir / "final_focus_alpha_mode_summary.csv" + alpha_mode.to_csv(alpha_mode_path, index=False) + written.append(alpha_mode_path) + + delta_path = output_dir / "final_focus_alpha_deltas.csv" + deltas.to_csv(delta_path, index=False) + written.append(delta_path) + + zone_path = output_dir / "final_focus_zone_summary.csv" + zones.to_csv(zone_path, index=False) + written.append(zone_path) + + headline = { + "bundle": str(bundle_dir), + "focus_cohort": "max_alpha_coverage", + "alpha_cells": int(deltas["alpha"].nunique()) if not deltas.empty else 0, + "alpha_min": float(deltas["alpha"].min()) if not deltas.empty else None, + "alpha_max": float(deltas["alpha"].max()) if not deltas.empty else None, + "mean_revenue_delta_pct": float(deltas["revenue_delta_pct"].mean()) + if not deltas.empty + else None, + "mean_reward_delta_pct": float(deltas["reward_delta_pct"].mean()) + if not deltas.empty + else None, + "zone_summary": zones.to_dict(orient="records"), + } + headline_path = output_dir / "final_focus_headline_summary.json" + headline_path.write_text(json.dumps(headline, indent=2) + "\n") + written.append(headline_path) + + written.append( + _plot_focus_revenue_by_alpha( + alpha_mode, + plot_dir / "final_focus_revenue_by_alpha.pdf", + ) + ) + written.append( + _plot_focus_revenue_delta( + deltas, + plot_dir / "final_focus_revenue_delta.pdf", + ) + ) + written.append( + _plot_focus_risk_deltas( + deltas, + plot_dir / "final_focus_risk_deltas.pdf", + ) + ) + + include_dir = Path(__file__).resolve().parent / "includes" / "final" + written.append( + _write_include( + include_dir / "final_focus_revenue_by_alpha.tex", + "chapters/figures/results/generated/final/plots/final_focus_revenue_by_alpha.pdf", + "0.98\\linewidth", + ) + ) + written.append( + _write_include( + include_dir / "final_focus_revenue_delta.tex", + "chapters/figures/results/generated/final/plots/final_focus_revenue_delta.pdf", + "0.95\\linewidth", + ) + ) + written.append( + _write_include( + include_dir / "final_focus_risk_deltas.tex", + "chapters/figures/results/generated/final/plots/final_focus_risk_deltas.pdf", + "0.95\\linewidth", + ) + ) + return written + + +def main() -> None: + parser = argparse.ArgumentParser( + description="Generate final paper figures/tables from the final sweep cohort" + ) + parser.add_argument("--bundle-dir", type=Path, default=_default_bundle_dir()) + parser.add_argument("--output-dir", type=Path, default=_default_output_dir()) + parser.add_argument("--plot-dir", type=Path, default=None) + args = parser.parse_args() + + _configure_style() + plot_dir = ( + args.plot_dir + if args.plot_dir is not None + else _default_plot_dir(args.output_dir) + ) + outputs = run( + bundle_dir=args.bundle_dir, output_dir=args.output_dir, plot_dir=plot_dir + ) + for path in outputs: + print(path) + + +if __name__ == "__main__": + main()