[fefe56]: / predict_clinical_trial_outcome_using_XGBoost.ipynb

Download this file

533 lines (532 with data), 64.2 kB

{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b0df3ee9",
   "metadata": {},
   "source": [
    "# Import libraries and define helper functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "625ef3b0",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import pickle\n",
    "\n",
    "def load_nctid2molecule_embedding_dict():\n",
    "    with open('data/nctid2molecule_embedding_dict.pkl', 'rb') as pickle_file:\n",
    "        return pickle.load(pickle_file)\n",
    "        \n",
    "def load_nctid2disease_embedding_dict():\n",
    "    with open('data/nctid2disease_embedding_dict.pkl', 'rb') as pickle_file:\n",
    "        return pickle.load(pickle_file)\n",
    "\n",
    "def load_sponsor2embedding_dict():\n",
    "    with open('data/sponsor2embedding_dict.pkl', 'rb') as pickle_file:\n",
    "        return pickle.load(pickle_file)\n",
    "\n",
    "def load_nctid2protocol_embedding_dict():\n",
    "    with open('data/nctid_2_protocol_embedding_dict.pkl', 'rb') as pickle_file:\n",
    "        return pickle.load(pickle_file)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63da8c43",
   "metadata": {},
   "source": [
    "# Import toy dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "5b7ed7c5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1028, 14) (146, 14) (295, 14)\n",
      "(1028,) (146,) (295,)\n"
     ]
    }
   ],
   "source": [
    "# Import toy dataset\n",
    "toy_df = pd.read_pickle('data/toy_df_full.pkl')\n",
    "\n",
    "train_df = toy_df[toy_df['split'] == 'train']\n",
    "val_df = toy_df[toy_df['split'] == 'valid']\n",
    "test_df = toy_df[toy_df['split'] == 'test']\n",
    "\n",
    "y_train = train_df['label']\n",
    "y_val = val_df['label']\n",
    "y_test = test_df['label']\n",
    "\n",
    "print(train_df.shape, val_df.shape, test_df.shape)\n",
    "print(y_train.shape, y_val.shape, y_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "fbc0292d",
   "metadata": {},
   "outputs": [
    {
     "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></th>\n",
       "      <th>nctid</th>\n",
       "      <th>phase</th>\n",
       "      <th>indications</th>\n",
       "      <th>drug_interventions</th>\n",
       "      <th>smiless</th>\n",
       "      <th>criteria</th>\n",
       "      <th>enrollment</th>\n",
       "      <th>lead_sponsor</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>NCT00000378</td>\n",
       "      <td>Phase 4</td>\n",
       "      <td>[Depression, Melancholia]</td>\n",
       "      <td>[Sertraline, Nortriptyline]</td>\n",
       "      <td>['CN[C@H]1CC[C@@H](C2=CC(Cl)=C(Cl)C=C2)C2=CC=C...</td>\n",
       "      <td>\\n        Inclusion Criteria:\\r\\n\\r\\n        -...</td>\n",
       "      <td>110</td>\n",
       "      <td>New York State Psychiatric Institute</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>NCT00001656</td>\n",
       "      <td>Phase 4</td>\n",
       "      <td>[Childhood Schizophrenia, Psychotic Disorder, ...</td>\n",
       "      <td>[Olanzapine, Clozapine]</td>\n",
       "      <td>['[H][C@]12[C@H](OC(=O)C3=CC=CC=C3)[C@]3(O)C[C...</td>\n",
       "      <td>\\n        -  INCLUSION CRITERIA:\\r\\n\\r\\n      ...</td>\n",
       "      <td>25</td>\n",
       "      <td>National Institute of Mental Health (NIMH)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>NCT00002863</td>\n",
       "      <td>Phase 1</td>\n",
       "      <td>[Sarcoma]</td>\n",
       "      <td>[chemotherapy]</td>\n",
       "      <td>['NC1=NC(=O)N(C=C1)[C@@H]1O[C@H](CO)[C@@H](O)C...</td>\n",
       "      <td>\\n        DISEASE CHARACTERISTICS: Biopsy-prov...</td>\n",
       "      <td>19</td>\n",
       "      <td>University of Southern California</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>NCT00003060</td>\n",
       "      <td>Phase 1</td>\n",
       "      <td>[Melanoma (Skin)]</td>\n",
       "      <td>[busulfan, cyclophosphamide, cyclosporine, met...</td>\n",
       "      <td>['N[C@@H](CCCNC(N)=N)C(O)=O', '[H][C@@]12C[C@H...</td>\n",
       "      <td>\\n        DISEASE CHARACTERISTICS: Biopsy prov...</td>\n",
       "      <td>6</td>\n",
       "      <td>Louisiana State University Health Sciences Cen...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>NCT00003567</td>\n",
       "      <td>Phase 1</td>\n",
       "      <td>[Brain and Central Nervous System Tumors, Lymp...</td>\n",
       "      <td>[O6-benzylguanine, carmustine, temozolomide]</td>\n",
       "      <td>['N=C1NC2=C(N=CN2)C(OCC2=CC=CC=C2)=N1', 'ClCCN...</td>\n",
       "      <td>\\n        DISEASE CHARACTERISTICS:\\r\\n\\r\\n    ...</td>\n",
       "      <td>8</td>\n",
       "      <td>Case Comprehensive Cancer Center</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         nctid    phase                                        indications  \\\n",
       "0  NCT00000378  Phase 4                          [Depression, Melancholia]   \n",
       "1  NCT00001656  Phase 4  [Childhood Schizophrenia, Psychotic Disorder, ...   \n",
       "2  NCT00002863  Phase 1                                          [Sarcoma]   \n",
       "3  NCT00003060  Phase 1                                  [Melanoma (Skin)]   \n",
       "4  NCT00003567  Phase 1  [Brain and Central Nervous System Tumors, Lymp...   \n",
       "\n",
       "                                  drug_interventions  \\\n",
       "0                        [Sertraline, Nortriptyline]   \n",
       "1                            [Olanzapine, Clozapine]   \n",
       "2                                     [chemotherapy]   \n",
       "3  [busulfan, cyclophosphamide, cyclosporine, met...   \n",
       "4       [O6-benzylguanine, carmustine, temozolomide]   \n",
       "\n",
       "                                             smiless  \\\n",
       "0  ['CN[C@H]1CC[C@@H](C2=CC(Cl)=C(Cl)C=C2)C2=CC=C...   \n",
       "1  ['[H][C@]12[C@H](OC(=O)C3=CC=CC=C3)[C@]3(O)C[C...   \n",
       "2  ['NC1=NC(=O)N(C=C1)[C@@H]1O[C@H](CO)[C@@H](O)C...   \n",
       "3  ['N[C@@H](CCCNC(N)=N)C(O)=O', '[H][C@@]12C[C@H...   \n",
       "4  ['N=C1NC2=C(N=CN2)C(OCC2=CC=CC=C2)=N1', 'ClCCN...   \n",
       "\n",
       "                                            criteria enrollment  \\\n",
       "0  \\n        Inclusion Criteria:\\r\\n\\r\\n        -...        110   \n",
       "1  \\n        -  INCLUSION CRITERIA:\\r\\n\\r\\n      ...         25   \n",
       "2  \\n        DISEASE CHARACTERISTICS: Biopsy-prov...         19   \n",
       "3  \\n        DISEASE CHARACTERISTICS: Biopsy prov...          6   \n",
       "4  \\n        DISEASE CHARACTERISTICS:\\r\\n\\r\\n    ...          8   \n",
       "\n",
       "                                        lead_sponsor  \n",
       "0               New York State Psychiatric Institute  \n",
       "1         National Institute of Mental Health (NIMH)  \n",
       "2                  University of Southern California  \n",
       "3  Louisiana State University Health Sciences Cen...  \n",
       "4                   Case Comprehensive Cancer Center  "
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_df[['nctid', 'phase', 'indications', 'drug_interventions', 'smiless', 'criteria', 'enrollment', 'lead_sponsor']].head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b07b3d7c",
   "metadata": {},
   "source": [
    "# Transform data into embeddings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "efc290d1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "input shape:  (1028, 14)\n",
      "embedding drug molecules..\n",
      "drug molecules successfully embedded into (1028, 1024) dimensions\n",
      "embedding protocols..\n",
      "protocols successfully embedded into (1028, 624) dimensions\n",
      "embedding disease indications..\n",
      "disease indications successfully embedded into (1028, 312) dimensions\n",
      "embedding sponsors..\n",
      "sponsors successfully embedded into (1028, 384) dimensions\n",
      "normalizing enrollment numbers..\n",
      "enrollment successfully embedded into (1028, 1) dimensions\n",
      "output shape:  (1028, 2345)\n",
      "input shape:  (146, 14)\n",
      "embedding drug molecules..\n",
      "drug molecules successfully embedded into (146, 1024) dimensions\n",
      "embedding protocols..\n",
      "protocols successfully embedded into (146, 624) dimensions\n",
      "embedding disease indications..\n",
      "disease indications successfully embedded into (146, 312) dimensions\n",
      "embedding sponsors..\n",
      "sponsors successfully embedded into (146, 384) dimensions\n",
      "normalizing enrollment numbers..\n",
      "enrollment successfully embedded into (146, 1) dimensions\n",
      "output shape:  (146, 2345)\n",
      "input shape:  (295, 14)\n",
      "embedding drug molecules..\n",
      "drug molecules successfully embedded into (295, 1024) dimensions\n",
      "embedding protocols..\n",
      "protocols successfully embedded into (295, 624) dimensions\n",
      "embedding disease indications..\n",
      "disease indications successfully embedded into (295, 312) dimensions\n",
      "embedding sponsors..\n",
      "sponsors successfully embedded into (295, 384) dimensions\n",
      "normalizing enrollment numbers..\n",
      "filling 1 NaNs with median value\n",
      "succesfully filled NaNs with median value: 0 NaNs left\n",
      "enrollment successfully embedded into (295, 1) dimensions\n",
      "output shape:  (295, 2345)\n"
     ]
    }
   ],
   "source": [
    "def embed_all(df):\n",
    "    print('input shape: ', df.shape)\n",
    "    ### EMBEDDING MOLECULES ###\n",
    "    print('embedding drug molecules..')\n",
    "    nctid2molecule_embedding_dict = load_nctid2molecule_embedding_dict()\n",
    "    h_m = np.stack(df['nctid'].map(nctid2molecule_embedding_dict)) \n",
    "    print(f\"drug molecules successfully embedded into {h_m.shape} dimensions\")\n",
    "    ### EMBEDDING PROTOCOLS ###\n",
    "    print('embedding protocols..')\n",
    "    nctid2protocol_embedding_dict = load_nctid2protocol_embedding_dict()\n",
    "    h_p = np.stack(df['nctid'].map(nctid2protocol_embedding_dict))\n",
    "    print(f\"protocols successfully embedded into {h_p.shape} dimensions\")\n",
    "    ### EMBEDDING DISEASE INDICATIONS ###\n",
    "    print('embedding disease indications..')\n",
    "    nctid2disease_embedding_dict = load_nctid2disease_embedding_dict()\n",
    "    h_d = np.stack(df['nctid'].map(nctid2disease_embedding_dict))\n",
    "    print(f\"disease indications successfully embedded into {h_d.shape} dimensions\")\n",
    "    ### EMBEDDING TRIAL SPONSORS ###\n",
    "    print('embedding sponsors..')\n",
    "    sponsor2embedding_dict = load_sponsor2embedding_dict()\n",
    "    h_s = np.stack(df['lead_sponsor'].map(sponsor2embedding_dict))\n",
    "    print(f\"sponsors successfully embedded into {h_s.shape} dimensions\")\n",
    "    ### EMBEDDING ENROLLMENT ###\n",
    "    print('normalizing enrollment numbers..')\n",
    "    enrollment = pd.to_numeric(df['enrollment'] , errors='coerce')\n",
    "    if enrollment.isna().sum() != 0:\n",
    "        print(f\"filling {enrollment.isna().sum()} NaNs with median value\")\n",
    "        enrollment.fillna(int(enrollment.median()), inplace=True)\n",
    "        print(f\"succesfully filled NaNs with median value: {enrollment.isna().sum()} NaNs left\")\n",
    "    enrollment = enrollment.astype(int)\n",
    "    h_e = np.array((enrollment - enrollment.mean())/enrollment.std()).reshape(len(df),-1)\n",
    "    print(f\"enrollment successfully embedded into {h_e.shape} dimensions\")\n",
    "    ### COMBINE ALL EMBEDDINGS ###\n",
    "    embedded_df = pd.DataFrame(data=np.column_stack((h_m, h_p, h_d, h_s, h_e)))\n",
    "    print('output shape: ', embedded_df.shape)\n",
    "    return embedded_df\n",
    "\n",
    "# Embed data\n",
    "X_train = embed_all(train_df)\n",
    "X_val = embed_all(val_df)\n",
    "X_test = embed_all(test_df)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59830525",
   "metadata": {},
   "source": [
    "# Define evaluation metrics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "294d4c9e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# evaluation functions adapted from https://github.com/futianfan/clinical-trial-outcome-prediction\n",
    "from sklearn.metrics import roc_auc_score, f1_score, average_precision_score, precision_score, recall_score, \\\n",
    "accuracy_score, roc_curve, precision_recall_curve\n",
    "\n",
    "def evaluation(predict_all, label_all, threshold = 0.5):\n",
    "    auc_score = roc_auc_score(label_all, predict_all)\n",
    "    figure_folder = \"figure\"\n",
    "    #### ROC-curve \n",
    "    fpr, tpr, thresholds = roc_curve(label_all, predict_all, pos_label=1)\n",
    "    #### PR-curve\n",
    "    precision, recall, thresholds = precision_recall_curve(label_all, predict_all)\n",
    "    label_all = [int(i) for i in label_all]\n",
    "    float2binary = lambda x:0 if x<threshold else 1\n",
    "    predict_all = list(map(float2binary, predict_all))\n",
    "    f1score = f1_score(label_all, predict_all)\n",
    "    prauc_score = average_precision_score(label_all, predict_all)\n",
    "    precision = precision_score(label_all, predict_all)\n",
    "    recall = recall_score(label_all, predict_all)\n",
    "    accuracy = accuracy_score(label_all, predict_all)\n",
    "    predict_1_ratio = sum(predict_all) / len(predict_all)\n",
    "    label_1_ratio = sum(label_all) / len(label_all)\n",
    "    return auc_score, f1score, prauc_score, precision, recall, accuracy, predict_1_ratio, label_1_ratio \n",
    "\n",
    "def print_results(predict_all, label_all):\n",
    "    print_num = 5\n",
    "    auc_score, f1score, prauc_score, precision, recall, accuracy, \\\n",
    "    predict_1_ratio, label_1_ratio = evaluation(predict_all, label_all, threshold = 0.5)\n",
    "    print(\"ROC AUC: \" + str(auc_score)[:print_num] + \"\\nF1: \" + str(f1score)[:print_num] \\\n",
    "         + \"\\nPR-AUC: \" + str(prauc_score)[:print_num] \\\n",
    "         + \"\\nPrecision: \" + str(precision)[:print_num] \\\n",
    "         + \"\\nrecall: \"+str(recall)[:print_num] + \"\\naccuracy: \"+str(accuracy)[:print_num] \\\n",
    "         + \"\\npredict 1 ratio: \" + str(predict_1_ratio)[:print_num] \\\n",
    "         + \"\\nlabel 1 ratio: \" + str(label_1_ratio)[:print_num])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c822eb15",
   "metadata": {},
   "source": [
    "# Train XGBoost and print results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "8377f8ef",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-----------Results on training data:-----------\n",
      "ROC AUC: 1.0\n",
      "F1: 1.0\n",
      "PR-AUC: 1.0\n",
      "Precision: 1.0\n",
      "recall: 1.0\n",
      "accuracy: 1.0\n",
      "predict 1 ratio: 0.661\n",
      "label 1 ratio: 0.661\n",
      "-----------Results on validation data:-----------\n",
      "ROC AUC: 0.765\n",
      "F1: 0.817\n",
      "PR-AUC: 0.799\n",
      "Precision: 0.840\n",
      "recall: 0.795\n",
      "accuracy: 0.773\n",
      "predict 1 ratio: 0.602\n",
      "label 1 ratio: 0.636\n",
      "-----------Results on test data:-----------\n",
      "ROC AUC: 0.742\n",
      "F1: 0.805\n",
      "PR-AUC: 0.757\n",
      "Precision: 0.790\n",
      "recall: 0.821\n",
      "accuracy: 0.759\n",
      "predict 1 ratio: 0.630\n",
      "label 1 ratio: 0.606\n"
     ]
    }
   ],
   "source": [
    "import xgboost as xgb\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\", category=FutureWarning)\n",
    "\n",
    "# Create an XGBoost classifier with specified hyperparameters\n",
    "xgb_classifier = xgb.XGBClassifier(\n",
    "    learning_rate=0.1,\n",
    "    max_depth=3,\n",
    "    n_estimators=200,\n",
    "    objective='binary:logistic',  # for binary classification\n",
    "    random_state=42\n",
    ")\n",
    "\n",
    "# Train the XGBoost model\n",
    "xgb_classifier.fit(X_train, y_train)\n",
    "# Make predictions\n",
    "y_train_pred = xgb_classifier.predict(X_train)\n",
    "y_val_pred = xgb_classifier.predict(X_val)\n",
    "y_test_pred = xgb_classifier.predict(X_test)\n",
    "print('-----------Results on training data:-----------')\n",
    "print_results(y_train_pred, y_train)\n",
    "print('-----------Results on validation data:-----------')\n",
    "print_results(y_val_pred, y_val)\n",
    "print('-----------Results on test data:-----------')\n",
    "print_results(y_test_pred, y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "caa8d394",
   "metadata": {},
   "source": [
    "# Plot results and compare with HINT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "869d94d8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAJOCAYAAABm7rQwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB+ZUlEQVR4nOzdeZxO5eP/8fc9+8ZgMAZjxr4vNT7VELITE/VRqDDWmJAISdaUyDJURhKTT7J8Ip8sYbKLZE1FSBjLyBayDWau3x9+c3+7zWKMce4ar+fjcT8e7utc55zrnLnOPXO/Xec6NmOMEQAAAAAAAGAhF2c3AAAAAAAAAA8eQikAAAAAAABYjlAKAAAAAAAAliOUAgAAAAAAgOUIpQAAAAAAAGA5QikAAAAAAABYjlAKAAAAAAAAliOUAgAAAAAAgOUIpQAAAAAAAGA5QikAyOF2796tjh07qnjx4vLy8pKfn58efvhhjR07VufOnXN28+67yMhIhYaGOrsZ92znzp2qU6eO/P39ZbPZFB0dnWa9devWycXFRW+88UaqZQcPHpSfn59atWqVatmSJUvUokULFS5cWB4eHsqVK5ceeughDRs2TPHx8Q51n3jiCdlsNvvL3d1doaGh6ty5s44cOZItx3svNm3apOHDh+v8+fPObkqarl+/ru7duysoKEiurq6qVq2as5uEDERGRsrPzy/d5X5+foqMjLS/P3z4sGw2m8aNG2cvW7t2rf162bx5c4b7iI2Ndbi+0nv93T7X3n//fZUqVUoeHh6y2Wx/2+sPAPD34ubsBgAA7p+PP/5YUVFRKlu2rPr3768KFSroxo0b2rZtm6ZOnarNmzfryy+/dHYz76shQ4bolVdecXYz7lmnTp10+fJlzZ07V3nz5k33C2mdOnXUu3dvjR07Vi1bttQjjzwiSUpOTlaHDh3k4+OjmJgYe/3k5GR17NhRs2bNUtOmTTV69GiFhobq6tWr2rp1q2bOnKkZM2bo6NGjDvspUaKEZs+eLelWyPLTTz9pxIgRiouL0y+//CIfH5/7cyIyYdOmTRoxYoQiIyOVJ08ep7UjPTExMfroo4/0/vvvKywsLMPAAznPgAEDtGHDhnSXN2vWLFVwFR4erlatWqlfv372Mk9Pz/vWxru1a9cu9e7dW126dFGHDh3k5uamXLlyObtZAIB/AEIpAMihNm/erB49eqhhw4ZatGiRwxeYhg0bql+/flq+fLkTW3h/XblyRT4+PipZsqSzm5ItfvrpJ3Xt2lVNmza9Y93Ro0fr66+/VocOHbRz5055eXlp3Lhx+vbbb7VgwQIVKFDAXnfMmDGaNWuWRo8erddff91hO02aNNGgQYP00UcfpdqHt7e3HnvsMfv72rVry8vLS507d9bGjRvVqFGjezjanCmlT/7000/y9vZWz549s23bV69elbe3d7ZtD/dHkyZNtHz5ci1evFgRERFp1ilQoIDDNZoiMDDQ4Zr7O0jp0z///LMkqWvXrvYgPLu2DQDI2bh9DwByqHfeeUc2m03Tpk1L83/UPTw89NRTT9nfJycna+zYsSpXrpw8PT1VsGBBtW/fXseOHXNY74knnlClSpW0efNm1ahRQ97e3goNDdXMmTMlSUuXLtXDDz8sHx8fVa5cOVXwNXz4cNlsNu3cuVPPPPOMcufOLX9/f7344os6ffq0Q9158+apUaNGCgoKkre3t8qXL6/XX39dly9fdqiXcuvLjz/+qEaNGilXrlyqX7++fdnto4r++9//6tFHH5W/v798fHxUokQJderUyaFOfHy8XnzxRRUsWFCenp4qX768xo8fr+TkZHudv96mM2HCBBUvXlx+fn4KDw/Xd999l9GPx+6nn35SixYtlDdvXnl5ealatWr69NNP7ctTbuW5efOmYmJi7LfuZMTb21uxsbHav3+/3njjDf30008aOnSoXnjhBT3zzDP2etevX9fYsWNVqVKlVIFUCjc3N7388suZOhZ/f39Jkru7u0P5xo0bVb9+feXKlUs+Pj6qUaOGli5detfnQrrVT0eNGqWyZcvK29tbefLkUZUqVTRp0iRJt/pX//79JUnFixe3n6+1a9em2+6U/vPzzz+rfv368vX1VYECBdSzZ09duXLFoa4xRlOmTFG1atXk7e2tvHnzqlWrVvrtt98c6qVcJ+vXr1eNGjXk4+OjTp06yWazafr06bp69aq9bbGxsZKka9euadCgQSpevLg8PDxUpEgRvfzyy6lugwoNDVXz5s21cOFCPfTQQ/Ly8tKIESPst4h9/vnnGjhwoIKCguTn56eIiAj9/vvv+vPPP9WtWzflz59f+fPnV8eOHXXp0iWHbX/44YeqXbu2ChYsKF9fX1WuXFljx47VjRs30jy+rVu3qlatWvbr6N1333W4RiTp/Pnz6tevn0qUKGH/bHnyySf1yy+/2Otcv35do0aNsn/+FChQQB07dkz1mXC76Oho2Ww2/frrr6mWDRw4UB4eHjpz5oykW7fANm/e3H5NFy5cWM2aNUv1GXc/RUZGqkKFCho0aJCSkpLu235SPjfi4uLUsWNH5cuXT76+voqIiEjVVyXpm2++Uf369ZU7d275+PioZs2aWrVqlUOdlM/uHTt2qFWrVsqbN69KliypJ554Qi+++KIk6dFHH5XNZnO4nXHGjBmqWrWqvLy8lC9fPj399NPau3evw7Yz+gy32Wzq2bOnZs6cab/uq1evru+++07GGL333nv2z9569eql6gtxcXFq0aKFihYtKi8vL5UqVUovvfSSvV/cfnw///yz2rZtK39/fwUGBqpTp066cOGCQ93k5GS9//779s+BPHny6LHHHtNXX33lUG/evHkKDw+Xr6+v/Pz81LhxY+3cuTMTP0EAeIAYAECOc/PmTePj42MeffTRTK/TrVs3I8n07NnTLF++3EydOtUUKFDABAcHm9OnT9vr1alTxwQEBJiyZcuaTz75xKxYscI0b97cSDIjRowwlStXNnPmzDHLli0zjz32mPH09DTHjx+3rz9s2DAjyYSEhJj+/fubFStWmAkTJhhfX1/z0EMPmevXr9vrvvXWW2bixIlm6dKlZu3atWbq1KmmePHipm7dug5t79Chg3F3dzehoaFm9OjRZtWqVWbFihX2ZSEhIfa6mzZtMjabzbRp08YsW7bMrF692sycOdO0a9fOXufUqVOmSJEipkCBAmbq1Klm+fLlpmfPnkaS6dGjh73eoUOHjCQTGhpqmjRpYhYtWmQWLVpkKleubPLmzWvOnz+f4Tn/5ZdfTK5cuUzJkiXNrFmzzNKlS03btm2NJDNmzBh7WzZv3mwkmVatWpnNmzebzZs3Z+pnOmDAAOPi4mKKFy9uChcubM6dO+ew/NtvvzWSzKBBgzK1vRR16tQxFStWNDdu3DA3btwwly9fNlu2bDFVqlQxJUqUMNeuXbPXXbt2rXF3dzdhYWFm3rx5ZtGiRaZRo0bGZrOZuXPn3tW5MMaY0aNHG1dXVzNs2DCzatUqs3z5chMdHW2GDx9ujDHm6NGjplevXkaSWbhwof18XbhwId3j6dChg/Hw8DDFihUzb7/9tlm5cqUZPny4cXNzM82bN3eo27VrV+Pu7m769etnli9fbj7//HNTrlw5ExgYaE6ePOlwjvLly2eCg4PN+++/b9asWWPWrVtnNm/ebJ588knj7e1tb9upU6dMcnKyady4sXFzczNDhgwxK1euNOPGjbNfF389pyEhISYoKMiUKFHCzJgxw6xZs8Z8//33Zs2aNfZrKzIy0n4d+/n5mbp165qGDRua1157zaxcudKMGTPGuLq6ml69ejkc36uvvmpiYmLM8uXLzerVq83EiRNN/vz5TceOHVP1gYCAAFO6dGkzdepUExcXZ6Kioowk8+mnn9rrXbx40VSsWNH4+vqakSNHmhUrVpgFCxaYV155xaxevdoYY0xSUpJp0qSJ8fX1NSNGjDBxcXFm+vTppkiRIqZChQrmypUr6f7sTp8+bTw8PMzgwYMdym/evGkKFy5snnnmGWOMMZcuXTIBAQGmevXqZv78+WbdunVm3rx5pnv37mbPnj3pbj+lf/j6+tr7++0vX19f06FDB3v9lM+F9957z16W8rP573//a/73v/8ZSeaTTz5JtY/0SDIvv/xyhu38q5kzZxpJJjg42HTq1Ml8/fXXZtq0aaZgwYImODjY/PHHH/a6//nPf4zNZjMtW7Y0CxcuNIsXLzbNmzc3rq6u5ptvvrHX++tn98CBA01cXJxZtGiR+fnnn82bb75pJJmZM2eazZs3m19//dUYY8w777xjJJm2bduapUuXmlmzZpkSJUoYf39/s3//fofjT+8zPGWfNWrUMAsXLjRffvmlKVOmjMmXL5959dVXTYsWLcySJUvM7NmzTWBgoKlSpYpJTk62bzsmJsaMHj3afPXVV2bdunXm008/NVWrVjVly5Z1+H2Tcnxly5Y1Q4cONXFxcWbChAnG09MzVf9v166dsdlspkuXLuZ///uf+frrr83bb79tJk2aZK/z9ttvG5vNZjp16mSWLFliFi5caMLDw42vr6/5+eefM/2zBICcjlAKAHKgkydPGkmmTZs2maq/d+9eI8lERUU5lG/ZssVIMm+88Ya9rE6dOkaS2bZtm73s7NmzxtXV1Xh7ezsEULt27TKSzOTJk+1lKX/4v/rqqw77mj17tpFkPvvsszTbmJycbG7cuGHWrVtnJJkffvjBvqxDhw5GkpkxY0aq9W4PpcaNG2ckZRgYvf7660aS2bJli0N5jx49jM1mM/v2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776rbt263fX6mXX752xK2V/7tCS1atUq3W2cO3fOIRDKbL++0++V24PyjD7Ds9KnpVtzPzVq1EgnTpzQkCFDVLlyZfn6+io5OVmPPfZYmp/Rd/o8P336tFxdXdM8tylSzmvKf4LcLit9BgByKkIpAMiBXF1dVb9+fX399dc6duyYihYtmmH9lD/CExISUtU9ceKE8ufPn+1tPHnypIoUKWJ/f/PmTZ09e9beltWrV+vEiRNau3atfXSUpFSTPqe40+Tff9WiRQu1aNFCiYmJ+u677zR69Gg9//zzCg0NVXh4uAICApSQkJBqvRMnTkhStp2P+7UfY4w6duwob29vTZ06VXnz5tWiRYvUpUsX/fjjj/ZHtYeFhSlv3rxavHix3nnnHfv6rq6u9i/gP/30U6b3GxQUpPz58+uHH36QdGukkIuLS6aOMbPnws3NTX379lXfvn11/vx5ffPNN3rjjTfUuHFjHT16NMtP67q9/0m3+mhK21LaYLPZtGHDhjQfHnB72d30yYCAAN28eVOnT592CKaMMTp58mSqL7d3s+3MWrRokS5fvqyFCxfaR5JI0q5du7K8zQIFCtxxIvH8+fMrICAg3aeBpvTX9KSMvJs8ebLOnz+vzz//XImJierYsaNDvcqVK2vu3Lkyxmj37t2KjY3VyJEj5e3tne5E//fT6NGjValSJYdrL7ul9OHby0qVKiXp/66r999/P90n+90ewma27/3198rt0vq9cj/69E8//aQffvhBsbGx6tChg708rYnxM6tAgQJKSkrSyZMn0w3oUo7tiy++cLiWAACpEdMDQA41aNAgGWPUtWtXXb9+PdXyGzduaPHixZJkv8Xos88+c6izdetW7d271/4UpOw0e/Zsh/fz58/XzZs39cQTT0j6vy8ot3/R/+ijj7KtDZ6enqpTp47GjBkjSfanItWvX1979uzRjh07HOrPmjVLNptNdevWzZb9169f3x6+3b4fHx+fLD/+fdKkSVq/fr1iYmJUsGBBubu7KzY2VidOnLA/mU66Naqgf//++umnn+zn4F4cO3ZMZ86cUcGCBSVJvr6+evTRR7Vw4UKHEQnJycn67LPPVLRoUfstaFk5F3ny5FGrVq308ssv69y5czp8+LCkzI9Uu93tffLzzz+XJHufbN68uYwxOn78uKpXr57qVbly5bva31+lXGO3X4ML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PAoICFDz5s118OBBSWkPad+1a5dsNpsOHz5sL/v2229Vp04d+fj4KG/evGrcuLH++OOPO+77iy++UOXKleXt7a2AgAA1aNBAly9fti+fMWOGKlasKE9PTwUFBalnz572ZfHx8WrRooX8/PyUO3duPffcc/r999/ty1OGL8+YMUMlSpSQp6enjDG6cOGCunXrpoIFCyp37tyqV6+efvjhh3s4g/gniIyMVK9evRQfHy+bzabQ0FA1bdpUo0aN0jPPPJPuelOmTFHp0qXl5eWlwMBAtWrVyr4sOTlZY8aMUalSpeTp6alixYrp7bffti//8ccfVa9ePXv/7tatmy5duuTQppYtW2r06NEqXLiwypQpI0k6fvy4Wrdurbx58yogIEAtWrRwuN7wz/bEE0+oZ8+e6tmzp/1z980331TKA3RDQ0M1atQoRUZGyt/fX127dpUkDRw4UGXKlJGPj49KlCihIUOGOPwhl9YtGn369NETTzxhf3+nPpue69evq2fPngoKCpKXl5dCQ0M1evRo+/Lz58+rW7duCgwMlJeXlypVqqQlS5bYly9YsMD+WR4aGqrx48c7bD+9Y960aZNq164tb29vBQcHq3fv3g6/I/DPkNU+f6eff2JiogYMGKDg4GB5enqqdOnS+uSTTySl/vvlyJEjioiIUN68eeXr66uKFStq2bJladaVMtdn33nnHXXq1Em5cuVSsWLFNG3atPt1CvEPldL3+/btq/z586thw4bas2ePnnzySfn5+SkwMFDt2rXTmTNn7Ovc6XP6Tr8LgDvJ6LufJB07dkxt2rRRvnz55Ovrq+rVq2vLli325V999ZWqV68uLy8v5c+f3+Hv6LTuPMiTJ49iY2MlSYcPH5bNZtP8+fP1xBNPyMvLS5999pnOnj2rtm3bqmjRovLx8VHlypU1Z84ch+1kdG3Uq1fP4XuiJJ09e1aenp5avXp1dpw2ZBKhFLLk8uXL6tu3r7Zu3apVq1bJxcVFTz/9tJKTkzO1/q5du1S/fn1VrFhRmzdv1saNGxUREaGkpKQM10tISFDbtm3VqVMn7d27V2vXrtUzzzxj/yM1JiZGL7/8srp166Yff/xRX331lUqVKiXp1txALVu21Llz57Ru3TrFxcXp4MGDat26tcM+fv31V82fP18LFiywzx/UrFkznTx5UsuWLdP27dv18MMPq379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",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "HINT_performance = {'ROC AUC': 0.800, 'F1': 0.798, 'PR-AUC': 0.735, 'Precision': 0.758, 'recall': 0.843, 'accuracy': 0.742}\n",
    "\n",
    "# Sample data for basic and improved performance for 5 metrics\n",
    "metrics = ['auc_score', 'f1score', 'prauc_score', 'precision', 'recall', 'accuracy']\n",
    "XGB_performance = evaluation(y_test_pred, y_test, threshold = 0.5)[:-2]\n",
    "HINT_performance = list(HINT_performance.values())\n",
    "\n",
    "# Width of each bar\n",
    "bar_width = 0.35\n",
    "\n",
    "# Create an array of indices for the metrics\n",
    "indices = np.arange(len(metrics))\n",
    "\n",
    "# Create the side-by-side bar chart\n",
    "plt.figure(figsize=(12, 6))\n",
    "plt.bar(indices - bar_width/2, XGB_performance, label='XGBoost Performance', width=bar_width, color='b', alpha=0.7)\n",
    "plt.bar(indices + bar_width/2, HINT_performance, label='HINT Performance', width=bar_width, color='orange', alpha=0.7)\n",
    "\n",
    "# Customize the chart\n",
    "plt.xlabel('Metrics')\n",
    "plt.ylabel('Performance')\n",
    "plt.title('Comparison of XGBoost performance vs HINT performance')\n",
    "plt.xticks(indices, metrics)\n",
    "plt.legend()\n",
    "\n",
    "# Show the chart\n",
    "plt.tight_layout()\n",
    "plt.savefig(\"fig/performance.png\")\n",
    "plt.show()\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}