""" Bootstrap confidence intervals for key metrics (accuracy, f1, auc) on test predictions. """ from pathlib import Path import json import numpy as np import joblib from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, f1_score, roc_auc_score from src.preprocess import build_dataset_from_folder def ci(arr, alpha=0.95): lo = (1 - alpha) / 2 hi = 1 - lo return float(np.quantile(arr, lo)), float(np.quantile(arr, hi)) def main(model_path='outputs/model_rf_real.joblib', n_boot=300, seed=42): X0, y0 = build_dataset_from_folder('data/relaxed', label=0) X1, y1 = build_dataset_from_folder('data/focused', label=1) X = np.vstack([X0, X1]) y = np.concatenate([y0, y1]) _, X_test, _, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y) mp = Path(model_path) if not mp.exists(): raise FileNotFoundError(f'Model not found: {mp}') clf = joblib.load(mp) pred = clf.predict(X_test) proba = clf.predict_proba(X_test)[:, 1] rng = np.random.default_rng(seed) n = len(y_test) accs, f1s, aucs = [], [], [] for _ in range(n_boot): idx = rng.integers(0, n, size=n) yt = y_test[idx] yp = pred[idx] pp = proba[idx] accs.append(accuracy_score(yt, yp)) f1s.append(f1_score(yt, yp)) try: aucs.append(roc_auc_score(yt, pp)) except Exception: pass out = { 'n_bootstrap': int(n_boot), 'accuracy_mean': float(np.mean(accs)), 'accuracy_ci95': ci(np.array(accs)), 'f1_mean': float(np.mean(f1s)), 'f1_ci95': ci(np.array(f1s)), 'auc_mean': float(np.mean(aucs)) if aucs else None, 'auc_ci95': ci(np.array(aucs)) if aucs else None, } od = Path('outputs'); od.mkdir(exist_ok=True) fp = od / 'bootstrap_ci_results.json' fp.write_text(json.dumps(out, indent=2), encoding='utf-8') print(json.dumps(out, indent=2)) print(f'Saved {fp}') if __name__ == '__main__': main()