{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b68ee162-c9f6-47ff-b4af-89ce5f30ff63",
   "metadata": {
    "tags": []
   },
   "source": [
    "# SDGRegressor to Predict Crowdness at the Gym\n",
    "\n",
    "I love going to the Gym, however, I hate it when it's crowded because I cannot follow my plan at my rythm. I often have to wait for the machine I need to free up, and it becomes next to impossible to follow my routine.\n",
    "\n",
    "Because of this, I decided to build a predictive model using Machine Learninhg, especifically a linear regressor using Stochastic Gradient Decsent.\n",
    "\n",
    "Using a dataset with over 60,000 observations and 11 featres including day, hour, temperature and other details, I will be creating a model that can predict how many people will be at the gym at a particular day and time. That way, I will be able to enjoy my excersise routine without waiting times."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6aae706a-ea92-4034-afea-8a77a7a82928",
   "metadata": {},
   "source": [
    "\n",
    "### Import Libraries and Load the Data\n",
    "\n",
    "The first step, is loading the libraries I will need to use to load and explore the data. I will be using the following ones:\n",
    "\n",
    "- Numpy\n",
    "- Pandas\n",
    "- Matplotlib\n",
    "- Seaborn\n",
    "\n",
    "Also nore I am using the magic inline command to plot graphs directly on to the notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "987a6b03-74ca-4882-83e7-26b8b8b70e0f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt \n",
    "import seaborn as sns\n",
    "%matplotlib inline "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "47132544-4282-4940-b660-f4da4e134275",
   "metadata": {},
   "source": [
    "The dataset csv file is called 'crowdness_gym_data'. I am using the Pandas `read_csv` comand to load it into a dataframe called **df**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ac732dcd-a579-4d14-9bce-7080f5824ab7",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv('crowdness_gym_data.csv')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2874521-a017-46ae-ba48-f68073104a6a",
   "metadata": {},
   "source": [
    "### EDA and Cleaning up the Data\n",
    "\n",
    "To get a sense of the data, I ran some basic exploration commands, starting with `.head()` to get a general sense of the data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "74da2c73-b077-4f62-8ba9-bf8f2ec1fdbc",
   "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>number_people</th>\n",
       "      <th>date</th>\n",
       "      <th>timestamp</th>\n",
       "      <th>day_of_week</th>\n",
       "      <th>is_weekend</th>\n",
       "      <th>is_holiday</th>\n",
       "      <th>temperature</th>\n",
       "      <th>is_start_of_semester</th>\n",
       "      <th>is_during_semester</th>\n",
       "      <th>month</th>\n",
       "      <th>hour</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>37</td>\n",
       "      <td>2015-08-14 17:00:11-07:00</td>\n",
       "      <td>61211</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>45</td>\n",
       "      <td>2015-08-14 17:20:14-07:00</td>\n",
       "      <td>62414</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>40</td>\n",
       "      <td>2015-08-14 17:30:15-07:00</td>\n",
       "      <td>63015</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>44</td>\n",
       "      <td>2015-08-14 17:40:16-07:00</td>\n",
       "      <td>63616</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>45</td>\n",
       "      <td>2015-08-14 17:50:17-07:00</td>\n",
       "      <td>64217</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   number_people                       date  timestamp  day_of_week  \\\n",
       "0             37  2015-08-14 17:00:11-07:00      61211            4   \n",
       "1             45  2015-08-14 17:20:14-07:00      62414            4   \n",
       "2             40  2015-08-14 17:30:15-07:00      63015            4   \n",
       "3             44  2015-08-14 17:40:16-07:00      63616            4   \n",
       "4             45  2015-08-14 17:50:17-07:00      64217            4   \n",
       "\n",
       "   is_weekend  is_holiday  temperature  is_start_of_semester  \\\n",
       "0           0           0        71.76                     0   \n",
       "1           0           0        71.76                     0   \n",
       "2           0           0        71.76                     0   \n",
       "3           0           0        71.76                     0   \n",
       "4           0           0        71.76                     0   \n",
       "\n",
       "   is_during_semester  month  hour  \n",
       "0                   0      8    17  \n",
       "1                   0      8    17  \n",
       "2                   0      8    17  \n",
       "3                   0      8    17  \n",
       "4                   0      8    17  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a39e008-dea3-4938-ba50-a1a0e3ef3736",
   "metadata": {},
   "source": [
    "Everything looks fairly straightforward and clean. Let's check out the shape of the data with `.shape`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "ac6cb280-5715-4194-a958-a072f82914c4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Data contains 62184 rows and 11 columns\n"
     ]
    }
   ],
   "source": [
    "print('Data contains', df.shape[0], 'rows and', df.shape[1], 'columns')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d923a27-2ed0-4622-bbfd-9491435f979b",
   "metadata": {},
   "source": [
    "There are 62,184 rows, or observations and 11 columns, or features.\n",
    "\n",
    "Now to get somne info on each of the features with `.info()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "fcc5c4e2-36eb-40c8-9753-5c558ab3775c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 62184 entries, 0 to 62183\n",
      "Data columns (total 11 columns):\n",
      " #   Column                Non-Null Count  Dtype  \n",
      "---  ------                --------------  -----  \n",
      " 0   number_people         62184 non-null  int64  \n",
      " 1   date                  62184 non-null  object \n",
      " 2   timestamp             62184 non-null  int64  \n",
      " 3   day_of_week           62184 non-null  int64  \n",
      " 4   is_weekend            62184 non-null  int64  \n",
      " 5   is_holiday            62184 non-null  int64  \n",
      " 6   temperature           62184 non-null  float64\n",
      " 7   is_start_of_semester  62184 non-null  int64  \n",
      " 8   is_during_semester    62184 non-null  int64  \n",
      " 9   month                 62184 non-null  int64  \n",
      " 10  hour                  62184 non-null  int64  \n",
      "dtypes: float64(1), int64(9), object(1)\n",
      "memory usage: 5.2+ MB\n"
     ]
    }
   ],
   "source": [
    "df.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "add41046-48e2-4eb1-ac7a-005495a9dcfb",
   "metadata": {},
   "source": [
    "Most of the data is numeric and integers, with the exceptions of the temperature, which is a float (expected as the temperature is seldom a whole number) and the date object, which could be a problem.\n",
    "\n",
    "We can get some more information with `.describe()` which gives us some basic statistics about the data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "6e28f00a-37c1-4a81-adc4-a0ea15636d21",
   "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>number_people</th>\n",
       "      <th>timestamp</th>\n",
       "      <th>day_of_week</th>\n",
       "      <th>is_weekend</th>\n",
       "      <th>is_holiday</th>\n",
       "      <th>temperature</th>\n",
       "      <th>is_start_of_semester</th>\n",
       "      <th>is_during_semester</th>\n",
       "      <th>month</th>\n",
       "      <th>hour</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>62184.000000</td>\n",
       "      <td>62184.000000</td>\n",
       "      <td>62184.000000</td>\n",
       "      <td>62184.000000</td>\n",
       "      <td>62184.000000</td>\n",
       "      <td>62184.000000</td>\n",
       "      <td>62184.000000</td>\n",
       "      <td>62184.000000</td>\n",
       "      <td>62184.000000</td>\n",
       "      <td>62184.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>29.072543</td>\n",
       "      <td>45799.437958</td>\n",
       "      <td>2.982504</td>\n",
       "      <td>0.282870</td>\n",
       "      <td>0.002573</td>\n",
       "      <td>58.557108</td>\n",
       "      <td>0.078831</td>\n",
       "      <td>0.660218</td>\n",
       "      <td>7.439824</td>\n",
       "      <td>12.236460</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>22.689026</td>\n",
       "      <td>24211.275891</td>\n",
       "      <td>1.996825</td>\n",
       "      <td>0.450398</td>\n",
       "      <td>0.050660</td>\n",
       "      <td>6.316396</td>\n",
       "      <td>0.269476</td>\n",
       "      <td>0.473639</td>\n",
       "      <td>3.445069</td>\n",
       "      <td>6.717631</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>38.140000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>9.000000</td>\n",
       "      <td>26624.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>55.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>7.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>28.000000</td>\n",
       "      <td>46522.500000</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>58.340000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>8.000000</td>\n",
       "      <td>12.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>43.000000</td>\n",
       "      <td>66612.000000</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>62.280000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>10.000000</td>\n",
       "      <td>18.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>145.000000</td>\n",
       "      <td>86399.000000</td>\n",
       "      <td>6.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>87.170000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>12.000000</td>\n",
       "      <td>23.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       number_people     timestamp   day_of_week    is_weekend    is_holiday  \\\n",
       "count   62184.000000  62184.000000  62184.000000  62184.000000  62184.000000   \n",
       "mean       29.072543  45799.437958      2.982504      0.282870      0.002573   \n",
       "std        22.689026  24211.275891      1.996825      0.450398      0.050660   \n",
       "min         0.000000      0.000000      0.000000      0.000000      0.000000   \n",
       "25%         9.000000  26624.000000      1.000000      0.000000      0.000000   \n",
       "50%        28.000000  46522.500000      3.000000      0.000000      0.000000   \n",
       "75%        43.000000  66612.000000      5.000000      1.000000      0.000000   \n",
       "max       145.000000  86399.000000      6.000000      1.000000      1.000000   \n",
       "\n",
       "        temperature  is_start_of_semester  is_during_semester         month  \\\n",
       "count  62184.000000          62184.000000        62184.000000  62184.000000   \n",
       "mean      58.557108              0.078831            0.660218      7.439824   \n",
       "std        6.316396              0.269476            0.473639      3.445069   \n",
       "min       38.140000              0.000000            0.000000      1.000000   \n",
       "25%       55.000000              0.000000            0.000000      5.000000   \n",
       "50%       58.340000              0.000000            1.000000      8.000000   \n",
       "75%       62.280000              0.000000            1.000000     10.000000   \n",
       "max       87.170000              1.000000            1.000000     12.000000   \n",
       "\n",
       "               hour  \n",
       "count  62184.000000  \n",
       "mean      12.236460  \n",
       "std        6.717631  \n",
       "min        0.000000  \n",
       "25%        7.000000  \n",
       "50%       12.000000  \n",
       "75%       18.000000  \n",
       "max       23.000000  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5642a0d7-5d01-4f5f-b1d9-401d74ad32a5",
   "metadata": {},
   "source": [
    "It all looks fairly straighforward. The date column, as it is an object, has no statistics, and the timestamp seems to be wierd to work with. Most of the others seem good, with some of the features like **is_holiday** and **is_weekend** being binary features.\n",
    "\n",
    "Finally, I will check to see if we have any empty (**Null**) values in the dataset with the `is.null()` and `.sum()` functions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "be532b27-a508-42cd-9514-5477bd4e7169",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "number_people           0\n",
       "date                    0\n",
       "timestamp               0\n",
       "day_of_week             0\n",
       "is_weekend              0\n",
       "is_holiday              0\n",
       "temperature             0\n",
       "is_start_of_semester    0\n",
       "is_during_semester      0\n",
       "month                   0\n",
       "hour                    0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.isnull().sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1af22ade-f2fd-45b4-99a4-a6a95d2d88f1",
   "metadata": {},
   "source": [
    "There are no null valies in the dataset.\n",
    "\n",
    "At the moment, the only feature that I feel is definitely problematic is the date column, since it is an object and because we already have other features that give us the specific day and time, I will get rid of the date column completely using `.drop()`.  Then run `.head()` again just to check the date column is gone."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "af652dee-44c7-4d21-a20e-67679aa479a1",
   "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>number_people</th>\n",
       "      <th>timestamp</th>\n",
       "      <th>day_of_week</th>\n",
       "      <th>is_weekend</th>\n",
       "      <th>is_holiday</th>\n",
       "      <th>temperature</th>\n",
       "      <th>is_start_of_semester</th>\n",
       "      <th>is_during_semester</th>\n",
       "      <th>month</th>\n",
       "      <th>hour</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>37</td>\n",
       "      <td>61211</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>45</td>\n",
       "      <td>62414</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>40</td>\n",
       "      <td>63015</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>44</td>\n",
       "      <td>63616</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>45</td>\n",
       "      <td>64217</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   number_people  timestamp  day_of_week  is_weekend  is_holiday  temperature  \\\n",
       "0             37      61211            4           0           0        71.76   \n",
       "1             45      62414            4           0           0        71.76   \n",
       "2             40      63015            4           0           0        71.76   \n",
       "3             44      63616            4           0           0        71.76   \n",
       "4             45      64217            4           0           0        71.76   \n",
       "\n",
       "   is_start_of_semester  is_during_semester  month  hour  \n",
       "0                     0                   0      8    17  \n",
       "1                     0                   0      8    17  \n",
       "2                     0                   0      8    17  \n",
       "3                     0                   0      8    17  \n",
       "4                     0                   0      8    17  "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = df.drop('date', axis=1)\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3d46651-8846-4aee-b53b-c6a98afd68d5",
   "metadata": {},
   "source": [
    "### Plots\n",
    "\n",
    "Now I am ready to do some EDA (Exploratory Data Analysis).\n",
    "\n",
    "I will start by doing Univariate Analysis on some of the features. This means we will take a deeper look at the distributions of specific features.\n",
    "\n",
    "I will plot histograms for the month, day and hour, since they probably have the largest influence on the ammount of people."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c922fe0a-0cc8-4469-9c74-f953121f8cac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 14260 characters]\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 8))\n",
    "\n",
    "plt.hist(df['month'])\n",
    "plt.title(\"Observations per Month of the Year\")\n",
    "plt.xlabel('Month')\n",
    "plt.ylabel('No. of Observavtions')\n",
    "plt.show()\n",
    "            "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18430639-5e5d-4aa7-a435-61e0dd93934c",
   "metadata": {},
   "source": [
    "Here we can see that December and January are the months with the most observations, probably because they are the most popular months to go to the gym. We can also see more obervations at the begining of the semester (August), then at the end, probably because everyone is very excited at the beguning and very busy at the end (March, April)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "8cf9ccbc-33aa-4663-90f2-18c22586b707",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 13328 characters]\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 8))\n",
    "\n",
    "plt.hist(df['day_of_week'])\n",
    "plt.title(\"Observations per Day of the Week\")\n",
    "plt.xlabel('Day of the Week')\n",
    "plt.ylabel('No. of Observavtions')\n",
    "plt.show()\n",
    "            "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33ca8df5-b48d-4931-ba46-2411443f0c5b",
   "metadata": {},
   "source": [
    "This one looks strange, but it sometimes happens with plots. Instead of fighting with it, I will replot it using the Seaborn library and a ditribution plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ee2bba39-0f65-42a3-89e4-a33e180ec3a5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 576x576 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 11788 characters]\n",
      "text/plain": [
       "<Figure size 360x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 8))\n",
    "\n",
    "sns.displot(df['day_of_week'], color='g')\n",
    "plt.title(\"Observations per Day of the Week\")\n",
    "plt.xlabel('Day of the Week')\n",
    "plt.ylabel('No. of Observavtions')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dab46b76-6fc1-411d-95d1-5c19d08094d0",
   "metadata": {},
   "source": [
    "Not a lot of information here, except that there is not a huge diference in the number of observations for each day of the week. Tuesday (1) seems to be the most common day, but not by much."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "195ec8f4-41bb-4d01-91c5-e0dfcce473ab",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 14156 characters]\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 8))\n",
    "\n",
    "plt.hist(df['hour'])\n",
    "plt.title(\"Observations per Day of the Week\")\n",
    "plt.xlabel('Hour')\n",
    "plt.ylabel('No. of Observavtions')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8681dc57-93f8-475b-99b4-cc7f83cd0080",
   "metadata": {},
   "source": [
    "This is much more interesting, but just in case, there are a lot of observations at early morning and mid afternoon, which is expected, but the one at midnight are a surprise. Seems like there are night owls going to the gym.\n",
    "\n",
    "This is interesting, but since I am building a model to predict the ammount of people (target variable), I can get more information from using Bivariate Analysis, meaning we confront two variables at the same time to see if there is any correlation between them.\n",
    "\n",
    "Let's plot the relations between month, day and hour compared to the number of people."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "8c62ed3e-2059-4d20-82ed-eb5822b25693",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 15556 characters]\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 8))\n",
    "\n",
    "plt.scatter(df['month'], df['number_people'])\n",
    "plt.title(\"Number of People VS Month\")\n",
    "plt.xlabel('Month')\n",
    "plt.ylabel('Number of People')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "de921635-1384-43e1-b00a-db69a27d1ce4",
   "metadata": {},
   "source": [
    "A clearer version of the relationship. We can see again that August and January are the months with the bigger peaks of people, and once again, that the begining of the semester has larger peaks than the end of it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "07b505ad-8cf3-401f-89af-de1afd302bb2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 16268 characters]\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 8))\n",
    "\n",
    "plt.scatter(df['day_of_week'], df['number_people'])\n",
    "plt.title(\"Number of People VS Day of the Week\")\n",
    "plt.xlabel('Day of the Week')\n",
    "plt.ylabel('Number of People')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "db81aaf6-03a2-4b01-b105-990dbb33cdb8",
   "metadata": {},
   "source": [
    "Here we can now see the largest peaks on Monday and Wednesday. And the lower peaks on Saturdays."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "94eb41d4-2bcf-4eb1-96bd-a6d884a9a1dd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 19224 characters]\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 8))\n",
    "\n",
    "plt.scatter(df['hour'], df['number_people'])\n",
    "plt.title(\"Number of People VS Hour\")\n",
    "plt.xlabel('Hour')\n",
    "plt.ylabel('Number of People')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f3c7b57-00c1-43f0-baa1-39c4a426060b",
   "metadata": {},
   "source": [
    "Now we can see a lot clearer, that the largest peaks of people are during the afternoon, evening, and still surprising, large peaks late at night. ALso we see very small peaks from 2am to 5am.\n",
    "\n",
    "I can go on with each variable, but to make it short, I will use a set of tools, from correlation tables, pairplots and a heatmap, to quickly see the relationship between each variable and out target (number of people).\n",
    "\n",
    "I will start with the Correlation Table."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "6e01a6c7-4921-46f8-80e1-06c85cdf67b1",
   "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>number_people</th>\n",
       "      <th>timestamp</th>\n",
       "      <th>day_of_week</th>\n",
       "      <th>is_weekend</th>\n",
       "      <th>is_holiday</th>\n",
       "      <th>temperature</th>\n",
       "      <th>is_start_of_semester</th>\n",
       "      <th>is_during_semester</th>\n",
       "      <th>month</th>\n",
       "      <th>hour</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>number_people</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.550218</td>\n",
       "      <td>-0.162062</td>\n",
       "      <td>-0.173958</td>\n",
       "      <td>-0.048249</td>\n",
       "      <td>0.373327</td>\n",
       "      <td>0.182683</td>\n",
       "      <td>0.335350</td>\n",
       "      <td>-0.097854</td>\n",
       "      <td>0.552049</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>timestamp</th>\n",
       "      <td>0.550218</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>-0.001793</td>\n",
       "      <td>-0.000509</td>\n",
       "      <td>0.002851</td>\n",
       "      <td>0.184849</td>\n",
       "      <td>0.009551</td>\n",
       "      <td>0.044676</td>\n",
       "      <td>-0.023221</td>\n",
       "      <td>0.999077</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>day_of_week</th>\n",
       "      <td>-0.162062</td>\n",
       "      <td>-0.001793</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.791338</td>\n",
       "      <td>-0.075862</td>\n",
       "      <td>0.011169</td>\n",
       "      <td>-0.011782</td>\n",
       "      <td>-0.004824</td>\n",
       "      <td>0.015559</td>\n",
       "      <td>-0.001914</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>is_weekend</th>\n",
       "      <td>-0.173958</td>\n",
       "      <td>-0.000509</td>\n",
       "      <td>0.791338</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>-0.031899</td>\n",
       "      <td>0.020673</td>\n",
       "      <td>-0.016646</td>\n",
       "      <td>-0.036127</td>\n",
       "      <td>0.008462</td>\n",
       "      <td>-0.000517</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>is_holiday</th>\n",
       "      <td>-0.048249</td>\n",
       "      <td>0.002851</td>\n",
       "      <td>-0.075862</td>\n",
       "      <td>-0.031899</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>-0.088527</td>\n",
       "      <td>-0.014858</td>\n",
       "      <td>-0.070798</td>\n",
       "      <td>-0.094942</td>\n",
       "      <td>0.002843</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>temperature</th>\n",
       "      <td>0.373327</td>\n",
       "      <td>0.184849</td>\n",
       "      <td>0.011169</td>\n",
       "      <td>0.020673</td>\n",
       "      <td>-0.088527</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.093242</td>\n",
       "      <td>0.152476</td>\n",
       "      <td>0.063125</td>\n",
       "      <td>0.185121</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>is_start_of_semester</th>\n",
       "      <td>0.182683</td>\n",
       "      <td>0.009551</td>\n",
       "      <td>-0.011782</td>\n",
       "      <td>-0.016646</td>\n",
       "      <td>-0.014858</td>\n",
       "      <td>0.093242</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.209862</td>\n",
       "      <td>-0.137160</td>\n",
       "      <td>0.010091</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>is_during_semester</th>\n",
       "      <td>0.335350</td>\n",
       "      <td>0.044676</td>\n",
       "      <td>-0.004824</td>\n",
       "      <td>-0.036127</td>\n",
       "      <td>-0.070798</td>\n",
       "      <td>0.152476</td>\n",
       "      <td>0.209862</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.096556</td>\n",
       "      <td>0.045581</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>month</th>\n",
       "      <td>-0.097854</td>\n",
       "      <td>-0.023221</td>\n",
       "      <td>0.015559</td>\n",
       "      <td>0.008462</td>\n",
       "      <td>-0.094942</td>\n",
       "      <td>0.063125</td>\n",
       "      <td>-0.137160</td>\n",
       "      <td>0.096556</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>-0.023624</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>hour</th>\n",
       "      <td>0.552049</td>\n",
       "      <td>0.999077</td>\n",
       "      <td>-0.001914</td>\n",
       "      <td>-0.000517</td>\n",
       "      <td>0.002843</td>\n",
       "      <td>0.185121</td>\n",
       "      <td>0.010091</td>\n",
       "      <td>0.045581</td>\n",
       "      <td>-0.023624</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                      number_people  timestamp  day_of_week  is_weekend  \\\n",
       "number_people              1.000000   0.550218    -0.162062   -0.173958   \n",
       "timestamp                  0.550218   1.000000    -0.001793   -0.000509   \n",
       "day_of_week               -0.162062  -0.001793     1.000000    0.791338   \n",
       "is_weekend                -0.173958  -0.000509     0.791338    1.000000   \n",
       "is_holiday                -0.048249   0.002851    -0.075862   -0.031899   \n",
       "temperature                0.373327   0.184849     0.011169    0.020673   \n",
       "is_start_of_semester       0.182683   0.009551    -0.011782   -0.016646   \n",
       "is_during_semester         0.335350   0.044676    -0.004824   -0.036127   \n",
       "month                     -0.097854  -0.023221     0.015559    0.008462   \n",
       "hour                       0.552049   0.999077    -0.001914   -0.000517   \n",
       "\n",
       "                      is_holiday  temperature  is_start_of_semester  \\\n",
       "number_people          -0.048249     0.373327              0.182683   \n",
       "timestamp               0.002851     0.184849              0.009551   \n",
       "day_of_week            -0.075862     0.011169             -0.011782   \n",
       "is_weekend             -0.031899     0.020673             -0.016646   \n",
       "is_holiday              1.000000    -0.088527             -0.014858   \n",
       "temperature            -0.088527     1.000000              0.093242   \n",
       "is_start_of_semester   -0.014858     0.093242              1.000000   \n",
       "is_during_semester     -0.070798     0.152476              0.209862   \n",
       "month                  -0.094942     0.063125             -0.137160   \n",
       "hour                    0.002843     0.185121              0.010091   \n",
       "\n",
       "                      is_during_semester     month      hour  \n",
       "number_people                   0.335350 -0.097854  0.552049  \n",
       "timestamp                       0.044676 -0.023221  0.999077  \n",
       "day_of_week                    -0.004824  0.015559 -0.001914  \n",
       "is_weekend                     -0.036127  0.008462 -0.000517  \n",
       "is_holiday                     -0.070798 -0.094942  0.002843  \n",
       "temperature                     0.152476  0.063125  0.185121  \n",
       "is_start_of_semester            0.209862 -0.137160  0.010091  \n",
       "is_during_semester              1.000000  0.096556  0.045581  \n",
       "month                           0.096556  1.000000 -0.023624  \n",
       "hour                            0.045581 -0.023624  1.000000  "
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.corr()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4225b79f-e383-491f-8454-769f6a5ebe42",
   "metadata": {},
   "source": [
    "This table gives is a sense of the correlation (positive or negative), between each factor and each other variable. Since we are mostly interested in the number of people, we can stick to the first column of the table.\n",
    "\n",
    "We cans ee how the **hour**, **temperature** and interestingly the **is_during_semester** variables have the largest weight. Also we can see that the timestamp and hour variables have a very similar weight, wich means they could be redundant.\n",
    "\n",
    "Other variables have weaker correlations as well, like **is_weekend** and **day_of_week** are negatively correlated which is very interesting.\n",
    "\n",
    "Another way to look at this is to use `pairplot()` function on seaborn, since it gives you a scatterplot for each pair of variables. It can be harder to read than the table though, but it can help us see some interesting pattern emerge."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "c49d441b-1646-4819-89cb-2041d4d91d5b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<seaborn.axisgrid.PairGrid at 0x29178bc9ac0>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 672840 characters]\n",
      "text/plain": [
       "<Figure size 1800x1800 with 110 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.pairplot(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eff8d9b0-0d55-4cdd-a727-81d67d291c06",
   "metadata": {},
   "source": [
    "There is not a lot of additional info to discover from the paired plots here. Still, and just to make sure, I want to try one more visual, the `heatmap()` from seaborn. \n",
    "\n",
    "In this case, we can create a heatmap using the correlation table, this will help us see the correlations with much more ease."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "aea6f1f6-06f1-45b0-b5d0-c218295aa146",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<AxesSubplot:>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 27988 characters]\n",
      "text/plain": [
       "<Figure size 648x648 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(9, 9))\n",
    "sns.heatmap(df.corr())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e3e574a-1eb9-48c2-861c-c9edec7ca4fe",
   "metadata": {},
   "source": [
    "This simply confirms our previous suspicions, that **temperature**, **hour** and **is_during_semester** variables are the most important.\n",
    "\n",
    "Another thing, the **timestamp** seems to be redundant, since it has the same correlation as the hour, and we already have all the information on the month, day and time. So I will remove the **timestamp** column before moving on to building the model.\n",
    "\n",
    "Also, check with `.head()` to make sure the column was removed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "e0606a01-395b-4b74-9a61-cb9d95ae365e",
   "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>number_people</th>\n",
       "      <th>day_of_week</th>\n",
       "      <th>is_weekend</th>\n",
       "      <th>is_holiday</th>\n",
       "      <th>temperature</th>\n",
       "      <th>is_start_of_semester</th>\n",
       "      <th>is_during_semester</th>\n",
       "      <th>month</th>\n",
       "      <th>hour</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>37</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>45</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>40</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>44</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>45</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>71.76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   number_people  day_of_week  is_weekend  is_holiday  temperature  \\\n",
       "0             37            4           0           0        71.76   \n",
       "1             45            4           0           0        71.76   \n",
       "2             40            4           0           0        71.76   \n",
       "3             44            4           0           0        71.76   \n",
       "4             45            4           0           0        71.76   \n",
       "\n",
       "   is_start_of_semester  is_during_semester  month  hour  \n",
       "0                     0                   0      8    17  \n",
       "1                     0                   0      8    17  \n",
       "2                     0                   0      8    17  \n",
       "3                     0                   0      8    17  \n",
       "4                     0                   0      8    17  "
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = df.drop('timestamp', axis=1)\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d01ef8d-d7d9-4aa7-a16e-28431266484a",
   "metadata": {},
   "source": [
    "## Getting ready to build our model with Stochastic Gradient Descent\n",
    "\n",
    "Now that the dataset is ready and we have our features, I need to import the tools needed to build the model. In this case, from the **Scikit Lean** library, the `train_test_split` and `SGDRegressor`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "8e1cd9b9-917e-4704-af89-c4250e2a5240",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.linear_model import SGDRegressor "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cccead1d-309c-4f00-80ec-c504bb52df8c",
   "metadata": {},
   "source": [
    "I need to split the data into train and test sets. I am using a test size of 30% (70% of the data for training and 30% for testing). I am also setting the random state, so as to be able to replicate in the future."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "84eca42d-f012-4749-a3db-3cbffcff4e98",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = df.values\n",
    "X = data[:, 1:]\n",
    "y = data[:, 0] \n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=42)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1e10d975-b890-42c6-a03a-069d9df3b4c6",
   "metadata": {},
   "source": [
    "Check to make sure the shape of each set is correct."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "86d9e103-8917-4955-b505-ca3c4bc9ffa8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training features shape: (43528, 8)\n",
      "Testing features shape: (18656, 8)\n",
      "Training label shape: (43528,)\n",
      "Testing label shape: (18656,)\n"
     ]
    }
   ],
   "source": [
    "print(f\"Training features shape: {X_train.shape}\")\n",
    "print(f\"Testing features shape: {X_test.shape}\")\n",
    "print(f\"Training label shape: {y_train.shape}\")\n",
    "print(f\"Testing label shape: {y_test.shape}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c1b80d58-18b6-4522-9241-8b7c89f9c822",
   "metadata": {},
   "source": [
    "Build the model object with `SGDRegressor`. Setting the learning rate to `optimal`, the loss function to hubber loss and using elasticnet for the penalty. \n",
    "\n",
    "The fitting the model with the training data.\n",
    "I set the `random_state` so as to be able to reproduce the training."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "15597142-00b4-434e-8551-ee47949261cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "sgd_v1 = SGDRegressor(alpha=0.0001, learning_rate='optimal', loss='huber', \n",
    "    penalty='elasticnet', random_state = 52)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "d9fee8b6-2772-42ad-bde4-71a16cb1e287",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SGDRegressor(learning_rate='optimal', loss='huber', penalty='elasticnet',\n",
       "             random_state=52)"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_v1.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c559b8f-4afd-4f75-841a-1776b090e862",
   "metadata": {},
   "source": [
    "## Measure the Performance of the Mode\n",
    "\n",
    "Now that we have trained our model, it is time to predict the target variable with the test data. I will be using Mean Squared Error, Mean Absolute Error and R Sqared."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "de5bd604-bc2e-4c52-a0bb-a9035057d8dc",
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred_v1 = sgd_v1.predict(X_test)  # Predict labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "d77be73a-3304-4802-84ca-e5b939bddd65",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mean squared error: 254.545\n",
      "R2 score: 0.506\n",
      "Mean absolute error: 12.135\n"
     ]
    }
   ],
   "source": [
    "# Let's evaluate the performance of the model.\n",
    "\n",
    "from sklearn.metrics import mean_squared_error, r2_score,mean_absolute_error\n",
    "# The mean squared error\n",
    "print(f\"Mean squared error: {round( mean_squared_error(y_test, y_pred_v1),3)}\")\n",
    "# Explained variance score: 1 is perfect prediction\n",
    "print(f\"R2 score: {round(r2_score(y_test, y_pred_v1),3)}\")\n",
    "# Mean Absolute Error\n",
    "print(f\"Mean absolute error: { round(mean_absolute_error(y_test, y_pred_v1),3)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "90de4ab1-8e47-4f91-b6e3-16a9efbe341d",
   "metadata": {},
   "source": [
    "1Mean Squared Error and Mean Absolute Error are fairly high (the closer to 0 the higher the accuracy), meaning the model is not incredibly accurate. With the R2 Score we can see there is a correlation of 0.506, wich is not terrible, but not that good either since we want it to be as close to 1 as possible.\n",
    "\n",
    "To try and imprive the model, we can scale the features to normalize them from -1 to 1, this mught help improve the model. For this, I will import the `StandardScaler` from Scikit Learn."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "07103651-1f54-4017-84c8-2016c9457d63",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler()\n",
    "scaler.fit(X_train)\n",
    "X_train_scaled = scaler.transform(X_train)\n",
    "X_test_scaled = scaler.transform(X_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c79ea619-7ee2-4432-90fd-66f14bcb204c",
   "metadata": {},
   "source": [
    "Now we can build another model with the scaled data and see if we can improve it.\n",
    "\n",
    "I am using the same `random_state` for consistent results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "dc5a2812-34f5-454b-8373-f183cc3842c6",
   "metadata": {},
   "outputs": [],
   "source": [
    "sgd_v2 = SGDRegressor(alpha=0.0001, learning_rate='optimal', loss='huber', \n",
    "    penalty='elasticnet', random_state = 52)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "a4a26f0e-689b-4b60-9149-bf761684d037",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SGDRegressor(learning_rate='optimal', loss='huber', penalty='elasticnet',\n",
       "             random_state=52)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_v2.fit(X_train_scaled, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "38e37206-1a02-468a-b43a-8943399ee686",
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred_v2 = sgd_v2.predict(X_test_scaled)  # Predict labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "e4d21c5a-37f1-441e-9388-255734bb358f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mean squared error: 254.325\n",
      "R2 score: 0.507\n",
      "Mean absolute error: 12.049\n"
     ]
    }
   ],
   "source": [
    "# The mean squared error\n",
    "print(f\"Mean squared error: {round( mean_squared_error(y_test, y_pred_v2),3)}\")\n",
    "# Explained variance score: 1 is perfect prediction\n",
    "print(f\"R2 score: {round(r2_score(y_test, y_pred_v2),3)}\")\n",
    "# Mean Absolute Error\n",
    "print(f\"Mean absolute error: { round(mean_absolute_error(y_test, y_pred_v2),3)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff15036e-8163-49d9-8560-78ee6ae78070",
   "metadata": {},
   "source": [
    "With the scaled data, the model performs slightly better, decresing the Mean Squared Error and Mean Absolute Error and increasing the R2 score by 0.001."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cee04550-86a3-4d0f-a8e7-d6eed9a88e88",
   "metadata": {},
   "source": [
    "## Visualizing the Results\n",
    "\n",
    "To see how our model performs, the best way is to visualize it. Here is the plot from our first model, using line plots with the actual test data on the back and the predicted data on the front. The parts where the plots converge are the points where the model performed well, and the divergence in the plots is where the model performed poorly."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "f63e153c-568e-4053-ae6b-e6721168e9c2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 87864 characters]\n",
      "text/plain": [
       "<Figure size 1080x1080 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15, 15))\n",
    "\n",
    "x_ax = range(len(y_test))\n",
    "plt.plot(x_ax, y_test, linewidth=1, label=\"original\")\n",
    "plt.plot(x_ax, y_pred_v1, linewidth=1.1, label=\"predicted\")\n",
    "plt.title(\"y-test and y-predicted data Model 1\")\n",
    "plt.xlabel('X-axis')\n",
    "plt.ylabel('Y-axis')\n",
    "plt.legend(loc='best',fancybox=True, shadow=True)\n",
    "plt.grid(True)\n",
    "plt.show() \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "1a5d1a69-8181-4b26-bb42-3c7c367409b8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 87916 characters]\n",
      "text/plain": [
       "<Figure size 1080x1080 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Model v2\n",
    "\n",
    "plt.figure(figsize=(15, 15))\n",
    "\n",
    "x_ax = range(len(y_test))\n",
    "plt.plot(x_ax, y_test, linewidth=1, label=\"original\")\n",
    "plt.plot(x_ax, y_pred_v2, linewidth=1.1, label=\"predicted\")\n",
    "plt.title(\"y-test and y-predicted data Model 2\")\n",
    "plt.xlabel('X-axis')\n",
    "plt.ylabel('Y-axis')\n",
    "plt.legend(loc='best',fancybox=True, shadow=True)\n",
    "plt.grid(True)\n",
    "plt.show() "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9bb1e0e-72d6-45ae-b1b1-0fabe156aba6",
   "metadata": {},
   "source": [
    "## Summarize your Results\n",
    "\n",
    "We can clearly see there is a lot of room for improvement. However, a linear regression model using Stochastic Gradient Descent is a good place to start for building such a prediction model.\n",
    "\n",
    "We can improve the model by making some changes. Regarding the data, I decided to remove the timestamp variable since I believed it to be redundant, nonetheless, maybe that redundancy might help the model get higher accuracy.\n",
    "\n",
    "Also, I might changing and testing other hyperparameters might be interesting, especially changing the loss function from `huber` to `squared_epsilon_insensitive` and maybe exploring changing the learning rate and penalty.\n",
    "\n",
    "In general, from the data and the model, for someone like me who likes to go to the gym often without having too many people there, any day at 5am seems like a safe bet.\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Programming",
   "language": "python",
   "name": "programming"
  },
  "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.9.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
