{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np \n", "import matplotlib.pyplot as plt \n", "import seaborn as sns\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.preprocessing import OneHotEncoder\n", "from sklearn.preprocessing import LabelEncoder\n", "from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, roc_auc_score\n", "\n", "from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier, AdaBoostClassifier\n", "from sklearn.tree import DecisionTreeClassifier\n", "from sklearn.neighbors import KNeighborsClassifier\n", "from xgboost import XGBClassifier\n", "from catboost import CatBoostClassifier\n", "\n", "from sklearn.compose import ColumnTransformer\n", "from sklearn.pipeline import Pipeline\n", "from sklearn.preprocessing import StandardScaler\n", "\n", "import warnings\n", "\n", "# Ignore warnings\n", "warnings.filterwarnings(\"ignore\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import os\n", "os.chdir(\"/config/workspace\")" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TemparatureHumidityMoistureSoil TypeCrop TypeNitrogenPotassiumPhosphorousFertilizer Name
0265238SandyMaize3700Urea
1295245LoamySugarcane12036DAP
2346562BlackCotton793014-35-14
3326234RedTobacco2202028-28
4285446ClayeyPaddy3500Urea
\n", "
" ], "text/plain": [ " Temparature Humidity Moisture Soil Type Crop Type Nitrogen Potassium \\\n", "0 26 52 38 Sandy Maize 37 0 \n", "1 29 52 45 Loamy Sugarcane 12 0 \n", "2 34 65 62 Black Cotton 7 9 \n", "3 32 62 34 Red Tobacco 22 0 \n", "4 28 54 46 Clayey Paddy 35 0 \n", "\n", " Phosphorous Fertilizer Name \n", "0 0 Urea \n", "1 36 DAP \n", "2 30 14-35-14 \n", "3 20 28-28 \n", "4 0 Urea " ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "FILE_PATH =r\"fertilizer-prediction/Fertilizer Prediction.csv\"\n", "\n", "# Loading the dataset into pandas\n", "df = pd.read_csv(FILE_PATH)\n", "\n", "df.head()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Shape of the dataset: (99, 9)\n" ] } ], "source": [ "print(f\"Shape of the dataset: {df.shape}\")" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "RangeIndex: 99 entries, 0 to 98\n", "Data columns (total 9 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 Temparature 99 non-null int64 \n", " 1 Humidity 99 non-null int64 \n", " 2 Moisture 99 non-null int64 \n", " 3 Soil Type 99 non-null object\n", " 4 Crop Type 99 non-null object\n", " 5 Nitrogen 99 non-null int64 \n", " 6 Potassium 99 non-null int64 \n", " 7 Phosphorous 99 non-null int64 \n", " 8 Fertilizer Name 99 non-null object\n", "dtypes: int64(6), object(3)\n", "memory usage: 7.1+ KB\n" ] } ], "source": [ "# datatypes \n", "df.info()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Temparature 0\n", "Humidity 0\n", "Moisture 0\n", "Soil Type 0\n", "Crop Type 0\n", "Nitrogen 0\n", "Potassium 0\n", "Phosphorous 0\n", "Fertilizer Name 0\n", "dtype: int64" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# checking for null values \n", "df.isnull().sum()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0kAAAJwCAYAAABceyqRAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAABC4ElEQVR4nO3dd5RV1d0//s+lzQxtDAoMHaxY0aBBbCAWwKhYosZHI6IhxhYVK4lSLA8xRsF8o5hoAE2MBQ1GMRqVpkGxIBpBg4gY9JESiYCAFJn9+8PF/Z0RhjICQ3m91rprcfbZZ5/Pvefey7znnLMnl1JKAQAAQEREVKnsAgAAALYkQhIAAECGkAQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISANuNjz76KHK5XAwbNmyT72vYsGGRy+Xio48+yre1bNkyjj/++E2+74iIsWPHRi6Xi7Fjx26W/QFsS4QkgC3cqh+2Vz0KCwujcePG0blz5/jNb34TX3zxRYXHfvnll6Nfv34xf/78jVfwt3D33XdvUIDJvi7VqlWLevXqRdu2beOyyy6Ld999t9Lq2py25NoAtla5lFKq7CIAKN+wYcOiR48eceONN0arVq1ixYoVMXv27Bg7dmw8//zz0bx583jyySdjv/322+Cxf/3rX8fVV18dM2bMiJYtW2784jfQPvvsEzvttNN6n/3I5XJxzDHHxDnnnBMppViwYEG8/fbbMXz48Fi8eHHceuut0atXr3z/lFIsW7YsqlevHlWrVt1kdUVErFy5MlasWBEFBQWRy+Ui4uszSfvss0+MHDlyvcepaG2lpaWxfPnyqFGjRlSp4neiABuiWmUXAMD66dq1axx44IH55d69e8fo0aPj+OOPjxNPPDHee++9KCoqqsQKK8fuu+8eZ599dpm2X/7yl3HCCSfElVdeGa1bt47jjjsuIiJ/Jm5TWrx4cdSqVSuqVq26QUFsY6tSpcomf64A2yq/WgLYinXq1CluuOGG+Pe//x1/+tOf8u3//Oc/49xzz42dd945CgsLo6SkJM4777yYN29evk+/fv3i6quvjoiIVq1a5S9bW3UPzdChQ6NTp07RoEGDKCgoiL322isGDx68Wg1vvPFGdO7cOXbaaacoKiqKVq1axXnnnVemT2lpaQwaNCj23nvvKCwsjIYNG8YFF1wQn3/+eb5Py5YtY8qUKTFu3Lh8LR07dqzQ67LjjjvGww8/HNWqVYtbbrkl376me5Jmz54dPXr0iKZNm0ZBQUE0atQounXrln8d1lbXqkshx40bFxdddFE0aNAgmjZtWmZd9p6kVZ577rnYf//9o7CwMPbaa6/4y1/+UmZ9v3798mefsr455tpqK++epOHDh0fbtm2jqKgodtpppzj77LPj//7v/8r0Offcc6N27drxf//3f3HSSSdF7dq1o379+nHVVVfFypUr1/HqA2z9nEkC2Mr96Ec/ip///Ofx3HPPRc+ePSMi4vnnn48PP/wwevToESUlJTFlypT4/e9/H1OmTIkJEyZELpeLU045Jd5///146KGHYuDAgbHTTjtFRET9+vUjImLw4MGx9957x4knnhjVqlWLp556Ki666KIoLS2Niy++OCIi5s6dG8cee2zUr18/rrvuuthhhx3io48+Wu2H/gsuuCB/2eDPfvazmDFjRvz2t7+NSZMmxfjx46N69eoxaNCguPTSS6N27drxi1/8IiIiGjZsWOHXpXnz5tGhQ4cYM2ZMLFy4MOrWrbvGfqeeempMmTIlLr300mjZsmXMnTs3nn/++Zg5c2a0bNlyveq66KKLon79+tGnT59YvHjxWuuaNm1anHHGGfHTn/40unfvHkOHDo3TTjstnn322TjmmGM26Dlu6Gu26hgcdNBBMWDAgJgzZ07ceeedMX78+Jg0aVLssMMO+b4rV66Mzp07R7t27eLXv/51vPDCC3H77bfHLrvsEhdeeOEG1Qmw1UkAbNGGDh2aIiK9/vrr5fYpLi5OBxxwQH55yZIlq/V56KGHUkSkF198Md922223pYhIM2bMWK3/msbo3Llz2nnnnfPLI0aMWGdtL730UoqI9OCDD5Zpf/bZZ1dr33vvvVOHDh3KHeubIiJdfPHF5a6/7LLLUkSkt99+O6WU0owZM1JEpKFDh6aUUvr8889TRKTbbrttrfspr65Vx+awww5LX3311RrXZV/bFi1apIhIjz/+eL5twYIFqVGjRmWOX9++fdOa/ote05jl1TZmzJgUEWnMmDEppZSWL1+eGjRokPbZZ5/05Zdf5vuNHDkyRUTq06dPvq179+4pItKNN95YZswDDjggtW3bdrV9AWxrXG4HsA2oXbt2mVnusvcmLV26ND777LM4+OCDIyLizTffXK8xs2MsWLAgPvvss+jQoUN8+OGHsWDBgoiI/JmHkSNHxooVK9Y4zvDhw6O4uDiOOeaY+Oyzz/KPtm3bRu3atWPMmDEb9Fw3RO3atSMiyp0BsKioKGrUqBFjx44tc+nfhurZs+d633/UuHHjOPnkk/PLdevWjXPOOScmTZoUs2fPrnAN6/LGG2/E3Llz46KLLipzr9L3v//9aN26dTz99NOrbfPTn/60zPLhhx8eH3744SarEWBLISQBbAMWLVoUderUyS//97//jcsuuywaNmwYRUVFUb9+/WjVqlVERD7grMv48ePj6KOPjlq1asUOO+wQ9evXj5///OdlxujQoUOceuqp0b9//9hpp52iW7duMXTo0Fi2bFl+nGnTpsWCBQuiQYMGUb9+/TKPRYsWxdy5czfWy7CaRYsWRUSUeW2yCgoK4tZbb41nnnkmGjZsGEcccUT86le/2uCwsuq1XR+77rrravcb7b777hERa7x/aWP597//HRERe+yxx2rrWrdunV+/SmFhYf7Sy1W+853vfKswCbC1cE8SwFbuk08+iQULFsSuu+6abzv99NPj5Zdfjquvvjr233//qF27dpSWlkaXLl2itLR0nWNOnz49jjrqqGjdunXccccd0axZs6hRo0b87W9/i4EDB+bHyOVy8dhjj8WECRPiqaeeir///e9x3nnnxe233x4TJkzI77dBgwbx4IMPrnFf3/xBfGOaPHlyVK1ada0h5vLLL48TTjghnnjiifj73/8eN9xwQwwYMCBGjx4dBxxwwHrtZ2PPKrimSRsiYrNOmlCZM/MBVDYhCWAr98c//jEiIjp37hwREZ9//nmMGjUq+vfvH3369Mn3mzZt2mrblvfD+FNPPRXLli2LJ598Mpo3b55vL+/SuIMPPjgOPvjguOWWW+LPf/5znHXWWfHwww/Hj3/849hll13ihRdeiEMPPXSdYaK8eipi5syZMW7cuGjfvn25Z5JW2WWXXeLKK6+MK6+8MqZNmxb7779/3H777fkZAzdmXR988EGklMqM+f7770dE5P9W1Xe+852IiJg/f36ZyRS+ebZnQ2pr0aJFRERMnTo1OnXqVGbd1KlT8+sBcLkdwFZt9OjRcdNNN0WrVq3irLPOioj//wxA+sbfCh80aNBq29eqVSsivv5hPGtNYyxYsCCGDh1apt/nn3++2n7233//iIj8JXenn356rFy5Mm666abV9v/VV1+V2XetWrVWq6Ui/vvf/8aZZ54ZK1euzM/6tiZLliyJpUuXlmnbZZddok6dOmUuGdxYdUVEfPrppzFixIj88sKFC+OBBx6I/fffP0pKSvI1RES8+OKL+X6LFy+O+++/f7Xx1re2Aw88MBo0aBD33HNPmef2zDPPxHvvvRff//73K/qUALY5ziQBbCWeeeaZ+Ne//hVfffVVzJkzJ0aPHh3PP/98tGjRIp588sn8zfh169bN31uzYsWKaNKkSTz33HMxY8aM1cZs27ZtRET84he/iB/+8IdRvXr1OOGEE+LYY4+NGjVqxAknnBAXXHBBLFq0KO69995o0KBBzJo1K7/9/fffH3fffXecfPLJscsuu8QXX3wR9957b9StWzf/B1w7dOgQF1xwQQwYMCDeeuutOPbYY6N69eoxbdq0GD58eNx5553xgx/8IF/P4MGD4+abb45dd901GjRosNpZj296//33409/+lOklGLhwoXx9ttvx/Dhw2PRokVxxx13RJcuXda67VFHHRWnn3567LXXXlGtWrUYMWJEzJkzJ374wx+WeZ02tK7y7L777nH++efH66+/Hg0bNowhQ4bEnDlzygTQY489Npo3bx7nn39+XH311VG1atUYMmRI1K9fP2bOnFlmvPWtrXr16nHrrbdGjx49okOHDnHmmWfmpwBv2bJlXHHFFRV6PgDbpEqdWw+AdVo17fOqR40aNVJJSUk65phj0p133pkWLly42jaffPJJOvnkk9MOO+yQiouL02mnnZY+/fTTFBGpb9++ZfredNNNqUmTJqlKlSplppd+8skn03777ZcKCwtTy5Yt06233pqGDBlSps+bb76ZzjzzzNS8efNUUFCQGjRokI4//vj0xhtvrFbT73//+9S2bdtUVFSU6tSpk/bdd990zTXXpE8//TTfZ/bs2en73/9+qlOnToqIdU4Hnn1dqlSpknbYYYd0wAEHpMsuuyxNmTJltf7fnAL8s88+SxdffHFq3bp1qlWrViouLk7t2rVLjz76aJntyqtrbdOzlzcF+Pe///3097//Pe23336poKAgtW7dOg0fPny17SdOnJjatWuXatSokZo3b57uuOOONY5ZXm3fnAJ8lUceeSQdcMABqaCgINWrVy+dddZZ6ZNPPinTp3v37qlWrVqr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JAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGZUakl588cU44YQTonHjxpHL5eKJJ54os/7cc8+NXC5X5tGlS5fKKRYAANguVGpIWrx4cbRp0ybuuuuucvt06dIlZs2alX889NBDm7FCAABge1OtMnfetWvX6Nq161r7FBQURElJyWaqCAAA2N5t8fckjR07Nho0aBB77LFHXHjhhTFv3ry19l+2bFksXLiwzAMAAGB9bdEhqUuXLvHAAw/EqFGj4tZbb41x48ZF165dY+XKleVuM2DAgCguLs4/mjVrthkrBgAAtnaVernduvzwhz/M/3vfffeN/fbbL3bZZZcYO3ZsHHXUUWvcpnfv3tGrV6/88sKFCwUlAABgvW3RZ5K+aeedd46ddtopPvjgg3L7FBQURN26dcs8AAAA1tdWFZI++eSTmDdvXjRq1KiySwEAALZRlXq53aJFi8qcFZoxY0a89dZbUa9evahXr170798/Tj311CgpKYnp06fHNddcE7vuumt07ty5EqsGAAC2ZZUakt5444048sgj88ur7iXq3r17DB48OP75z3/G/fffH/Pnz4/GjRvHscceGzfddFMUFBRUVskAAMA2rlJDUseOHSOlVO76v//975uxGgAAgK3sniQAAIBNTUgCAADIEJIAAAAyhCQAAIAMIQkAACBDSAIAAMgQkgAAADKEJAAAgAwhCQAAIENIAgAAyBCSAAAAMoQkAACADCEJAAAgQ0gCAADIEJIAAAAyhCQAAICMapVdALB9O/T/HVrZJWzzxl86vrJLADaSW87+QWWXsE37xZ8eq+wS2EI4kwQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISAABAhpAEAACQISQBAABkCEkAAAAZQhIAAECGkAQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISAABAhpAEAACQISQBAABkCEkAAAAZQhIAAECGkAQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISAABAhpAEAACQISQBAABkCEkAAAAZQhIAAECGkAQAAJAhJAEAAGQISQAAABkVCkmdOnWK+fPnr9a+cOHC6NSp07etCQAAoNJUKCSNHTs2li9fvlr70qVL46WXXvrWRQEAAFSWahvS+Z///Gf+3++++27Mnj07v7xy5cp49tlno0mTJhuvOgAAgM1sg0LS/vvvH7lcLnK53BovqysqKor/9//+30YrDgAAYHPboJA0Y8aMSCnFzjvvHK+99lrUr18/v65GjRrRoEGDqFq16kYvEgAAYHPZoJDUokWLiIgoLS3dJMUAAABUtg0KSVnTpk2LMWPGxNy5c1cLTX369PnWhQEAAFSGCoWke++9Ny688MLYaaedoqSkJHK5XH5dLpcTkgAAgK1WhULSzTffHLfccktce+21G7seAACASlWhv5P0+eefx2mnnbaxawEAAKh0FQpJp512Wjz33HMbuxYAAIBKV6HL7Xbddde44YYbYsKECbHvvvtG9erVy6z/2c9+tlGKAwAA2NwqFJJ+//vfR+3atWPcuHExbty4MutyuZyQBAAAbLUqFJJmzJixsesAAADYIlToniQAAIBtVYXOJJ133nlrXT9kyJAKFQMAAFDZKhSSPv/88zLLK1asiMmTJ8f8+fOjU6dOG6UwAACAylChkDRixIjV2kpLS+PCCy+MXXbZ5VsXBQAAUFk22j1JVapUiV69esXAgQM31pAAAACb3UaduGH69Onx1VdfbcwhAQAANqsKXW7Xq1evMssppZg1a1Y8/fTT0b17941SGAAAQGWoUEiaNGlSmeUqVapE/fr14/bbb1/nzHcAAABbsgqFpDFjxmzsOgAAALYIFQpJq/znP/+JqVOnRkTEHnvsEfXr198oRQEAAFSWCk3csHjx4jjvvPOiUaNGccQRR8QRRxwRjRs3jvPPPz+WLFmysWsEAADYbCoUknr16hXjxo2Lp556KubPnx/z58+Pv/71rzFu3Li48sorN3aNAAAAm02FLrd7/PHH47HHHouOHTvm24477rgoKiqK008/PQYPHryx6gMAANisKnQmacmSJdGwYcPV2hs0aOByOwAAYKtWoZDUvn376Nu3byxdujTf9uWXX0b//v2jffv2G604AACAza1Cl9sNGjQounTpEk2bNo02bdpERMTbb78dBQUF8dxzz23UAgEAADanCoWkfffdN6ZNmxYPPvhg/Otf/4qIiDPPPDPOOuusKCoq2qgFAgAAbE4VCkkDBgyIhg0bRs+ePcu0DxkyJP7zn//Etddeu1GKAwAA2NwqdE/S7373u2jduvVq7XvvvXfcc88937oo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JAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISAABAhpAEAACQISQBAABkCEkAAAAZQhIAAECGkAQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISAABAhpAEAACQISQBAABkCEkAAAAZQhIAAECGkAQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISAABAhpAEAACQISQBAABkCEkAAAAZQhIAAECGkAQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISAABAhpAEAACQISQBAABkCEkAAAAZQhIAAECGkAQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISAABAhpAEAACQISQBAABkCEkAAAAZQhIAAECGkAQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISAABAhpAEAACQISQBAABkCEkAAAAZQhIAAECGkAQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISAABAhpAEAACQISQBAABkCEkAAAAZQhIAAECGkAQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGUISAABAhpAEAACQISQBAABkCEkAAAAZQhIAAECGkAQAAJAhJAEAAGQISQAAABlCEgAAQIaQBAAAkCEkAQAAZAhJAAAAGVtFSLrrrruiZcuWUVhYGO3atYvXXnutsksCAAC2UVt8SHrkkUeiV69e0bdv33jzzTejTZs20blz55g7d25llwYAAGyDtviQdMcdd0TPnj2jR48esddee8U999wTNWvWjCFDhlR2aQAAwDaoWmUXsDbLly+PiRMnRu/evfNtVapUiaOPPjpeeeWVNW6zbNmyWLZsWX55wYIFERGxcOHC9drnymVffouKWR/reyw21BdLV26ScfnapjpuX3351SYZl//fpjp2i79y7Da1TXXsvly2ZJOMy9c21XGLiFi6YsUmG5tNd+wWLV28Scbl/7e+x25Vv5TSWvvl0rp6VKJPP/00mjRpEi+//HK0b98+337NNdfEuHHj4tVXX11tm379+kX//v03Z5kAAMBW5OOPP46mTZuWu36LPpNUEb17945evXrll0tLS+O///1v7LjjjpHL5Sqxso1v4cKF0axZs/j444+jbt26lV0OG8Cx23o5dlsnx23r5dhtvRy7rde2fOxSSvHFF19E48aN19pviw5JO+20U1StWjXmzJlTpn3OnDlRUlKyxm0KCgqioKCgTNsOO+ywqUrcItStW3ebewNvLxy7rZdjt3Vy3LZejt3Wy7Hbem2rx664uHidfbboiRtq1KgRbdu2jVGjRuXbSktLY9SoUWUuvwMAANhYtugzSRERvXr1iu7du8eBBx4Y3/ve92LQoEGxePHi6NGjR2WXBgAAbIO2+JB0xhlnxH/+85/o06dPzJ49O/bff/949tlno2HDhpVdWqUrKCiIvn37rnZ5IVs+x27r5dhtnRy3rZdjt/Vy7LZejt0WPrsdAADA5rZF35MEAACwuQlJAAAAGUISAABAhpAEAACQISRtATp27BiXX375au3Dhg3b5v8Q7rbi3HPPjVwuF7lcLqpXrx4NGzaMY445JoYMGRKlpaWr9e/cuXNUrVo1Xn/99bWOVaNGjdh1113jxhtvjK+++mpzPJWtyosvvhgnnHBCNG7cOHK5XDzxxBPl9v3pT38auVwuBg0atNYx582bF126dInGjRtHQUFBNGvWLC655JJYuHBhvs/YsWPzxyj7mD179lrH/stf/hLHHnts7LjjjpHL5eKtt94qt29KKbp27brO57WtGzBgQBx00EFRp06daNCgQZx00kkxderUMn1mz54dP/rRj6KkpCRq1aoV3/3ud+Pxxx9f67hvv/12nHnmmdGsWbMoKiqKPffcM+68887V+j344IPRpk2bqFmzZjRq1CjOO++8mDdv3kZ9jluTdX3m1vS5yOVycdttt6113J/97GfRtm3bKCgoiP3333+19f369VvjuLVq1fpW9X6bmrdl6/O5W7p0aVx88cWx4447Ru3atePUU0+NOXPmrHXcsWPHRrdu3aJRo0ZRq1at2H///ePBBx9crd/w4cOjdevWUVhYGPvuu2/87W9/26jPb2uzrvdxSin69OkTjRo1iqKiojj66KNj2rRpax1zfb8Dly1bFr/4xS+iRYsWUVBQEC1btowhQ4asdez1ef9ERLzyyivRqVOnqFWrVtStWzeOOOKI+PLLL9f9gmwmQtJWavny5ZVdAt/QpUuXmDVrVnz00UfxzDPPxJFHHhmXXXZZHH/88WUCzsyZM+Pll1+OSy65pNwvmlVjTZs2La688sro16/fdv0fdnkWL14cbdq0ibvuumut/UaMGBETJkyIxo0br3PMKlWqRLdu3eLJJ5+M999/P4YNGxYvvPBC/PSnP12t79SpU2PWrFn5R4MGDdZZ72GHHRa33nrrOusYNGhQ5HK5dfbb1o0bNy4uvvjimDBhQjz//POxYsWKOPbYY2Px4sX5Puecc05MnTo1nnzyyXjnnXfilFNOidNPPz0mTZpU7rgTJ06MBg0axJ/+9KeYMmVK/OIXv4jevXvHb3/723yf8ePHxznnnBPnn39+TJkyJYYPHx6vvfZa9OzZc5M+5y3Zuj5z2c/DrFmzYsiQIZHL5eLUU09d59jnnXdenHHGGWtcd9VVV6029l577RWnnXbat6r329a8rVqfz90VV1wRTz31VAwfPjzGjRsXn376aZxyyilrHffll1+O/fbbLx5//PH45z//GT169IhzzjknRo4cWabPmWeeGeeff35MmjQpTjrppDjppJNi8uTJm+z5bunW9T7+1a9+Fb/5zW/innvuiVdffTVq1aoVnTt3jqVLl5Y75vp8B0ZEnH766TFq1Kj4wx/+EFOnTo2HHnoo9thjj7XWuz7vn1deeSW6dOkSxx57bLz22mvx+uuvxyWXXBJVqmxB0SRR6Tp06JAuu+yy1dqHDh2aiouLU0opde/ePXXr1i3dfPPNqVGjRqlly5YppZRmzpyZTjvttFRcXJy+853vpBNPPDHNmDEjP8Zrr72Wjj766LTjjjumunXrpiOOOCJNnDhxMzyr7cuq4/NNo0aNShGR7r333nxbv3790g9/+MP03nvvpeLi4rRkyZJ1jnXMMcekgw8+eFOUvs2IiDRixIjV2j/55JPUpEmTNHny5NSiRYs0cODADR77zjvvTE2bNs0vjxkzJkVE+vzzzytU64wZM1JEpEmTJq1x/aRJk1KTJk3SrFmzyn1e26u5c+emiEjjxo3Lt9WqVSs98MADZfrVq1evzOdufVx00UXpyCOPzC/fdtttaeeddy7T5ze/+U1q0qRJBSrf9qzPe7Nbt26pU6dO6z1m3759U5s2bdbZ76233koRkV588cX1Hnt9P0sbWvP24Jufu/nz56fq1aun4cOH5/u89957KSLSK6+8skFjH3fccalHjx755dNPPz19//vfL9OnXbt26YILLvgWz2Db8c33cWlpaSopKUm33XZbvm3+/PmpoKAgPfTQQxs09je/A5955plUXFyc5s2b961qXtP3drt27dL111//rcbd1LaguMa6jBo1KqZOnRrPP/98jBw5MlasWBGdO3eOOnXqxEsvvRTjx4+P2rVrR5cuXfJnmr744ovo3r17/OMf/4gJEybEbrvtFscdd1x88cUXlfxstg+dOnWKNm3axF/+8peI+PqU+NChQ+Pss8+O1q1bx6677hqPPfbYOscpKipy9rACSktL40c/+lFcffXVsffee1dojE8//TT+8pe/RIcOHVZbt//++0ejRo3imGOOifHjx3/bciMiYsmSJfE///M/cdddd0VJSclGGXNbsmDBgoiIqFevXr7tkEMOiUceeST++9//RmlpaTz88MOxdOnS6Nix4waPnR23ffv28fHHH8ff/va3SCnFnDlz4rHHHovjjjtuozyXbd2cOXPi6aefjvPPP3+jj33ffffF7rvvHocffvhGHXdT1rw1++bnbuLEibFixYo4+uij831at24dzZs3j1deeWWDx85+7l555ZUy40Z8fYn6ho67vZgxY0bMnj27zGtWXFwc7dq1+9bH4sknn4wDDzwwfvWrX0WTJk1i9913j6uuumqDL4n75vtn7ty58eqrr0aDBg3ikEMOiYYNG0aHDh3iH//4xwaNu6kJSVuRWrVqxX333Rd777137L333vHII49EaWlp3HfffbHvvvvGnnvuGUOHDo2ZM2fG2LFjI+LrH9JX/UC+5557xu9///tYsmRJjBs3rnKfzHakdevW8dFHH0VExAsvvBBLliyJzp07R0TE2WefHX/4wx/K3TalFC+88EL8/e9/j06dOm2Ocrcpt956a1SrVi1+9rOfbfC2Z555ZtSsWTOaNGkSdevWjfvuuy+/rlGjRnHPPffE448/Ho8//ng0a9YsOnbsGG+++ea3rvmKK66IQw45JLp16/atx9rWlJaWxuWXXx6HHnpo7LPPPvn2Rx99NFasWBE77rhjFBQUxAUXXBAjRoyIXXfddb3Hfvnll+ORRx6Jn/zkJ/m2Qw89NB588ME444wzokaNGlFSUhLFxcXrvLyTr91///1Rp06ddV6CtaGWLl0aDz744CYJMpuq5q3Zmj53s2fPjho1aqx233TDhg3XeW9m1qOPPhqvv/569OjRI982e/bsaNiw4bcad3uy6nX5tq/Zmr4DP/zww/jHP/4RkydPjhEjRsSgQYPisccei4suumi9x13T++fDDz+MiK/vNezZs2c8++yz8d3vfjeOOuqodd5LtTkJSVuRfffdN2rUqJFffvvtt+ODDz6IOnXqRO3ataN27dpRr169WLp0aUyfPj0ivv6tWM+ePWO33XaL4uLiqFu3bixatChmzpxZWU9ju5NSyt9bMmTIkDjjjDOiWrVqEfH1D+Ljx4/PH69VRo4cGbVr147CwsLo2rVrnHHGGdGvX7/NXfpWbeLEiXHnnXfGsGHDyr23p2vXrvnPzjfPNA0cODDefPPN+Otf/xrTp0+PXr165dftscceccEFF0Tbtm3jkEMOiSFDhsQhhxwSAwcOjIivb/ZfNW7t2rXjpZdeWq+an3zyyRg9evQ6J5fYXl188cUxefLkePjhh8u033DDDTF//vx44YUX4o033ohevXrF6aefHu+8805ErP04R0RMnjw5unXrFn379o1jjz023/7uu+/GZZddFn369ImJEyfGs88+Gx999NEa709jdUOGDImzzjorCgsL823rOhbrY8SIEfmrJFZ56aWXynzm1jQZQEVr3t6V97lbl7333jt/PLp27bra+jFjxkSPHj3i3nvvrfB7gfVT0e/A0tLSyOVy8eCDD8b3vve9OO644+KOO+6I+++/P7788sv1+tyt6f2zakKrCy64IHr06BEHHHBADBw4MPbYY491TgqxOVWr7AKIqFu3bv5UZNb8+fOjuLg4v/zNWXwWLVoUbdu2XeObsn79+hER0b1795g3b17ceeed+ZlJ2rdv79Ktzei9996LVq1axX//+98YMWJErFixIgYPHpxfv3LlyhgyZEjccsst+bYjjzwyBg8eHDVq1IjGjRvnQxXr76WXXoq5c+dG8+bN820rV66MK6+8MgYNGhQfffRR3HffffnLBqpXr15m+5KSkigpKYnWrVtHvXr14vDDD48bbrghGjVqtMb9fe9738tfKnDiiSdGu3bt8uuaNGmyXjWPHj06pk+fvtpvZ0899dQ4/PDD82eIt0eXXHJJjBw5Ml588cVo2rRpvn369Onx29/+NiZPnpz/z79Nmzbx0ksvxV133RX33HPPWo/zu+++G0cddVT85Cc/ieuvv77MugEDBsShhx4aV199dURE7LffflGrVq04/PDD4+abby73vcDXn7+pU6fGI488UqZ9bcdifd13331x/PHHl/nN+YEHHlhmtshv/lb929S8PSvvc1dSUhLLly+P+fPnl/m+mjNnTv4y4b/97W+xYsWKiPj6kvGscePGxQknnBADBw6Mc845p8y6kpKS1WbJy45LWatelzlz5pT5TpozZ05+psiKfgc2atQomjRpUuZn0T333DNSSvHJJ5+s83NX3vtnVZ177bVXmf577rnnFvVLfD95bQH22GOPeO6551Zrf/PNN2P33Xcvd7vvfve78cgjj0SDBg2ibt26a+wzfvz4uPvuu/PX0H/88cfx2WefbZzCWafRo0fHO++8E1dccUU8+OCD0bRp09Wm7nzuuefi9ttvjxtvvDGqVq0aEV8H4g25VIjV/ehHP1rjde0/+tGP8pd2rG94WfVbr2XLlpXb56233sp/8depUyfq1KmzwTVfd9118eMf/7hM27777hsDBw6ME044YYPH2xaklOLSSy+NESNGxNixY6NVq1Zl1i9ZsiQiYrUZkapWrZo/buUd5ylTpkSnTp2ie/fuZX5JkR37m7+gWPUZTSlV7AltJ/7whz9E27Zto02bNmXa1/czV54ZM2bEmDFj4sknnyzTXlRU9K2/M8ureXu0rs9d27Zto3r16jFq1Kj8LIBTp06NmTNnRvv27SMiokWLFmsce+zYsXH88cfHrbfeWubSrlXat28fo0aNKvOnUZ5//vn8uJTVqlWrKCkpiVGjRuVD0cKFC+PVV1+NCy+8MCIq/h146KGHxvDhw2PRokVRu3btiIh4//33o0qVKtG0adNyP3frev+0bNkyGjduvNq04O+///4azzpWmkqbMoK86dOnp8LCwnTppZemt99+O/3rX/9Kt99+e6pWrVp65plnUkprnvFs8eLFabfddksdO3ZML774Yvrwww/TmDFj0qWXXpo+/vjjlFJKBxxwQDrmmGPSu+++myZMmJAOP/zwVFRUVKEZvihf9+7dU5cuXdKsWbPSJ598kiZOnJhuueWWVLt27XT88cenr776KrVp0yZde+21q207f/78VKNGjTRy5Mj8WGuaKY/VffHFF2nSpElp0qRJKSLSHXfckSZNmpT+/e9/r7H/+sxu9/TTT6chQ4akd955J82YMSONHDky7bnnnunQQw/N9xk4cGB64okn0rRp09I777yTLrvsslSlSpX0wgsvrHXsefPmpUmTJqWnn346RUR6+OGH06RJk9KsWbPK3Sa289ntLrzwwlRcXJzGjh2bZs2alX+smhVy+fLladddd02HH354evXVV9MHH3yQfv3rX6dcLpeefvrpcsd95513Uv369dPZZ59dZty5c+fm+wwdOjRVq1Yt3X333Wn69OnpH//4RzrwwAPT9773vU3+vLdU6/OZW7BgQapZs2YaPHjweo87bdq0NGnSpHTBBRek3XffPb+PZcuWlel3/fXXp8aNG6evvvpqo9Vb0Zq3Zev63KWU0k9/+tPUvHnzNHr06PTGG2+k9u3bp/bt26913NGjR6eaNWum3r17lxk3O3va+PHjU7Vq1dKvf/3r9N5776W+ffum6tWrp3feeWeTPd8t3brex7/85S/TDjvskP7617+mf/7zn6lbt26pVatW6csvvyx3zPX5Dvziiy9S06ZN0w9+8IM0ZcqUNG7cuLTbbrulH//4x2utd33ePwMHDkx169ZNw4cPT9OmTUvXX399KiwsTB988MG3fLU2HiFpC/Haa6+lY445JtWvXz8VFxendu3alfnBqLwfnGfNmpXOOeectNNOO6WCgoK08847p549e6YFCxaklFJ6880304EHHpgKCwvTbrvtloYPH17haZApX/fu3VNEpIhI1apVS/Xr109HH310GjJkSFq5cmV64403UkSk1157bY3bd+3aNZ188sn5sYSk9bNqKu5vPrp3777G/uvz3h89enRq3759Ki4uzn9urr322jLTfd96661pl112SYWFhalevXqpY8eOafTo0eusd+jQoWust2/fvuVus72HpDW9XhGRhg4dmu/z/vvvp1NOOSU1aNAg1axZM+23336rTQn+TX379l3juC1atCjT7ze/+U3aa6+9UlFRUWrUqFE666yz0ieffLIJnunWYX0+c7/73e9SUVFRmj9//nqP26FDhzWOm/2TFitXrkxNmzZNP//5zzdqvRWteVu2Pp+7L7/8Ml100UXpO9/5TqpZs2Y6+eST1/oLn5TK/l+ZfXTo0KFMv0cffTTtvvvuqUaNGmnvvfde6y88tgfreh+XlpamG264ITVs2DAVFBSko446Kk2dOnWtY67vd+B7772Xjj766FRUVJSaNm2aevXqtdqfLvmm9Xn/pJTSgAEDUtOmTVPNmjVT+/bt00svvbShL80mlUvJNQMAAACrmN0OAAAgQ0gCAADIEJIAAAAyhCQAAIAMIQkAACBDSAIAAMgQkgAAADKEJAAAgAwhCYAtQseOHePyyy/PL7ds2TIGDRqUX87lcvHEE09s9roA2P4ISQCU69xzz41cLrfa44MPPqjwmGPHjo1cLhfz588v0/6Xv/wlbrrppnK3mzVrVnTt2rXC+62oXC4XhYWF8e9//7tM+0knnRTnnnvuZq8HgE1PSAJgrbp06RKzZs0q82jVqlWFxlqxYkW56+rVqxd16tQpd31JSUkUFBRUaL/rklKKr776qtz1uVwu+vTps0n2DcCWR0gCYK0KCgqipKSkzKNq1aoREfHXv/41vvvd70ZhYWHsvPPO0b9//zJhI5fLxeDBg+PEE0+MWrVqRc+ePePII4+MiIjvfOc7kcvl8mdjvnm53TdlL7fr16/fGs9wDRs2LCIiSktLY8CAAdGqVasoKiqKNm3axGOPPZYfa9XZrGeeeSbatm0bBQUF8Y9//KPcfV9yySXxpz/9KSZPnlxun2effTYOO+yw2GGHHWLHHXeM448/PqZPn55f/9FHH0Uul4tHH300Dj/88CgqKoqDDjoo3n///Xj99dfjwAMPjNq1a0fXrl3jP//5T5mx77vvvthzzz2jsLAwWrduHXfffXe5dQDw7QlJAFTISy+9FOecc05cdtll8e6778bvfve7GDZsWNxyyy1l+vXr1y9OPvnkeOedd6J///7x+OOPR0TE1KlTY9asWXHnnXdu8L6vuuqqMme2fv3rX0fNmjXjwAMPjIiIAQMGxAMPPBD33HNPTJkyJa644oo4++yzY9y4cWXGue666+KXv/xlvPfee7HffvuVu79DDz00jj/++LjuuuvK7bN48eLo1atXvPHGGzFq1KioUqVKnHzyyVFaWlqmX9++feP666+PN998M6pVqxb/8z//E9dcc03ceeed8dJLL8UHH3xQ5qzVgw8+GH369Ilbbrkl3nvvvfjf//3fuOGGG+L+++/f4NcNgPWUAKAc3bt3T1WrVk21atXKP37wgx+klFI66qij0v/+7/+W6f/HP/4xNWrUKL8cEenyyy8v02fMmDEpItLnn39epr1Dhw7psssuyy+3aNEiDRw4sMxYI0aMWK3GV155JRUWFqZHHnkkpZTS0qVLU82aNdPLL79cpt/555+fzjzzzDI1PPHEE+t8DVbtd8qUKalq1arpxRdfTCml1K1bt9S9e/dyt/vPf/6TIiK98847KaWUZsyYkSIi3Xffffk+Dz30UIqINGrUqHzbgAED0h577JFf3mWXXdKf//znMmPfdNNNqX379uusHYCKqVZ58QyArcGRRx4ZgwcPzi/XqlUrIiLefvvtGD9+fJkzRytXroylS5fGkiVLombNmhER+bM7m8LMmTPjpJNOiquuuipOP/30iIj44IMPYsmSJXHMMceU6bt8+fI44IADyrRtSG177bVXnHPOOXHdddfF+PHjV1s/bdq06NOnT7z66qvx2Wef5c8gzZw5M/bZZ598v+wZq4YNG0ZExL777lumbe7cuRHx9dmp6dOnx/nnnx89e/bM9/nqq6+iuLh4vWsHYMMISQCsVa1atWLXXXddrX3RokXRv3//OOWUU1ZbV1hYWGb7TWHx4sVx4oknRvv27ePGG28sU1dExNNPPx1NmjQps803J37Y0Nr69+8fu++++xqnIj/hhBOiRYsWce+990bjxo2jtLQ09tlnn1i+fHmZftWrV8//O5fLrbFtVcBa9VzuvffeaNeuXZlxVt0XBsDGJyQBUCHf/e53Y+rUqWsMUGtTo0aNiPj6rFNFpZTi7LPPjtLS0vjjH/+YDxsRX5/xKSgoiJkzZ0aHDh0qvI81adasWVxyySXx85//PHbZZZd8+7x582Lq1Klx7733xuGHHx4RsdaJINZXw4YNo3HjxvHhhx/GWWed9a3HA2D9CEkAVEifPn3i+OOPj+bNm8cPfvCDqFKlSrz99tsxefLkuPnmm8vdrkWLFpHL5WLkyJFx3HHHRVFRUdSuXXuD9t2vX7944YUX4rnnnotFixblz7gUFxdHnTp14qqrroorrrgiSktL47DDDosFCxbE+PHjo27dutG9e/dv9bx79+4d9957b8yYMSPOOOOMiPh6pr4dd9wxfv/730ejRo1i5syZa53kYUP0798/fvazn0VxcXF06dIlli1bFm+88UZ8/vnn0atXr42yDwDKMrsdABXSuXPnGDlyZDz33HNx0EEHxcEHHxwDBw6MFi1arHW7Jk2aRP/+/eO6666Lhg0bxiWXXLLB+x43blwsWrQoDjnkkGjUqFH+8cgjj0RExE033RQ33HBDDBgwIPbcc8/o0qVLPP300xX++05Z9erVi2uvvTaWLl2ab6tSpUo8/PDDMXHixNhnn33iiiuuiNtuu+1b7ysi4sc//nHcd999MXTo0Nh3332jQ4cOMWzYsI3yXABYs1xKKVV2EQAAAFsKZ5IAAAAyhCQAAIAMIQkAACBDSAIAAMgQkgAAADKEJAAAgAwhCQAAIENIAgAAyBCSAAAAMoQkAACADCEJAAAg4/8DkDqrpYigst4AAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# checking the data distribution \n", "plt.figure(figsize=(10, 7))\n", "\n", "sns.countplot(data=df, x='Fertilizer Name')\n", "plt.title(\"Dataset Distribution\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['Sandy', 'Loamy', 'Black', 'Red', 'Clayey'], dtype=object)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# soil type\n", "df['Soil Type'].unique()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['Maize', 'Sugarcane', 'Cotton', 'Tobacco', 'Paddy', 'Barley',\n", " 'Wheat', 'Millets', 'Oil seeds', 'Pulses', 'Ground Nuts'],\n", " dtype=object)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Crop Type'].unique()" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Shape of the training dataset: (79, 8)\n", "Shape of the testing dataset: (20, 8)\n" ] } ], "source": [ "# splitting the dataset \n", "X = df.drop(columns=[\"Fertilizer Name\"])\n", "y = df[\"Fertilizer Name\"]\n", "\n", "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n", "\n", "print(f\"Shape of the training dataset: {X_train.shape}\")\n", "print(f\"Shape of the testing dataset: {X_test.shape}\")" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Temparature', 'Humidity ', 'Moisture', 'Nitrogen', 'Potassium', 'Phosphorous']\n" ] } ], "source": [ "# numerical columns in the dataset\n", "print(df._get_numeric_data().columns.tolist())" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Soil Type', 'Crop Type']" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# segrating categorical columns\n", "categorical_columns = [i for i in df.columns if (i not in df._get_numeric_data().columns) & (i !='Fertilizer Name')]\n", "categorical_columns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Encoding" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "ohe = OneHotEncoder(drop='first')\n", "standard_scaler = StandardScaler()\n", "\n", "preprocessor = ColumnTransformer(\n", " transformers =[\n", " ('StandaradScaling', standard_scaler, df._get_numeric_data().columns),\n", " ('One_hot_encoding', ohe, categorical_columns)\n", " ],\n", " remainder='passthrough'\n", ")\n", "\n", "pipeline = Pipeline([\n", " ('preprocess', preprocessor)\n", "])" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "X_train_transformed = pipeline.fit_transform(X_train)\n", "X_test_transformed = pipeline.transform(X_test)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "le = LabelEncoder()\n", "\n", "y_train_transformed = le.fit_transform(y_train)\n", "y_test_transformed = le.transform(y_test)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "def evaluate_clf(true, predicted):\n", " '''\n", " This function takes in true values and predicted values\n", " Returns: Accuracy, F1-Score, Precision, Recall, Roc-auc Score\n", " '''\n", " acc = accuracy_score(true, predicted)\n", " f1 = f1_score(true, predicted, average='weighted')\n", " precision = precision_score(true, predicted, average='weighted')\n", " recall = recall_score(true, predicted, average='weighted')\n", " \n", " return acc, f1, precision, recall" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "# create a function which can evaluate models and returns a report \n", "def evaluate_model(X_train, X_test, y_train, y_test, models):\n", " '''\n", " This function takes X_train, X_test, y_train, y_test and models dictionary as input\n", " Iterate through the given model directory and evaluate metrics\n", "\n", " Returns:\n", " DataFrame which contains report of all models metrics \n", " '''\n", "\n", " model_list = []\n", " metric_list = []\n", "\n", " for i in range(len(list(models))):\n", " model = list(models.values())[i]\n", " model.fit(X_train, y_train)\n", "\n", " # Make predictions\n", " y_train_pred = model.predict(X_train)\n", " y_test_pred = model.predict(X_test)\n", "\n", " # Training set performances\n", " model_train_accuracy, model_train_f1, model_train_precision, \\\n", " model_train_recall = evaluate_clf(y_train, y_train_pred)\n", "\n", " # Test set peformances \n", " model_test_accuracy, model_test_f1, model_test_precision, \\\n", " model_test_recall = evaluate_clf(y_test, y_test_pred)\n", "\n", " print(list(models.keys())[i])\n", " model_list.append(list(models.keys())[i])\n", "\n", " result_dict ={'model_name':list(models.keys())[i], \n", " \"train_accuracy\": model_train_accuracy, \"test_accuracy\": model_test_accuracy,\n", " \"train_precision\": model_train_precision, \"test_precision\": model_test_precision,\n", " 'train_recall': model_train_recall, \"test_recall\":model_test_recall,\n", " \"train_f1_score\": model_train_f1, \"test_f1_score\": model_test_f1}\n", "\n", " metric_list.append(result_dict)\n", "\n", " \n", " return metric_list\n" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "# Model Dictionary\n", "models = {\n", " \"Random Forest\": RandomForestClassifier(),\n", " \"Decision Tree\": DecisionTreeClassifier(),\n", " \"Gradient Boosting\": GradientBoostingClassifier(),\n", " \"K-Neighbors Classifier\": KNeighborsClassifier(),\n", " \"XGBClassifier\": XGBClassifier(), \n", " \"CatBoosting Classifier\": CatBoostClassifier(verbose=False),\n", " \"AdaBoost Classifier\": AdaBoostClassifier()\n", "}" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Random Forest\n", "Decision Tree\n", "Gradient Boosting\n", "K-Neighbors Classifier\n", "XGBClassifier\n", "CatBoosting Classifier\n", "AdaBoost Classifier\n" ] } ], "source": [ "resultant_metrics = evaluate_model(X_train_transformed, X_test_transformed, y_train_transformed, y_test_transformed, models)\n", "\n", "resultant_metrics_df = pd.DataFrame(data=resultant_metrics)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
model_nametrain_accuracytest_accuracytrain_precisiontest_precisiontrain_recalltest_recalltrain_f1_scoretest_f1_score
1Decision Tree1.0000001.001.0000001.0000001.0000001.001.0000001.000000
4XGBClassifier1.0000001.001.0000001.0000001.0000001.001.0000001.000000
5CatBoosting Classifier1.0000001.001.0000001.0000001.0000001.001.0000001.000000
0Random Forest1.0000000.951.0000001.0000001.0000000.951.0000000.966667
2Gradient Boosting1.0000000.951.0000000.9750001.0000000.951.0000000.955556
6AdaBoost Classifier0.5949370.700.4779180.6571430.5949370.700.5041470.662500
3K-Neighbors Classifier0.8987340.650.9045390.6666670.8987340.650.8975990.647727
\n", "
" ], "text/plain": [ " model_name train_accuracy test_accuracy train_precision \\\n", "1 Decision Tree 1.000000 1.00 1.000000 \n", "4 XGBClassifier 1.000000 1.00 1.000000 \n", "5 CatBoosting Classifier 1.000000 1.00 1.000000 \n", "0 Random Forest 1.000000 0.95 1.000000 \n", "2 Gradient Boosting 1.000000 0.95 1.000000 \n", "6 AdaBoost Classifier 0.594937 0.70 0.477918 \n", "3 K-Neighbors Classifier 0.898734 0.65 0.904539 \n", "\n", " test_precision train_recall test_recall train_f1_score test_f1_score \n", "1 1.000000 1.000000 1.00 1.000000 1.000000 \n", "4 1.000000 1.000000 1.00 1.000000 1.000000 \n", "5 1.000000 1.000000 1.00 1.000000 1.000000 \n", "0 1.000000 1.000000 0.95 1.000000 0.966667 \n", "2 0.975000 1.000000 0.95 1.000000 0.955556 \n", "6 0.657143 0.594937 0.70 0.504147 0.662500 \n", "3 0.666667 0.898734 0.65 0.897599 0.647727 " ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "resultant_metrics_df = resultant_metrics_df.sort_values(by='test_f1_score', ascending=False)\n", "resultant_metrics_df" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.8.10 64-bit", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a" } } }, "nbformat": 4, "nbformat_minor": 2 }