{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session\n\n# Use the kagglehub client library to attach Kaggle resources like competitions, datasets, and models to your session\n# Learn more about kagglehub: https://github.com/Kaggle/kagglehub/blob/main/README.md\n\nimport kagglehub\n# kagglehub.dataset_download('<owner>/<dataset-slug>')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-06-13T17:49:55.290983Z","iopub.execute_input":"2026-06-13T17:49:55.291337Z","iopub.status.idle":"2026-06-13T17:50:01.931400Z","shell.execute_reply.started":"2026-06-13T17:49:55.291310Z","shell.execute_reply":"2026-06-13T17:50:01.930384Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\nimport torch\nimport torch.nn as nn\nimport torchvision.models as models\nimport torchvision.transforms as T\nfrom torch.utils.data import Dataset, DataLoader\nfrom sklearn.preprocessing import StandardScaler, label_binarize\nfrom sklearn.metrics import roc_curve, auc\nfrom sklearn.multiclass import OneVsRestClassifier\nimport pickle\nfrom PIL import Image\nimport warnings\nwarnings.filterwarnings('ignore')\n\nDEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nSEED = 42\nIMG_SIZE = 224\nBATCH_SIZE = 64\nNUM_CLASSES = 5\nMEAN = [0.485, 0.456, 0.406]\nSTD  = [0.229, 0.224, 0.225]\nBASE = '/kaggle/input/competitions/aptos2019-blindness-detection'\nprint(f\"Device: {DEVICE}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T17:56:28.633197Z","iopub.execute_input":"2026-06-13T17:56:28.633783Z","iopub.status.idle":"2026-06-13T17:56:30.612347Z","shell.execute_reply.started":"2026-06-13T17:56:28.633750Z","shell.execute_reply":"2026-06-13T17:56:30.611384Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def apply_clahe_fast(image_path, img_size=IMG_SIZE, clip_limit=2.0):\n    try:\n        img = cv2.imread(image_path)\n        if img is None:\n            raise ValueError('Cannot read')\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        img = cv2.resize(img, (img_size, img_size))\n        lab = cv2.cvtColor(img, cv2.COLOR_RGB2LAB)\n        l, a, b = cv2.split(lab)\n        clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=(8, 8))\n        l = clahe.apply(l)\n        lab = cv2.merge([l, a, b])\n        img = cv2.cvtColor(lab, cv2.COLOR_LAB2RGB)\n        return Image.fromarray(img)\n    except:\n        return Image.new('RGB', (img_size, img_size))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T17:56:58.625942Z","iopub.execute_input":"2026-06-13T17:56:58.626418Z","iopub.status.idle":"2026-06-13T17:56:58.633415Z","shell.execute_reply.started":"2026-06-13T17:56:58.626390Z","shell.execute_reply":"2026-06-13T17:56:58.632329Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class DRDataset(Dataset):\n    def __init__(self, df, transform=None):\n        self.df = df.reset_index(drop=True)\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        img = apply_clahe_fast(row['filepath'])\n        if self.transform:\n            img = self.transform(img)\n        label = int(row['label'])\n        return img, label\n\nval_tfm = T.Compose([\n    T.ToTensor(),\n    T.Normalize(MEAN, STD),\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T17:57:17.510244Z","iopub.execute_input":"2026-06-13T17:57:17.510553Z","iopub.status.idle":"2026-06-13T17:57:17.517776Z","shell.execute_reply.started":"2026-06-13T17:57:17.510527Z","shell.execute_reply":"2026-06-13T17:57:17.516742Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"checkpoint = torch.load(\n    \"/kaggle/input/datasets/snehachalla73/best-final-model/effb0_fast_best.pth\",\n    map_location=\"cpu\"\n)\n\nprint(type(checkpoint))\nprint(list(checkpoint.keys())[:20])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T17:58:27.625434Z","iopub.execute_input":"2026-06-13T17:58:27.625816Z","iopub.status.idle":"2026-06-13T17:58:27.694010Z","shell.execute_reply.started":"2026-06-13T17:58:27.625785Z","shell.execute_reply":"2026-06-13T17:58:27.693080Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"checkpoint = torch.load(\n    \"/kaggle/input/datasets/snehachalla73/best-final-model/effb0_fast_best.pth\",\n    map_location=\"cpu\"\n)\n\nfor k in checkpoint.keys():\n    if \"classifier\" in k:\n        print(k, checkpoint[k].shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T17:58:58.222318Z","iopub.execute_input":"2026-06-13T17:58:58.223205Z","iopub.status.idle":"2026-06-13T17:58:58.294025Z","shell.execute_reply.started":"2026-06-13T17:58:58.223143Z","shell.execute_reply":"2026-06-13T17:58:58.293142Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom torchvision import models\n\nNUM_CLASSES = 5\n\nclass EfficientNetB0_DR(nn.Module):\n    def __init__(self):\n        super().__init__()\n\n        base = models.efficientnet_b0(weights=None)\n\n        self.features = base.features\n        self.avgpool = base.avgpool\n\n        self.classifier = nn.Sequential(\n            nn.Dropout(0.4),          # index 0\n            nn.Linear(1280, 512),     # index 1\n            nn.BatchNorm1d(512),      # index 2\n            nn.ReLU(inplace=True),    # index 3\n\n            nn.Dropout(0.3),          # index 4\n            nn.Linear(512, 256),      # index 5\n            nn.BatchNorm1d(256),      # index 6\n            nn.ReLU(inplace=True),    # index 7\n\n            nn.Dropout(0.2),          # index 8\n            nn.Linear(256, 5)         # index 9\n        )\n\n    def forward(self, x):\n        x = self.features(x)\n        x = self.avgpool(x)\n        x = torch.flatten(x, 1)\n        return self.classifier(x)\n\n    def extract_features(self, x):\n        x = self.features(x)\n        x = self.avgpool(x)\n        x = torch.flatten(x, 1)\n        return x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T18:00:00.595517Z","iopub.execute_input":"2026-06-13T18:00:00.595892Z","iopub.status.idle":"2026-06-13T18:00:00.606130Z","shell.execute_reply.started":"2026-06-13T18:00:00.595866Z","shell.execute_reply":"2026-06-13T18:00:00.605192Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"DEVICE = torch.device(\n    \"cuda\" if torch.cuda.is_available() else \"cpu\"\n)\n\nmodel = EfficientNetB0_DR().to(DEVICE)\n\ncheckpoint = torch.load(\n    \"/kaggle/input/datasets/snehachalla73/best-final-model/effb0_fast_best.pth\",\n    map_location=DEVICE\n)\n\nmodel.load_state_dict(checkpoint)\n\nmodel.eval()\n\nprint(\"Model Loaded Successfully\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T18:00:11.266331Z","iopub.execute_input":"2026-06-13T18:00:11.266749Z","iopub.status.idle":"2026-06-13T18:00:11.461940Z","shell.execute_reply.started":"2026-06-13T18:00:11.266690Z","shell.execute_reply":"2026-06-13T18:00:11.461004Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nfrom sklearn.model_selection import train_test_split\n\ndef find_image(id_code, folders):\n    for folder in folders:\n        path = f\"{BASE}/{folder}/{id_code}.png\"\n        if os.path.exists(path):\n            return path\n    return None\n\ndf_raw = pd.read_csv(f'{BASE}/train.csv')\ndf_raw['label']    = df_raw['diagnosis']\ndf_raw['filepath'] = df_raw['id_code'].apply(\n    lambda x: find_image(x, ['train_images'])\n)\ndf_raw = df_raw[df_raw['filepath'].notna()].reset_index(drop=True)\n\n_, df_te = train_test_split(\n    df_raw, test_size=0.20,\n    stratify=df_raw['label'], random_state=SEED\n)\nprint(f\"Test set size: {len(df_te)}\")\nprint(df_te['label'].value_counts().sort_index())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T18:01:06.563802Z","iopub.execute_input":"2026-06-13T18:01:06.564115Z","iopub.status.idle":"2026-06-13T18:01:11.369898Z","shell.execute_reply.started":"2026-06-13T18:01:06.564091Z","shell.execute_reply":"2026-06-13T18:01:11.368716Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_ds = DRDataset(df_te, transform=val_tfm)\ntest_dl = DataLoader(test_ds, batch_size=BATCH_SIZE, shuffle=False,\n                     num_workers=2, pin_memory=True)\n\n@torch.no_grad()\ndef extract_features(model, dataloader, device):\n    feats, labs = [], []\n    for images, labels in dataloader:\n        images = images.to(device)\n        f = model.extract_features(images).cpu().numpy()\n        feats.append(f)\n        labs.extend(labels.numpy())\n    return np.vstack(feats), np.array(labs)\n\ntest_features, test_labels = extract_features(model, test_dl, DEVICE)\nprint(f\"Features shape : {test_features.shape}\")\nprint(f\"Labels shape   : {test_labels.shape}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T18:01:25.443853Z","iopub.execute_input":"2026-06-13T18:01:25.444180Z","iopub.status.idle":"2026-06-13T18:02:30.392512Z","shell.execute_reply.started":"2026-06-13T18:01:25.444153Z","shell.execute_reply":"2026-06-13T18:02:30.391668Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import joblib\n\nscaler = joblib.load(\n    \"/kaggle/input/datasets/snehachalla73/p-files/scaler.pkl\"\n)\n\nsvm_model = joblib.load(\n    \"/kaggle/input/datasets/snehachalla73/p-files/svm_model.pkl\"\n)\n\nprint(type(scaler))\nprint(type(svm_model))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T18:03:44.214961Z","iopub.execute_input":"2026-06-13T18:03:44.215342Z","iopub.status.idle":"2026-06-13T18:03:44.617184Z","shell.execute_reply.started":"2026-06-13T18:03:44.215313Z","shell.execute_reply":"2026-06-13T18:03:44.616274Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_scaled = scaler.transform(test_features)\n\n# Get probabilities for all 5 classes\ntest_proba = svm_model.predict_proba(test_scaled)\ntest_pred  = svm_model.predict(test_scaled)\n\nprint(f\"Probabilities shape : {test_proba.shape}\")\nprint(f\"Predictions shape   : {test_pred.shape}\")\nprint(f\"\\nSample probabilities (first 3 rows):\")\nprint(np.round(test_proba[:3], 4))\nprint(f\"\\nUnique predicted classes: {np.unique(test_pred)}\")\nprint(f\"True class distribution : {np.bincount(test_labels)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T18:07:36.508847Z","iopub.execute_input":"2026-06-13T18:07:36.509205Z","iopub.status.idle":"2026-06-13T18:07:38.624592Z","shell.execute_reply.started":"2026-06-13T18:07:36.509168Z","shell.execute_reply":"2026-06-13T18:07:38.623751Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from itertools import cycle\n\nCLASS_NAMES = [\n    'No DR (0)',\n    'Mild (1)',\n    'Moderate (2)',\n    'Severe (3)',\n    'Proliferative DR (4)'\n]\n\n# Binarize labels → shape (n_samples, 5)\ny_bin = label_binarize(test_labels, classes=list(range(NUM_CLASSES)))\n\nfpr, tpr, roc_auc = {}, {}, {}\n\n# Per-class ROC\nfor i in range(NUM_CLASSES):\n    fpr[i], tpr[i], _ = roc_curve(y_bin[:, i], test_proba[:, i])\n    roc_auc[i] = auc(fpr[i], tpr[i])\n\n# Macro-average ROC\nall_fpr  = np.unique(np.concatenate([fpr[i] for i in range(NUM_CLASSES)]))\nmean_tpr = np.zeros_like(all_fpr)\nfor i in range(NUM_CLASSES):\n    mean_tpr += np.interp(all_fpr, fpr[i], tpr[i])\nmean_tpr /= NUM_CLASSES\n\nfpr['macro']     = all_fpr\ntpr['macro']     = mean_tpr\nroc_auc['macro'] = auc(all_fpr, mean_tpr)\n\n# Micro-average ROC\nfpr['micro'], tpr['micro'], _ = roc_curve(\n    y_bin.ravel(), test_proba.ravel()\n)\nroc_auc['micro'] = auc(fpr['micro'], tpr['micro'])\n\nprint(\"AUC Scores:\")\nprint(\"-\" * 40)\nfor i in range(NUM_CLASSES):\n    print(f\"  {CLASS_NAMES[i]:<25}: {roc_auc[i]:.4f}\")\nprint(f\"  {'Macro-Average':<25}: {roc_auc['macro']:.4f}\")\nprint(f\"  {'Micro-Average':<25}: {roc_auc['micro']:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T18:08:15.705208Z","iopub.execute_input":"2026-06-13T18:08:15.706125Z","iopub.status.idle":"2026-06-13T18:08:15.728261Z","shell.execute_reply.started":"2026-06-13T18:08:15.706094Z","shell.execute_reply":"2026-06-13T18:08:15.727355Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"COLORS = ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00']\n\nfig, ax = plt.subplots(figsize=(9, 7))\n\nfor i in range(NUM_CLASSES):\n    ax.plot(\n        fpr[i], tpr[i],\n        color=COLORS[i], lw=2,\n        label=f'{CLASS_NAMES[i]}  (AUC = {roc_auc[i]:.3f})'\n    )\n\nax.plot([0, 1], [0, 1], 'k--', lw=1.5, label='Random Classifier')\nax.set_xlim([0.0, 1.0])\nax.set_ylim([0.0, 1.02])\nax.set_xlabel('False Positive Rate', fontsize=13)\nax.set_ylabel('True Positive Rate', fontsize=13)\nax.set_title(\n    'ROC Curves — Per Class (One-vs-Rest)\\nEfficientNet-B0 + SVM  |  APTOS 2019',\n    fontsize=14, fontweight='bold'\n)\nax.legend(loc='lower right', fontsize=11)\nax.grid(True, alpha=0.3)\n\nplt.tight_layout()\nplt.savefig('roc_per_class.png', dpi=150, bbox_inches='tight')\nplt.show()\nprint(\"Saved: roc_per_class.png\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T18:08:32.965476Z","iopub.execute_input":"2026-06-13T18:08:32.965936Z","iopub.status.idle":"2026-06-13T18:08:33.632553Z","shell.execute_reply.started":"2026-06-13T18:08:32.965908Z","shell.execute_reply":"2026-06-13T18:08:33.631764Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(8, 7))\n\nax.plot(\n    fpr['macro'], tpr['macro'],\n    color='navy', lw=2.5, linestyle='-',\n    label=f'Macro-Average  (AUC = {roc_auc[\"macro\"]:.3f})'\n)\nax.fill_between(fpr['macro'], tpr['macro'], alpha=0.10, color='navy')\n\nax.plot(\n    fpr['micro'], tpr['micro'],\n    color='darkorange', lw=2.5, linestyle='--',\n    label=f'Micro-Average  (AUC = {roc_auc[\"micro\"]:.3f})'\n)\nax.fill_between(fpr['micro'], tpr['micro'], alpha=0.10, color='darkorange')\n\nax.plot([0, 1], [0, 1], 'k--', lw=1.5, label='Random Classifier')\nax.set_xlim([0.0, 1.0])\nax.set_ylim([0.0, 1.02])\nax.set_xlabel('False Positive Rate', fontsize=13)\nax.set_ylabel('True Positive Rate', fontsize=13)\nax.set_title(\n    'Macro & Micro Average ROC Curves\\nEfficientNet-B0 + SVM  |  APTOS 2019',\n    fontsize=14, fontweight='bold'\n)\nax.legend(loc='lower right', fontsize=12)\nax.grid(True, alpha=0.3)\n\nplt.tight_layout()\nplt.savefig('roc_average.png', dpi=150, bbox_inches='tight')\nplt.show()\nprint(\"Saved: roc_average.png\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T18:09:36.174461Z","iopub.execute_input":"2026-06-13T18:09:36.174848Z","iopub.status.idle":"2026-06-13T18:09:36.696476Z","shell.execute_reply.started":"2026-06-13T18:09:36.174820Z","shell.execute_reply":"2026-06-13T18:09:36.695411Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, axes = plt.subplots(2, 3, figsize=(18, 11))\naxes = axes.flatten()\n\n# Individual class subplots\nfor i in range(NUM_CLASSES):\n    ax = axes[i]\n    ax.plot(fpr[i], tpr[i], color=COLORS[i], lw=2.5,\n            label=f'AUC = {roc_auc[i]:.3f}')\n    ax.fill_between(fpr[i], tpr[i], alpha=0.12, color=COLORS[i])\n    ax.plot([0, 1], [0, 1], 'k--', lw=1.2)\n    ax.set_xlim([0, 1]); ax.set_ylim([0, 1.02])\n    ax.set_title(f'{CLASS_NAMES[i]}', fontsize=12, fontweight='bold')\n    ax.set_xlabel('FPR', fontsize=10)\n    ax.set_ylabel('TPR', fontsize=10)\n    ax.legend(loc='lower right', fontsize=11)\n    ax.grid(True, alpha=0.3)\n\n# Last subplot: all averages together\nax = axes[5]\nax.plot(fpr['macro'], tpr['macro'], color='navy', lw=2.5,\n        label=f'Macro  AUC = {roc_auc[\"macro\"]:.3f}')\nax.plot(fpr['micro'], tpr['micro'], color='darkorange', lw=2.5,\n        linestyle='--', label=f'Micro  AUC = {roc_auc[\"micro\"]:.3f}')\nfor i in range(NUM_CLASSES):\n    ax.plot(fpr[i], tpr[i], color=COLORS[i], lw=1.2, alpha=0.5)\nax.plot([0, 1], [0, 1], 'k--', lw=1.2)\nax.set_xlim([0, 1]); ax.set_ylim([0, 1.02])\nax.set_title('All Classes + Averages', fontsize=12, fontweight='bold')\nax.set_xlabel('FPR', fontsize=10)\nax.set_ylabel('TPR', fontsize=10)\nax.legend(loc='lower right', fontsize=10)\nax.grid(True, alpha=0.3)\n\nfig.suptitle(\n    'Full AUC Analysis — EfficientNet-B0 + SVM  |  APTOS 2019 DR Detection',\n    fontsize=15, fontweight='bold', y=1.01\n)\nplt.tight_layout()\nplt.savefig('roc_full_analysis.png', dpi=150, bbox_inches='tight')\nplt.show()\nprint(\"Saved: roc_full_analysis.png\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T18:09:57.240150Z","iopub.execute_input":"2026-06-13T18:09:57.240508Z","iopub.status.idle":"2026-06-13T18:09:59.281853Z","shell.execute_reply.started":"2026-06-13T18:09:57.240478Z","shell.execute_reply":"2026-06-13T18:09:59.281004Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(10, 5))\n\nbar_labels = CLASS_NAMES + ['Macro-Avg', 'Micro-Avg']\nbar_scores = ([roc_auc[i] for i in range(NUM_CLASSES)]\n              + [roc_auc['macro'], roc_auc['micro']])\nbar_colors = COLORS + ['navy', 'darkorange']\n\nbars = ax.bar(bar_labels, bar_scores,\n              color=bar_colors, edgecolor='black',\n              width=0.6, alpha=0.85)\n\nax.set_ylim([0.5, 1.08])\nax.axhline(y=0.90, color='gray', linestyle='--',\n           alpha=0.7, lw=1.5, label='AUC = 0.90 reference')\nax.axhline(y=1.00, color='green', linestyle=':',\n           alpha=0.5, lw=1.5, label='Perfect AUC = 1.00')\nax.set_ylabel('AUC Score', fontsize=13)\nax.set_title(\n    'AUC Score per Class — EfficientNet-B0 + SVM',\n    fontsize=14, fontweight='bold'\n)\nax.set_xticklabels(bar_labels, rotation=20, ha='right', fontsize=10)\nax.legend(fontsize=10)\n\nfor bar, score in zip(bars, bar_scores):\n    ax.text(\n        bar.get_x() + bar.get_width() / 2,\n        bar.get_height() + 0.010,\n        f'{score:.3f}',\n        ha='center', va='bottom',\n        fontsize=11, fontweight='bold'\n    )\n\nplt.tight_layout()\nplt.savefig('auc_bar_summary.png', dpi=150, bbox_inches='tight')\nplt.show()\nprint(\"Saved: auc_bar_summary.png\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-13T18:10:39.539571Z","iopub.execute_input":"2026-06-13T18:10:39.540450Z","iopub.status.idle":"2026-06-13T18:10:40.012932Z","shell.execute_reply.started":"2026-06-13T18:10:39.540416Z","shell.execute_reply":"2026-06-13T18:10:40.012016Z"}},"outputs":[],"execution_count":null}]}