Spaces:
Sleeping
Sleeping
feat: enhance visualization pipeline with additional figures and manifest support
Browse files
app/training/visualize_results.py
CHANGED
|
@@ -945,6 +945,7 @@ def generate_all_figures(
|
|
| 945 |
results_path: str | Path,
|
| 946 |
features_csv: str | Path,
|
| 947 |
output_dir: str | Path = "figures",
|
|
|
|
| 948 |
) -> None:
|
| 949 |
"""Generate all publication-quality figures."""
|
| 950 |
results_path = Path(results_path)
|
|
@@ -952,47 +953,70 @@ def generate_all_figures(
|
|
| 952 |
output_dir = Path(output_dir)
|
| 953 |
output_dir.mkdir(parents=True, exist_ok=True)
|
| 954 |
|
| 955 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 956 |
with open(results_path, "r") as f:
|
| 957 |
saved_results = json.load(f)
|
| 958 |
|
| 959 |
-
# We need y_true/y_pred/y_prob arrays — check if they're stored
|
| 960 |
-
# If not in the saved JSON, we can't plot ROC/PR curves
|
| 961 |
has_arrays = any(
|
| 962 |
"y_true" in v for k, v in saved_results.items()
|
| 963 |
if isinstance(v, dict) and not k.startswith("_")
|
| 964 |
)
|
| 965 |
|
| 966 |
-
print(f"\nGenerating figures in {output_dir}/...\n")
|
| 967 |
|
| 968 |
if has_arrays:
|
| 969 |
-
print("[1/
|
| 970 |
plot_roc_curves(saved_results, output_dir)
|
| 971 |
|
| 972 |
-
print("[2/
|
| 973 |
plot_pr_curves(saved_results, output_dir)
|
| 974 |
|
| 975 |
-
print("[3/
|
| 976 |
plot_confusion_matrices(saved_results, output_dir)
|
| 977 |
else:
|
| 978 |
-
print("[1-3/
|
| 979 |
|
| 980 |
-
print("[4/
|
| 981 |
plot_model_comparison(saved_results, output_dir)
|
| 982 |
|
| 983 |
-
print("[5/
|
| 984 |
plot_feature_importance(saved_results, output_dir)
|
| 985 |
|
| 986 |
-
print("[6/
|
| 987 |
plot_correlation_heatmap(features_csv, output_dir)
|
| 988 |
|
| 989 |
-
print("[7/
|
| 990 |
plot_feature_distributions(features_csv, output_dir, saved_results)
|
| 991 |
|
| 992 |
-
print("[8/
|
| 993 |
generate_latex_table(saved_results, output_dir)
|
| 994 |
|
| 995 |
-
print(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 996 |
|
| 997 |
|
| 998 |
if __name__ == "__main__":
|
|
|
|
| 945 |
results_path: str | Path,
|
| 946 |
features_csv: str | Path,
|
| 947 |
output_dir: str | Path = "figures",
|
| 948 |
+
manifest_csv: str | Path | None = None,
|
| 949 |
) -> None:
|
| 950 |
"""Generate all publication-quality figures."""
|
| 951 |
results_path = Path(results_path)
|
|
|
|
| 953 |
output_dir = Path(output_dir)
|
| 954 |
output_dir.mkdir(parents=True, exist_ok=True)
|
| 955 |
|
| 956 |
+
if manifest_csv is None:
|
| 957 |
+
manifest_csv = features_csv.parent / "manifest.csv"
|
| 958 |
+
manifest_csv = Path(manifest_csv)
|
| 959 |
+
|
| 960 |
+
print(f"\nLoading results from {results_path}...", flush=True)
|
| 961 |
with open(results_path, "r") as f:
|
| 962 |
saved_results = json.load(f)
|
| 963 |
|
|
|
|
|
|
|
| 964 |
has_arrays = any(
|
| 965 |
"y_true" in v for k, v in saved_results.items()
|
| 966 |
if isinstance(v, dict) and not k.startswith("_")
|
| 967 |
)
|
| 968 |
|
| 969 |
+
print(f"\nGenerating figures in {output_dir}/...\n", flush=True)
|
| 970 |
|
| 971 |
if has_arrays:
|
| 972 |
+
print("[1/13] ROC Curves", flush=True)
|
| 973 |
plot_roc_curves(saved_results, output_dir)
|
| 974 |
|
| 975 |
+
print("[2/13] Precision-Recall Curves", flush=True)
|
| 976 |
plot_pr_curves(saved_results, output_dir)
|
| 977 |
|
| 978 |
+
print("[3/13] Confusion Matrices", flush=True)
|
| 979 |
plot_confusion_matrices(saved_results, output_dir)
|
| 980 |
else:
|
| 981 |
+
print("[1-3/13] Skipping ROC/PR/CM — no per-sample predictions stored", flush=True)
|
| 982 |
|
| 983 |
+
print("[4/13] Model Comparison Bar Chart", flush=True)
|
| 984 |
plot_model_comparison(saved_results, output_dir)
|
| 985 |
|
| 986 |
+
print("[5/13] Feature Importance", flush=True)
|
| 987 |
plot_feature_importance(saved_results, output_dir)
|
| 988 |
|
| 989 |
+
print("[6/13] Feature Correlation Heatmap", flush=True)
|
| 990 |
plot_correlation_heatmap(features_csv, output_dir)
|
| 991 |
|
| 992 |
+
print("[7/13] Feature Distributions (AI vs Human)", flush=True)
|
| 993 |
plot_feature_distributions(features_csv, output_dir, saved_results)
|
| 994 |
|
| 995 |
+
print("[8/13] LaTeX / Markdown Tables", flush=True)
|
| 996 |
generate_latex_table(saved_results, output_dir)
|
| 997 |
|
| 998 |
+
print("[9/13] Dataset Statistics", flush=True)
|
| 999 |
+
plot_dataset_statistics(manifest_csv, output_dir)
|
| 1000 |
+
|
| 1001 |
+
print("[10/13] Per-Source Class Balance", flush=True)
|
| 1002 |
+
plot_per_source_balance(manifest_csv, output_dir)
|
| 1003 |
+
|
| 1004 |
+
print("[11/13] Feature Space Embedding (PCA + t-SNE)", flush=True)
|
| 1005 |
+
plot_feature_embedding(features_csv, output_dir)
|
| 1006 |
+
|
| 1007 |
+
if has_arrays:
|
| 1008 |
+
print("[12/13] Calibration Curves", flush=True)
|
| 1009 |
+
plot_calibration_curves(saved_results, output_dir)
|
| 1010 |
+
|
| 1011 |
+
print("[13/13] Prediction Score Distribution", flush=True)
|
| 1012 |
+
plot_score_distribution(saved_results, output_dir)
|
| 1013 |
+
else:
|
| 1014 |
+
print("[12-13/13] Skipping calibration/score dist — no probabilities stored", flush=True)
|
| 1015 |
+
|
| 1016 |
+
print("\n[EXTRA] Report Summary (Markdown)", flush=True)
|
| 1017 |
+
generate_extended_summary(saved_results, manifest_csv, features_csv, output_dir)
|
| 1018 |
+
|
| 1019 |
+
print(f"\nAll figures saved to {output_dir}/", flush=True)
|
| 1020 |
|
| 1021 |
|
| 1022 |
if __name__ == "__main__":
|