Spaces:
Runtime error
Runtime error
Download training/evaluate.py from Satyam311/maintenance-classifier-api: direct link, hf CLI and curl.
- Browser
- Download file 4.33 kB
-
https://huggingface.co/spaces/Satyam311/maintenance-classifier-api/resolve/main/training/evaluate.py
- Command line
-
hf download hf://spaces/Satyam311/maintenance-classifier-api/training/evaluate.py
-
curl -L -o evaluate.py https://huggingface.co/spaces/Satyam311/maintenance-classifier-api/resolve/main/training/evaluate.py
4.33 kB
| """ | |
| Ticket 6 — Evaluation & Confusion Matrix Report (ATA classifier). | |
| Runs the trained model against the TEST split (never used for training or | |
| checkpoint selection -- that was val) and produces: | |
| - overall accuracy / macro-F1 (comparable to the PRD's success metric) | |
| - per-class precision/recall/F1 (exposes which classes are actually weak, | |
| which a single headline number hides) | |
| - a confusion matrix image | |
| - a metrics JSON, for the Model Performance Dashboard (Ticket 16) to read later | |
| """ | |
| import json | |
| from pathlib import Path | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| import pandas as pd | |
| import torch | |
| from sklearn.metrics import ( | |
| accuracy_score, | |
| classification_report, | |
| confusion_matrix, | |
| precision_recall_fscore_support, | |
| ) | |
| from transformers import AutoModelForSequenceClassification, AutoTokenizer | |
| MODEL_DIR = "models/ata_classifier" | |
| TEST_CSV = "data/processed/test.csv" | |
| MAX_LENGTH = 256 | |
| OUT_DIR = "reports/ata_classifier" | |
| def main(): | |
| Path(OUT_DIR).mkdir(parents=True, exist_ok=True) | |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_DIR, local_files_only=True) | |
| model = AutoModelForSequenceClassification.from_pretrained(MODEL_DIR, local_files_only=True) | |
| model.eval() | |
| with open(f"{MODEL_DIR}/label_map.json") as f: | |
| label_map = json.load(f) | |
| id2label = {int(k): v for k, v in label_map["id2label"].items()} | |
| label2id = label_map["label2id"] | |
| df = pd.read_csv(TEST_CSV) | |
| df = df[df["ata_chapter_label"].notna()].reset_index(drop=True) | |
| print(f"Test examples (ATA-labeled): {len(df)}") | |
| true_labels = df["ata_chapter_label"].astype(str).tolist() | |
| y_true = [label2id[t] for t in true_labels] | |
| y_pred = [] | |
| with torch.no_grad(): | |
| for text in df["narrative_text"].tolist(): | |
| inputs = tokenizer(text, truncation=True, max_length=MAX_LENGTH, return_tensors="pt") | |
| logits = model(**inputs).logits | |
| pred_id = int(torch.argmax(logits, dim=1).item()) | |
| y_pred.append(pred_id) | |
| acc = accuracy_score(y_true, y_pred) | |
| precision, recall, f1, support = precision_recall_fscore_support( | |
| y_true, y_pred, average="macro", zero_division=0 | |
| ) | |
| print(f"\n=== TEST SET RESULTS (never used in training or checkpoint selection) ===") | |
| print(f"Accuracy: {acc:.1%} (PRD target: >=80%)") | |
| print(f"Macro F1: {f1:.3f}") | |
| print(f"Macro Precision: {precision:.3f} Macro Recall: {recall:.3f}") | |
| labels_present = sorted(set(y_true) | set(y_pred)) | |
| target_names = [id2label[i] for i in labels_present] | |
| report_dict = classification_report( | |
| y_true, y_pred, labels=labels_present, target_names=target_names, | |
| zero_division=0, output_dict=True | |
| ) | |
| print("\nPer-class report:") | |
| print(classification_report(y_true, y_pred, labels=labels_present, target_names=target_names, zero_division=0)) | |
| cm = confusion_matrix(y_true, y_pred, labels=labels_present) | |
| fig, ax = plt.subplots(figsize=(10, 9)) | |
| im = ax.imshow(cm, cmap="Blues") | |
| ax.set_xticks(range(len(target_names))) | |
| ax.set_yticks(range(len(target_names))) | |
| ax.set_xticklabels(target_names, rotation=90) | |
| ax.set_yticklabels(target_names) | |
| ax.set_xlabel("Predicted") | |
| ax.set_ylabel("True") | |
| ax.set_title("ATA Chapter Classifier — Confusion Matrix (Test Set)") | |
| for i in range(len(target_names)): | |
| for j in range(len(target_names)): | |
| if cm[i, j] > 0: | |
| ax.text(j, i, str(cm[i, j]), ha="center", va="center", | |
| color="white" if cm[i, j] > cm.max() / 2 else "black", fontsize=7) | |
| fig.colorbar(im) | |
| fig.tight_layout() | |
| fig.savefig(f"{OUT_DIR}/confusion_matrix.png", dpi=150) | |
| print(f"\nSaved confusion matrix to {OUT_DIR}/confusion_matrix.png") | |
| metrics_out = { | |
| "test_accuracy": acc, | |
| "test_macro_f1": f1, | |
| "test_macro_precision": precision, | |
| "test_macro_recall": recall, | |
| "n_test_examples": len(df), | |
| "per_class": report_dict, | |
| "prd_target_accuracy": 0.80, | |
| "meets_prd_target": acc >= 0.80, | |
| } | |
| with open(f"{OUT_DIR}/metrics.json", "w") as f: | |
| json.dump(metrics_out, f, indent=2) | |
| print(f"Saved metrics JSON to {OUT_DIR}/metrics.json") | |
| if __name__ == "__main__": | |
| main() | |