{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "# Install necessary packages\n",
    "\n",
    "We can install the necessary packages by either running `pip install --user <package_name>` or include everything in a `requirements.txt` file and run `pip install --user -r requirements.txt`.\n",
    "\n",
    "> NOTE: Do not forget to use the `--user` argument. It is necessary if you want to use Kale to transform this notebook into a Kubeflow pipeline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "skip"
    ]
   },
   "outputs": [],
   "source": [
    "!pip3 install --user -r requirements.txt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "# Imports\n",
    "\n",
    "In this section we import the packages we need for this example. Make it a habbit to gather your imports in a single place. It will make your life easier if you are going to transform this notebook into a Kubeflow pipeline using Kale."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "imports"
    ]
   },
   "outputs": [],
   "source": [
    "import sklearn\n",
    "import numpy as np\n",
    "\n",
    "from sklearn import datasets\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.metrics import precision_score, recall_score, f1_score, accuracy_score"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "# Project hyper-parameters\n",
    "\n",
    "In this cell, we define the different hyper-parameters variables. Defining them in one place makes it easier to experiment with their values and also facilitates the execution of HP Tuning experiments using Kale and Katib."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "pipeline-parameters"
    ]
   },
   "outputs": [],
   "source": [
    "N_ESTIMATORS = 500\n",
    "MAX_DEPTH = 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "# Load and preprocess data\n",
    "\n",
    "In this section, we load and process the dataset to get it in a ready-to-use form by the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "step:load_transform_data",
     "report:disabled"
    ]
   },
   "outputs": [],
   "source": [
    "x, y = datasets.load_iris(return_X_y=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "x_trn, x_tst, y_trn, y_tst = train_test_split(x, y, test_size=.2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "# Define and train the model\n",
    "\n",
    "We are now ready to define our model. In this example, we use the scikit-learn implementation of Random Forest."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "prev:load_transform_data",
     "step:train_model"
    ]
   },
   "outputs": [],
   "source": [
    "model = RandomForestClassifier(n_estimators=int(N_ESTIMATORS),\n",
    "                               max_depth=int(MAX_DEPTH))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "model.fit(x_trn, y_trn)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "# Evaluate the model\n",
    "\n",
    "Finally, we are ready to evaluate the model using the test set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "step:evaluate_model",
     "prev:load_transform_data",
     "prev:train_model",
     "report:disabled"
    ]
   },
   "outputs": [],
   "source": [
    "preds = model.predict(x_tst)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "precision = precision_score(y_tst, preds, average='macro')\n",
    "recall = recall_score(y_tst, preds, average='macro')\n",
    "f1 = f1_score(y_tst, preds, average='macro')\n",
    "accuracy = accuracy_score(y_tst, preds)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "# Pipeline metrics\n",
    "\n",
    "In the last cell of the Notebook, we print the pipeline metrics. These will be picked up by Kubeflow Pipelines, which will make them available through its UI."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": [
     "pipeline-metrics"
    ]
   },
   "outputs": [],
   "source": [
    "print(precision)\n",
    "print(recall)\n",
    "print(f1)\n",
    "print(accuracy)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "kubeflow_notebook": {
   "enable_caching": false,
   "experiment": {
    "id": "new",
    "name": "iris-experiment"
   },
   "experiment_name": "iris-experiment",
   "katib_metadata": {
    "algorithm": {
     "algorithmName": "grid",
     "algorithmSettings": [
      {
       "name": "random_state",
       "value": "10"
      },
      {
       "name": "acq_optimizer",
       "value": "auto"
      },
      {
       "name": "acq_func",
       "value": "gp_hedge"
      },
      {
       "name": "base_estimator",
       "value": "GP"
      }
     ]
    },
    "maxFailedTrialCount": 3,
    "maxTrialCount": 15,
    "objective": {
     "additionalMetricNames": [
      "precision",
      "recall",
      "f1"
     ],
     "goal": 1,
     "objectiveMetricName": "accuracy",
     "type": "maximize"
    },
    "parallelTrialCount": 3,
    "parameters": [
     {
      "feasibleSpace": {
       "max": "0.3",
       "min": "0.1",
       "step": "0.1"
      },
      "name": "ETA",
      "parameterType": "double"
     },
     {
      "feasibleSpace": {
       "max": "6",
       "min": "2",
       "step": "1"
      },
      "name": "MAX_DEPTH",
      "parameterType": "int"
     },
     {
      "feasibleSpace": {
       "list": [
        "multi:softprob",
        "multi:softmax"
       ]
      },
      "name": "OBJECTIVE",
      "parameterType": "categorical"
     },
     {
      "feasibleSpace": {
       "max": "100",
       "min": "20",
       "step": "10"
      },
      "name": "STEPS",
      "parameterType": "int"
     }
    ]
   },
   "katib_run": false,
   "pipeline_description": "Train a Random Forest classifier on the Iris dataset",
   "pipeline_name": "iris-pipeline",
   "snapshot_volumes": true,
   "steps_defaults": [
    "label:access-ml-pipeline:true"
   ],
   "volumes": [
    {
     "annotations": [],
     "mount_point": "/home/jovyan",
     "name": "workspace-examples-serving-bgsd4h5em",
     "size": 5,
     "size_type": "Gi",
     "snapshot": false,
     "type": "clone"
    },
    {
     "annotations": [],
     "mount_point": "/home/jovyan/data",
     "name": "data-8lbdjmzdh",
     "size": 10,
     "size_type": "Gi",
     "snapshot": false,
     "type": "clone"
    }
   ]
  },
  "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.12.9"
  },
  "nteract": {
   "version": "0.25.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
