Opens a larger view. Escape closes it.

hardware-counters

plot_nn2.py

"""Figure: what fixed the neural network."""
import numpy as np, pandas as pd
import matplotlib; matplotlib.use("Agg")
import matplotlib.pyplot as plt

D = "/work/project/project/user"
OUT = f"{D}/analysis/out"
ab = pd.read_csv(f"{OUT}/nn_ablation.csv", index_col=0)

fig, ax = plt.subplots(1, 2, figsize=(13, 4.6))

# ---- left: cumulative ablation -------------------------------------------
steps = [c for c in ab.index if c not in ("Random Forest", "constant baseline")]
vals  = ab.loc[steps, "overall"].values
short = ["original\nrecipe", "+lbfgs\n(H5)", "+alpha\n10->1", "+log1p\n(H2)",
         "+missing\nindic. (H3)", "+bagging\n(H4)"][:len(steps)]
cols = ["tab:red" if i == 0 else
        ("tab:green" if vals[i] < vals[i-1] else "tab:orange")
        for i in range(len(vals))]
ax[0].bar(range(len(vals)), vals, color=cols)
ax[0].axhline(ab.loc["Random Forest", "overall"], ls="--", c="tab:blue",
              label=f"Random Forest ({ab.loc['Random Forest','overall']:.3f})")
ax[0].axhline(ab.loc["constant baseline", "overall"], ls=":", c="k",
              label=f"no-counter baseline ({ab.loc['constant baseline','overall']:.3f})")
for i, v in enumerate(vals):
    ax[0].text(i, v + .004, f"{v:.3f}", ha="center", fontsize=8)
ax[0].set(xticks=range(len(vals)), ylim=[1.0, 1.22],
          ylabel="median error factor (leave-one-app-out)",
          title="Ablation: lowering over-regularisation was the\nlargest single modelling gain")
ax[0].set_xticklabels(short, fontsize=7.5)
ax[0].legend(fontsize=8); ax[0].grid(alpha=.3, axis="y")

# ---- right: per-application, final vs original vs RF ---------------------
per = ab.drop(columns=["overall"])
apps = [c for c in per.columns]
rows = {"original recipe": per.loc[steps[0]],
        "final MLP":       per.loc[steps[3]],       # +log1p, before H3/H4
        "Random Forest":   per.loc["Random Forest"]}
w, xs = 0.26, np.arange(len(apps))
for i, (k, v) in enumerate(rows.items()):
    ax[1].bar(xs + (i-1)*w, v.values, w, label=k)
ax[1].axhline(1.0, c="k", lw=1)
ax[1].set(xticks=xs, ylabel="median error factor", ylim=[1.0, 1.25],
          title="STREAM is an extrapolation fold:\n0% of its rows lie inside the training range")
ax[1].set_xticklabels(apps, fontsize=9)
ax[1].legend(fontsize=8); ax[1].grid(alpha=.3, axis="y")

fig.tight_layout(); fig.savefig(f"{OUT}/fig_nn_fixed.png", dpi=150)
print("wrote", f"{OUT}/fig_nn_fixed.png")