File size: 1,901 Bytes
d1f3f31 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parents[1]
METRICS_PATH = PROJECT_ROOT / "models" / "sales_conversion_metrics.json"
def main() -> int:
parser = argparse.ArgumentParser(description="Validate saved conversion-model performance metrics.")
parser.add_argument("--min-accuracy", type=float, default=0.73)
parser.add_argument("--min-recall", type=float, default=0.80)
parser.add_argument("--min-f1", type=float, default=0.74)
args = parser.parse_args()
if not METRICS_PATH.exists():
print(json.dumps({"status": "failed", "failures": [f"{METRICS_PATH.name} not found"]}, indent=2))
return 2
metrics = json.loads(METRICS_PATH.read_text(encoding="utf-8"))
failures = []
if float(metrics.get("accuracy", 0)) < args.min_accuracy:
failures.append(f"accuracy {metrics.get('accuracy')} is below {args.min_accuracy}")
if float(metrics.get("recall", 0)) < args.min_recall:
failures.append(f"recall {metrics.get('recall')} is below {args.min_recall}")
if float(metrics.get("f1", 0)) < args.min_f1:
failures.append(f"f1 {metrics.get('f1')} is below {args.min_f1}")
print(
json.dumps(
{
"status": "passed" if not failures else "failed",
"model": metrics.get("model_name"),
"accuracy": metrics.get("accuracy"),
"precision": metrics.get("precision"),
"recall": metrics.get("recall"),
"f1": metrics.get("f1"),
"roc_auc": metrics.get("roc_auc"),
"threshold": metrics.get("classification_threshold"),
"failures": failures,
},
indent=2,
)
)
return 1 if failures else 0
if __name__ == "__main__":
sys.exit(main())
|