docs: redesign final research figures and update README

This commit is contained in:
willtanoe committed 2026-10-09 00:47:01 +07:00
1 parent 8a9bdcf63c
commit 87f9b14ada
20 files changed
+609 -18

No files matched your search

+89 -18
View File
@@ -472,47 +472,117 @@ Representative confusion-matrix files:
## 16. Final Figures and Visualizations
All figures are under `artifacts/figures/final/` and load from the `final__*` analysis tables. They
were generated with matplotlib; no training was involved.
All figures live in `artifacts/figures/final/` and are regenerated from the audited
`artifacts/analysis/final__*` tables by `scripts/make_final_figures.py` (no training; every number is
loaded from an artifact). Each figure is saved as a high-resolution PNG (220 dpi) and a vector PDF.
**Fig A — pooled validation rare-class macro-F1 vs beta** (per dataset). Axes: `beta` (x) vs pooled
validation per-client-mean rare-class macro-F1 (y); one line per alpha. Evidence: the validation
curve is non-monotone and the selected `beta` differs by condition.
**Naming and legend conventions used throughout.**
- **Charcoal (`original_protean`)**: the frozen reproduced baseline.
- **Teal (`support_weighted`, validation-selected beta)**: the proposed method at the beta selected by
pooled validation for that condition.
- **Gray (`beta = 0` control)**: the equal-weight `support_weighted` run; a control, *not*
automatically the same recorded configuration as `original_protean`.
- Alpha conditions are distinguished by colour **and** marker **and** line style, so colour is never
the only cue.
**Comparison types (so figures are not misread).**
| Figure | Comparison type | Baseline actually plotted |
|---|---|---|
| A (both) | Beta candidate comparison within `support_weighted` | none (support_weighted candidates only) |
| B | Beta selection surface | none (selection, not performance) |
| C | Dataset heterogeneity | none (data distribution) |
| D, E | Fixed-snapshot comparison vs `beta = 0` | `beta = 0` control |
| F | Direct comparison vs `original_protean` | `original_protean` |
| G | Per-client comparison vs `beta = 0` | `beta = 0` control |
| H | Paired `original_protean` vs selected beta | `original_protean` |
### Fig A1 / A2 — Validation-based beta selection (support_weighted)
**Compared:** the five `support_weighted` beta candidates, separately for each alpha. **Level/split:**
pooled validation, per-client mean across seeds `{0,1,2}`. **Metric:** rare-class macro-F1
(per-client mean). **Observation:** the validation response is non-monotone and the selected beta
differs by condition. **Limits:** this is a selection figure; no `original_protean` run is plotted,
and the error bars are ±1 sample std across three project-defined seeds, not a confidence interval.
![Pooled validation beta curve, 5G-NIDD](artifacts/figures/final/figA_5gnidd_pooled_validation_beta_curve.png)
![Pooled validation beta curve, X-IIoTID](artifacts/figures/final/figA_xiiotid_pooled_validation_beta_curve.png)
**Fig B — selected beta by condition.** Bar chart of the six validation-selected betas; shows that
selections take `{0.00, 0.50, 1.00}` and are not universal.
### Fig B — Validation-selected beta by dataset and alpha
**Compared:** none (selection only). **Level:** pooled validation. **Metric:** selected beta under
the selection rule. **Observation:** selections take `{0.00, 0.50, 1.00}` and are not universal.
**Limits:** selection surface, not a performance comparison; a higher beta is not automatically
better. No `original_protean` comparison is implied.
![Selected beta by condition](artifacts/figures/final/figB_selected_beta_by_condition.png)
**Fig C — realized support CV.** Condition-level mean class-support CV; shows realized imbalance
decreases as alpha rises.
### Fig C — Realized class-support imbalance
**Compared:** none (data distribution). **Level:** training partitions. **Metric:** mean class-support
CV of `N_ij` across contributing clients (std/mean), averaged over classes and seeds. **Observation:**
realized imbalance decreases as the configured alpha rises. **Limits:** this describes the data,
not the relative performance of original vs modified PROTEAN; Dirichlet alpha is the configuration
knob and is not the same as the realized imbalance.
![Realized support CV](artifacts/figures/final/figC_realized_support_cv.png)
**Fig D — prototype displacement at beta=0 vs beta=1.** Fixed-snapshot mean displacement per class;
shows displacement grows with `beta` and larger where support imbalance is larger.
### Fig D — Support-weighted aggregation: beta=1 vs beta=0 control
**Compared:** `beta = 1` against the `beta = 0` control (not `original_protean`). **Level:**
fixed round-0 snapshots, same local prototypes and `N_ij`, no retraining. **Metric:** mean
`‖Cbar_j(1) − Cbar_j(0)‖` across classes. **Observation:** displacement increases with beta and is
largest where realized imbalance is largest. **Limits:** displacement is a representation metric,
not detection quality.
![Prototype displacement beta0 vs beta1](artifacts/figures/final/figD_prototype_displacement_beta0_vs_beta1.png)
**Fig E — support CV vs displacement.** Scatter of realized support CV (x) vs beta=1 displacement
(y) across conditions; a descriptive co-variation, not a causal relation.
### Fig E — Realized support CV vs prototype displacement
**Compared:** `beta = 1` displacement against the `beta = 0` control, across conditions. **Level:**
fixed snapshots. **Metric:** realized support CV (x) vs `beta = 1` displacement (y). **Observation:**
larger realized imbalance accompanies larger displacement. **Limits:** descriptive association only;
the imbalance-displacement link is mechanical under the beta formula and is not causal evidence.
![Support CV vs displacement](artifacts/figures/final/figE_support_cv_vs_displacement.png)
**Fig F — selected vs original test rare-class macro-F1.** Paired comparison per condition; shows
small, mixed-sign differences.
### Fig F — Selected-beta PROTEAN vs ORIGINAL PROTEAN (test)
**Compared:** `original_protean` (charcoal) against `support_weighted` at the validation-selected
beta (teal), per condition. **Level/split:** test, mean over seeds `{0,1,2}`. **Metric:** test
rare-class macro-F1; error bars = ±1 sample std across seeds. **Observation:** signed deltas are
`+0.0230`, `+0.0014`, `+0.0168` (positive), `−0.0086` (negative), and `−0.0007`/`−0.0010` at the two
`beta = 0` conditions (floating-point ~0). **Limits:** no statistical significance test (three
seeds); the largest gain is within seed noise; the weighting does not consistently outperform
`original_protean`.
![Selected vs original test rare macro-F1](artifacts/figures/final/figF_selected_vs_original_test_rare_macro_f1.png)
**Fig G — per-client effect at the selected beta.** Per-client validation delta relative to
`beta = 0`; shows within-condition heterogeneity across clients.
### Fig G — Per-client effect of selected beta relative to the beta=0 control
**Compared:** selected-beta `support_weighted` against the `beta = 0` control (not
`original_protean`). **Level/split:** validation, per client, per seed. **Metric:** per-client
rare-class macro-F1 delta; a client is "improved"/"degraded" if its delta is above/below 0,
"unchanged" otherwise. **Observation:** within a condition some clients improve and others degrade;
at both `alpha = 0.25` conditions the selected beta is 0, so all clients are unchanged. **Limits:**
client ids are per-seed realizations and are not pooled.
![Client effect at selected beta](artifacts/figures/final/figG_client_effect_at_selected_beta.png)
### Fig H (supplemental) — Paired test confusion matrices
**Compared:** `original_protean` (left) against selected-beta `support_weighted` (right) for a valid
paired condition (5G-NIDD, `alpha = 0.75`, `seed = 0`). **Level/split:** test; global counts over the
evaluation split. **Metric:** raw 9×9 counts (log colour scale), identical class order and colour
scale. **Observation:** the dominant off-diagonal error is `Benign → UDPFlood` (~56.9k vs ~57.1k) and
is essentially unchanged by beta. **Limits:** no statistical significance is inferred from the visual
difference; the matrices come from the same manifest, split, seed, and class order.
![Paired confusion matrices](artifacts/figures/final/figH_confusion_matrix_5gnidd_a0.75_seed0.png)
## 17. Main Scientific Findings
1. **Changing `beta` changes the global prototype.** Contribution weights become proportional to
@@ -650,7 +720,8 @@ Analysis outputs (`artifacts/analysis/`), by function:
| Prototype snapshots & weights | `*__prototype_snapshot.json`, `*__prototype_weights.csv`, `*__prototype_effect*.csv` |
Partition manifests: `artifacts/partitions/<dataset>__alpha<alpha>__seed<seed>.json` (18 files).
Figures: `artifacts/figures/final/figA–figG*.png` (8 files).
Figures: `artifacts/figures/final/` — 9 figures (figA–figH) as PNG (220 dpi) plus matching vector PDF;
regenerated reproducibly by `scripts/make_final_figures.py`.
Key documents: