""" Evaluate the reasoning classifier on evaluation CSV. Reports accuracy, ROC-AUC, and calibration (Brier score). """ import argparse import csv from typing import List, Dict import joblib from sklearn.metrics import accuracy_score, roc_auc_score, brier_score_loss from backend.models.reasoning_classifier import build_feature_vector, default_model_path def load_csv(path: str) -> List[Dict[str, str]]: with open(path, "r", encoding="utf-8") as f: reader = csv.DictReader(f) return list(reader) def parse_bool(value: str) -> int: if isinstance(value, bool): return int(value) v = str(value).strip().lower() return 1 if v in ["1", "true", "yes"] else 0 def build_features_from_row(row: Dict[str, str]) -> List[float]: return build_feature_vector( symbolic_score=float(row.get("symbolic_score", 0.0)), logical_score=float(row.get("logical_score", 0.0)), avg_consensus=float(row.get("avg_consensus", 0.0)), hallucination_rate=float(row.get("hallucination_rate", 0.0)), num_flagged_steps=int(float(row.get("num_flagged_steps", 0))), ocr_confidence=float(row.get("ocr_confidence", 1.0)), steps_count=int(float(row.get("steps_count", 0))), reasoning_length=int(float(row.get("reasoning_length", 0))), consensus_total_steps=int(float(row.get("consensus_total_steps", 0))) ) def main(): parser = argparse.ArgumentParser() parser.add_argument("--csv", type=str, default="evaluation_results.csv", help="Evaluation CSV") parser.add_argument("--model", type=str, default="", help="Model path") parser.add_argument("--split", type=str, default="test", help="Split name to evaluate") args = parser.parse_args() rows = load_csv(args.csv) rows = [r for r in rows if r.get("split") == args.split] if not rows: raise ValueError("No rows found for requested split.") X = [build_features_from_row(r) for r in rows] y = [parse_bool(r.get("is_correct", 0)) for r in rows] model_path = args.model or default_model_path() model = joblib.load(model_path) y_pred = model.predict(X) y_proba = model.predict_proba(X)[:, 1] acc = accuracy_score(y, y_pred) try: auc = roc_auc_score(y, y_proba) except Exception: auc = 0.0 brier = brier_score_loss(y, y_proba) print(f"[RESULT] Split: {args.split}") print(f"Accuracy: {acc:.4f}") print(f"ROC-AUC: {auc:.4f}") print(f"Brier: {brier:.4f}") if __name__ == "__main__": main()