{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "dd98f908",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/shezin/.local/lib/python3.8/site-packages/pandas/core/computation/expressions.py:20: UserWarning: Pandas requires version '2.7.3' or newer of 'numexpr' (version '2.7.1' currently installed).\n",
      "  from pandas.core.computation.check import NUMEXPR_INSTALLED\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Metric</th>\n",
       "      <th>Set</th>\n",
       "      <th>Model</th>\n",
       "      <th>Accuracy</th>\n",
       "      <th>Sensitivity</th>\n",
       "      <th>Specificity</th>\n",
       "      <th>PPV</th>\n",
       "      <th>NPV</th>\n",
       "      <th>AUC</th>\n",
       "      <th>F1</th>\n",
       "      <th>F2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Tier 1 (6 features)</td>\n",
       "      <td>LogisticRegression</td>\n",
       "      <td>0.537</td>\n",
       "      <td>0.768</td>\n",
       "      <td>0.507</td>\n",
       "      <td>0.167</td>\n",
       "      <td>0.944</td>\n",
       "      <td>0.696</td>\n",
       "      <td>0.275</td>\n",
       "      <td>0.447</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Tier 1 (6 features)</td>\n",
       "      <td>RandomForest</td>\n",
       "      <td>0.660</td>\n",
       "      <td>0.624</td>\n",
       "      <td>0.665</td>\n",
       "      <td>0.194</td>\n",
       "      <td>0.932</td>\n",
       "      <td>0.708</td>\n",
       "      <td>0.296</td>\n",
       "      <td>0.432</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Tier 1 (6 features)</td>\n",
       "      <td>LightGBM</td>\n",
       "      <td>0.647</td>\n",
       "      <td>0.638</td>\n",
       "      <td>0.648</td>\n",
       "      <td>0.190</td>\n",
       "      <td>0.933</td>\n",
       "      <td>0.705</td>\n",
       "      <td>0.292</td>\n",
       "      <td>0.433</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Tier 1 (6 features)</td>\n",
       "      <td>XGBoost</td>\n",
       "      <td>0.577</td>\n",
       "      <td>0.728</td>\n",
       "      <td>0.558</td>\n",
       "      <td>0.176</td>\n",
       "      <td>0.941</td>\n",
       "      <td>0.707</td>\n",
       "      <td>0.283</td>\n",
       "      <td>0.446</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Tier 2 (10 features)</td>\n",
       "      <td>LogisticRegression</td>\n",
       "      <td>0.821</td>\n",
       "      <td>0.914</td>\n",
       "      <td>0.809</td>\n",
       "      <td>0.382</td>\n",
       "      <td>0.986</td>\n",
       "      <td>0.925</td>\n",
       "      <td>0.539</td>\n",
       "      <td>0.715</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Tier 2 (10 features)</td>\n",
       "      <td>RandomForest</td>\n",
       "      <td>0.831</td>\n",
       "      <td>0.901</td>\n",
       "      <td>0.823</td>\n",
       "      <td>0.396</td>\n",
       "      <td>0.985</td>\n",
       "      <td>0.927</td>\n",
       "      <td>0.550</td>\n",
       "      <td>0.718</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Tier 2 (10 features)</td>\n",
       "      <td>LightGBM</td>\n",
       "      <td>0.843</td>\n",
       "      <td>0.885</td>\n",
       "      <td>0.837</td>\n",
       "      <td>0.413</td>\n",
       "      <td>0.983</td>\n",
       "      <td>0.928</td>\n",
       "      <td>0.563</td>\n",
       "      <td>0.721</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Tier 2 (10 features)</td>\n",
       "      <td>XGBoost</td>\n",
       "      <td>0.831</td>\n",
       "      <td>0.906</td>\n",
       "      <td>0.821</td>\n",
       "      <td>0.395</td>\n",
       "      <td>0.985</td>\n",
       "      <td>0.928</td>\n",
       "      <td>0.550</td>\n",
       "      <td>0.720</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Tier 3 (24 features)</td>\n",
       "      <td>LogisticRegression</td>\n",
       "      <td>0.831</td>\n",
       "      <td>0.911</td>\n",
       "      <td>0.820</td>\n",
       "      <td>0.396</td>\n",
       "      <td>0.986</td>\n",
       "      <td>0.932</td>\n",
       "      <td>0.552</td>\n",
       "      <td>0.723</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Tier 3 (24 features)</td>\n",
       "      <td>RandomForest</td>\n",
       "      <td>0.838</td>\n",
       "      <td>0.899</td>\n",
       "      <td>0.831</td>\n",
       "      <td>0.407</td>\n",
       "      <td>0.985</td>\n",
       "      <td>0.932</td>\n",
       "      <td>0.560</td>\n",
       "      <td>0.724</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>Tier 3 (24 features)</td>\n",
       "      <td>LightGBM</td>\n",
       "      <td>0.857</td>\n",
       "      <td>0.876</td>\n",
       "      <td>0.855</td>\n",
       "      <td>0.438</td>\n",
       "      <td>0.982</td>\n",
       "      <td>0.934</td>\n",
       "      <td>0.584</td>\n",
       "      <td>0.730</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>Tier 3 (24 features)</td>\n",
       "      <td>XGBoost</td>\n",
       "      <td>0.831</td>\n",
       "      <td>0.907</td>\n",
       "      <td>0.821</td>\n",
       "      <td>0.396</td>\n",
       "      <td>0.986</td>\n",
       "      <td>0.933</td>\n",
       "      <td>0.551</td>\n",
       "      <td>0.721</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Metric                   Set               Model  Accuracy  Sensitivity  \\\n",
       "0        Tier 1 (6 features)  LogisticRegression     0.537        0.768   \n",
       "1        Tier 1 (6 features)        RandomForest     0.660        0.624   \n",
       "2        Tier 1 (6 features)            LightGBM     0.647        0.638   \n",
       "3        Tier 1 (6 features)             XGBoost     0.577        0.728   \n",
       "4       Tier 2 (10 features)  LogisticRegression     0.821        0.914   \n",
       "5       Tier 2 (10 features)        RandomForest     0.831        0.901   \n",
       "6       Tier 2 (10 features)            LightGBM     0.843        0.885   \n",
       "7       Tier 2 (10 features)             XGBoost     0.831        0.906   \n",
       "8       Tier 3 (24 features)  LogisticRegression     0.831        0.911   \n",
       "9       Tier 3 (24 features)        RandomForest     0.838        0.899   \n",
       "10      Tier 3 (24 features)            LightGBM     0.857        0.876   \n",
       "11      Tier 3 (24 features)             XGBoost     0.831        0.907   \n",
       "\n",
       "Metric  Specificity    PPV    NPV    AUC     F1     F2  \n",
       "0             0.507  0.167  0.944  0.696  0.275  0.447  \n",
       "1             0.665  0.194  0.932  0.708  0.296  0.432  \n",
       "2             0.648  0.190  0.933  0.705  0.292  0.433  \n",
       "3             0.558  0.176  0.941  0.707  0.283  0.446  \n",
       "4             0.809  0.382  0.986  0.925  0.539  0.715  \n",
       "5             0.823  0.396  0.985  0.927  0.550  0.718  \n",
       "6             0.837  0.413  0.983  0.928  0.563  0.721  \n",
       "7             0.821  0.395  0.985  0.928  0.550  0.720  \n",
       "8             0.820  0.396  0.986  0.932  0.552  0.723  \n",
       "9             0.831  0.407  0.985  0.932  0.560  0.724  \n",
       "10            0.855  0.438  0.982  0.934  0.584  0.730  \n",
       "11            0.821  0.396  0.986  0.933  0.551  0.721  "
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "model_files = {\n",
    "    \"LogisticRegression\": \"../results/logreg_5fold_threshold0.50_by_tier.csv\",\n",
    "    \"RandomForest\":       \"../results/rf_5fold_threshold0.50_by_tier.csv\",\n",
    "    \"LightGBM\":           \"../results/lightgbm_5fold_threshold0.50_by_tier.csv\",\n",
    "    \"XGBoost\":            \"../results/xgb_5fold_threshold0.50_by_tier.csv\",\n",
    "}\n",
    "\n",
    "metrics_keep = [\"Accuracy\", \"Sensitivity\", \"Specificity\", \"PPV\", \"NPV\", \"AUC\", \"F1\", \"F2\"]\n",
    "\n",
    "\n",
    "tier_to_set_label = {\n",
    "    \"Tier_1_Basic\":        \"Tier 1 (6 features)\",\n",
    "    \"Tier_2_Clinical\":     \"Tier 2 (10 features)\",\n",
    "    \"Tier_3_Personalized\": \"Tier 3 (24 features)\",\n",
    "}\n",
    "\n",
    "# tier_feature_counts = {\"Tier_1_Basic\": 6, \"Tier_2_Clinical\": 10, \"Tier_3_Personalized\": 24}\n",
    "tier_feature_counts = None \n",
    "\n",
    "\n",
    "def load_model_means(csv_path: str, model_name: str) -> pd.DataFrame:\n",
    "    df = pd.read_csv(csv_path)\n",
    "\n",
    "    # keeping only needed metrics\n",
    "    df = df[df[\"Metric\"].isin(metrics_keep)].copy()\n",
    "\n",
    "    # pivot: rows=tier, cols=Metric, values=Mean\n",
    "    wide = df.pivot_table(index=\"Tier\", columns=\"Metric\", values=\"Mean\", aggfunc=\"first\").reset_index()\n",
    "\n",
    "    wide.insert(1, \"Model\", model_name)\n",
    "    return wide\n",
    "\n",
    "\n",
    "all_models = []\n",
    "for model_name, path in model_files.items():\n",
    "    one = load_model_means(path, model_name)\n",
    "    all_models.append(one)\n",
    "\n",
    "combined = pd.concat(all_models, ignore_index=True)\n",
    "\n",
    "\n",
    "def format_set(tier_name: str) -> str:\n",
    "    base = tier_to_set_label.get(tier_name, tier_name)\n",
    "    if isinstance(tier_feature_counts, dict) and tier_name in tier_feature_counts:\n",
    "        return f\"{base} ({tier_feature_counts[tier_name]} features)\"\n",
    "    return base\n",
    "\n",
    "combined.insert(0, \"Set\", combined[\"Tier\"].map(format_set))\n",
    "\n",
    "\n",
    "final_cols = [\"Set\", \"Model\"] + metrics_keep\n",
    "final_table = combined[final_cols].copy()\n",
    "\n",
    "set_order = [format_set(k) for k in [\"Tier_1_Basic\", \"Tier_2_Clinical\", \"Tier_3_Personalized\"]]\n",
    "model_order = [\"LogisticRegression\", \"RandomForest\", \"LightGBM\", \"XGBoost\"]\n",
    "\n",
    "final_table[\"Set\"] = pd.Categorical(final_table[\"Set\"], categories=set_order, ordered=True)\n",
    "final_table[\"Model\"] = pd.Categorical(final_table[\"Model\"], categories=model_order, ordered=True)\n",
    "final_table = final_table.sort_values([\"Set\", \"Model\"]).reset_index(drop=True)\n",
    "\n",
    "final_table[metrics_keep] = final_table[metrics_keep].round(3)\n",
    "\n",
    "final_table\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "cec44d06",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saved:\n",
      "- ../results/model_comparison_table_means.csv\n"
     ]
    }
   ],
   "source": [
    "final_table.to_csv(\"../results/model_comparison_table_means.csv\", index=False)\n",
    "\n",
    "print(\"Saved:\")\n",
    "print(\"- ../results/model_comparison_table_means.csv\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
