Spaces:
Running
Running
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import math | |
| from pathlib import Path | |
| from statistics import mean | |
| from typing import Any | |
| def load_jsonl(path: Path) -> list[dict[str, Any]]: | |
| return [json.loads(line) for line in path.read_text(encoding="utf-8").splitlines() if line.strip()] | |
| def parse_prediction(row: dict[str, Any]) -> dict[str, Any] | None: | |
| text = row.get("predictionText", "") | |
| if isinstance(text, dict): | |
| return text | |
| start = str(text).find("{") | |
| end = str(text).rfind("}") | |
| if start < 0 or end <= start: | |
| return None | |
| try: | |
| parsed = json.loads(str(text)[start : end + 1]) | |
| except json.JSONDecodeError: | |
| return None | |
| return parsed if isinstance(parsed, dict) else None | |
| def invite(value: dict[str, Any]) -> bool: | |
| return bool(value.get("invite_to_speed_date") or value.get("passed")) | |
| def main() -> None: | |
| parser = argparse.ArgumentParser(description="Evaluate matchmaker predictions against teacher or feedback labels.") | |
| parser.add_argument("--dataset", type=Path, required=True, help="Test/eval JSONL produced by prepare_dataset.py.") | |
| parser.add_argument("--predictions", type=Path, help="Prediction JSONL produced by predict.py.") | |
| args = parser.parse_args() | |
| dataset = {row["pairHash"]: row for row in load_jsonl(args.dataset)} | |
| if not args.predictions: | |
| scores = [float(row["target"]["compatibility"]) for row in dataset.values()] | |
| labels = {row["target"]["label"] for row in dataset.values()} | |
| print( | |
| json.dumps( | |
| { | |
| "pairs": len(dataset), | |
| "meanTeacherCompatibility": round(mean(scores), 3) if scores else 0, | |
| "positiveRate": round(sum(invite(row["target"]) for row in dataset.values()) / max(1, len(dataset)), 4), | |
| "labels": sorted(labels), | |
| }, | |
| indent=2, | |
| sort_keys=True, | |
| ) | |
| ) | |
| return | |
| pred_rows = load_jsonl(args.predictions) | |
| mae_values: list[float] = [] | |
| exact_invite = 0 | |
| valid_json = 0 | |
| evaluated = 0 | |
| for pred_row in pred_rows: | |
| target_row = dataset.get(pred_row["pairHash"]) | |
| if not target_row: | |
| continue | |
| evaluated += 1 | |
| parsed = parse_prediction(pred_row) | |
| if not parsed: | |
| continue | |
| valid_json += 1 | |
| target_score = float(target_row["target"]["compatibility"]) | |
| pred_score = float(parsed.get("compatibility", math.nan)) | |
| if not math.isnan(pred_score): | |
| mae_values.append(abs(pred_score - target_score)) | |
| exact_invite += int(invite(parsed) == invite(target_row["target"])) | |
| print( | |
| json.dumps( | |
| { | |
| "evaluated": evaluated, | |
| "validJsonRate": round(valid_json / max(1, evaluated), 4), | |
| "compatibilityMae": round(mean(mae_values), 3) if mae_values else None, | |
| "inviteAccuracy": round(exact_invite / max(1, evaluated), 4), | |
| }, | |
| indent=2, | |
| sort_keys=True, | |
| ) | |
| ) | |
| if __name__ == "__main__": | |
| main() | |