diff --git a/notebooks/regression/Perceptron.ipynb b/notebooks/regression/Perceptron.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..9871c62c4c00089980e2625b94c49ee18e257533 --- /dev/null +++ b/notebooks/regression/Perceptron.ipynb @@ -0,0 +1,1673 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 42, + "id": "4e148684-d4ca-468c-b41c-197d6ca3ceac", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>date</th>\n", + " <th>targeted_productivity</th>\n", + " <th>smv</th>\n", + " <th>over_time</th>\n", + " <th>incentive</th>\n", + " <th>no_of_style_change</th>\n", + " <th>no_of_workers</th>\n", + " <th>actual_productivity</th>\n", + " <th>overtime_bin</th>\n", + " <th>wip_log</th>\n", + " <th>idle_men_ratio</th>\n", + " <th>idle_ratio</th>\n", + " <th>day_num</th>\n", + " <th>day_sin</th>\n", + " <th>day_cos</th>\n", + " <th>department_encoded</th>\n", + " <th>team_encoded</th>\n", + " <th>quarter_encoded</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>2015-01-01</td>\n", + " <td>0.80</td>\n", + " <td>26.16</td>\n", + " <td>7080</td>\n", + " <td>98</td>\n", + " <td>0</td>\n", + " <td>59.0</td>\n", + " <td>0.940725</td>\n", + " <td>5001-10000</td>\n", + " <td>7.011214</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>3</td>\n", + " <td>0.433884</td>\n", + " <td>-0.900969</td>\n", + " <td>0.722013</td>\n", + " <td>0.674148</td>\n", + " <td>0.759686</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>2015-01-01</td>\n", + " <td>0.75</td>\n", + " <td>3.94</td>\n", + " <td>960</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>8.0</td>\n", + " <td>0.886500</td>\n", + " <td>501-1000</td>\n", + " <td>6.946976</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>3</td>\n", + " <td>0.433884</td>\n", + " <td>-0.900969</td>\n", + " <td>0.752951</td>\n", + " <td>0.821054</td>\n", + " <td>0.759686</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>2015-01-01</td>\n", + " <td>0.80</td>\n", + " <td>11.41</td>\n", + " <td>3660</td>\n", + " <td>50</td>\n", + " <td>0</td>\n", + " <td>30.5</td>\n", + " <td>0.800570</td>\n", + " <td>2001-5000</td>\n", + " <td>6.876265</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>3</td>\n", + " <td>0.433884</td>\n", + " <td>-0.900969</td>\n", + " <td>0.722013</td>\n", + " <td>0.681985</td>\n", + " <td>0.759686</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>2015-01-01</td>\n", + " <td>0.80</td>\n", + " <td>11.41</td>\n", + " <td>3660</td>\n", + " <td>50</td>\n", + " <td>0</td>\n", + " <td>30.5</td>\n", + " <td>0.800570</td>\n", + " <td>2001-5000</td>\n", + " <td>6.876265</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>3</td>\n", + " <td>0.433884</td>\n", + " <td>-0.900969</td>\n", + " <td>0.722013</td>\n", + " <td>0.779055</td>\n", + " <td>0.759686</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>2015-01-01</td>\n", + " <td>0.80</td>\n", + " <td>25.90</td>\n", + " <td>1920</td>\n", + " <td>50</td>\n", + " <td>0</td>\n", + " <td>56.0</td>\n", + " <td>0.800382</td>\n", + " <td>1001-2000</td>\n", + " <td>7.065613</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>3</td>\n", + " <td>0.433884</td>\n", + " <td>-0.900969</td>\n", + " <td>0.722013</td>\n", + " <td>0.685385</td>\n", + " <td>0.759686</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " date targeted_productivity smv over_time incentive \\\n", + "0 2015-01-01 0.80 26.16 7080 98 \n", + "1 2015-01-01 0.75 3.94 960 0 \n", + "2 2015-01-01 0.80 11.41 3660 50 \n", + "3 2015-01-01 0.80 11.41 3660 50 \n", + "4 2015-01-01 0.80 25.90 1920 50 \n", + "\n", + " no_of_style_change no_of_workers actual_productivity overtime_bin \\\n", + "0 0 59.0 0.940725 5001-10000 \n", + "1 0 8.0 0.886500 501-1000 \n", + "2 0 30.5 0.800570 2001-5000 \n", + "3 0 30.5 0.800570 2001-5000 \n", + "4 0 56.0 0.800382 1001-2000 \n", + "\n", + " wip_log idle_men_ratio idle_ratio day_num day_sin day_cos \\\n", + "0 7.011214 0.0 0.0 3 0.433884 -0.900969 \n", + "1 6.946976 0.0 0.0 3 0.433884 -0.900969 \n", + "2 6.876265 0.0 0.0 3 0.433884 -0.900969 \n", + "3 6.876265 0.0 0.0 3 0.433884 -0.900969 \n", + "4 7.065613 0.0 0.0 3 0.433884 -0.900969 \n", + "\n", + " department_encoded team_encoded quarter_encoded \n", + "0 0.722013 0.674148 0.759686 \n", + "1 0.752951 0.821054 0.759686 \n", + "2 0.722013 0.681985 0.759686 \n", + "3 0.722013 0.779055 0.759686 \n", + "4 0.722013 0.685385 0.759686 " + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "# Replace 'your_file.csv' with the actual filename\n", + "df = pd.read_csv('svm_neuralnet_ready.csv')\n", + "\n", + "# Show the first few rows to confirm it's loaded\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "28346333-5262-4509-bf97-ccee64d91ede", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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goOD8fvvvxu5dERERKQHZtMbi4iIiKghMNghIiIiXWOwQ0RERLrGYIeIiIh0jcEOERER6RqDHSIiItI1BjtERESkawx2iIiISNcY7BAREZGuMdghIiIiXWOwQ0RERLrGYIeIiIh0jcEOERER6RqDHSIiItI1BjtERESkawx2iIiISNcY7BAREZGuMdghIiIiXWOwQ0RERLrGYIeIiIh0jcEOERER6RqDHSIiItI1BjtERESkawx2iIiISNcY7BAREZGuMdghIiIiXWOwQ0RERLrGYIeIiIh0jcEOERER6RqDHSIiItI1BjtERESkawx2iIiISNcY7BAREZGuMdghIiIiXWOwQ0RERLrGYIeIiIh0jcEOERER6RqDHSIiItI1BjtERESkawx2iIiISNcY7BAREZGuMdghIiIiXWOwQ0RERLrGYIeIiIh0jcEOERER6RqDHSIiItI1BjtERESkawx2iIiISNcY7BAREZGuMdghIiIiXWOwQ0RERLrGYIeIiIh0jcEOERER6RqDHSIiItI1BjtERESkawx2iIiISNcY7BAREZGuMdghIiIiXWOwQ0RERLrGYIeIiIh0jcEOERER6ZpJg51NmzbhhhtuQEBAAKysrLBixYpy90+dOlXdXna59tpry62TnJyMiRMnwt3dHZ6enpg2bRoyMzMb+ZUQERGRuTJpsJOVlYVu3bph4cKFVa4jwc2FCxdKl2+//bbc/RLoHDlyBGvWrMGqVatUADVjxoxGKD0RERE1BbamfPLrrrtOLdVxcHBAixYtKr0vIiICq1evxq5du9C7d29124IFCzBmzBi88847qsaIiIiILJvZ5+xs2LABvr6+CA0NxQMPPICkpKTS+7Zt26aargyBjhg5ciSsra2xY8eOKreZl5eH9PT0cgsRERHpk1kHO9KE9fXXX2PdunV46623sHHjRlUTVFRUpO6Pi4tTgVBZtra28PLyUvdVZd68efDw8ChdWrVq1eCvhYiIiCywGetK7rjjjtLLXbp0QdeuXRESEqJqe0aMGFHn7T799NOYPXt26XWp2WHAQ0REpE9mXbNTUdu2beHj44NTp06p65LLk5CQUG6dwsJC1UOrqjwfQx6Q9N4quxAREZE+NalgJzo6WuXs+Pv7q+sDBgxAamoq9uzZU7rO+vXrUVxcjH79+pmwpERERGQuTNqMJePhGGpp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aVbZdu+991589913qjYtJCTkstotIkvDYIdIx5o1a6ZqBuSkJ00bkjwrycoG0rwl+R4yBowEAadPn1a9lyS/RkiT15kzZ9TJPTExUeWdSC2GNCm9+eabqhlImlsq5pVIECJJxH/++afKi5GcGckLqg9pApOySzDy7bffYsGCBXj00UerfYzk76xbt0710pJySJLzRx99pGqdhOT+SO3Jfffdp4IpCTIkUChbU1OT1yu9xCQB+Y477lCvW5rJJElYymrYjwcPHlTXZT9WFRTJehIkSo2YBDE33nhjtTU4UjZJIJcanLS0tNL7Ro8erZosX3vtNVWjRmTxNCLStTVr1mjh4eGag4OD1rVrV23Dhg3SHqP9/PPP6v6zZ89qEyZM0Nzd3TVnZ2etd+/e2o4dO9R9ubm56j5PT0/1mMWLF6vbjx49qg0YMEBzcnLSunfvrv3111/q/r///rv0cVOnTtU8PDzUYx944AHtqaee0rp161ZarilTpmjjxo2r0Wu46qqrtAcffFC7//77VTmbNWumPfPMM1pxcXHpOsHBwdr7779/2WOXL1+udezYUbOzs9OCgoK0t99+u9z9Fy5c0MaOHav2j9z/9ddfX7atK71eceDAAe2aa65R+9DNzU0bMmSIFhkZqe5LSEjQRo0apbm6upY+7syZM+ryvn37ypXn448/Vrfffffdl72WssdNfPbZZ1qrVq00a2trtY/Kev755zUbGxstNja2RvuYSM+s5I+pAy4ioupIl25J4G3oKRz0RGqHpKedDClAZOnY9ZyISEekOUu65UuCMwMdohIMdojIpCQXp2PHjlXeL+PiUM2NGzdOjRt0//33Y9SoUaYuDpFZYDMWEZmU9IaSqROqIkm7MhYOEVFdMdghIiIiXWPXcyIiItI1BjtERESkawx2iIiISNcY7BAREZGuMdghIiIiXWOwQ0RERLrGYIeIiIh0jcEOERERQc/+H1QH4egRyiozAAAAAElFTkSuQmCC", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "\n", + "sns.histplot(df['actual_productivity'], kde=True)\n", + "plt.title(\"Target Distribution: actual_productivity\")\n", + "plt.xlabel(\"actual_productivity\")\n", + "plt.ylabel(\"Count\")\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "6b71d343-dac2-4fd2-b307-e6af69a86df4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "date 0\n", + "targeted_productivity 0\n", + "smv 0\n", + "over_time 0\n", + "incentive 0\n", + "no_of_style_change 0\n", + "no_of_workers 0\n", + "actual_productivity 0\n", + "overtime_bin 0\n", + "wip_log 0\n", + "idle_men_ratio 0\n", + "idle_ratio 0\n", + "day_num 0\n", + "day_sin 0\n", + "day_cos 0\n", + "department_encoded 0\n", + "team_encoded 0\n", + "quarter_encoded 0\n", + "dtype: int64\n", + "date object\n", + "targeted_productivity float64\n", + "smv float64\n", + "over_time int64\n", + "incentive int64\n", + "no_of_style_change int64\n", + "no_of_workers float64\n", + "actual_productivity float64\n", + "overtime_bin object\n", + "wip_log float64\n", + "idle_men_ratio float64\n", + "idle_ratio float64\n", + "day_num int64\n", + "day_sin float64\n", + "day_cos float64\n", + "department_encoded float64\n", + "team_encoded float64\n", + "quarter_encoded float64\n", + "dtype: object\n" + ] + }, + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>date</th>\n", + " <th>targeted_productivity</th>\n", + " <th>smv</th>\n", + " <th>over_time</th>\n", + " <th>incentive</th>\n", + " <th>no_of_style_change</th>\n", + " <th>no_of_workers</th>\n", + " <th>actual_productivity</th>\n", + " <th>overtime_bin</th>\n", + " <th>wip_log</th>\n", + " <th>idle_men_ratio</th>\n", + " <th>idle_ratio</th>\n", + " <th>day_num</th>\n", + " <th>day_sin</th>\n", + " <th>day_cos</th>\n", + " <th>department_encoded</th>\n", + " <th>team_encoded</th>\n", + " <th>quarter_encoded</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>967</th>\n", + " <td>2015-02-28</td>\n", + " <td>0.8</td>\n", + " <td>15.26</td>\n", + " <td>1700</td>\n", + " <td>62</td>\n", + " <td>0</td>\n", + " <td>34.0</td>\n", + " <td>0.800261</td>\n", + " <td>1001-2000</td>\n", + " <td>7.085901</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>5</td>\n", + " <td>-0.974928</td>\n", + " <td>-0.222521</td>\n", + " <td>0.722013</td>\n", + " <td>0.779055</td>\n", + " <td>0.709067</td>\n", + " </tr>\n", + " <tr>\n", + " <th>646</th>\n", + " <td>2015-02-07</td>\n", + " <td>0.8</td>\n", + " <td>3.94</td>\n", + " <td>960</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>8.0</td>\n", + " <td>0.771583</td>\n", + " <td>501-1000</td>\n", + " <td>6.946976</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>5</td>\n", + " <td>-0.974928</td>\n", + " <td>-0.222521</td>\n", + " <td>0.752951</td>\n", + " <td>0.734462</td>\n", + " <td>0.759686</td>\n", + " </tr>\n", + " <tr>\n", + " <th>38</th>\n", + " <td>2015-01-03</td>\n", + " <td>0.8</td>\n", + " <td>2.90</td>\n", + " <td>960</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>8.0</td>\n", + " <td>0.628333</td>\n", + " <td>501-1000</td>\n", + " <td>6.946976</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>5</td>\n", + " <td>-0.974928</td>\n", + " <td>-0.222521</td>\n", + " <td>0.752951</td>\n", + " <td>0.674148</td>\n", + " <td>0.759686</td>\n", + " </tr>\n", + " <tr>\n", + " <th>563</th>\n", + " <td>2015-02-02</td>\n", + " <td>0.8</td>\n", + " <td>22.52</td>\n", + " <td>7020</td>\n", + " <td>88</td>\n", + " <td>0</td>\n", + " <td>58.5</td>\n", + " <td>0.900158</td>\n", + " <td>5001-10000</td>\n", + " <td>9.970492</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>0</td>\n", + " <td>0.000000</td>\n", + " <td>1.000000</td>\n", + " <td>0.722013</td>\n", + " <td>0.770855</td>\n", + " <td>0.759686</td>\n", + " </tr>\n", + " <tr>\n", + " <th>878</th>\n", + " <td>2015-02-22</td>\n", + " <td>0.7</td>\n", + " <td>30.10</td>\n", + " <td>8160</td>\n", + " <td>33</td>\n", + " <td>2</td>\n", + " <td>58.0</td>\n", + " <td>0.626578</td>\n", + " <td>5001-10000</td>\n", + " <td>6.948897</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>6</td>\n", + " <td>-0.781831</td>\n", + " <td>0.623490</td>\n", + " <td>0.722013</td>\n", + " <td>0.803880</td>\n", + " <td>0.709067</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " date targeted_productivity smv over_time incentive \\\n", + "967 2015-02-28 0.8 15.26 1700 62 \n", + "646 2015-02-07 0.8 3.94 960 0 \n", + "38 2015-01-03 0.8 2.90 960 0 \n", + "563 2015-02-02 0.8 22.52 7020 88 \n", + "878 2015-02-22 0.7 30.10 8160 33 \n", + "\n", + " no_of_style_change no_of_workers actual_productivity overtime_bin \\\n", + "967 0 34.0 0.800261 1001-2000 \n", + "646 0 8.0 0.771583 501-1000 \n", + "38 0 8.0 0.628333 501-1000 \n", + "563 0 58.5 0.900158 5001-10000 \n", + "878 2 58.0 0.626578 5001-10000 \n", + "\n", + " wip_log idle_men_ratio idle_ratio day_num day_sin day_cos \\\n", + "967 7.085901 0.0 0.0 5 -0.974928 -0.222521 \n", + "646 6.946976 0.0 0.0 5 -0.974928 -0.222521 \n", + "38 6.946976 0.0 0.0 5 -0.974928 -0.222521 \n", + "563 9.970492 0.0 0.0 0 0.000000 1.000000 \n", + "878 6.948897 0.0 0.0 6 -0.781831 0.623490 \n", + "\n", + " department_encoded team_encoded quarter_encoded \n", + "967 0.722013 0.779055 0.709067 \n", + "646 0.752951 0.734462 0.759686 \n", + "38 0.752951 0.674148 0.759686 \n", + "563 0.722013 0.770855 0.759686 \n", + "878 0.722013 0.803880 0.709067 " + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Check null values\n", + "print(df.isnull().sum())\n", + "\n", + "# Check datatypes\n", + "print(df.dtypes)\n", + "\n", + "# View a sample\n", + "df.sample(5)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "a4541b66-9311-4c6b-9e7b-e240ca27510e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>targeted_productivity</th>\n", + " <th>smv</th>\n", + " <th>over_time</th>\n", + " <th>incentive</th>\n", + " <th>no_of_style_change</th>\n", + " <th>no_of_workers</th>\n", + " <th>actual_productivity</th>\n", + " <th>wip_log</th>\n", + " <th>idle_men_ratio</th>\n", + " <th>idle_ratio</th>\n", + " <th>...</th>\n", + " <th>day_cos</th>\n", + " <th>department_encoded</th>\n", + " <th>team_encoded</th>\n", + " <th>quarter_encoded</th>\n", + " <th>overtime_bin_10001-20000</th>\n", + " <th>overtime_bin_1001-2000</th>\n", + " <th>overtime_bin_20001+</th>\n", + " <th>overtime_bin_2001-5000</th>\n", + " <th>overtime_bin_5001-10000</th>\n", + " <th>overtime_bin_501-1000</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>0.80</td>\n", + " <td>26.16</td>\n", + " <td>7080</td>\n", + " <td>98</td>\n", + " <td>0</td>\n", + " <td>59.0</td>\n", + " <td>0.940725</td>\n", + " <td>7.011214</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>...</td>\n", + " <td>-0.900969</td>\n", + " <td>0.722013</td>\n", + " <td>0.674148</td>\n", + " <td>0.759686</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>1</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>0.75</td>\n", + " <td>3.94</td>\n", + " <td>960</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>8.0</td>\n", + " <td>0.886500</td>\n", + " <td>6.946976</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>...</td>\n", + " <td>-0.900969</td>\n", + " <td>0.752951</td>\n", + " <td>0.821054</td>\n", + " <td>0.759686</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>1</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>0.80</td>\n", + " <td>11.41</td>\n", + " <td>3660</td>\n", + " <td>50</td>\n", + " <td>0</td>\n", + " <td>30.5</td>\n", + " <td>0.800570</td>\n", + " <td>6.876265</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>...</td>\n", + " <td>-0.900969</td>\n", + " <td>0.722013</td>\n", + " <td>0.681985</td>\n", + " <td>0.759686</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>1</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>0.80</td>\n", + " <td>11.41</td>\n", + " <td>3660</td>\n", + " <td>50</td>\n", + " <td>0</td>\n", + " <td>30.5</td>\n", + " <td>0.800570</td>\n", + " <td>6.876265</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>...</td>\n", + " <td>-0.900969</td>\n", + " <td>0.722013</td>\n", + " <td>0.779055</td>\n", + " <td>0.759686</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>1</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>0.80</td>\n", + " <td>25.90</td>\n", + " <td>1920</td>\n", + " <td>50</td>\n", + " <td>0</td>\n", + " <td>56.0</td>\n", + " <td>0.800382</td>\n", + " <td>7.065613</td>\n", + " <td>0.0</td>\n", + " <td>0.0</td>\n", + " <td>...</td>\n", + " <td>-0.900969</td>\n", + " <td>0.722013</td>\n", + " <td>0.685385</td>\n", + " <td>0.759686</td>\n", + " <td>0</td>\n", + " <td>1</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " <td>0</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>5 rows × 22 columns</p>\n", + "</div>" + ], + "text/plain": [ + " targeted_productivity smv over_time incentive no_of_style_change \\\n", + "0 0.80 26.16 7080 98 0 \n", + "1 0.75 3.94 960 0 0 \n", + "2 0.80 11.41 3660 50 0 \n", + "3 0.80 11.41 3660 50 0 \n", + "4 0.80 25.90 1920 50 0 \n", + "\n", + " no_of_workers actual_productivity wip_log idle_men_ratio idle_ratio \\\n", + "0 59.0 0.940725 7.011214 0.0 0.0 \n", + "1 8.0 0.886500 6.946976 0.0 0.0 \n", + "2 30.5 0.800570 6.876265 0.0 0.0 \n", + "3 30.5 0.800570 6.876265 0.0 0.0 \n", + "4 56.0 0.800382 7.065613 0.0 0.0 \n", + "\n", + " ... day_cos department_encoded team_encoded quarter_encoded \\\n", + "0 ... -0.900969 0.722013 0.674148 0.759686 \n", + "1 ... -0.900969 0.752951 0.821054 0.759686 \n", + "2 ... -0.900969 0.722013 0.681985 0.759686 \n", + "3 ... -0.900969 0.722013 0.779055 0.759686 \n", + "4 ... -0.900969 0.722013 0.685385 0.759686 \n", + "\n", + " overtime_bin_10001-20000 overtime_bin_1001-2000 overtime_bin_20001+ \\\n", + "0 0 0 0 \n", + "1 0 0 0 \n", + "2 0 0 0 \n", + "3 0 0 0 \n", + "4 0 1 0 \n", + "\n", + " overtime_bin_2001-5000 overtime_bin_5001-10000 overtime_bin_501-1000 \n", + "0 0 1 0 \n", + "1 0 0 1 \n", + "2 1 0 0 \n", + "3 1 0 0 \n", + "4 0 0 0 \n", + "\n", + "[5 rows x 22 columns]" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Drop date column\n", + "df = df.drop(columns=['date'])\n", + "\n", + "# One-hot encode overtime_bin\n", + "df = pd.get_dummies(df, columns=['overtime_bin'], drop_first=True, dtype=int)\n", + "\n", + "# Confirm\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "1a6e2e30-9f01-4671-afa0-9a5958bb50d9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Feature correlations with target:\n", + "targeted_productivity 0.421594\n", + "team_encoded 0.294280\n", + "wip_log 0.172146\n", + "overtime_bin_1001-2000 0.158944\n", + "quarter_encoded 0.131581\n", + "department_encoded 0.087624\n", + "incentive 0.076538\n", + "overtime_bin_10001-20000 0.025611\n", + "day_cos 0.014380\n", + "overtime_bin_2001-5000 0.001174\n", + "day_num 0.000030\n", + "day_sin -0.018568\n", + "over_time -0.054206\n", + "no_of_workers -0.057991\n", + "overtime_bin_20001+ -0.063851\n", + "overtime_bin_5001-10000 -0.081499\n", + "idle_ratio -0.082272\n", + "smv -0.122089\n", + "overtime_bin_501-1000 -0.135879\n", + "idle_men_ratio -0.184774\n", + "no_of_style_change -0.207366\n", + "Name: actual_productivity, dtype: float64\n" + ] + } + ], + "source": [ + "correlation = df.corr(numeric_only=True)\n", + "target_corr = correlation['actual_productivity'].drop('actual_productivity')\n", + "target_corr = target_corr.sort_values(ascending=False)\n", + "\n", + "print(\"Feature correlations with target:\")\n", + "print(target_corr)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "fdb8ad09-b984-4fb6-8ecf-597dd11e6617", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>Feature</th>\n", + " <th>F-score</th>\n", + " <th>p-value</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>targeted_productivity</td>\n", + " <td>258.314084</td>\n", + " <td>8.997899e-53</td>\n", + " </tr>\n", + " <tr>\n", + " <th>13</th>\n", + " <td>team_encoded</td>\n", + " <td>113.299745</td>\n", + " <td>2.428823e-25</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>no_of_style_change</td>\n", + " <td>53.694481</td>\n", + " <td>4.299784e-13</td>\n", + " </tr>\n", + " <tr>\n", + " <th>7</th>\n", + " <td>idle_men_ratio</td>\n", + " <td>42.241233</td>\n", + " <td>1.182042e-10</td>\n", + " </tr>\n", + " <tr>\n", + " <th>6</th>\n", + " <td>wip_log</td>\n", + " <td>36.494402</td>\n", + " <td>2.041955e-09</td>\n", + " </tr>\n", + " <tr>\n", + " <th>16</th>\n", + " <td>overtime_bin_1001-2000</td>\n", + " <td>30.972045</td>\n", + " <td>3.229131e-08</td>\n", + " </tr>\n", + " <tr>\n", + " <th>20</th>\n", + " <td>overtime_bin_501-1000</td>\n", + " <td>22.478314</td>\n", + " <td>2.380888e-06</td>\n", + " </tr>\n", + " <tr>\n", + " <th>14</th>\n", + " <td>quarter_encoded</td>\n", + " <td>21.054217</td>\n", + " <td>4.935447e-06</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>smv</td>\n", + " <td>18.081815</td>\n", + " <td>2.281130e-05</td>\n", + " </tr>\n", + " <tr>\n", + " <th>12</th>\n", + " <td>department_encoded</td>\n", + " <td>9.246175</td>\n", + " <td>2.411260e-03</td>\n", + " </tr>\n", + " <tr>\n", + " <th>8</th>\n", + " <td>idle_ratio</td>\n", + " <td>8.143783</td>\n", + " <td>4.395462e-03</td>\n", + " </tr>\n", + " <tr>\n", + " <th>19</th>\n", + " <td>overtime_bin_5001-10000</td>\n", + " <td>7.990303</td>\n", + " <td>4.781241e-03</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>incentive</td>\n", + " <td>7.041570</td>\n", + " <td>8.069572e-03</td>\n", + " </tr>\n", + " <tr>\n", + " <th>17</th>\n", + " <td>overtime_bin_20001+</td>\n", + " <td>4.891926</td>\n", + " <td>2.717121e-02</td>\n", + " </tr>\n", + " <tr>\n", + " <th>5</th>\n", + " <td>no_of_workers</td>\n", + " <td>4.032236</td>\n", + " <td>4.486346e-02</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>over_time</td>\n", + " <td>3.521583</td>\n", + " <td>6.081808e-02</td>\n", + " </tr>\n", + " <tr>\n", + " <th>15</th>\n", + " <td>overtime_bin_10001-20000</td>\n", + " <td>0.784346</td>\n", + " <td>3.759934e-01</td>\n", + " </tr>\n", + " <tr>\n", + " <th>10</th>\n", + " <td>day_sin</td>\n", + " <td>0.412164</td>\n", + " <td>5.209965e-01</td>\n", + " </tr>\n", + " <tr>\n", + " <th>11</th>\n", + " <td>day_cos</td>\n", + " <td>0.247143</td>\n", + " <td>6.191856e-01</td>\n", + " </tr>\n", + " <tr>\n", + " <th>18</th>\n", + " <td>overtime_bin_2001-5000</td>\n", + " <td>0.001647</td>\n", + " <td>9.676358e-01</td>\n", + " </tr>\n", + " <tr>\n", + " <th>9</th>\n", + " <td>day_num</td>\n", + " <td>0.000001</td>\n", + " <td>9.991721e-01</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Feature F-score p-value\n", + "0 targeted_productivity 258.314084 8.997899e-53\n", + "13 team_encoded 113.299745 2.428823e-25\n", + "4 no_of_style_change 53.694481 4.299784e-13\n", + "7 idle_men_ratio 42.241233 1.182042e-10\n", + "6 wip_log 36.494402 2.041955e-09\n", + "16 overtime_bin_1001-2000 30.972045 3.229131e-08\n", + "20 overtime_bin_501-1000 22.478314 2.380888e-06\n", + "14 quarter_encoded 21.054217 4.935447e-06\n", + "1 smv 18.081815 2.281130e-05\n", + "12 department_encoded 9.246175 2.411260e-03\n", + "8 idle_ratio 8.143783 4.395462e-03\n", + "19 overtime_bin_5001-10000 7.990303 4.781241e-03\n", + "3 incentive 7.041570 8.069572e-03\n", + "17 overtime_bin_20001+ 4.891926 2.717121e-02\n", + "5 no_of_workers 4.032236 4.486346e-02\n", + "2 over_time 3.521583 6.081808e-02\n", + "15 overtime_bin_10001-20000 0.784346 3.759934e-01\n", + "10 day_sin 0.412164 5.209965e-01\n", + "11 day_cos 0.247143 6.191856e-01\n", + "18 overtime_bin_2001-5000 0.001647 9.676358e-01\n", + "9 day_num 0.000001 9.991721e-01" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from sklearn.feature_selection import SelectKBest, f_regression\n", + "\n", + "# Features & target\n", + "X = df.drop(columns=['actual_productivity'])\n", + "y = df['actual_productivity']\n", + "\n", + "# Apply SelectKBest\n", + "selector = SelectKBest(score_func=f_regression, k='all') # You can set k=10 later\n", + "selector.fit(X, y)\n", + "\n", + "# Results\n", + "scores = selector.scores_\n", + "pvalues = selector.pvalues_\n", + "\n", + "# Combine into DataFrame\n", + "kbest_result = pd.DataFrame({\n", + " 'Feature': X.columns,\n", + " 'F-score': scores,\n", + " 'p-value': pvalues\n", + "}).sort_values('F-score', ascending=False)\n", + "\n", + "kbest_result" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "a7a3c710-4172-4876-8186-f42841a96973", + "metadata": {}, + "outputs": [], + "source": [ + "selected_features = [\n", + " 'targeted_productivity',\n", + " 'team_encoded',\n", + " 'no_of_style_change',\n", + " 'idle_men_ratio',\n", + " 'wip_log',\n", + " 'overtime_bin_1001-2000',\n", + " 'overtime_bin_501-1000',\n", + " 'quarter_encoded',\n", + " 'smv',\n", + " 'idle_ratio' # Optional but decent\n", + "]\n" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "0191eeb1-6857-494b-b316-2b56abe8770c", + "metadata": {}, + "outputs": [], + "source": [ + "# Final dataset\n", + "X = df[selected_features]\n", + "y = df['actual_productivity']" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "42785415-f444-43ad-bd5a-853e012fd5d9", + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "# Split the dataset (80% train, 20% test)\n", + "X_train, X_test, y_train, y_test = train_test_split(\n", + " X, y, test_size=0.2, random_state=42\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "93f61889-3599-40b0-9cab-02b71508980e", + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "# Initialize and fit scaler\n", + "scaler = StandardScaler()\n", + "X_train_scaled = scaler.fit_transform(X_train)\n", + "X_test_scaled = scaler.transform(X_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "245e1345-c170-42c6-86ca-a74644991b87", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<style>#sk-container-id-2 {\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-2 {\n", + " color: var(--sklearn-color-text);\n", + "}\n", + "\n", + "#sk-container-id-2 pre {\n", + " padding: 0;\n", + "}\n", + "\n", + "#sk-container-id-2 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-2 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-2 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-2 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-2 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-2 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-2 div.sk-parallel-item {\n", + " display: flex;\n", + " flex-direction: column;\n", + "}\n", + "\n", + "#sk-container-id-2 div.sk-parallel-item:first-child::after {\n", + " align-self: flex-end;\n", + " width: 50%;\n", + "}\n", + "\n", + "#sk-container-id-2 div.sk-parallel-item:last-child::after {\n", + " align-self: flex-start;\n", + " width: 50%;\n", + "}\n", + "\n", + "#sk-container-id-2 div.sk-parallel-item:only-child::after {\n", + " width: 0;\n", + "}\n", + "\n", + "/* Serial-specific style estimator block */\n", + "\n", + "#sk-container-id-2 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-2 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-2 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-2 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-2 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-2 label.sk-toggleable__label-arrow:hover:before {\n", + " color: var(--sklearn-color-text);\n", + "}\n", + "\n", + "/* Toggleable content - dropdown */\n", + "\n", + "#sk-container-id-2 div.sk-toggleable__content {\n", + " max-height: 0;\n", + " max-width: 0;\n", + " overflow: hidden;\n", + " text-align: left;\n", + " /* unfitted */\n", + " background-color: var(--sklearn-color-unfitted-level-0);\n", + "}\n", + "\n", + "#sk-container-id-2 div.sk-toggleable__content.fitted {\n", + " /* fitted */\n", + " background-color: var(--sklearn-color-fitted-level-0);\n", + "}\n", + "\n", + "#sk-container-id-2 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-2 div.sk-toggleable__content.fitted pre {\n", + " /* unfitted */\n", + " background-color: var(--sklearn-color-fitted-level-0);\n", + "}\n", + "\n", + "#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n", + " /* Expand drop-down */\n", + " max-height: 200px;\n", + " max-width: 100%;\n", + " overflow: auto;\n", + "}\n", + "\n", + "#sk-container-id-2 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-2 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-2 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-2 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-2 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-2 div.sk-label label.sk-toggleable__label,\n", + "#sk-container-id-2 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-2 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-2 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-2 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-2 div.sk-label-container {\n", + " text-align: center;\n", + "}\n", + "\n", + "/* Estimator-specific */\n", + "#sk-container-id-2 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-2 div.sk-estimator.fitted {\n", + " /* fitted */\n", + " background-color: var(--sklearn-color-fitted-level-0);\n", + "}\n", + "\n", + "/* on hover */\n", + "#sk-container-id-2 div.sk-estimator:hover {\n", + " /* unfitted */\n", + " background-color: var(--sklearn-color-unfitted-level-2);\n", + "}\n", + "\n", + "#sk-container-id-2 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-2 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-2 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-2 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-2 a.estimator_doc_link.fitted:hover {\n", + " /* fitted */\n", + " background-color: var(--sklearn-color-fitted-level-3);\n", + "}\n", + "</style><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>SGDRegressor(alpha=1e-05, eta0=0.001, learning_rate='adaptive',\n", + " penalty='elasticnet', random_state=42)</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-2\" type=\"checkbox\" checked><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>SGDRegressor</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.linear_model.SGDRegressor.html\">?<span>Documentation for SGDRegressor</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>SGDRegressor(alpha=1e-05, eta0=0.001, learning_rate='adaptive',\n", + " penalty='elasticnet', random_state=42)</pre></div> </div></div></div></div>" + ], + "text/plain": [ + "SGDRegressor(alpha=1e-05, eta0=0.001, learning_rate='adaptive',\n", + " penalty='elasticnet', random_state=42)" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from sklearn.linear_model import SGDRegressor\n", + "\n", + "# Initialize the model\n", + "model = SGDRegressor(\n", + " loss='squared_error', # standard linear regression loss\n", + " penalty='elasticnet', # regularization (optional: 'l2', 'l1', 'elasticnet')\n", + " alpha=1e-5, # regularization strength\n", + " learning_rate='adaptive',\n", + " eta0=0.001,\n", + " max_iter=1000,\n", + " random_state=42\n", + ")\n", + "\n", + "# Train the model\n", + "model.fit(X_train_scaled, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "c869d2d8-7d2a-42cb-85cc-a33c31dd4e1a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Mean Squared Error: 0.0203\n", + "R² Score : 0.2349\n", + "Mean Absolute Error: 0.1038\n" + ] + } + ], + "source": [ + "from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error\n", + "\n", + "# Make predictions\n", + "y_pred = model.predict(X_test_scaled)\n", + "\n", + "# Evaluate\n", + "mse = mean_squared_error(y_test, y_pred)\n", + "r2 = r2_score(y_test, y_pred)\n", + "mae = mean_absolute_error(y_test, y_pred)\n", + "\n", + "print(f\"Mean Squared Error: {mse:.4f}\")\n", + "print(f\"R² Score : {r2:.4f}\")\n", + "print(f\"Mean Absolute Error: {mae:.4f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "5f6f268e-e8a5-4f9e-9bc1-02474897aa02", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fitting 5 folds for each of 20 candidates, totalling 100 fits\n", + "Best Parameters: {'sgd__penalty': 'elasticnet', 'sgd__max_iter': 1500, 'sgd__learning_rate': 'adaptive', 'sgd__eta0': 0.005, 'sgd__alpha': 0.0001}\n", + "Tuned MSE: 0.020302359461082282\n", + "Tuned R² : 0.23538706119742847\n", + "Tuned MAE: 0.10378416921028938\n" + ] + } + ], + "source": [ + "from sklearn.model_selection import RandomizedSearchCV\n", + "from sklearn.linear_model import SGDRegressor\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "# Pipeline with scaler and model\n", + "pipeline = Pipeline([\n", + " ('scaler', StandardScaler()),\n", + " ('sgd', SGDRegressor(loss='squared_error', random_state=42))\n", + "])\n", + "\n", + "# Parameter grid\n", + "param_distributions = {\n", + " 'sgd__penalty': ['l2', 'elasticnet'], # remove 'l1' for stability\n", + " 'sgd__alpha': [1e-5, 1e-4, 1e-3], # reduce strength\n", + " 'sgd__learning_rate': ['constant', 'adaptive'],\n", + " 'sgd__eta0': [0.0005, 0.001, 0.005], # smaller learning rate\n", + " 'sgd__max_iter': [1000, 1500]\n", + "}\n", + "\n", + "# Randomized search\n", + "random_search = RandomizedSearchCV(\n", + " estimator=pipeline,\n", + " param_distributions=param_distributions,\n", + " n_iter=20, # You can increase for better search\n", + " scoring='neg_mean_squared_error',\n", + " cv=5,\n", + " verbose=2,\n", + " random_state=42,\n", + " n_jobs=-1\n", + ")\n", + "\n", + "# Fit to data\n", + "random_search.fit(X_train, y_train)\n", + "\n", + "# Best model and evaluation\n", + "best_model = random_search.best_estimator_\n", + "y_pred = best_model.predict(X_test)\n", + "\n", + "from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error\n", + "print(\"Best Parameters:\", random_search.best_params_)\n", + "print(\"Tuned MSE:\", mean_squared_error(y_test, y_pred))\n", + "print(\"Tuned R² :\", r2_score(y_test, y_pred))\n", + "print(\"Tuned MAE:\", mean_absolute_error(y_test, y_pred))" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "d30ba3b4-d9e1-4185-852c-ee26b13f0fed", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Poly MSE : 0.0242\n", + "Poly R² : 0.0878\n", + "Poly MAE : 0.1235\n" + ] + } + ], + "source": [ + "from sklearn.preprocessing import PolynomialFeatures\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.linear_model import SGDRegressor\n", + "from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error\n", + "\n", + "# Create pipeline: polynomial transformation + scaling + SGD\n", + "poly_pipeline = Pipeline([\n", + " ('poly', PolynomialFeatures(degree=2, include_bias=False)), # You can try degree=2 or 3\n", + " ('scaler', StandardScaler()),\n", + " ('sgd', SGDRegressor(\n", + " loss='squared_error',\n", + " penalty='elasticnet',\n", + " alpha=0.001,\n", + " learning_rate='adaptive',\n", + " eta0=0.0001,\n", + " max_iter=1500,\n", + " random_state=42\n", + " ))\n", + "])\n", + "\n", + "# Train on original train data (X_train, y_train — not scaled or poly-transformed yet)\n", + "poly_pipeline.fit(X_train, y_train)\n", + "\n", + "# Predict on X_test\n", + "y_poly_pred = poly_pipeline.predict(X_test)\n", + "\n", + "# Evaluate\n", + "mse = mean_squared_error(y_test, y_poly_pred)\n", + "r2 = r2_score(y_test, y_poly_pred)\n", + "mae = mean_absolute_error(y_test, y_poly_pred)\n", + "\n", + "print(f\"Poly MSE : {mse:.4f}\")\n", + "print(f\"Poly R² : {r2:.4f}\")\n", + "print(f\"Poly MAE : {mae:.4f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ada8b857-bc21-4019-b8ab-02e06e071094", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}