"""Compare fixed classifiers under a declared cost contract; no policy selection.""" import argparse import hashlib import json from pathlib import Path from baseline import (load_rows, split_rows, fit_scaler, train_logistic, predict_logistic, majority_label, DATA_SHA256, SALT) from costs import score ROOT = Path(__file__).resolve().parent def record(): parts = split_rows(load_rows()) scaler = fit_scaler(parts['training']) model = train_logistic(parts['training'], scaler) majority = majority_label(parts['training']) validation = parts['validation'] cases = [{'id': hashlib.sha256(row['key'].encode()).hexdigest(), 'label': row['label']} for row in validation] fixed = {'majority': [majority] * len(cases), 'logistic': [predict_logistic(model, scaler, row) for row in validation]} contract = json.loads((ROOT / 'costs.json').read_text()) results = {} for name, labels in fixed.items(): predictions = [{'id': case['id'], 'label': label} for case, label in zip(cases, labels)] results[name] = score(cases, predictions, contract['matrix']) return {'data_sha256': DATA_SHA256, 'split_salt': SALT, 'split': 'validation', 'cases': len(cases), 'cost_contract': contract, 'results': results} def main(): parser = argparse.ArgumentParser() parser.add_argument('--save', type=Path, help='Write a new local result JSON') parser.add_argument('--check', action='store_true', help='Compare with the bundled result') args = parser.parse_args() result = record() if args.check and result != json.loads((ROOT / 'result.json').read_text()): raise SystemExit('current result differs from the bundled record') if args.save: args.save.write_text(json.dumps(result, indent=2) + '\n') print(f"validation: {result['cases']} ID-aligned cases; fixed majority and logistic classifiers") for name, row in result['results'].items(): print(f"{name}: accuracy={row['metrics']['accuracy']:.4f}; errors={len(row['errors'])}; " f"cost={row['total_cost']:g}; cost/case={row['cost_per_case']:.6f}") print('Cost unit:', result['cost_contract']['unit']) print('Costs are declared scenario assumptions. No monetary impact or threshold improvement was measured.') if __name__ == '__main__': main()