{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "fihFj3tMwplr"
   },
   "source": [
    "# Purpose of Notebook\n",
    "\n",
    "The purpose of this notebook is to offer an example answer to the guided project for the Optimizing Models course. The reference model will be the same for all students, but any other models are constructed by the student. Results may vary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "id": "RfWzhN9BaIK_"
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.linear_model import LinearRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "id": "vfAO-T-5l4h4"
   },
   "outputs": [],
   "source": [
    "# Load in the insurance dataset\n",
    "fires = pd.read_csv(\"/content/drive/MyDrive/fires.csv\")\n",
    "\n",
    "fires_reference = fires[[\"wind\", \"temp\", \"area\"]].dropna()\n",
    "reference_X = fires_reference[[\"wind\", \"temp\"]]\n",
    "\n",
    "reference = LinearRegression()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "7Ea_gbpU1iG-",
    "outputId": "d6dea921-85cb-44b3-cfc4-3d5a087ddef7"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The Unnamed: 0 column has 0 missing values.\n",
      "The X column has 0 missing values.\n",
      "The Y column has 0 missing values.\n",
      "The month column has 0 missing values.\n",
      "The day column has 0 missing values.\n",
      "The FFMC column has 48 missing values.\n",
      "The DMC column has 21 missing values.\n",
      "The DC column has 43 missing values.\n",
      "The ISI column has 2 missing values.\n",
      "The temp column has 21 missing values.\n",
      "The RH column has 30 missing values.\n",
      "The wind column has 35 missing values.\n",
      "The rain column has 32 missing values.\n",
      "The area column has 0 missing values.\n"
     ]
    }
   ],
   "source": [
    "for col in fires.columns:\n",
    "    num_na = sum(pd.isna(fires[col]))\n",
    "    print(f\"The {col} column has {num_na} missing values.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "CK7iWUZX4R25"
   },
   "source": [
    "# Data Processing\n",
    "\n",
    "First, we'll convert the `month` column into a categorical feature. Instead of using the strings, we'll convert it into an indicator for the summer months in the northern hemisphere.\n",
    "\n",
    "For the sake of completion, we'll impute all of the features so that we can have the biggest set to choose from for sequential feature selection. We'll go with K-nearest neighbors imputation since we expect area damage to be similar among similar fires. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 316
    },
    "id": "Rcqnhb76PpUk",
    "outputId": "feddd9c6-103b-424c-df3f-69c11ea2e150"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7fa8f866a950>]],\n",
       "      dtype=object)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 6528 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fires.hist(\"area\", bins=30)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "apVd2ZvbQCie"
   },
   "source": [
    "The outcome is highly right-skewed with extremely damaging fires. Furthermore, many of the rows have outcome values that are zero or near-zero. It might be worth it to log-transform the data. Note though that some of the outcomes are actually 0, so we can add `1` to prevent any errors. Recall that $log(0)$ is undefined."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 316
    },
    "id": "wXwiZuoDQh87",
    "outputId": "2e49a72f-c5f1-4814-ea0b-4ad38605b827"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7fa8f868af10>]],\n",
       "      dtype=object)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 6928 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fires[\"log_area\"] = np.log(fires[\"area\"] + 1)\n",
    "\n",
    "fires.hist(\"log_area\", bins=30)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "cGXK7TxAReM9"
   },
   "source": [
    "We can see that performing a log-transformation doesn't produce a bell-shaped distribution, but it does spread out the data a bit more than without the transformation. It's probably the case that most fires do not appreciably damage the forest, so we would be mistaken in removing all of these rows. \n",
    "\n",
    "Instead of using `month` directly, we'll derive another feature called `summer` that takes a value of 1 when the fire occurred during the summer. The idea here is that summer months are typically hotter, so fires are more likely. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "id": "2JQ88NLeGJlt"
   },
   "outputs": [],
   "source": [
    "def is_summer_month(month):\n",
    "    if month in [\"jun\", \"jul\", \"aug\"]:\n",
    "        return 1\n",
    "    else:\n",
    "        return 0\n",
    "\n",
    "fires[\"summer\"] = [is_summer_month(m) for m in fires[\"month\"]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 424
    },
    "id": "59Xkc88p2wrY",
    "outputId": "bbfe51c4-e278-4778-8176-d91d76b06805"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "  <div id=\"df-0ef61c4f-fc46-44ff-8c5d-ec621618d83d\">\n",
       "    <div class=\"colab-df-container\">\n",
       "      <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>FFMC</th>\n",
       "      <th>DMC</th>\n",
       "      <th>DC</th>\n",
       "      <th>ISI</th>\n",
       "      <th>temp</th>\n",
       "      <th>RH</th>\n",
       "      <th>wind</th>\n",
       "      <th>rain</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>86.2</td>\n",
       "      <td>26.200000</td>\n",
       "      <td>94.300000</td>\n",
       "      <td>5.1</td>\n",
       "      <td>16.6</td>\n",
       "      <td>51.0</td>\n",
       "      <td>6.700000</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>90.6</td>\n",
       "      <td>56.433333</td>\n",
       "      <td>669.100000</td>\n",
       "      <td>6.7</td>\n",
       "      <td>18.0</td>\n",
       "      <td>33.0</td>\n",
       "      <td>0.900000</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>90.6</td>\n",
       "      <td>43.700000</td>\n",
       "      <td>470.833333</td>\n",
       "      <td>6.7</td>\n",
       "      <td>14.6</td>\n",
       "      <td>33.0</td>\n",
       "      <td>1.300000</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>91.7</td>\n",
       "      <td>33.300000</td>\n",
       "      <td>77.500000</td>\n",
       "      <td>9.0</td>\n",
       "      <td>8.3</td>\n",
       "      <td>97.0</td>\n",
       "      <td>4.000000</td>\n",
       "      <td>0.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>89.3</td>\n",
       "      <td>51.300000</td>\n",
       "      <td>102.200000</td>\n",
       "      <td>9.6</td>\n",
       "      <td>11.4</td>\n",
       "      <td>99.0</td>\n",
       "      <td>4.333333</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>512</th>\n",
       "      <td>81.6</td>\n",
       "      <td>56.700000</td>\n",
       "      <td>665.600000</td>\n",
       "      <td>1.9</td>\n",
       "      <td>27.8</td>\n",
       "      <td>32.0</td>\n",
       "      <td>2.700000</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>513</th>\n",
       "      <td>81.6</td>\n",
       "      <td>56.700000</td>\n",
       "      <td>665.600000</td>\n",
       "      <td>1.9</td>\n",
       "      <td>21.9</td>\n",
       "      <td>71.0</td>\n",
       "      <td>5.800000</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>514</th>\n",
       "      <td>81.6</td>\n",
       "      <td>56.700000</td>\n",
       "      <td>665.600000</td>\n",
       "      <td>1.9</td>\n",
       "      <td>21.2</td>\n",
       "      <td>70.0</td>\n",
       "      <td>6.700000</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>515</th>\n",
       "      <td>94.4</td>\n",
       "      <td>146.000000</td>\n",
       "      <td>614.700000</td>\n",
       "      <td>11.3</td>\n",
       "      <td>25.6</td>\n",
       "      <td>42.0</td>\n",
       "      <td>4.000000</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>516</th>\n",
       "      <td>79.5</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>106.700000</td>\n",
       "      <td>1.1</td>\n",
       "      <td>11.8</td>\n",
       "      <td>31.0</td>\n",
       "      <td>4.500000</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>517 rows × 8 columns</p>\n",
       "</div>\n",
       "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-0ef61c4f-fc46-44ff-8c5d-ec621618d83d')\"\n",
       "              title=\"Convert this dataframe to an interactive table.\"\n",
       "              style=\"display:none;\">\n",
       "        \n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
       "       width=\"24px\">\n",
       "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
       "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
       "  </svg>\n",
       "      </button>\n",
       "      \n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      flex-wrap:wrap;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "      <script>\n",
       "        const buttonEl =\n",
       "          document.querySelector('#df-0ef61c4f-fc46-44ff-8c5d-ec621618d83d button.colab-df-convert');\n",
       "        buttonEl.style.display =\n",
       "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "        async function convertToInteractive(key) {\n",
       "          const element = document.querySelector('#df-0ef61c4f-fc46-44ff-8c5d-ec621618d83d');\n",
       "          const dataTable =\n",
       "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                     [key], {});\n",
       "          if (!dataTable) return;\n",
       "\n",
       "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "            + ' to learn more about interactive tables.';\n",
       "          element.innerHTML = '';\n",
       "          dataTable['output_type'] = 'display_data';\n",
       "          await google.colab.output.renderOutput(dataTable, element);\n",
       "          const docLink = document.createElement('div');\n",
       "          docLink.innerHTML = docLinkHtml;\n",
       "          element.appendChild(docLink);\n",
       "        }\n",
       "      </script>\n",
       "    </div>\n",
       "  </div>\n",
       "  "
      ],
      "text/plain": [
       "     FFMC         DMC          DC   ISI  temp    RH      wind  rain\n",
       "0    86.2   26.200000   94.300000   5.1  16.6  51.0  6.700000   0.0\n",
       "1    90.6   56.433333  669.100000   6.7  18.0  33.0  0.900000   0.0\n",
       "2    90.6   43.700000  470.833333   6.7  14.6  33.0  1.300000   0.0\n",
       "3    91.7   33.300000   77.500000   9.0   8.3  97.0  4.000000   0.2\n",
       "4    89.3   51.300000  102.200000   9.6  11.4  99.0  4.333333   0.0\n",
       "..    ...         ...         ...   ...   ...   ...       ...   ...\n",
       "512  81.6   56.700000  665.600000   1.9  27.8  32.0  2.700000   0.0\n",
       "513  81.6   56.700000  665.600000   1.9  21.9  71.0  5.800000   0.0\n",
       "514  81.6   56.700000  665.600000   1.9  21.2  70.0  6.700000   0.0\n",
       "515  94.4  146.000000  614.700000  11.3  25.6  42.0  4.000000   0.0\n",
       "516  79.5    3.000000  106.700000   1.1  11.8  31.0  4.500000   0.0\n",
       "\n",
       "[517 rows x 8 columns]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.impute import KNNImputer\n",
    "\n",
    "imp = KNNImputer(missing_values = np.nan, n_neighbors=3)\n",
    "\n",
    "fires_missing = fires[fires.columns[5:13]] # FFMC to rain\n",
    "imputed = pd.DataFrame(imp.fit_transform(fires_missing), \n",
    "                       columns = fires.columns[5:13])\n",
    "imputed"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "-A9-irrtAnD8"
   },
   "source": [
    "We'll examine the data for outliers using boxplots:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 282
    },
    "id": "NKD1Jgul6_95",
    "outputId": "4c5096c2-c9a3-4aec-b40c-f004a78aa5ef"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7fa8f55ba750>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 9336 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "imputed.boxplot(column=[\"FFMC\", \"DMC\", \"DC\", \"ISI\", \"temp\", \"RH\", \"wind\", \"rain\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "lGOBnfyZCG60"
   },
   "source": [
    "The dots indicate that there are some outliers in the data. Let's examine the number of outliers in each of the columns."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "tPKtl1FfBsLa",
    "outputId": "fdb12867-9693-4dae-be06-7203af4f1c4a"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The FFMC column has 0 according to the boxplot method.\n",
      "The DMC column has 0 according to the boxplot method.\n",
      "The DC column has 0 according to the boxplot method.\n",
      "The ISI column has 0 according to the boxplot method.\n",
      "The temp column has 0 according to the boxplot method.\n",
      "The RH column has 0 according to the boxplot method.\n",
      "The wind column has 0 according to the boxplot method.\n",
      "The rain column has 0 according to the boxplot method.\n"
     ]
    }
   ],
   "source": [
    "for col in imputed:\n",
    "\n",
    "    quartiles = np.percentile(fires[col], [25, 50, 75])\n",
    "    iqr = quartiles[2] - quartiles[0]\n",
    "    lower_bound = quartiles[0] - (1.5 * iqr)\n",
    "    upper_bound = quartiles[2] + (1.5 * iqr)\n",
    "    num_outliers =sum((imputed[col] < lower_bound) | (imputed[col] > upper_bound))\n",
    "\n",
    "    print(f\"The {col} column has {num_outliers} according to the boxplot method.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "7CUialCuDUSx"
   },
   "source": [
    "Despite the visual cue in the boxplots, based on the actual calculations, there don't seem to be any outliers. In this case, we'll leave the dataset as-is. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "kzs2mQR_OWoO"
   },
   "source": [
    "Now that the dataset has been inspected for missing values and outliers, we can proceed to standardize it. These standardized values will help for standardization. Afterwards, we'll append the `summmer` feature back into the dataset. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 424
    },
    "id": "N1Sxq-Pe5Vin",
    "outputId": "ea66385f-b731-44aa-9cde-d9ef1664c491"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "  <div id=\"df-c474322b-6ccd-49c7-8bea-2c72241fc695\">\n",
       "    <div class=\"colab-df-container\">\n",
       "      <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>summer</th>\n",
       "      <th>FFMC</th>\n",
       "      <th>DMC</th>\n",
       "      <th>DC</th>\n",
       "      <th>ISI</th>\n",
       "      <th>temp</th>\n",
       "      <th>RH</th>\n",
       "      <th>wind</th>\n",
       "      <th>rain</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>-0.812283</td>\n",
       "      <td>-1.335942</td>\n",
       "      <td>-1.846711</td>\n",
       "      <td>-0.860187</td>\n",
       "      <td>-0.398187</td>\n",
       "      <td>0.418726</td>\n",
       "      <td>1.514159</td>\n",
       "      <td>-0.073268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>-0.010735</td>\n",
       "      <td>-0.859009</td>\n",
       "      <td>0.509582</td>\n",
       "      <td>-0.508736</td>\n",
       "      <td>-0.155493</td>\n",
       "      <td>-0.715565</td>\n",
       "      <td>-1.761003</td>\n",
       "      <td>-0.073268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>-0.010735</td>\n",
       "      <td>-1.059878</td>\n",
       "      <td>-0.303178</td>\n",
       "      <td>-0.508736</td>\n",
       "      <td>-0.744894</td>\n",
       "      <td>-0.715565</td>\n",
       "      <td>-1.535130</td>\n",
       "      <td>-0.073268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>0.189652</td>\n",
       "      <td>-1.223939</td>\n",
       "      <td>-1.915580</td>\n",
       "      <td>-0.003526</td>\n",
       "      <td>-1.837021</td>\n",
       "      <td>3.317471</td>\n",
       "      <td>-0.010485</td>\n",
       "      <td>0.603155</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>-0.247556</td>\n",
       "      <td>-0.939988</td>\n",
       "      <td>-1.814327</td>\n",
       "      <td>0.128267</td>\n",
       "      <td>-1.299625</td>\n",
       "      <td>3.443503</td>\n",
       "      <td>0.177742</td>\n",
       "      <td>-0.073268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>512</th>\n",
       "      <td>1</td>\n",
       "      <td>-1.650265</td>\n",
       "      <td>-0.854803</td>\n",
       "      <td>0.495235</td>\n",
       "      <td>-1.563087</td>\n",
       "      <td>1.543370</td>\n",
       "      <td>-0.778581</td>\n",
       "      <td>-0.744573</td>\n",
       "      <td>-0.073268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>513</th>\n",
       "      <td>1</td>\n",
       "      <td>-1.650265</td>\n",
       "      <td>-0.854803</td>\n",
       "      <td>0.495235</td>\n",
       "      <td>-1.563087</td>\n",
       "      <td>0.520585</td>\n",
       "      <td>1.679050</td>\n",
       "      <td>1.005944</td>\n",
       "      <td>-0.073268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>514</th>\n",
       "      <td>1</td>\n",
       "      <td>-1.650265</td>\n",
       "      <td>-0.854803</td>\n",
       "      <td>0.495235</td>\n",
       "      <td>-1.563087</td>\n",
       "      <td>0.399238</td>\n",
       "      <td>1.616034</td>\n",
       "      <td>1.514159</td>\n",
       "      <td>-0.073268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>515</th>\n",
       "      <td>1</td>\n",
       "      <td>0.681511</td>\n",
       "      <td>0.553912</td>\n",
       "      <td>0.286579</td>\n",
       "      <td>0.501683</td>\n",
       "      <td>1.161993</td>\n",
       "      <td>-0.148419</td>\n",
       "      <td>-0.010485</td>\n",
       "      <td>-0.073268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>516</th>\n",
       "      <td>0</td>\n",
       "      <td>-2.032821</td>\n",
       "      <td>-1.701924</td>\n",
       "      <td>-1.795880</td>\n",
       "      <td>-1.738812</td>\n",
       "      <td>-1.230284</td>\n",
       "      <td>-0.841597</td>\n",
       "      <td>0.271856</td>\n",
       "      <td>-0.073268</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>517 rows × 9 columns</p>\n",
       "</div>\n",
       "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-c474322b-6ccd-49c7-8bea-2c72241fc695')\"\n",
       "              title=\"Convert this dataframe to an interactive table.\"\n",
       "              style=\"display:none;\">\n",
       "        \n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
       "       width=\"24px\">\n",
       "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
       "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
       "  </svg>\n",
       "      </button>\n",
       "      \n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      flex-wrap:wrap;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "      <script>\n",
       "        const buttonEl =\n",
       "          document.querySelector('#df-c474322b-6ccd-49c7-8bea-2c72241fc695 button.colab-df-convert');\n",
       "        buttonEl.style.display =\n",
       "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "        async function convertToInteractive(key) {\n",
       "          const element = document.querySelector('#df-c474322b-6ccd-49c7-8bea-2c72241fc695');\n",
       "          const dataTable =\n",
       "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                     [key], {});\n",
       "          if (!dataTable) return;\n",
       "\n",
       "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "            + ' to learn more about interactive tables.';\n",
       "          element.innerHTML = '';\n",
       "          dataTable['output_type'] = 'display_data';\n",
       "          await google.colab.output.renderOutput(dataTable, element);\n",
       "          const docLink = document.createElement('div');\n",
       "          docLink.innerHTML = docLinkHtml;\n",
       "          element.appendChild(docLink);\n",
       "        }\n",
       "      </script>\n",
       "    </div>\n",
       "  </div>\n",
       "  "
      ],
      "text/plain": [
       "     summer      FFMC       DMC        DC       ISI      temp        RH  \\\n",
       "0         0 -0.812283 -1.335942 -1.846711 -0.860187 -0.398187  0.418726   \n",
       "1         0 -0.010735 -0.859009  0.509582 -0.508736 -0.155493 -0.715565   \n",
       "2         0 -0.010735 -1.059878 -0.303178 -0.508736 -0.744894 -0.715565   \n",
       "3         0  0.189652 -1.223939 -1.915580 -0.003526 -1.837021  3.317471   \n",
       "4         0 -0.247556 -0.939988 -1.814327  0.128267 -1.299625  3.443503   \n",
       "..      ...       ...       ...       ...       ...       ...       ...   \n",
       "512       1 -1.650265 -0.854803  0.495235 -1.563087  1.543370 -0.778581   \n",
       "513       1 -1.650265 -0.854803  0.495235 -1.563087  0.520585  1.679050   \n",
       "514       1 -1.650265 -0.854803  0.495235 -1.563087  0.399238  1.616034   \n",
       "515       1  0.681511  0.553912  0.286579  0.501683  1.161993 -0.148419   \n",
       "516       0 -2.032821 -1.701924 -1.795880 -1.738812 -1.230284 -0.841597   \n",
       "\n",
       "         wind      rain  \n",
       "0    1.514159 -0.073268  \n",
       "1   -1.761003 -0.073268  \n",
       "2   -1.535130 -0.073268  \n",
       "3   -0.010485  0.603155  \n",
       "4    0.177742 -0.073268  \n",
       "..        ...       ...  \n",
       "512 -0.744573 -0.073268  \n",
       "513  1.005944 -0.073268  \n",
       "514  1.514159 -0.073268  \n",
       "515 -0.010485 -0.073268  \n",
       "516  0.271856 -0.073268  \n",
       "\n",
       "[517 rows x 9 columns]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler()\n",
    "scaled = scaler.fit_transform(imputed)\n",
    "scaled = pd.DataFrame(scaled, columns = fires.columns[5:13])\n",
    "\n",
    "final = pd.concat([fires[\"summer\"], scaled], axis=1)\n",
    "\n",
    "final"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "r2VHEBeRUS-G"
   },
   "source": [
    "# Subset Selection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "x5pquOswH1fE",
    "outputId": "1b554434-91ba-49e0-b5cb-b621255d9b33"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Features selected in 2 feature model: ['FFMC' 'DC']\n",
      "Features selected in 4 feature model: ['FFMC' 'DC' 'RH' 'wind']\n",
      "Features selected in 6 feature model: ['summer' 'FFMC' 'DC' 'ISI' 'RH' 'wind']\n"
     ]
    }
   ],
   "source": [
    "from sklearn.feature_selection import SequentialFeatureSelector\n",
    "\n",
    "y = fires[\"log_area\"]\n",
    "\n",
    "sfs_model = LinearRegression()\n",
    "sfs_model2 = LinearRegression()\n",
    "sfs_model3 = LinearRegression()\n",
    "\n",
    "forward2 = SequentialFeatureSelector(estimator=sfs_model,\n",
    "                                     n_features_to_select=2, \n",
    "                                     direction=\"forward\")\n",
    "\n",
    "forward4 = SequentialFeatureSelector(estimator=sfs_model2,\n",
    "                                     n_features_to_select=4, \n",
    "                                     direction=\"forward\")\n",
    "\n",
    "forward6 = SequentialFeatureSelector(estimator=sfs_model3,\n",
    "                                       n_features_to_select=6, \n",
    "                                       direction=\"forward\")\n",
    "\n",
    "forward2.fit(final, y)\n",
    "forward4.fit(final, y)\n",
    "forward6.fit(final, y)\n",
    "\n",
    "print(\"Features selected in 2 feature model:\", forward2.get_feature_names_out())\n",
    "print(\"Features selected in 4 feature model:\", forward4.get_feature_names_out())\n",
    "print(\"Features selected in 6 feature model:\", forward6.get_feature_names_out())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "krNnlYx7YG0J",
    "outputId": "a94f6c39-81a9-46be-f1f4-3f73cc8b3fd5"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Features selected in 2 feature model: ['DC' 'wind']\n",
      "Features selected in 4 feature model: ['FFMC' 'DC' 'RH' 'wind']\n",
      "Features selected in 6 feature model: ['summer' 'FFMC' 'DC' 'ISI' 'RH' 'wind']\n"
     ]
    }
   ],
   "source": [
    "backward2 = SequentialFeatureSelector(estimator=sfs_model,\n",
    "                                     n_features_to_select=2, \n",
    "                                     direction=\"backward\")\n",
    "\n",
    "backward4 = SequentialFeatureSelector(estimator=sfs_model,\n",
    "                                     n_features_to_select=4, \n",
    "                                     direction=\"backward\")\n",
    "\n",
    "backward6 = SequentialFeatureSelector(estimator=sfs_model,\n",
    "                                       n_features_to_select=6, \n",
    "                                       direction=\"backward\")\n",
    "\n",
    "backward2.fit(final, y)\n",
    "backward4.fit(final, y)\n",
    "backward6.fit(final, y)\n",
    "\n",
    "print(\"Features selected in 2 feature model:\", backward2.get_feature_names_out())\n",
    "print(\"Features selected in 4 feature model:\", backward4.get_feature_names_out())\n",
    "print(\"Features selected in 6 feature model:\", backward6.get_feature_names_out())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "lsujk2bVY9K2"
   },
   "source": [
    "Based on the features chosen by forward and backward selection, it seems like `DC`, `wind` and `FFMC` seem to be the most impactful on predicting `log_area`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "id": "CgfBlupqJLad"
   },
   "outputs": [],
   "source": [
    "fw2_model = LinearRegression() # .fit(final[forward2.get_feature_names_out()], y)\n",
    "fw4_model = LinearRegression() # .fit(final[forward4.get_feature_names_out()], y)\n",
    "fw6_model = LinearRegression() # .fit(final[forward6.get_feature_names_out()], y)\n",
    "\n",
    "bw2_model = LinearRegression() # .fit(final[backward2.get_feature_names_out()], y)\n",
    "bw4_model = LinearRegression() # .fit(final[backward4.get_feature_names_out()], y)\n",
    "bw6_model = LinearRegression() # .fit(final[backward6.get_feature_names_out()], y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "vku4dsrH1H4B"
   },
   "source": [
    "# More Candidate Models\n",
    "\n",
    "Another approach we might consider taking is using regularized versions of linear regression. Fires have many factors that can increase the damaage they have, so it seems unhelpful to restrict our model to a univariate, non-linear model. There are such models; however, they were beyond the scope of the course, but they might be plausible candidates for further next steps."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "Z0FTDs2FYrZ4",
    "outputId": "75520a53-6672-4da1-9fed-3322892e1f0a"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ridge tuning parameter:  1372.2342342342342\n",
      "LASSO tuning parameter:  10000.0\n",
      "Ridge coefficients:  [-0.01455017  0.01311215  0.02006457  0.02004741 -0.01073465  0.01297049\n",
      " -0.01489714  0.02670554  0.00816103]\n",
      "LASSO coefficients:  [-0.  0.  0.  0. -0.  0. -0.  0.  0.]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.linear_model import LassoCV, RidgeCV\n",
    "\n",
    "ridge = RidgeCV(alphas = np.linspace(1, 10000, num=1000))\n",
    "lasso = LassoCV(alphas = np.linspace(1, 10000, num=1000))\n",
    "\n",
    "ridge.fit(final, y)\n",
    "lasso.fit(final, y)\n",
    "\n",
    "print(\"Ridge tuning parameter: \", ridge.alpha_)\n",
    "print(\"LASSO tuning parameter: \", lasso.alpha_)\n",
    "\n",
    "print(\"Ridge coefficients: \", ridge.coef_)\n",
    "print(\"LASSO coefficients: \", lasso.coef_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "rLItzlCRVmVC"
   },
   "source": [
    "The LASSO tuning parameter always seems to be on the extreme. Given that the outcome has many small values, it suggests that having no features at all is better than having any. We'll try to home in on a better tuning parameter value below by choosing a smaller range to pick from."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "7LtiwEd4VmHW",
    "outputId": "7984bf0e-28dc-4de2-aa61-e609cabc7b80"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ridge tuning parameter:  1371.3713713713714\n"
     ]
    }
   ],
   "source": [
    "ridge = RidgeCV(alphas = np.linspace(1000, 1500, num=1000))\n",
    "ridge.fit(final, y)\n",
    "print(\"Ridge tuning parameter: \", ridge.alpha_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "8lCKgqRaWWvd"
   },
   "source": [
    "We'll use this value in k-fold cross-validation, rounded to the hundredths place. We'll use a ridge regression and choose not to use a LASSO model here since the regularization results aren't helpful."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "KUbG_WwI879s"
   },
   "source": [
    "# K-Fold Cross-Validation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "id": "icmdHtm_9VaV"
   },
   "outputs": [],
   "source": [
    "from sklearn.model_selection import cross_val_score \n",
    "\n",
    "reference_cv = cross_val_score(reference, final[[\"wind\", \"temp\"]], y, cv = 5, scoring = \"neg_mean_squared_error\")\n",
    "fw2_cv = cross_val_score(fw2_model, final[forward2.get_feature_names_out()], y, cv = 5, scoring = \"neg_mean_squared_error\")\n",
    "fw4_cv = cross_val_score(fw4_model, final[forward4.get_feature_names_out()], y, cv = 5, scoring = \"neg_mean_squared_error\")\n",
    "fw6_cv = cross_val_score(fw6_model, final[forward6.get_feature_names_out()], y, cv = 5, scoring = \"neg_mean_squared_error\")\n",
    "bw2_cv = cross_val_score(bw2_model, final[backward2.get_feature_names_out()], y, cv = 5, scoring = \"neg_mean_squared_error\")\n",
    "bw4_cv = cross_val_score(bw4_model, final[backward4.get_feature_names_out()], y, cv = 5, scoring = \"neg_mean_squared_error\")\n",
    "bw6_cv = cross_val_score(bw6_model, final[backward6.get_feature_names_out()], y, cv = 5, scoring = \"neg_mean_squared_error\")\n",
    "ridge_cv = cross_val_score(ridge, final, y, cv = 5, scoring = \"neg_mean_squared_error\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "Q-hz_HaG_-Y6",
    "outputId": "5e328f7f-f31b-4d12-b5b1-e3d1345fe49b"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Reference Model, Avg Test MSE:  -2.204650013004116  SD:  1.0600403553786375\n",
      "Forward-2 Model, Avg Test MSE:  -2.1735431721198535  SD:  1.0208083278697586\n",
      "Forward-4 Model, Avg Test MSE:  -2.193528106772711  SD:  1.0004774710977682\n",
      "Forward-6 Model, Avg Test MSE:  -2.239722553934875  SD:  1.0123323877770343\n",
      "Backward-2 Model, Avg Test MSE:  -2.173357302739327  SD:  1.0038109503795956\n",
      "Backward-4 Model, Avg Test MSE:  -2.193528106772711  SD:  1.0004774710977682\n",
      "Backward-6 Model, Avg Test MSE:  -2.239722553934875  SD:  1.0123323877770343\n",
      "Ridge Model, Avg Test MSE:  -2.239722553934875  SD:  1.0123323877770343\n"
     ]
    }
   ],
   "source": [
    "print(\"Reference Model, Avg Test MSE: \", np.mean(reference_cv), \" SD: \", np.std(reference_cv))\n",
    "print(\"Forward-2 Model, Avg Test MSE: \", np.mean(fw2_cv), \" SD: \", np.std(fw2_cv))\n",
    "print(\"Forward-4 Model, Avg Test MSE: \", np.mean(fw4_cv), \" SD: \", np.std(fw4_cv))\n",
    "print(\"Forward-6 Model, Avg Test MSE: \", np.mean(fw6_cv), \" SD: \", np.std(fw6_cv))\n",
    "print(\"Backward-2 Model, Avg Test MSE: \", np.mean(bw2_cv), \" SD: \", np.std(bw2_cv))\n",
    "print(\"Backward-4 Model, Avg Test MSE: \", np.mean(bw4_cv), \" SD: \", np.std(bw4_cv))\n",
    "print(\"Backward-6 Model, Avg Test MSE: \", np.mean(bw6_cv), \" SD: \", np.std(bw6_cv))\n",
    "print(\"Ridge Model, Avg Test MSE: \", np.mean(bw6_cv), \" SD: \", np.std(bw6_cv))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "J6BPP8qmW7_x"
   },
   "source": [
    "Among our candidate models, the backward selection model using two features performs the best, with an average MSE of -2.17. However, note that this is on the log-scale, so this suggests that the predictions are off by a magnitude of about 2. On the surface, this suggests that the models overall are not good predictors. \n",
    "\n",
    "However, this problem is known to be a difficult one. The extreme skew in the outcome hurts many of the assumptions needed by linear models. We hope that this showcases that machine learning is not a universal fix. Several problems have characteristics that make prediction difficult."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "id": "v6Sq9R9FRDqC"
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
