{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ee453d40",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys, os\n",
    "sys.path.append(os.path.abspath(\"..\"))\n",
    "\n",
    "from datasets.datasets import SyntheticFACE, SyntheticMoons, Dataset, CaliforniaHousing, GermanCredit, GermanCreditv2, GiveMeSomeCredit, AdultIncome\n",
    "from visualisation import *\n",
    "\n",
    "from models.mlp_pytorch import PyTorchMLP\n",
    "\n",
    "from conformal.split_conformal import SplitConformalPrediction\n",
    "from conformal.localised_conformal_baselcp import BaseLCP\n",
    "from conformal.localised_conformal_tree import ConformalCONFEXTree\n",
    "\n",
    "from counterfactual_explanations.counterfactual_benchmarker import *\n",
    "from counterfactual_explanations.gradient_based.auxillary_models import *\n",
    "from counterfactual_explanations.gradient_based.cf_gradient_based import *\n",
    "from counterfactual_explanations.gradient_based.losses import *\n",
    "\n",
    "from counterfactual_explanations.milp_based.cf_conformal import *\n",
    "from counterfactual_explanations.milp_based.cf_mindist import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "aa5d525b",
   "metadata": {},
   "outputs": [],
   "source": [
    "os.chdir(\"..\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f1292775",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The autoreload extension is already loaded. To reload it, use:\n",
      "  %reload_ext autoreload\n"
     ]
    }
   ],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "00a647ab",
   "metadata": {},
   "outputs": [],
   "source": [
    "Dataset = AdultIncome\n",
    "# factual = np.array([1, 1.5])\n",
    "# y_target = 1 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "638d5992",
   "metadata": {},
   "outputs": [],
   "source": [
    "mlp_config = {\"epochs\": 100, \"batch_size\": 64}\n",
    "mlp_config_big = {\"epochs\": 50, \"batch_size\": 256}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "134cef74",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: >"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 148400 characters]",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dataset = Dataset(0.6, 0.2, 0.2)\n",
    "X_train, y_train, X_calib, y_calib, X_test, y_test = dataset.get_X_y_split()\n",
    "plot_split_dataset(X_train, X_test, y_train, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "a86e8297",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Sequential(\n",
       "  (0): Linear(in_features=45, out_features=50, bias=True)\n",
       "  (1): ReLU()\n",
       "  (2): Linear(in_features=50, out_features=2, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model = PyTorchMLP(config=mlp_config_big, input_properties=dataset.input_properties)\n",
    "model.train(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "4493a380",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'loss': 0.340981662273407,\n",
       " 'accuracy': 84.49923962633066,\n",
       " 'precision': 84.1006367834689,\n",
       " 'f1_score': 84.2417334051623}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.evaluate(X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "58413262",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  display: none;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  overflow: visible;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".estimator-table summary {\n",
       "    padding: .5rem;\n",
       "    font-family: monospace;\n",
       "    cursor: pointer;\n",
       "}\n",
       "\n",
       ".estimator-table details[open] {\n",
       "    padding-left: 0.1rem;\n",
       "    padding-right: 0.1rem;\n",
       "    padding-bottom: 0.3rem;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table {\n",
       "    margin-left: auto !important;\n",
       "    margin-right: auto !important;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(odd) {\n",
       "    background-color: #fff;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(even) {\n",
       "    background-color: #f6f6f6;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:hover {\n",
       "    background-color: #e0e0e0;\n",
       "}\n",
       "\n",
       ".estimator-table table td {\n",
       "    border: 1px solid rgba(106, 105, 104, 0.232);\n",
       "}\n",
       "\n",
       ".user-set td {\n",
       "    color:rgb(255, 94, 0);\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td.value pre {\n",
       "    color:rgb(255, 94, 0) !important;\n",
       "    background-color: transparent !important;\n",
       "}\n",
       "\n",
       ".default td {\n",
       "    color: black;\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td i,\n",
       ".default td i {\n",
       "    color: black;\n",
       "}\n",
       "\n",
       ".copy-paste-icon {\n",
       "    background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNy4yIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTIwOCAwTDMzMi4xIDBjMTIuNyAwIDI0LjkgNS4xIDMzLjkgMTQuMWw2Ny45IDY3LjljOSA5IDE0LjEgMjEuMiAxNC4xIDMzLjlMNDQ4IDMzNmMwIDI2LjUtMjEuNSA0OC00OCA0OGwtMTkyIDBjLTI2LjUgMC00OC0yMS41LTQ4LTQ4bDAtMjg4YzAtMjYuNSAyMS41LTQ4IDQ4LTQ4ek00OCAxMjhsODAgMCAwIDY0LTY0IDAgMCAyNTYgMTkyIDAgMC0zMiA2NCAwIDAgNDhjMCAyNi41LTIxLjUgNDgtNDggNDhMNDggNTEyYy0yNi41IDAtNDgtMjEuNS00OC00OEwwIDE3NmMwLTI2LjUgMjEuNS00OCA0OC00OHoiLz48L3N2Zz4=);\n",
       "    background-repeat: no-repeat;\n",
       "    background-size: 14px 14px;\n",
       "    background-position: 0;\n",
       "    display: inline-block;\n",
       "    width: 14px;\n",
       "    height: 14px;\n",
       "    cursor: pointer;\n",
       "}\n",
       "</style><body><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>RandomForestClassifier(n_estimators=5, random_state=0)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>RandomForestClassifier</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.ensemble.RandomForestClassifier.html\">?<span>Documentation for RandomForestClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"\">\n",
       "        <div class=\"estimator-table\">\n",
       "            <details>\n",
       "                <summary>Parameters</summary>\n",
       "                <table class=\"parameters-table\">\n",
       "                  <tbody>\n",
       "                    \n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('n_estimators',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">n_estimators&nbsp;</td>\n",
       "            <td class=\"value\">5</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('criterion',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">criterion&nbsp;</td>\n",
       "            <td class=\"value\">&#x27;gini&#x27;</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_depth',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_depth&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('min_samples_split',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">min_samples_split&nbsp;</td>\n",
       "            <td class=\"value\">2</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('min_samples_leaf',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">min_samples_leaf&nbsp;</td>\n",
       "            <td class=\"value\">1</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('min_weight_fraction_leaf',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">min_weight_fraction_leaf&nbsp;</td>\n",
       "            <td class=\"value\">0.0</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_features',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_features&nbsp;</td>\n",
       "            <td class=\"value\">&#x27;sqrt&#x27;</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_leaf_nodes',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_leaf_nodes&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('min_impurity_decrease',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">min_impurity_decrease&nbsp;</td>\n",
       "            <td class=\"value\">0.0</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('bootstrap',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">bootstrap&nbsp;</td>\n",
       "            <td class=\"value\">True</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('oob_score',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">oob_score&nbsp;</td>\n",
       "            <td class=\"value\">False</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('n_jobs',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">n_jobs&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('random_state',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">random_state&nbsp;</td>\n",
       "            <td class=\"value\">0</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('verbose',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">verbose&nbsp;</td>\n",
       "            <td class=\"value\">0</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('warm_start',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">warm_start&nbsp;</td>\n",
       "            <td class=\"value\">False</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('class_weight',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">class_weight&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('ccp_alpha',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">ccp_alpha&nbsp;</td>\n",
       "            <td class=\"value\">0.0</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_samples',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_samples&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('monotonic_cst',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">monotonic_cst&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "                  </tbody>\n",
       "                </table>\n",
       "            </details>\n",
       "        </div>\n",
       "    </div></div></div></div></div><script>function copyToClipboard(text, element) {\n",
       "    // Get the parameter prefix from the closest toggleable content\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text;\n",
       "\n",
       "    const originalStyle = element.style;\n",
       "    const computedStyle = window.getComputedStyle(element);\n",
       "    const originalWidth = computedStyle.width;\n",
       "    const originalHTML = element.innerHTML.replace('Copied!', '');\n",
       "\n",
       "    navigator.clipboard.writeText(fullParamName)\n",
       "        .then(() => {\n",
       "            element.style.width = originalWidth;\n",
       "            element.style.color = 'green';\n",
       "            element.innerHTML = \"Copied!\";\n",
       "\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        })\n",
       "        .catch(err => {\n",
       "            console.error('Failed to copy:', err);\n",
       "            element.style.color = 'red';\n",
       "            element.innerHTML = \"Failed!\";\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        });\n",
       "    return false;\n",
       "}\n",
       "\n",
       "document.querySelectorAll('.fa-regular.fa-copy').forEach(function(element) {\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const paramName = element.parentElement.nextElementSibling.textContent.trim();\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName;\n",
       "\n",
       "    element.setAttribute('title', fullParamName);\n",
       "});\n",
       "</script></body>"
      ],
      "text/plain": [
       "RandomForestClassifier(n_estimators=5, random_state=0)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tree = RandomForestSKLearn({}, dataset.input_properties)\n",
    "tree.train(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "1456243e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'accuracy': 83.34781664132088,\n",
       " 'precision': 83.00630389033202,\n",
       " 'f1_score': 83.14606104619082}"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tree.evaluate(X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "5e10dbab",
   "metadata": {},
   "outputs": [],
   "source": [
    "factual = X_test[2]\n",
    "y_target = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "05cedd94",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.2, 0.8])"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tree.predict(factual)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "3b99e94f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# plot_decision_boundary(model, X_train, X_test, y_train, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "b10fc3b8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Set parameter TimeLimit to value 60\n",
      "Warning for adding constraints: zero or small (< 1e-13) coefficients, ignored\n",
      "Gurobi Optimizer version 11.0.3 build v11.0.3rc0 (mac64[arm] - Darwin 23.6.0 23G80)\n",
      "\n",
      "CPU model: Apple M3 Pro\n",
      "Thread count: 12 physical cores, 12 logical processors, using up to 12 threads\n",
      "\n",
      "Academic license 2688232 - for non-commercial use only - registered to am___@kcl.ac.uk\n",
      "Optimize a model with 227 rows, 253 columns and 2809 nonzeros\n",
      "Model fingerprint: 0x1a0e4cba\n",
      "Model has 50 general constraints\n",
      "Variable types: 196 continuous, 57 integer (18 binary)\n",
      "Coefficient statistics:\n",
      "  Matrix range     [1e-05, 1e+01]\n",
      "  Objective range  [1e+00, 1e+00]\n",
      "  Bounds range     [1e+00, 1e+00]\n",
      "  RHS range        [3e-03, 1e+00]\n",
      "Presolve removed 67 rows and 43 columns\n",
      "Presolve time: 0.01s\n",
      "Presolved: 160 rows, 210 columns, 2427 nonzeros\n",
      "Variable types: 105 continuous, 105 integer (104 binary)\n",
      "Found heuristic solution: objective 3.0349847\n",
      "Found heuristic solution: objective 2.4624004\n",
      "\n",
      "Root relaxation: objective 1.866667e+00, 52 iterations, 0.00 seconds (0.00 work units)\n",
      "\n",
      "    Nodes    |    Current Node    |     Objective Bounds      |     Work\n",
      " Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time\n",
      "\n",
      "*    0     0               0       1.8666667    1.86667  0.00%     -    0s\n",
      "\n",
      "Explored 1 nodes (52 simplex iterations) in 0.02 seconds (0.01 work units)\n",
      "Thread count was 12 (of 12 available processors)\n",
      "\n",
      "Solution count 3: 1.86667 2.4624 3.03498 \n",
      "\n",
      "Optimal solution found (tolerance 1.00e-04)\n",
      "Best objective 1.866666666667e+00, best bound 1.866666666667e+00, gap 0.0000%\n"
     ]
    }
   ],
   "source": [
    "#Min distance CF\n",
    "cf_gen = MinDistanceCF(model, dataset.input_properties, config={\"db_distance\":0.05})\n",
    "counterfactual = cf_gen.generate_counterfactual(factual, y_target)\n",
    "# plot_counterfactual(factual, counterfactual, model, X_train, X_test, y_train, y_test, faded_background=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e3dd3ba3",
   "metadata": {},
   "outputs": [],
   "source": [
    "#FeatureTweak\n",
    "#Focus"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "578c19e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "from counterfactual_explanations.tree.cf_featuretweak import FeatureTweakGenerator\n",
    "from counterfactual_explanations.tree.cf_focus import FOCUSGenerator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "c7099bb3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.6, 0.4])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "generator = FeatureTweakGenerator(tree, dataset.input_properties, {}, None, False)\n",
    "generator.setup(X_train, y_train, X_calib, y_calib)\n",
    "cf = generator.generate_counterfactual(factual, y_target)\n",
    "tree.predict(cf)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "480b7350",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.6, 0.4])"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "generator2 = FOCUSGenerator(tree, dataset.input_properties, {\"n_iter\": 50}, None, False)\n",
    "generator2.setup(X_train, y_train, X_calib, y_calib)\n",
    "cf2 = generator.generate_counterfactual(factual, y_target)\n",
    "tree.predict(cf2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "c9589805",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Set parameter TimeLimit to value 60\n",
      "Warning for adding constraints: zero or small (< 1e-13) coefficients, ignored\n",
      "Gurobi Optimizer version 11.0.3 build v11.0.3rc0 (mac64[arm] - Darwin 23.6.0 23G80)\n",
      "\n",
      "CPU model: Apple M3 Pro\n",
      "Thread count: 12 physical cores, 12 logical processors, using up to 12 threads\n",
      "\n",
      "Academic license 2688232 - for non-commercial use only - registered to am___@kcl.ac.uk\n",
      "Optimize a model with 230 rows, 255 columns and 2815 nonzeros\n",
      "Model fingerprint: 0xcc2690d3\n",
      "Model has 50 general constraints\n",
      "Variable types: 198 continuous, 57 integer (18 binary)\n",
      "Coefficient statistics:\n",
      "  Matrix range     [1e-05, 1e+01]\n",
      "  Objective range  [1e+00, 1e+00]\n",
      "  Bounds range     [1e+00, 1e+00]\n",
      "  RHS range        [3e-03, 3e+00]\n",
      "Presolve removed 68 rows and 44 columns\n",
      "Presolve time: 0.01s\n",
      "Presolved: 162 rows, 211 columns, 2431 nonzeros\n",
      "Variable types: 106 continuous, 105 integer (104 binary)\n",
      "\n",
      "Root relaxation: objective 1.533333e+00, 40 iterations, 0.00 seconds (0.00 work units)\n",
      "\n",
      "    Nodes    |    Current Node    |     Objective Bounds      |     Work\n",
      " Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time\n",
      "\n",
      "     0     0    1.53333    0    1          -    1.53333      -     -    0s\n",
      "H    0     0                      10.6658580    1.53333  85.6%     -    0s\n",
      "H    0     0                       2.5209186    1.53333  39.2%     -    0s\n",
      "H    0     0                       2.0616536    1.53333  25.6%     -    0s\n",
      "     0     0    1.53333    0    1    2.06165    1.53333  25.6%     -    0s\n",
      "     0     0    1.53333    0    3    2.06165    1.53333  25.6%     -    0s\n",
      "H    0     0                       1.9524808    1.53333  21.5%     -    0s\n",
      "     0     0    1.53333    0    2    1.95248    1.53333  21.5%     -    0s\n",
      "     0     0    1.53333    0    3    1.95248    1.53333  21.5%     -    0s\n",
      "H    0     0                       1.6889880    1.53333  9.22%     -    0s\n",
      "H    0     0                       1.6283892    1.53333  5.84%     -    0s\n",
      "H    0     0                       1.6140254    1.53333  5.00%     -    0s\n",
      "     0     0    1.53333    0    3    1.61403    1.53333  5.00%     -    0s\n",
      "     0     0    1.53333    0    4    1.61403    1.53333  5.00%     -    0s\n",
      "     0     0    1.53333    0    5    1.61403    1.53333  5.00%     -    0s\n",
      "     0     0    1.53333    0    8    1.61403    1.53333  5.00%     -    0s\n",
      "     0     0    1.53333    0    9    1.61403    1.53333  5.00%     -    0s\n",
      "     0     0    1.53333    0    8    1.61403    1.53333  5.00%     -    0s\n",
      "     0     0    1.53333    0    9    1.61403    1.53333  5.00%     -    0s\n",
      "     0     0    1.53333    0    9    1.61403    1.53333  5.00%     -    0s\n",
      "     0     0    1.54161    0    9    1.61403    1.54161  4.49%     -    0s\n",
      "     0     0    1.54161    0    4    1.61403    1.54161  4.49%     -    0s\n",
      "H    0     0                       1.6073323    1.54161  4.09%     -    0s\n",
      "H    0     0                       1.6011023    1.60110  0.00%     -    0s\n",
      "     0     0    1.60110    0    4    1.60110    1.60110  0.00%     -    0s\n",
      "\n",
      "Cutting planes:\n",
      "  Gomory: 3\n",
      "  Cover: 1\n",
      "  Clique: 1\n",
      "  MIR: 5\n",
      "  Flow cover: 5\n",
      "  Relax-and-lift: 3\n",
      "\n",
      "Explored 1 nodes (228 simplex iterations) in 0.07 seconds (0.04 work units)\n",
      "Thread count was 12 (of 12 available processors)\n",
      "\n",
      "Solution count 9: 1.6011 1.60733 1.61403 ... 10.6659\n",
      "\n",
      "Optimal solution found (tolerance 1.00e-04)\n",
      "Best objective 1.601102287586e+00, best bound 1.601102287586e+00, gap 0.0000%\n"
     ]
    }
   ],
   "source": [
    "conformalCF = ConformalCF(model, dataset.input_properties, config={\"conformal_class\": SplitConformalPrediction, \"conformal_config\": {\"alpha\": 0.01}})\n",
    "conformalCF.setup(X_train, y_train, X_calib, y_calib)\n",
    "counterfactual_conformal = conformalCF.generate_counterfactual(factual, y_target)\n",
    "# plot_counterfactual(factual, counterfactual_conformal, model, X_train, X_test, y_train, y_test, conformal=conformalCF.conformal)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "20a1b6f1",
   "metadata": {},
   "outputs": [],
   "source": [
    "ccf = {\"alpha\": 0.05,\n",
    "        \"scorefn_name\":'linear2',\n",
    "        \"kernel_name\":'box_l1', \n",
    "        \"kernel_bandwidth\": 0.7}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "bd53960d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Set parameter TimeLimit to value 60\n",
      "Warning for adding constraints: zero or small (< 1e-13) coefficients, ignored\n",
      "Gurobi Optimizer version 11.0.3 build v11.0.3rc0 (mac64[arm] - Darwin 23.6.0 23G80)\n",
      "\n",
      "CPU model: Apple M3 Pro\n",
      "Thread count: 12 physical cores, 12 logical processors, using up to 12 threads\n",
      "\n",
      "\n",
      "Warning: excessive time spent in model updates.\n",
      "Consider calling update less frequently.\n",
      "\n",
      "Academic license 2688232 - for non-commercial use only - registered to am___@kcl.ac.uk\n",
      "Optimize a model with 38459 rows, 47310 columns and 88098 nonzeros\n",
      "Model fingerprint: 0xed794a0b\n",
      "Model has 7 quadratic constraints\n",
      "Model has 2991 general constraints\n",
      "Variable types: 41373 continuous, 5937 integer (5898 binary)\n",
      "Coefficient statistics:\n",
      "  Matrix range     [1e-05, 1e+01]\n",
      "  QMatrix range    [1e+00, 1e+00]\n",
      "  QLMatrix range   [1e+00, 1e+00]\n",
      "  Objective range  [1e+00, 1e+00]\n",
      "  Bounds range     [1e+00, 1e+00]\n",
      "  RHS range        [1e-06, 3e+00]\n",
      "  GenCon rhs range [2e+00, 2e+00]\n",
      "  GenCon coe range [1e+00, 1e+00]\n",
      "Presolve removed 35319 rows and 44582 columns\n",
      "Presolve time: 0.12s\n",
      "Presolved: 3140 rows, 2728 columns, 22430 nonzeros\n",
      "Variable types: 109 continuous, 2619 integer (2618 binary)\n",
      "\n",
      "Root relaxation: objective 1.533333e+00, 82 iterations, 0.00 seconds (0.00 work units)\n",
      "\n",
      "    Nodes    |    Current Node    |     Objective Bounds      |     Work\n",
      " Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time\n",
      "\n",
      "     0     0    1.53333    0    7          -    1.53333      -     -    0s\n",
      "H    0     0                       1.5880911    1.53333  3.45%     -    0s\n",
      "H    0     0                       1.5333333    1.53333  0.00%     -    0s\n",
      "\n",
      "Cutting planes:\n",
      "  Gomory: 4\n",
      "  Relax-and-lift: 7\n",
      "\n",
      "Explored 1 nodes (82 simplex iterations) in 0.17 seconds (0.30 work units)\n",
      "Thread count was 12 (of 12 available processors)\n",
      "\n",
      "Solution count 2: 1.53333 1.58809 \n",
      "\n",
      "Optimal solution found (tolerance 1.00e-04)\n",
      "Best objective 1.533333333333e+00, best bound 1.533333333333e+00, gap 0.0000%\n"
     ]
    }
   ],
   "source": [
    "conformalCF_baselcp = ConformalCF(model, dataset.input_properties, {\"conformal_class\": ConformalCONFEXTree, \"conformal_config\": ccf})\n",
    "conformalCF_baselcp.setup(X_train, y_train, X_calib, y_calib)\n",
    "counterfactual_conformalbaselcp = conformalCF_baselcp.generate_counterfactual(factual, y_target)\n",
    "# plot_counterfactual(factual, counterfactual_conformalbaselcp, model, X_train, X_test, y_train, y_test, conformal=conformalCF_baselcp.conformal)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "8291e31c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Set parameter TimeLimit to value 60\n",
      "Warning for adding constraints: zero or small (< 1e-13) coefficients, ignored\n",
      "Gurobi Optimizer version 11.0.3 build v11.0.3rc0 (mac64[arm] - Darwin 23.6.0 23G80)\n",
      "\n",
      "CPU model: Apple M3 Pro\n",
      "Thread count: 12 physical cores, 12 logical processors, using up to 12 threads\n",
      "\n",
      "\n",
      "Warning: excessive time spent in model updates.\n",
      "Consider calling update less frequently.\n",
      "\n",
      "Academic license 2688232 - for non-commercial use only - registered to am___@kcl.ac.uk\n",
      "Optimize a model with 38459 rows, 47310 columns and 88098 nonzeros\n",
      "Model fingerprint: 0xed794a0b\n",
      "Model has 7 quadratic constraints\n",
      "Model has 2991 general constraints\n",
      "Variable types: 41373 continuous, 5937 integer (5898 binary)\n",
      "Coefficient statistics:\n",
      "  Matrix range     [1e-05, 1e+01]\n",
      "  QMatrix range    [1e+00, 1e+00]\n",
      "  QLMatrix range   [1e+00, 1e+00]\n",
      "  Objective range  [1e+00, 1e+00]\n",
      "  Bounds range     [1e+00, 1e+00]\n",
      "  RHS range        [1e-06, 3e+00]\n",
      "  GenCon rhs range [2e+00, 2e+00]\n",
      "  GenCon coe range [1e+00, 1e+00]\n",
      "Presolve removed 35319 rows and 44582 columns\n",
      "Presolve time: 0.13s\n",
      "Presolved: 3140 rows, 2728 columns, 22430 nonzeros\n",
      "Variable types: 109 continuous, 2619 integer (2618 binary)\n",
      "\n",
      "Root relaxation: objective 1.533333e+00, 82 iterations, 0.00 seconds (0.00 work units)\n",
      "\n",
      "    Nodes    |    Current Node    |     Objective Bounds      |     Work\n",
      " Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time\n",
      "\n",
      "     0     0    1.53333    0    7          -    1.53333      -     -    0s\n",
      "H    0     0                       1.5880911    1.53333  3.45%     -    0s\n",
      "H    0     0                       1.5333333    1.53333  0.00%     -    0s\n",
      "\n",
      "Cutting planes:\n",
      "  Gomory: 4\n",
      "  Relax-and-lift: 7\n",
      "\n",
      "Explored 1 nodes (82 simplex iterations) in 0.18 seconds (0.30 work units)\n",
      "Thread count was 12 (of 12 available processors)\n",
      "\n",
      "Solution count 2: 1.53333 1.58809 \n",
      "\n",
      "Optimal solution found (tolerance 1.00e-04)\n",
      "Best objective 1.533333333333e+00, best bound 1.533333333333e+00, gap 0.0000%\n"
     ]
    }
   ],
   "source": [
    "conformalCF_cfxt = ConformalCF(model, dataset.input_properties, {\"conformal_class\": ConformalCONFEXTree, \"conformal_config\": ccf})\n",
    "conformalCF_cfxt.setup(X_train, y_train, X_calib, y_calib)\n",
    "counterfactual_conformalcfxt = conformalCF_cfxt.generate_counterfactual(factual, y_target)\n",
    "# plot_counterfactual(factual, counterfactual_conformalcfxt, model, X_train, X_test, y_train, y_test, conformal=conformalCF_cfxt.conformal)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "id": "07c59fd4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: >"
      ]
     },
     "execution_count": 144,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 94804 characters]",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_decision_boundary(conformal_cfxt.trees[()], X_calib, X_calib, y_calib, y_calib, unary=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 168,
   "id": "86249cde",
   "metadata": {},
   "outputs": [],
   "source": [
    "from conformal.localised_conformal_tree import ConformalCONFEXTreeS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 256,
   "id": "e8a5da27",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: >"
      ]
     },
     "execution_count": 256,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 86372 characters]",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "ccf3 = {\"alpha\": 0.005,\n",
    "        \"scorefn_name\":'linear',\n",
    "        \"kernel_name\":'box_l1', \n",
    "        \"kernel_bandwidth\": 0.3,\n",
    "        \"inf_quantile\": False,\n",
    "        \"prune_by_label\": True,\n",
    "        \"incorporate_global\": False,\n",
    "        \"global_quantile\": True}\n",
    "\n",
    "conformal_cfxts = ConformalCONFEXTreeS(model, dataset.input_properties, ccf3)\n",
    "conformal_cfxts.calibrate(X_calib, y_calib, None)\n",
    "plot_conformal_prediction(model, conformal_cfxts, X_calib, X_calib, y_calib, y_calib)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 219,
   "id": "9f876059",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: >"
      ]
     },
     "execution_count": 219,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 94896 characters]",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_decision_boundary(conformal_cfxts.trees[(1,)], X_calib, X_calib, y_calib, y_calib, unary=True)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "confexplus",
   "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.10.15"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
