{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "toc": true
   },
   "source": [
    "<h1>Table of Contents<span class=\"tocSkip\"></span></h1>\n",
    "<div class=\"toc\"><ul class=\"toc-item\"></ul></div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:53:44.993606Z",
     "start_time": "2022-05-25T11:53:44.967589Z"
    },
    "hide_input": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>\n",
       ".title {\n",
       "    font-size: 30pt;\n",
       "    font-weight: bold;\n",
       "    margin-bottom: 3rem;\n",
       "}\n",
       "\n",
       ".subtitle {\n",
       "    font-size: 20pt;\n",
       "    font-weight: bold;\n",
       "    margin-bottom: 5rem;\n",
       "}\n",
       "\n",
       ".header {\n",
       "    font-size: 24pt !important;\n",
       "    margin-bottom: 1rem !important;\n",
       "    color: darkblue;\n",
       "    margin-bottom: 1em !important;\n",
       "}\n",
       "\n",
       ".subheader {\n",
       "    font-size: 18pt;\n",
       "    margin-bottom: 2rem;\n",
       "}\n",
       "\n",
       ".caption {\n",
       "    text-align: center;\n",
       "    font-size: 16pt;\n",
       "}\n",
       "\n",
       "li {\n",
       "    font-size: 14pt;\n",
       "    line-height: 2rem;\n",
       "}\n",
       "</style>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%html\n",
    "<style>\n",
    ".title {\n",
    "    font-size: 30pt;\n",
    "    font-weight: bold;\n",
    "    margin-bottom: 3rem;\n",
    "}\n",
    "\n",
    ".subtitle {\n",
    "    font-size: 20pt;\n",
    "    font-weight: bold;\n",
    "    margin-bottom: 5rem;\n",
    "}\n",
    "\n",
    ".header {\n",
    "    font-size: 24pt !important;\n",
    "    margin-bottom: 1rem !important;\n",
    "    color: darkblue;\n",
    "    margin-bottom: 1em !important;\n",
    "}\n",
    "\n",
    ".subheader {\n",
    "    font-size: 18pt;\n",
    "    margin-bottom: 2rem;\n",
    "}\n",
    "\n",
    ".caption {\n",
    "    text-align: center;\n",
    "    font-size: 16pt;\n",
    "}\n",
    "\n",
    "li {\n",
    "    font-size: 14pt;\n",
    "    line-height: 2rem;\n",
    "}\n",
    "</style>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"font-size: 18px;\">\n",
    "Master in Computer Science <br>\n",
    "Master in Data Science and Economics\n",
    "</div>\n",
    "\n",
    "<div style=\"font-size: 24px; margin-top: 2rem; margin-bottom: 4rem;\">Algorithms for massive datasets</div>\n",
    "\n",
    "<div class=\"title\">Gradient Boosting</div>\n",
    "\n",
    "<div class=\"header\">aka Gradient Boosting Machines, GBM, ...</div>\n",
    "\n",
    "\n",
    "Prof. Dario Malchiodi\n",
    "\n",
    "<div style=\"width: 50%; margin: auto;\">\n",
    "<img src=\"img/logo-di.jpg\" style=\"height: 4rem; margin-top: 4.75rem; float: left;\">\n",
    "<img src=\"img/logo-demm.jpg\" style=\"height: 3.5rem; margin-top: 5rem; margin-left: 0.5rem; margin-right: 0.5rem; float: left;\">\n",
    "<img src=\"img/logo-unimi.jpg\" style=\"height: 3.5rem; margin-top: 5rem; float: left;\">\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Background</div>\n",
    "\n",
    "<ul>\n",
    "    <li>Boosting refers in general to combination of <i>weak</i> learners\n",
    "        into a more powerful composite model</li>\n",
    "    <li>This combination is often done via building an <i>ensemble</i> of\n",
    "        learners, each trained separately</li>\n",
    "    <li>The ensemble is then queried aggregating the results of the single\n",
    "        components (majority vote, averaging, ...)</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Additive modeling</div>\n",
    "\n",
    "<p>Decompose a function additively</p>\n",
    "\n",
    "$$F_M(x) = \\sum_{i=0}^M f_i(x)$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">For instance...</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:54:43.118973Z",
     "start_time": "2022-05-25T11:54:38.411607Z"
    }
   },
   "outputs": [],
   "source": [
    "import io\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import math\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\", category=UserWarning)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul>\n",
    "    <li>We will focus on regression (although the overall methodology applies\n",
    "        also to classification)</li>\n",
    "    <li>Here is the graph of a target function $F$ (the actual code producing the\n",
    "        graph is hidden)</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:54:46.255220Z",
     "start_time": "2022-05-25T11:54:46.058087Z"
    },
    "hide_input": true,
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "f = lambda x: 30 + x + np.sin(x)\n",
    "x = np.linspace(-30, 30, 100)\n",
    "plt.plot(x, f(x))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul>\n",
    "    <li>The simplest function we can use as an approximation of $F$ is a constant\n",
    "        function $f_0$</li>\n",
    "    <li>We can fix the constant value according to the average value perceived\n",
    "        in the graph, which is 30</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:54:51.950990Z",
     "start_time": "2022-05-25T11:54:51.825499Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.linspace(-30, 30, 100)\n",
    "f_0 = np.vectorize(lambda x: 30)\n",
    "plt.plot(x, f(x))\n",
    "plt.plot(x, f_0(x))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul>\n",
    "    <li>$F$ approximately increases with $x$</li>\n",
    "    <li>so we can add to our approximation the term $f_1(x) = x$</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:54:55.565674Z",
     "start_time": "2022-05-25T11:54:55.431998Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "f_1 = lambda x: x\n",
    "plt.plot(x, f(x))\n",
    "plt.plot(x, f_0(x) + f_1(x))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul>\n",
    "    <li>Finally, we notice an oscillating behaviour</li>\n",
    "    <li>We model it through a third term $f_2(x) = \\sin x$</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:54:58.416003Z",
     "start_time": "2022-05-25T11:54:58.291400Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "f_2 = lambda x: np.sin(x)\n",
    "plt.plot(x, f(x))\n",
    "plt.plot(x, f_0(x) + f_1(x) + f_2(x))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We see how the composite result $F_2(x) = f_0(x) + f_1(x) + f_2(x)$ perfectly\n",
    "superposes with $F$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Boosting</div>\n",
    "\n",
    "<ul>\n",
    "    <li>Given a set of <i>examples</i> $\\{ (x_1, y_1), \\dots, (x_n, y_n) \\}$</li>\n",
    "    <li>where for each $i$, $y_i = F(x_i)$ for some unknown, yet fixed $F$</li>\n",
    "    <li>Suppose that $F = F_M$ as above, for suitable $M$ (or that $F_M$ is\n",
    "        a good approximation for $F$)</li>\n",
    "    <li>That is, $y = F(x)$ can be predicted using $\\hat y = F_m(x)$ in an\n",
    "        incremental tweaking process: $F_m(x) = F_{m-1}(x) + f_m(x)$ (having\n",
    "        fixed an initial $f_0$)</li>\n",
    "    <li>This is an example of boosting where $f_i$s are the weak learners\n",
    "        and aggregation is done through summing.</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Gradient boosting</div>\n",
    "\n",
    "<ul>\n",
    "    <li><i>Incrementally</i> learn $f_i$s</li>\n",
    "    <li>That is, let $$F_M(x) = f_0(x) + \\sum_{i=1}^M \\Delta_i(x)$$</li>\n",
    "</ul>\n",
    "\n",
    "where\n",
    "\n",
    "<ul>\n",
    "    <li>$f_0$ is an initial baseline learnt from data</li>\n",
    "    <li>$\\Delta_1$ represents an attempt to improve $F_0(x) = f_0(x)$,\n",
    "        obtained through learning the <i>residue</i> $F(x) - F_0(x)$</li>\n",
    "    <li>$\\Delta_2$ represents a further attempt to improve\n",
    "        $F_1(x) = f_0(x) + \\Delta_1(x)$, learning the residue $F(x) - F_1(x)$</li>\n",
    "    <li>and so forth</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">An analogy</div>\n",
    "\n",
    "<img src=\"https://explained.ai/gradient-boosting/images/golf-dir-vector.png\"\n",
    "     style=\"width: 50%;\">\n",
    "<div class=\"caption\">[Source: <a href=\"https://explained.ai/gradient-boosting/images/golf-dir-vector.png\">explained.ai</a>]</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">A working example</div>\n",
    "\n",
    "<p>Let us consider a toy dataset associating the surface of a flat with its\n",
    "    monthly rent</p>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:55:02.699545Z",
     "start_time": "2022-05-25T11:55:02.675467Z"
    }
   },
   "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>sqfeet</th>\n",
       "      <th>rent</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>750</td>\n",
       "      <td>1160</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>800</td>\n",
       "      <td>1200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>850</td>\n",
       "      <td>1280</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>900</td>\n",
       "      <td>1450</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>950</td>\n",
       "      <td>2000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sqfeet  rent\n",
       "0     750  1160\n",
       "1     800  1200\n",
       "2     850  1280\n",
       "3     900  1450\n",
       "4     950  2000"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = pd.read_csv(io.StringIO('''sqfeet,rent\\n\n",
    "750,1160\\n\n",
    "800,1200\\n\n",
    "850,1280\\n\n",
    "900,1450\\n\n",
    "950,2000'''))\n",
    "\n",
    "data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p>Each row contains</p>\n",
    "<ul>\n",
    "    <li>the observation of a <i>feature</i> $x_i$, in this case the surface</li>\n",
    "    <li>the value for a <i>label</i> $y_i$, that is the rent</li>\n",
    "    <li>in more general settings, $x_i$s will be vectors</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:55:06.477350Z",
     "start_time": "2022-05-25T11:55:06.272351Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(data['sqfeet'], data['rent'], 'o', c='orange')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul>\n",
    "    <li>Let us choose as baseline $f_0$ the constant function whose value\n",
    "        equals the average of labels</li>\n",
    "    <li>We put $f_0$ inside a list <code>fs</code>, which will also contain the subsequently\n",
    "        generated $f_i$s</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:55:09.075595Z",
     "start_time": "2022-05-25T11:55:09.071553Z"
    }
   },
   "outputs": [],
   "source": [
    "base = round(data['rent'].mean(), 1)\n",
    "\n",
    "fs = [lambda x: base]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul>\n",
    "    <li>The use of <code>fs</code> allows us to define once and for all\n",
    "        a function <code>F</code> which is the equivalent of $F_M$\n",
    "        regardless of the number of improvements</li>\n",
    "    <li>For now, invoking <code>F</code> is equivalent to evaluating $F_0$</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:55:11.446784Z",
     "start_time": "2022-05-25T11:55:11.427913Z"
    }
   },
   "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>sqfeet</th>\n",
       "      <th>rent</th>\n",
       "      <th>F_0</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>750</td>\n",
       "      <td>1160</td>\n",
       "      <td>1418.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>800</td>\n",
       "      <td>1200</td>\n",
       "      <td>1418.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>850</td>\n",
       "      <td>1280</td>\n",
       "      <td>1418.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>900</td>\n",
       "      <td>1450</td>\n",
       "      <td>1418.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>950</td>\n",
       "      <td>2000</td>\n",
       "      <td>1418.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sqfeet  rent     F_0\n",
       "0     750  1160  1418.0\n",
       "1     800  1200  1418.0\n",
       "2     850  1280  1418.0\n",
       "3     900  1450  1418.0\n",
       "4     950  2000  1418.0"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def F(x):\n",
    "    return sum([f(x) for f in fs])\n",
    "\n",
    "data['F_0'] = data['sqfeet'].map(F)\n",
    "\n",
    "data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul>\n",
    "    <li>Let us plot $f_0$ (or, analogously, $F_0$) against the dataset</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:55:14.622965Z",
     "start_time": "2022-05-25T11:55:14.476512Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAD4CAYAAAAAczaOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAR00lEQVR4nO3dfYxl9V3H8fenuxYZDbWVaYP7wI6GNkJjHxg3RFOtbRVqaqEazZpVMDZuSlDb+lgkae0fTbQPGvsHNKsllGYLYmwLJlKLjWn9A9zMVigsFNk6AltW2EpiSVZR1q9/nLPh7nDn4c7OzJ2Z3/uV3Nxzv+ecO9979refOfecc+emqpAkteFF425AkrR2DH1JaoihL0kNMfQlqSGGviQ1ZOu4G1jMueeeW7t27Rp3G5K0oRw6dOhbVTU5t77uQ3/Xrl3MzMyMuw1J2lCSPDqs7uEdSWqIoS9JDTH0Jakhhr4kNcTQl6SGLBr6SXYk+YckDyU5nOTdff1lSe5K8kh//9KBda5NciTJw0kuHahfnOT+ft7Hk2R1XpYkbVCzB+Dzu+AzL+ruZw+s6NMvZU//OeC3q+oHgUuAa5JcCLwP+FJVXQB8qX9MP28PcBFwGXB9ki39c90A7AMu6G+XreBrkaSNbfYAHNwHJx4Fqrs/uG9Fg3/R0K+qY1X11X76GeAhYBtwOfCpfrFPAVf005cDt1bVs1U1CxwBdic5Dzinqu6u7u853zywjiTpvuvg5InTaydPdPUVMtIx/SS7gNcB/wS8oqqOQfeLAXh5v9g24PGB1Y72tW399Nz6sJ+zL8lMkpnjx4+P0qIkbVwnHhutvgxLDv0k3w38NfCeqvr2QosOqdUC9RcWq/ZX1XRVTU9OvuBTxJK0OU3sHK2+DEsK/STfQRf4B6rqs335yf6QDf39U339KLBjYPXtwBN9ffuQuiQJ4DUfgi0Tp9e2THT1FbKUq3cCfBJ4qKr+ZGDWHcBV/fRVwO0D9T1JzkoyRXfC9mB/COiZJJf0z3nlwDqSpKm9sHs/TJwPpLvfvb+rr5Cl/MG1HwV+Gbg/yb197Q+APwJuS/JO4DHg5wGq6nCS24AH6a78uaaqTvbrXQ3cBJwN3NnfJEmnTO1d0ZCfK+v9i9Gnp6fLv7IpSaNJcqiqpufW/USuJDXE0Jekhhj6ktQQQ1+SGmLoS1JDDH1JaoihL0kNMfQlqSGGviQ1xNCXpIYY+pLUEENfkhpi6EtSQwx9SWqIoS9JDTH0Jakhhr4kNcTQl6SGGPqS1BBDX5IaYuhLUkMMfUlqiKEvSQ0x9CWpIYa+JDXE0Jekhhj6ktQQQ1+SGmLoS1JDDH1JaoihL0kNMfQlqSGGviQ1xNCXpIYY+pLUEENfkhpi6EtSQwx9SWrIoqGf5MYkTyV5YKD22iT3JLk3yUyS3QPzrk1yJMnDSS4dqF+c5P5+3seTZOVfjiRpIUvZ078JuGxO7cPAB6vqtcD7+8ckuRDYA1zUr3N9ki39OjcA+4AL+tvc55QkrbJFQ7+qvgI8PbcMnNNPvwR4op++HLi1qp6tqlngCLA7yXnAOVV1d1UVcDNwxQr0L0kawdZlrvce4O+SfJTuF8eP9PVtwD0Dyx3ta//bT8+tD5VkH927Anbu3LnMFiVJcy33RO7VwHuragfwXuCTfX3YcfpaoD5UVe2vqumqmp6cnFxmi5KkuZYb+lcBn+2n/wo4dSL3KLBjYLntdId+jvbTc+uSpDW03NB/AvjxfvpNwCP99B3AniRnJZmiO2F7sKqOAc8kuaS/audK4PYz6FuStAyLHtNPcgvwRuDcJEeBDwC/BvxZkq3Af9Mff6+qw0luAx4EngOuqaqT/VNdTXcl0NnAnf1NkrSG0l1Ms35NT0/XzMzMuNuQpA0lyaGqmp5b9xO5ktQQQ1+SGmLoS1JDDH1JaoihL0kNMfQlqSGGviQ1xNCXpIYY+pLUEENfkhpi6EtSQwx9SWqIoS9JDTH0Jakhhr4kNcTQl6SGGPqS1BBDX5IaYuhLUkMMfUlqiKEvSQ0x9CWpIYa+JDXE0Jekhhj6ktQQQ1+SGmLoS1JDDH1JaoihL0kNMfQlqSGGviQ1xNCXpIYY+pLUEENfkhpi6EtSQwx9SWqIoS9JDTH0Jakhi4Z+khuTPJXkgTn130jycJLDST48UL82yZF+3qUD9YuT3N/P+3iSrOxLkSQtZil7+jcBlw0WkvwEcDnwQ1V1EfDRvn4hsAe4qF/n+iRb+tVuAPYBF/S3055TkrT6Fg39qvoK8PSc8tXAH1XVs/0yT/X1y4Fbq+rZqpoFjgC7k5wHnFNVd1dVATcDV6zQa5AkLdFyj+m/EnhDkn9K8uUkP9zXtwGPDyx3tK9t66fn1odKsi/JTJKZ48ePL7NFSdJcyw39rcBLgUuA3wVu64/RDztOXwvUh6qq/VU1XVXTk5OTy2xRkjTXckP/KPDZ6hwE/g84t6/vGFhuO/BEX98+pC5JWkPLDf3PA28CSPJK4MXAt4A7gD1JzkoyRXfC9mBVHQOeSXJJ/47gSuD2M21ekjSarYstkOQW4I3AuUmOAh8AbgRu7C/j/B/gqv4E7eEktwEPAs8B11TVyf6prqa7Euhs4M7+JklaQ+myev2anp6umZmZcbchSRtKkkNVNT237idyJakhhr4kNcTQl6SGGPqS1BBDX5IaYuhLUkMMfUlqiKEvSQ0x9CWpIYa+JDXE0Jekhhj6ktQQQ1+SGmLoS1JDDH1JaoihL0kNMfQlqSGGviQ1xNCXpIYY+pLUEENfkhpi6EtSQwx9SWqIoS9JDTH0Jakhhr4kNcTQl6SGGPqSVtfsAfj8LvjMi7r72QPj7qhpW8fdgKRNbPYAHNwHJ090j0882j0GmNo7vr4a5p6+pNVz33XPB/4pJ090dY2FoS9p9Zx4bLS6Vp2hL2n1TOwcra5VZ+hLWj2v+RBsmTi9tmWiq2ssDH1Jq2dqL+zeDxPnA+nud+/3JO4YefWOpNU1tdeQX0fc05ekhmzaPf0P/s1hHnzi2+NuQ5KW5cLvO4cP/MxFK/687ulLUkMW3dNPciPwNuCpqnr1nHm/A3wEmKyqb/W1a4F3AieB36yqv+vrFwM3AWcDfwu8u6pq5V7K6VbjN6QkbXRL2dO/CbhsbjHJDuAngccGahcCe4CL+nWuT7Kln30DsA+4oL+94DklSatr0dCvqq8ATw+Z9afA7wGDe+uXA7dW1bNVNQscAXYnOQ84p6ru7vfubwauONPmJUmjWdYx/SRvB75ZVffNmbUNeHzg8dG+tq2fnluf7/n3JZlJMnP8+PHltChJGmLk0E8yAVwHvH/Y7CG1WqA+VFXtr6rpqpqenJwctUVJ0jyWc8nmDwBTwH1JALYDX02ym24PfsfAstuBJ/r69iF1SdIaGnlPv6rur6qXV9WuqtpFF+ivr6p/B+4A9iQ5K8kU3Qnbg1V1DHgmySXpflNcCdy+ci9DkrQUi4Z+kluAu4FXJTma5J3zLVtVh4HbgAeBLwDXVNXJfvbVwF/Qndz9BnDnGfYuSRpRVvFS+RUxPT1dMzMz425DkjaUJIeqanpu3U/kSlJDDH1JaoihL0kNMfQlqSGGviQ1xNCXpIYY+pLUEENfkhpi6EtSQwx9SWqIoS9JDTH0Jakhhr4kNcTQl6SGGPqS1BBDX5IaYuhLUkMMfUlqiKEvSQ0x9CWpIYa+NKrZA/D5XfCZF3X3swfG3ZG0ZFvH3YC0ocwegIP74OSJ7vGJR7vHAFN7x9eXtETu6UujuO+65wP/lJMnurq0ARj60ihOPDZaXVpnDH1pFBM7R6tL64yhL43iNR+CLROn17ZMdHVpAzD0pVFM7YXd+2HifCDd/e79nsTVhuHVO9KopvYa8tqw3NOXpIYY+pLUEENfkhpi6EtSQwx9SWqIoS9JDTH0Jakhhr4kNcTQl6SGGPqS1JBFQz/JjUmeSvLAQO0jSb6e5GtJPpfkewbmXZvkSJKHk1w6UL84yf39vI8nyYq/GknSgpayp38TcNmc2l3Aq6vqh4B/Aa4FSHIhsAe4qF/n+iRb+nVuAPYBF/S3uc+pcfHr/6RmLBr6VfUV4Ok5tS9W1XP9w3uA7f305cCtVfVsVc0CR4DdSc4Dzqmqu6uqgJuBK1boNehMnPr6vxOPAvX81/8Z/NKmtBLH9H8VuLOf3gY8PjDvaF/b1k/PrWvc/Po/qSlnFPpJrgOeA07tFg47Tl8L1Od73n1JZpLMHD9+/Exa1GL8+j+pKcsO/SRXAW8D9vaHbKDbg98xsNh24Im+vn1Ifaiq2l9V01U1PTk5udwWtRR+/Z/UlGWFfpLLgN8H3l5Vg8cG7gD2JDkryRTdCduDVXUMeCbJJf1VO1cCt59h71oJfv2f1JRFvzkryS3AG4FzkxwFPkB3tc5ZwF39lZf3VNW7qupwktuAB+kO+1xTVSf7p7qa7kqgs+nOAdyJxu/UN0Ddd113SGdiZxf4fjOUtCnl+SMz69P09HTNzMyMuw1J2lCSHKqq6bl1P5ErSQ3ZnKHvh40kaahFj+lvOKc+bHTq2vNTHzYCj1NLat7m29P3w0aSNK/NF/p+2EiS5rX5Qt8PG0nSvDZf6PthI0ma1+YL/am9sHs/TJwPpLvfvd+TuJLEZrx6B7qAN+Ql6QU2356+JGlehr4kNcTQl6SGGPqS1BBDX5Iasu7/tHKS48Cjy1z9XOBbK9jOSrGv0djXaOxrNJu1r/Or6gVfPbjuQ/9MJJkZ9vekx82+RmNfo7Gv0bTWl4d3JKkhhr4kNWSzh/7+cTcwD/sajX2Nxr5G01Rfm/qYviTpdJt9T1+SNMDQl6SGbNjQT/KqJPcO3L6d5D1J/jDJNwfqPz2wzrVJjiR5OMmla9zXXw7U/i3Jvf3yu5L818C8T6xGX/3Pem+Sw0keSHJLku9M8rIkdyV5pL9/6cDyq769FujrI0m+nuRrST6X5Hv6Zce9vcY6vhboaz2Mr3f3PR1O8p6+th7G17C+1sP4GtbX6o+vqtrwN2AL8O/A+cAfAr8zZJkLgfuAs4Ap4BvAlrXqa079Y8D7++ldwANrsI22AbPA2f3j24BfAT4MvK+vvQ/447XcXgv09VPA1r72xwN9jXt7jXV8zdfXOhhfrwYeACbo/mT73wMXrIPxNV9f4x5f8/W16uNrw+7pz/Fm4BtVtdAndy8Hbq2qZ6tqFjgC7F7rvpIE+AXgllX+2cNsBc5OspVusD1Bt10+1c//FHBFP72W2+sFfVXVF6vquX7+PcD2VfrZI/W1wLJj3V6nZoxxfP0gcE9Vnej/3b4MvIPxj6+hfa2D8TXf9prPim2vzRL6ezh9kP96/7btxoG3k9uAxweWOdrX1rIvgDcAT1bVIwO1qST/nOTLSd6wGo1U1TeBjwKPAceA/6yqLwKvqKpj/TLHgJf3q6zJ9lqgr0G/Ctw58Hic2wvGOL6WsL3GMr7o9lp/LMn3JpkAfhrYwZjH1wJ9DVrz8bVIX6s6vjZ86Cd5MfB24K/60g3ADwCvpftP8bFTiw5ZfdWuVx3S1ym/yOm/CI4BO6vqdcBvAZ9Jcs4q9PNSur2FKeD7gO9K8ksLrTKktuLba7G+klwHPAcc6Evj3l5jHV9L+Hccy/iqqofoDpPcBXyB7lDEcwussibba7G+xjW+Fuhr1cfXhg994K3AV6vqSYCqerKqTlbV/wF/zvNvgY5y+m/47Sz8dn1F+wLo347/LPCXp2r927X/6KcP0R2re+Uq9PMWYLaqjlfV/wKfBX4EeDLJeX1/5wFP9cuv1faary+SXAW8Ddhb/YHNcW+vdTC+Ftpe4xxfVNUnq+r1VfVjwNPAI4x/fM3X17jH19C+1mJ8bYbQP23P5tQA672D7m0UwB3AniRnJZmiO2lycK366r0F+HpVHR3odzLJln76+/u+/nUV+nkMuCTJRH/c983AQ3Tb5ap+mauA2/vptdpeQ/tKchnw+8Dbq+rEqYXHvb3Wwfia798Rxju+SPLy/n4n3S+fWxj/+Bra1zoYX/P1tfrj60zPQo/zRncS6z+AlwzUPg3cD3yt31DnDcy7ju4398PAW9eyr75+E/CuObWfAw7Tvb37KvAzq9jXB4Gv9wPp03RXAnwv8CW6vZ8vAS8bw/Ya1tcRumOY9/a3T6yT7bUextcL+lon4+sfgQf7n/XmvrYextewvtbD+BrW16qPL/8MgyQ1ZDMc3pEkLZGhL0kNMfQlqSGGviQ1xNCXpIYY+pLUEENfkhry/4vLtkbZcvjEAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.linspace(data['sqfeet'].min(), data['sqfeet'].max(), 100)\n",
    "y = list(map(F, x))\n",
    "plt.plot(x, y)\n",
    "plt.plot(data['sqfeet'], data['rent'], 'o', c='orange')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul>\n",
    "    <li>Let us compute the residuals, that is the difference between\n",
    "        each label and the predicted value</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:55:17.511918Z",
     "start_time": "2022-05-25T11:55:17.493572Z"
    }
   },
   "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>sqfeet</th>\n",
       "      <th>rent</th>\n",
       "      <th>F_0</th>\n",
       "      <th>R_0</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>750</td>\n",
       "      <td>1160</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-258.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>800</td>\n",
       "      <td>1200</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-218.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>850</td>\n",
       "      <td>1280</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-138.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>900</td>\n",
       "      <td>1450</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>32.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>950</td>\n",
       "      <td>2000</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>582.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sqfeet  rent     F_0    R_0\n",
       "0     750  1160  1418.0 -258.0\n",
       "1     800  1200  1418.0 -218.0\n",
       "2     850  1280  1418.0 -138.0\n",
       "3     900  1450  1418.0   32.0\n",
       "4     950  2000  1418.0  582.0"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data['R_0'] = round(data['rent'] - data['F_0'], 1)\n",
    "data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul>\n",
    "    <li>We want thus to learn to predict the <code>R_0</code> column values\n",
    "        starting from the corresponding observations</li>\n",
    "    <li>We do so using <i>regression tree stumps</i>, that is regression\n",
    "        trees having depth equal to 1 and splitting on a condition involving\n",
    "        only one feature</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-05-25T11:55:21.797852Z",
     "start_time": "2022-05-25T11:55:20.483162Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: Tree Pages: 1 -->\n",
       "<svg width=\"264pt\" height=\"135pt\"\n",
       " viewBox=\"0.00 0.00 263.50 135.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 131)\">\n",
       "<title>Tree</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-131 259.5,-131 259.5,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M183.5,-127C183.5,-127 73.5,-127 73.5,-127 67.5,-127 61.5,-121 61.5,-115 61.5,-115 61.5,-86 61.5,-86 61.5,-80 67.5,-74 73.5,-74 73.5,-74 183.5,-74 183.5,-74 189.5,-74 195.5,-80 195.5,-86 195.5,-86 195.5,-115 195.5,-115 195.5,-121 189.5,-127 183.5,-127\"/>\n",
       "<text text-anchor=\"middle\" x=\"128.5\" y=\"-111.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">sqfeet &lt;= 925.0</text>\n",
       "<text text-anchor=\"middle\" x=\"128.5\" y=\"-96.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 5</text>\n",
       "<text text-anchor=\"middle\" x=\"128.5\" y=\"-81.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = 0.0</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M109,-38C109,-38 12,-38 12,-38 6,-38 0,-32 0,-26 0,-26 0,-12 0,-12 0,-6 6,0 12,0 12,0 109,0 109,0 115,0 121,-6 121,-12 121,-12 121,-26 121,-26 121,-32 115,-38 109,-38\"/>\n",
       "<text text-anchor=\"middle\" x=\"60.5\" y=\"-22.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 4</text>\n",
       "<text text-anchor=\"middle\" x=\"60.5\" y=\"-7.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = &#45;145.5</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M106.61,-73.91C99,-65.01 90.46,-55.03 82.82,-46.09\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"85.26,-43.56 76.1,-38.24 79.94,-48.11 85.26,-43.56\"/>\n",
       "<text text-anchor=\"middle\" x=\"74.16\" y=\"-59.46\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">True</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M243.5,-38C243.5,-38 151.5,-38 151.5,-38 145.5,-38 139.5,-32 139.5,-26 139.5,-26 139.5,-12 139.5,-12 139.5,-6 145.5,0 151.5,0 151.5,0 243.5,0 243.5,0 249.5,0 255.5,-6 255.5,-12 255.5,-12 255.5,-26 255.5,-26 255.5,-32 249.5,-38 243.5,-38\"/>\n",
       "<text text-anchor=\"middle\" x=\"197.5\" y=\"-22.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 1</text>\n",
       "<text text-anchor=\"middle\" x=\"197.5\" y=\"-7.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = 582.0</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M150.71,-73.91C158.51,-64.92 167.28,-54.82 175.09,-45.82\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"177.76,-48.09 181.67,-38.24 172.47,-43.5 177.76,-48.09\"/>\n",
       "<text text-anchor=\"middle\" x=\"183.43\" y=\"-59.48\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">False</text>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.sources.Source at 0x7eff5d460be0>"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn import tree\n",
    "import graphviz\n",
    "\n",
    "r = tree.DecisionTreeRegressor(max_depth=1)\n",
    "r.fit(data[['sqfeet']], data['R_0'])\n",
    "\n",
    "graphviz.Source(tree.export_graphviz(r,\n",
    "                                     out_file=None,\n",
    "                                     feature_names=data.columns[0:1],\n",
    "                                     rounded=True,\n",
    "                                     impurity=False))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">How regression trees are built?</div>\n",
    "\n",
    "<ul>\n",
    "    <li>Split is chosen so that an <i>impurity</i> measure\n",
    "        is optimized on the two subgroups of observations identifying\n",
    "        the two leaves</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">In our case...</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "R_0_left = data[data['sqfeet'] <= 925]['R_0']\n",
    "R_0_right = data[data['sqfeet'] > 925]['R_0']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   -258.0\n",
       "1   -218.0\n",
       "2   -138.0\n",
       "3     32.0\n",
       "Name: R_0, dtype: float64"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "R_0_left"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4    582.0\n",
       "Name: R_0, dtype: float64"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "R_0_right"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-145.5, 16491.666666666668)"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(R_0_left.mean(), R_0_left.var())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(582.0, 0.0)"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(R_0_right.mean(), R_0_right.var(ddof=0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Why regression tree stumps?</div>\n",
    "\n",
    "<ul>\n",
    "    <li>Because we want to use <i>weak</i> learners</li>\n",
    "    <li>There are, of course, other possibilities</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Let us continue</div>\n",
    "\n",
    "<ul>\n",
    "    <li>Let's build $f_1$ as the prediction done by the regression tree</li>\n",
    "    <li>If we add $f_1$ as a second member of the list <code>fs</code>...</li>\n",
    "    <li>...invoking $F(x)$ will be the equivalent of evaluating $F_1(x)$</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [],
   "source": [
    "fs.append(lambda x: r.predict([[x]])[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<function __main__.<lambda>(x)>, <function __main__.<lambda>(x)>]"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {
    "scrolled": false
   },
   "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>sqfeet</th>\n",
       "      <th>rent</th>\n",
       "      <th>F_0</th>\n",
       "      <th>R_0</th>\n",
       "      <th>F_1</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>750</td>\n",
       "      <td>1160</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-258.0</td>\n",
       "      <td>1272.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>800</td>\n",
       "      <td>1200</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-218.0</td>\n",
       "      <td>1272.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>850</td>\n",
       "      <td>1280</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-138.0</td>\n",
       "      <td>1272.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>900</td>\n",
       "      <td>1450</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>32.0</td>\n",
       "      <td>1272.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>950</td>\n",
       "      <td>2000</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>582.0</td>\n",
       "      <td>2000.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sqfeet  rent     F_0    R_0     F_1\n",
       "0     750  1160  1418.0 -258.0  1272.5\n",
       "1     800  1200  1418.0 -218.0  1272.5\n",
       "2     850  1280  1418.0 -138.0  1272.5\n",
       "3     900  1450  1418.0   32.0  1272.5\n",
       "4     950  2000  1418.0  582.0  2000.0"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data['F_1'] = round(data['sqfeet'].map(F), 1)\n",
    "data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul>\n",
    "    <li>Let us plot the prediction (blue stepwise curve) against the dataset...</li>\n",
    "    <li>...as well as the residuals</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAD4CAYAAADlwTGnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAbb0lEQVR4nO3df5Ac5X3n8fcHScgiPgkwgiP6YSmO7Bi2dLbZqEic+HyWHWTHWCRVUYk6G+XOOdVRxDaupBI4nzFxlaqIzzFnVQ6uFMwhfARqk5CAXYEEK05sV/HjVgbrBzKHbNloQaAlVARlcyDtfO+P7tWOVrM7s7s900/3fF5VUzPzdPfuV6On95nn+/TztCICMzPrP2eUHYCZmZXDDYCZWZ9yA2Bm1qfcAJiZ9Sk3AGZmfWp+2QG0c95558WqVavKDsNqavfu3S9GxNJe/17Xa+um3bt3vww8HBEbptsv+QZg1apVDA8Plx2G1ZSkH5fxe12vrZskPd3ujz84BWRm1rfcAJi1IOlsSX8p6fuSDkj6JUnnSnpI0tP58zlN+18v6aCkpyRdVmbsZp1yA2DW2peBByPiF4B/AxwArgN2RcQaYFf+HkkXAZuBi4ENwC2S5pUStdkMuAEwm0TSYuA9wFcAIuL1iPgXYCOwM99tJ3BF/nojcE9EvBYRh4CDwLpexmw2G24AzE73c8Ao8L8kPS7pNkk/A1wQEUcA8ufz8/2XAYebjh/Jy04haaukYUnDo6Oj3f0XmHWgbQMgaYWkb+Z50P2SPpWXzzgfKukSSXvzbdslqTv/LDNgzxDcPAA3np097xnq9Mj5wLuAWyPincBPyNM9U2hVj09bZTEidkTEYEQMLl3a8ytPrU5mX7dP0UkP4ATwexHxduBS4Jo85zmbfOitwFZgTf5oe5mS2azsGYKvfRKOHQYie/7aJzs9UUaAkYh4NH//l2QNwguSLgTIn4827b+i6fjlwHNF/DPMTjO3un2KtvMA8q7ueLf3FUkHyLq3G4H35rvtBP4R+EOa8qHAIUkHgXWSfgQsjoiHASTdSZZDfWDGUVtf+NGLP+Hex5+FWSxZ/ju7P8vi46+eWnj8Vdj1eVi7adpjI+J5SYclvS0ingLWA0/mjy3ATfnzffkh9wN/LulLwM+Sfbl5bMZBW994YO8RDhx5eVbHzqVuTzajiWCSVgHvBB5lUj5UUnM+9JGmw8bzocfz15PLW/2erWQ9BVauXDmTEK1G7nr0x/zZtw8xm0ThtWc+3zoxc2ykRWFLnwDuknQm8EPgP5D1mIckfRx4BvgtgIjYL2mIrIE4AVwTEWMzj9r6xXX37uXYq8fLqtsnddwASHoj8FfAtRHx8jTp+6nyoR3lSSHLlQI7AAYHB33Hmj51fCxYsmgB3/vcr8384JtX5F3kSZYs7+jwiHgCGGyxaf0U+28DtnUcn/W1E2MNfudXVvNfP3zRzA+eY91u1tFVQJIWkP3xvysi7s2LZ5oPHclfTy43aykiOGO2lwmsvwEWLDq1bMGirNysZI2AM2ZbuQus251cBSSy66EPRMSXmjbdT5YHhdPzoZslLZS0mjwfmqeLXpF0af4zr2o6xuw0jYAzZnuh2NpNcPl2WLICUPZ8+fYZ50jNuqERMav0D1Bo3e4kBfRu4GPAXklP5GX/hWwgbKb50KuBO4BFZIO/HgC2KWUnyRyuFF67yX/wLUkxly83UFjd7uQqoO/QOn8PM8yHRsQwMDCTAK1/NeaSAjJL2FgiddszgS1ZjcYcvyWZJSr7clN+3XYDYMlyD8DqKCKIYG7pzYK4AbBkNRI5ScyKND6vMYUvN24ALFkRwRmuoVYzjbwFcArIbBqp5EnNitRwD8CsvTnNAzBL1HgPIIX0phsAS9acJsuYJWp8DGBeAl0ANwCWrAiY5xbAamZiDKDkQHADYAnzGIDVkQeBzTrgFJDV0fggsMcAzKYx5pnAVkONhlNAZm15HoDVkVNAZh3wGIDVkecBmHXAS0FYHYXnAZi158XgrI4megDlV243AJasOd80wyxBngdg1gH3AKyOPAhs1oE53xLSLEEnl4NO4NuNGwBLVsNLQVgNOQVk1gHPA7A68iCwWQe8HLTV0cRy0CUHghsAS5jHAKyOwoPAZu01Gr4KyOpnrJE9uwEwm4ZTQFZHHgQ264DnAVgd+ZaQZh3wWkBWR+HF4MzaC/cArIY8E9isA14O2uqo4ZvCm7XnQWCrI88DMOtAIyKJ9VLMiuR5AGYdyJaDLjsKs2J5KQizDngMwOrIN4U360C2FETZUZgVa7wHkMIlzm4ALFmNRhrdZLMieSawWQfKngksaZ6kxyV9PX9/rqSHJD2dP5/TtO/1kg5KekrSZeVFbak72QAk0AK4AbBkJTAG8CngQNP764BdEbEG2JW/R9JFwGbgYmADcIukeT2O1Sqi4ZnAZu2VuRSEpOXArwO3NRVvBHbmr3cCVzSV3xMRr0XEIeAgsK5HoVrFeC0gsw6UvBTEfwf+AGg0lV0QEUcA8ufz8/JlwOGm/UbyslNI2ippWNLw6OhoV4K29FVqHoCk2yUdlbSvqewdkh6R9EReodc1bWuZC5V0iaS9+bbtSqH5s6SVNRNY0oeBoxGxu9NDWpTFaQUROyJiMCIGly5dOqcYrboa+VeKFO533UkP4A6yvGazLwB/FBHvAG7I37fLhd4KbAXW5I/JP9PsFCUOAr8b+IikHwH3AO+T9L+BFyRdCJA/H833HwFWNB2/HHiud+FalVRqKYiI+Bbw0uRiYHH+egkTlb1lLjQ/WRZHxMOR9X/uZCJ/atZSo1HOLSEj4vqIWB4Rq8i+0PxDRHwUuB/Yku+2Bbgvf30/sFnSQkmryb7gPNbjsK0iUpoJPH+Wx10L/J2kL5I1Ir+cly8DHmnabzwXejx/Pbm8JUlbyXoLrFy5cpYhWtVFpLFiYpObgCFJHweeAX4LICL2SxoCngROANdExFh5YVrKTo4BJDACO9sQrgY+HRErgE8DX8nLp8qFdpQjPbnBuVKj/HkAABHxjxHx4fz1P0fE+ohYkz+/1LTftoh4S0S8LSIeKC9iS11KPYDZNgBbgHvz13/BxCVvU+VCR/LXk8vNpuTloK2O6jAT+Dng3+av3wc8nb9umQvNL5l7RdKl+dU/VzGRPzVraSzKGQMw66aU5gG0HQOQdDfwXuA8SSPA54D/BHxZ0nzg/5Hn69vkQq8mu6JoEfBA/jCbkm8JaXWU0i0h2zYAEXHlFJsumWL/bcC2FuXDwMCMorO+5hSQ1dH4PIAUvtwkMA5t1loKg8BmRUupB+AGwJIUEUSJawGZdUuMXwWUwLcbNwCWpEjoUjmzItXhKiCzrkrpJDErUh3mAZh1VSOhbrJZkSq1FpBZGVIaKDMrUqWWgzYrw8QYQLlxmBXNKSCzNtwDsLpKaXzLDYAlKaU8qVmRxnsAKVzi7AbAkjQxW7L8k8SsSI2GewBm00qpm2xWpJTSm24ALEknTxK3AFYzHgQ2ayOlPKlZkRo1uCOYWVeFU0BWU54HYNZGSt1ksyKlVLfdAFiSPAhsdZVS3XYDYElK6UoJsyKlNL7lBsCS5OWgra5SutWpGwBLUkpXSpgVKbvTXRotgE8vS1JKA2VmRUrpXtduACxJY43xtYDSOFHMitJoRDJrXLkBsCR5HoDVlVNAZm04BWR1laWAyo4i4wbAkpTStdJmRWpEJLPGlRsAS9LE/QDSOFHMihIeBDabnucBWF01PA/AbHpOAVldeRDYrI2Tg8BuAaxmGpFOatMNgCXJawFZXXkpCLM2PA/A6qrRSOeLjRsAS5LnAVhdeRDYrI2JpSBKDsSsYGMRHgMwm47HAKyuItJZ5TaRMMxO5XkAVleNCOYlUq/dAFiSypwHIGmFpG9KOiBpv6RP5eXnSnpI0tP58zlNx1wv6aCkpyRd1vuorSq8HLRZGyXfNu8E8HsR8XbgUuAaSRcB1wG7ImINsCt/T75tM3AxsAG4RdK8MgK39DXCy0GbTavMHkBEHImI7+avXwEOAMuAjcDOfLedwBX5643APRHxWkQcAg4C63oatFVGeCaw2fQikUFgSauAdwKPAhdExBHIGgng/Hy3ZcDhpsNG8rLJP2urpGFJw6Ojo12N29JVqXkAkm6XdFTSvknln8jznfslfaGpvGUuVNIlkvbm27YrleugLEmNRvZc5oki6Y3AXwHXRsTL0+3aoixOK4jYERGDETG4dOnSosK0iqlaCugOsrzmSZL+HVm3d21EXAx8MS+fLhd6K7AVWJM/TvmZZs3Kvim8pAVkf/zvioh78+IXJF2Yb78QOJqXjwArmg5fDjzXq1itWio1CBwR3wJemlR8NXBTRLyW7zN+IrTMheYny+KIeDiyvv2dTORPzU5T5kzgvHf6FeBARHypadP9wJb89RbgvqbyzZIWSlpN9gXnsV7Fa9USEZWfB/BW4FclPSrpnyT9Yl4+VS50Wf56cnlLzpVayWMA7wY+BrxP0hP540PATcAHJD0NfCB/T0TsB4aAJ4EHgWsiYqyMwC19KS0HPX8Ox51DdoncLwJDkn6OqXOhHeVIT26I2AHsABgcHJxyP6uvsXKvAvoOresswPopjtkGbOtaUFYbYzVYDnoEuDcyjwEN4DymzoWO5K8nl5u1VPI8ALOuqcNy0H8DvA9A0luBM4EXmSIXml8y94qkS/P86lVM5E/NTuPloK2uUloKom0KSNLdwHuB8ySNAJ8Dbgduzy8NfR3Ykg/u7pc0ngs9wam50KvJrihaBDyQP8xa8mJwVlcpzQNo2wBExJVTbProFPu3zIVGxDAwMKPorG+lMA/ArBuqNg/ArOfGewCpnChmRYkqzQMwK8PJ5aA9CGA106jBPACzripzMTizbkppHoAbAEvS+GWgqVwtYVaURg3mAZh11cQYQBonillR6jAPwKyrPA/A6qpSi8GZlaHMxeDMuqnhHoDZ9MYanghm9TTW8CCw2bROjgG4hlrNeB6AWRvhFJDVlOcBmLXheQBWV9lSEGlUbDcAliQPAltdOQVk1obXArK68lVAZm2UfEtIs67xPACzNrwUhNWVl4M2a8MpIKsrjwGYtZEtmOW1gKx+PAZg1kYktGSuWZG8HLRZG9l0+bKjMCveWCOdGx25AbAkpbRmulmRvBy0WRspnSRmRXIKyKyNlE4SsyJ5HoBZGymdJGZF8jwAszZSOknMiuR5AGZtpHSSmBXJ8wDM2kjpJDErUkrjW24ALEmNCOa5BbAaSukSZzcAVqw9Q3DzANx4dva8Z2hWPyalk8QMKKxup3SJ8/yyA7Aa2TMEX/skHH81e3/scPYeYO2mGf2olE4SsyLrdiNIpnfrHoAVZ9fnJ06QccdfzcpnKFsKIo2TxKzoup1K79YNgBXn2MjMyqfheQCWlILqdiR2r2s3AFacJctnVj4NzwOwpBRUt1O717UbACvO+htgwaJTyxYsyspnyPMALCkF1e2GewBWW2s3weXbYckKQNnz5dtnPEgGngdgiSmobk/c6S6Nyu2rgKxYazfN6g/+ZFUcA5C0AfgyMA+4LSJuKjkkK1IBdTucAjJrr2pjAJLmAf8D+CBwEXClpIvKjcpS4xSQWQcqeEvIdcDBiPhhRLwO3ANsLDkmS4wHgc060GikM1mmQ8uAw03vR/KykyRtlTQsaXh0dLSnwVkaJsYASg4k17YBkHS7pKOS9rXY9vuSQtJ5TWXXSzoo6SlJlzWVXyJpb75tu1IZBbEkZSmgSlWRVsHGKW8idkTEYEQMLl26tEdhWUqikT1XqQdwB7BhcqGkFcAHgGeayi4CNgMX58fckudGAW4FtgJr8sdpP9NsXDYIXHYUMzICrGh6vxx4rqRYLFHjPYBUerdtG4CI+BbwUotNNwN/wKnfcjYC90TEaxFxCDgIrJN0IbA4Ih6ObCrcncAVcw3e6quCYwD/B1gjabWkM8m+CN1fckyWmFoMAkv6CPBsRHxv0qap8qDL8teTy6f6+c6V9rmxis0DiIgTwO8CfwccAIYiYn+5UVlqxqo+D0DSWcBngF9rtblFWUxT3lJE7AB2AAwODk65n9VXFZeDjoi/Bf627DgsXanNA5jNRLC3AKuB7+Un6HLgu5LWMXUedCR/PbncrCUvB211VPkUUETsjYjzI2JVRKwi++P+roh4niznuVnSQkmryQZ7H4uII8Arki7Nr/65CrivuH+G1U1Kt80zK0rl5gFIuht4GHibpBFJH59q3zznOQQ8CTwIXBMRY/nmq4HbyAaGfwA8MMfYrcYajXROErOiNBppzQNomwKKiCvbbF816f02YFuL/YaBgRnGZ32qaktBmHUitTEAzwS2JHk5aKujk2MAifzlTSQMs1M1IpKZLGNWlIlB4DTqthsAS5JTQFZH44PAqVzi7AbAklTF+wGYtTN+T+B5idRtNwCWJM8DsDqauAy03DjGuQGwJI15HoDV0FgjraUg3ABYkhqNdE4Ss6JUfiawWS/4pvBWR54HYNYBzwOwOvI8ALMONCKSOUnMitJIbDlon2KWpAreEtKsrcotBmdWBqeArI7Cg8Bm7XkQ2OrIPQCzDjQindmSZkXxWkBmHfAYgNWR5wGYdSAbAyg7CrNinZwHkEjldgNgSRpreCkIq5/xpSAS+fvvBsDS5HkAVkeeB2DWgUakc5KYFcVLQZh1wMtBWx15ENi6Y88Q3DwAN56dPe8ZKjuiOWl4OWiDGtbr7DmVuj2/7ACsAHuG4GufhOOvZu+PHc7eA6zdVF5cc+A7glk96/X4GEDJgeTcA6iDXZ+fOEnGHX81K68o3xPY6livI7GJYJXsAfz09RN85+kXyw4jGR84NkKr6hTHRnho//M9j6cIx8cayZwkvXTw6Cv8cPQnZYeRhDrW68cP/wvgBmBOXnzldbZ+dXfZYSTjO2e+ieVnnN4gPtt4U6U/p7MXLSg7hJ77m8ef40+/ebDsMJJQ13oNsHhRGn9604hihi5YspCvf+JXyg4jGXHwszS+fR1nnJjoLjfmLyJ+9bN8/eer+TmdIfHWC95Ydhg997FfejMbBv512WEkoY71GmDJogVcuGRR2WEAFW0AFs6fx8CyJWWHkY5lvw3nnJXlRo+NwJLlnLH+Blas3cSKsmOzGblg8Ru4YPEbyg4jDa7XXVfJBsBaWLupsldGmE3J9bqrfBWQmVmfcgNgZtan3ACYmfUpNwBmZn3KDYCZWZ9yA2Bm1qfcAJg1kfTfJH1f0h5Jfy3p7KZt10s6KOkpSZc1lV8iaW++bbt8IwOrCDcAZqd6CBiIiLXA/wWuB5B0EbAZuBjYANwiaV5+zK3AVmBN/tjQ66DNZsMNgFmTiPj7iDiRv30EWJ6/3gjcExGvRcQh4CCwTtKFwOKIeDiypR7vBK7oddxms+EGwGxq/xF4IH+9DDjctG0kL1uWv55cfhpJWyUNSxoeHR3tQrhmM9O2AZB0u6SjkvY1lTlPapX1/ve/n4GBAQYGBgAulrQvf2wc30fSZ4ATwF3jRS1+VExTfnphxI6IGIyIwaVLl87tH2FWgE56AHdwek7TeVKo3e3q+sU3vvEN9u3bx759+wD2R8RA/rgPQNIW4MPAv4/xO3hk3+yb1yBbDjyXly9vUV5trtt9oW0DEBHfAl6aVOY86fjt6o4dBmLidnU+USpN0gbgD4GPRMRPmzbdD2yWtFDSarIvMY9FxBHgFUmX5r3aq4D7eh54kVy3+0YRYwCF5kkro4a3qzMA/hT4V8BDkp6Q9D8BImI/MAQ8CTwIXBMRY/kxVwO3kX3h+QET50M1uW73jTktB92NPGn+c7eSpYtYuXLlXELsnmMjMyu3SoiIn59m2zZgW4vyYWCgm3H1lOt235h1D6CbedJKDJYtWT6zcrOqcN3uG7NqAJwnBdbfAAsm3dZtwaKs3KzKXLf7RtsUkKS7gfcC50kaAT5HdtXPQrI8KcAjEfGfI2K/pPE86QlOz5PeASwiy5FWO086fpeiptvVsf4G373Iqs91u29oInuTpsHBwRgeHi47DKspSbsjYrDXv9f12rqp03rtmcBmZn2qmg2AJ6lYHbleW4/N6TLQUoxPUhm/Tnl8kgo4R2nV5XptJaheD8CTVKyOXK+tBNVrADxJxerI9dpKUL0GwJNUrI5cr60E1WsAPEnF6sj12kpQvQZg7Sa4fDssWQEoe758uwfKrNpcr60E1bsKCLKTwieG1Y3rtfVY9XoAZmZWCDcAZmZ9yg2AmVmfcgNgZtan3ACYmfWp5JeDljQK/HiKzecBL/YwnKmkEgekE0sqccD0sbw5Inp+27mK1GtIJ5ZU4oBqxLIGeDgiNkx3cPINwHQkDZexlnuqcUA6saQSB6QVSydSijeVWFKJA+oVi1NAZmZ9yg2AmVmfqnoDsKPsAHKpxAHpxJJKHJBWLJ1IKd5UYkklDqhRLJUeAzAzs9mreg/AzMxmyQ2AmVmfSrYBkPQ2SU80PV6WdK2kGyU921T+oaZjrpd0UNJTki4rMJZPS9ovaZ+kuyW9QdK5kh6S9HT+fE6345gmljI+k0/lMeyXdG1eVtZn0iqWnn8mHcaaTL3Of3YSdTuVep3/7P6p2xGR/AOYBzwPvBm4Efj9FvtcBHwPWAisBn4AzCvgdy8DDgGL8vdDwG8DXwCuy8uuA/64m3G0iaXXn8kAsA84i2xJ8W+QTTwp4zOZKpaefiZVq9cp1e1U6nU/1u1kewCTrAd+EBFTzZwE2AjcExGvRcQh4CCwrqDfPx9YJGk+2X/Gc/nv25lv3wlc0YM4poplKt2K5e3AIxHx04g4AfwT8BuU85lMFctUuv3/MxNl12tIp26nUK+hz+p2VRqAzcDdTe9/V9IeSbc3dcWWAYeb9hnJy+YkIp4Fvgg8AxwBjkXE3wMXRMSRfJ8jwPndjKNNLNDDz4TsW8l7JL1J0lnAh4AVlPCZTBML9PYzmY3S6jWkU7cTqtfQZ3U7+QZA0pnAR4C/yItuBd4CvIOssvzJ+K4tDp/zNa75h7uRrEv1s8DPSProdId0I442sfT0M4mIA8AfAw8BD5J1O09MF3o34mgTS08/k5kqu17nMSRRt1Op19B/dTv5BgD4IPDdiHgBICJeiIixiGgAf8ZEF2eEidYRYDnTdyM79X7gUESMRsRx4F7gl4EXJF0IkD8f7XIcU8ZSwmdCRHwlIt4VEe8BXgKeppzPpGUsZXwmM1R2vYZ06nYy9Rr6q25XoQG4kqZu8vh/Qu43yLpJAPcDmyUtlLSabLDksQJ+/zPApZLOkiSyvO2B/PdtyffZAtzX5TimjKWEzwRJ5+fPK4HfJPs/KuMzaRlLGZ/JDJVdryGdup1MvYY+q9tFjFZ360E2GPTPwJKmsq8Ce4E9+T/4wqZtnyEb+X4K+GCBcfwR8P38g/4q2Sj7m4BdZN8OdgHndjuOaWIp4zP5NvAkWbd0fV5W1mfSKpaefyZVq9cp1e1U6nW/1W0vBWFm1qeqkAIyM7MucANgZtan3ACYmfUpNwBmZn3KDYCZWZ9yA2Bm1qfcAJiZ9an/D1wfLmvjUz8jAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.subplot(121)\n",
    "y = list(map(F, x))\n",
    "plt.plot(x, y)\n",
    "plt.plot(data['sqfeet'], data['rent'], 'o')\n",
    "\n",
    "plt.subplot(122)\n",
    "y = list(map(fs[-1], x))\n",
    "plt.plot(x, y)\n",
    "plt.plot(data['sqfeet'], data['R_0'], 'o')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Adding improvements</div>\n",
    "\n",
    "<ul>\n",
    "    <li>Let us write a function that abstracts out the operations done so far</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [],
   "source": [
    "def add_improvement(i):\n",
    "    data[f'R_{i-1}'] = round(data['rent'] - data[f'F_{i-1}'], 1)\n",
    "    r = tree.DecisionTreeRegressor(max_depth=1)\n",
    "    r.fit(data[['sqfeet']], data[f'R_{i-1}'])\n",
    "\n",
    "    t = graphviz.Source(tree.export_graphviz(r,\n",
    "                                         out_file=None,\n",
    "                                         feature_names=data.columns[0:1],\n",
    "                                         rounded=True,\n",
    "                                         impurity=False))\n",
    "    \n",
    "    fs.append(lambda x: r.predict([[x]])[0])\n",
    "    data[f'F_{i}'] = round(data['sqfeet'].map(F), 1)\n",
    "    \n",
    "    plt.subplot(121)\n",
    "    y = list(map(F, x))\n",
    "    plt.plot(x, y)\n",
    "    plt.plot(data['sqfeet'], data['rent'], 'o', c='orange')\n",
    "    \n",
    "    plt.subplot(122)\n",
    "    y = list(map(fs[-1], x))\n",
    "    plt.plot(x, y)\n",
    "    plt.plot(data['sqfeet'], data[f'R_{i-1}'], 'o')\n",
    "    plt.show()\n",
    "    return t"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul>\n",
    "    <li>The function accepts as argument the index $i$ of $\\Delta_i$</li>\n",
    "    <li>computes $\\Delta_i$</li>\n",
    "    <li>draws the prediction and residual for the improved function</li>\n",
    "    <li>(globally) updates the <i>DataFrame</i> adding columns for the residual and\n",
    "        the improved function</li>\n",
    "    <li>and returns the learnt regression tree stump</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "t = add_improvement(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: Tree Pages: 1 -->\n",
       "<svg width=\"264pt\" height=\"135pt\"\n",
       " viewBox=\"0.00 0.00 263.50 135.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 131)\">\n",
       "<title>Tree</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-131 259.5,-131 259.5,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M179,-127C179,-127 69,-127 69,-127 63,-127 57,-121 57,-115 57,-115 57,-86 57,-86 57,-80 63,-74 69,-74 69,-74 179,-74 179,-74 185,-74 191,-80 191,-86 191,-86 191,-115 191,-115 191,-121 185,-127 179,-127\"/>\n",
       "<text text-anchor=\"middle\" x=\"124\" y=\"-111.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">sqfeet &lt;= 825.0</text>\n",
       "<text text-anchor=\"middle\" x=\"124\" y=\"-96.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 5</text>\n",
       "<text text-anchor=\"middle\" x=\"124\" y=\"-81.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = 0.0</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M100,-38C100,-38 12,-38 12,-38 6,-38 0,-32 0,-26 0,-26 0,-12 0,-12 0,-6 6,0 12,0 12,0 100,0 100,0 106,0 112,-6 112,-12 112,-12 112,-26 112,-26 112,-32 106,-38 100,-38\"/>\n",
       "<text text-anchor=\"middle\" x=\"56\" y=\"-22.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 2</text>\n",
       "<text text-anchor=\"middle\" x=\"56\" y=\"-7.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = &#45;92.5</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M102.11,-73.91C94.5,-65.01 85.96,-55.03 78.32,-46.09\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"80.76,-43.56 71.6,-38.24 75.44,-48.11 80.76,-43.56\"/>\n",
       "<text text-anchor=\"middle\" x=\"69.66\" y=\"-59.46\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">True</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M243.5,-38C243.5,-38 142.5,-38 142.5,-38 136.5,-38 130.5,-32 130.5,-26 130.5,-26 130.5,-12 130.5,-12 130.5,-6 136.5,0 142.5,0 142.5,0 243.5,0 243.5,0 249.5,0 255.5,-6 255.5,-12 255.5,-12 255.5,-26 255.5,-26 255.5,-32 249.5,-38 243.5,-38\"/>\n",
       "<text text-anchor=\"middle\" x=\"193\" y=\"-22.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 3</text>\n",
       "<text text-anchor=\"middle\" x=\"193\" y=\"-7.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = 61.667</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M146.21,-73.91C154.01,-64.92 162.78,-54.82 170.59,-45.82\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"173.26,-48.09 177.17,-38.24 167.97,-43.5 173.26,-48.09\"/>\n",
       "<text text-anchor=\"middle\" x=\"178.93\" y=\"-59.48\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">False</text>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.sources.Source at 0x7eff5d45e400>"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "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>sqfeet</th>\n",
       "      <th>rent</th>\n",
       "      <th>F_0</th>\n",
       "      <th>R_0</th>\n",
       "      <th>F_1</th>\n",
       "      <th>R_1</th>\n",
       "      <th>F_2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>750</td>\n",
       "      <td>1160</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-258.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>-112.5</td>\n",
       "      <td>1180.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>800</td>\n",
       "      <td>1200</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-218.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>-72.5</td>\n",
       "      <td>1180.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>850</td>\n",
       "      <td>1280</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-138.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>7.5</td>\n",
       "      <td>1334.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>900</td>\n",
       "      <td>1450</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>32.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>177.5</td>\n",
       "      <td>1334.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>950</td>\n",
       "      <td>2000</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>582.0</td>\n",
       "      <td>2000.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2061.7</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sqfeet  rent     F_0    R_0     F_1    R_1     F_2\n",
       "0     750  1160  1418.0 -258.0  1272.5 -112.5  1180.0\n",
       "1     800  1200  1418.0 -218.0  1272.5  -72.5  1180.0\n",
       "2     850  1280  1418.0 -138.0  1272.5    7.5  1334.2\n",
       "3     900  1450  1418.0   32.0  1272.5  177.5  1334.2\n",
       "4     950  2000  1418.0  582.0  2000.0    0.0  2061.7"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "t = add_improvement(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: Tree Pages: 1 -->\n",
       "<svg width=\"246pt\" height=\"135pt\"\n",
       " viewBox=\"0.00 0.00 245.50 135.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 131)\">\n",
       "<title>Tree</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-131 241.5,-131 241.5,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M172.5,-127C172.5,-127 62.5,-127 62.5,-127 56.5,-127 50.5,-121 50.5,-115 50.5,-115 50.5,-86 50.5,-86 50.5,-80 56.5,-74 62.5,-74 62.5,-74 172.5,-74 172.5,-74 178.5,-74 184.5,-80 184.5,-86 184.5,-86 184.5,-115 184.5,-115 184.5,-121 178.5,-127 172.5,-127\"/>\n",
       "<text text-anchor=\"middle\" x=\"117.5\" y=\"-111.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">sqfeet &lt;= 925.0</text>\n",
       "<text text-anchor=\"middle\" x=\"117.5\" y=\"-96.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 5</text>\n",
       "<text text-anchor=\"middle\" x=\"117.5\" y=\"-81.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = &#45;0.02</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M95,-38C95,-38 12,-38 12,-38 6,-38 0,-32 0,-26 0,-26 0,-12 0,-12 0,-6 6,0 12,0 12,0 95,0 95,0 101,0 107,-6 107,-12 107,-12 107,-26 107,-26 107,-32 101,-38 95,-38\"/>\n",
       "<text text-anchor=\"middle\" x=\"53.5\" y=\"-22.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 4</text>\n",
       "<text text-anchor=\"middle\" x=\"53.5\" y=\"-7.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = 15.4</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M96.9,-73.91C89.74,-65.01 81.7,-55.03 74.5,-46.09\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"77.18,-43.83 68.18,-38.24 71.73,-48.22 77.18,-43.83\"/>\n",
       "<text text-anchor=\"middle\" x=\"65.5\" y=\"-59.39\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">True</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M225.5,-38C225.5,-38 137.5,-38 137.5,-38 131.5,-38 125.5,-32 125.5,-26 125.5,-26 125.5,-12 125.5,-12 125.5,-6 131.5,0 137.5,0 137.5,0 225.5,0 225.5,0 231.5,0 237.5,-6 237.5,-12 237.5,-12 237.5,-26 237.5,-26 237.5,-32 231.5,-38 225.5,-38\"/>\n",
       "<text text-anchor=\"middle\" x=\"181.5\" y=\"-22.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 1</text>\n",
       "<text text-anchor=\"middle\" x=\"181.5\" y=\"-7.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = &#45;61.7</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M138.1,-73.91C145.26,-65.01 153.3,-55.03 160.5,-46.09\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"163.27,-48.22 166.82,-38.24 157.82,-43.83 163.27,-48.22\"/>\n",
       "<text text-anchor=\"middle\" x=\"169.5\" y=\"-59.39\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">False</text>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.sources.Source at 0x7eff5eaba0d0>"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "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>sqfeet</th>\n",
       "      <th>rent</th>\n",
       "      <th>F_0</th>\n",
       "      <th>R_0</th>\n",
       "      <th>F_1</th>\n",
       "      <th>R_1</th>\n",
       "      <th>F_2</th>\n",
       "      <th>R_2</th>\n",
       "      <th>F_3</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>750</td>\n",
       "      <td>1160</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-258.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>-112.5</td>\n",
       "      <td>1180.0</td>\n",
       "      <td>-20.0</td>\n",
       "      <td>1195.4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>800</td>\n",
       "      <td>1200</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-218.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>-72.5</td>\n",
       "      <td>1180.0</td>\n",
       "      <td>20.0</td>\n",
       "      <td>1195.4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>850</td>\n",
       "      <td>1280</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-138.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>7.5</td>\n",
       "      <td>1334.2</td>\n",
       "      <td>-54.2</td>\n",
       "      <td>1349.6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>900</td>\n",
       "      <td>1450</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>32.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>177.5</td>\n",
       "      <td>1334.2</td>\n",
       "      <td>115.8</td>\n",
       "      <td>1349.6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>950</td>\n",
       "      <td>2000</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>582.0</td>\n",
       "      <td>2000.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2061.7</td>\n",
       "      <td>-61.7</td>\n",
       "      <td>2000.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sqfeet  rent     F_0    R_0     F_1    R_1     F_2    R_2     F_3\n",
       "0     750  1160  1418.0 -258.0  1272.5 -112.5  1180.0  -20.0  1195.4\n",
       "1     800  1200  1418.0 -218.0  1272.5  -72.5  1180.0   20.0  1195.4\n",
       "2     850  1280  1418.0 -138.0  1272.5    7.5  1334.2  -54.2  1349.6\n",
       "3     900  1450  1418.0   32.0  1272.5  177.5  1334.2  115.8  1349.6\n",
       "4     950  2000  1418.0  582.0  2000.0    0.0  2061.7  -61.7  2000.0"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "t = add_improvement(4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: Tree Pages: 1 -->\n",
       "<svg width=\"264pt\" height=\"135pt\"\n",
       " viewBox=\"0.00 0.00 263.50 135.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 131)\">\n",
       "<title>Tree</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-131 259.5,-131 259.5,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M188,-127C188,-127 78,-127 78,-127 72,-127 66,-121 66,-115 66,-115 66,-86 66,-86 66,-80 72,-74 78,-74 78,-74 188,-74 188,-74 194,-74 200,-80 200,-86 200,-86 200,-115 200,-115 200,-121 194,-127 188,-127\"/>\n",
       "<text text-anchor=\"middle\" x=\"133\" y=\"-111.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">sqfeet &lt;= 875.0</text>\n",
       "<text text-anchor=\"middle\" x=\"133\" y=\"-96.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 5</text>\n",
       "<text text-anchor=\"middle\" x=\"133\" y=\"-81.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = 0.0</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M118,-38C118,-38 12,-38 12,-38 6,-38 0,-32 0,-26 0,-26 0,-12 0,-12 0,-6 6,0 12,0 12,0 118,0 118,0 124,0 130,-6 130,-12 130,-12 130,-26 130,-26 130,-32 124,-38 118,-38\"/>\n",
       "<text text-anchor=\"middle\" x=\"65\" y=\"-22.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 3</text>\n",
       "<text text-anchor=\"middle\" x=\"65\" y=\"-7.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = &#45;33.467</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M111.11,-73.91C103.5,-65.01 94.96,-55.03 87.32,-46.09\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"89.76,-43.56 80.6,-38.24 84.44,-48.11 89.76,-43.56\"/>\n",
       "<text text-anchor=\"middle\" x=\"78.66\" y=\"-59.46\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">True</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M243.5,-38C243.5,-38 160.5,-38 160.5,-38 154.5,-38 148.5,-32 148.5,-26 148.5,-26 148.5,-12 148.5,-12 148.5,-6 154.5,0 160.5,0 160.5,0 243.5,0 243.5,0 249.5,0 255.5,-6 255.5,-12 255.5,-12 255.5,-26 255.5,-26 255.5,-32 249.5,-38 243.5,-38\"/>\n",
       "<text text-anchor=\"middle\" x=\"202\" y=\"-22.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 2</text>\n",
       "<text text-anchor=\"middle\" x=\"202\" y=\"-7.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = 50.2</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M155.21,-73.91C163.01,-64.92 171.78,-54.82 179.59,-45.82\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"182.26,-48.09 186.17,-38.24 176.97,-43.5 182.26,-48.09\"/>\n",
       "<text text-anchor=\"middle\" x=\"187.93\" y=\"-59.48\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">False</text>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.sources.Source at 0x7eff604f4a60>"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "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>sqfeet</th>\n",
       "      <th>rent</th>\n",
       "      <th>F_0</th>\n",
       "      <th>R_0</th>\n",
       "      <th>F_1</th>\n",
       "      <th>R_1</th>\n",
       "      <th>F_2</th>\n",
       "      <th>R_2</th>\n",
       "      <th>F_3</th>\n",
       "      <th>R_3</th>\n",
       "      <th>F_4</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>750</td>\n",
       "      <td>1160</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-258.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>-112.5</td>\n",
       "      <td>1180.0</td>\n",
       "      <td>-20.0</td>\n",
       "      <td>1195.4</td>\n",
       "      <td>-35.4</td>\n",
       "      <td>1161.9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>800</td>\n",
       "      <td>1200</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-218.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>-72.5</td>\n",
       "      <td>1180.0</td>\n",
       "      <td>20.0</td>\n",
       "      <td>1195.4</td>\n",
       "      <td>4.6</td>\n",
       "      <td>1161.9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>850</td>\n",
       "      <td>1280</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-138.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>7.5</td>\n",
       "      <td>1334.2</td>\n",
       "      <td>-54.2</td>\n",
       "      <td>1349.6</td>\n",
       "      <td>-69.6</td>\n",
       "      <td>1316.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>900</td>\n",
       "      <td>1450</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>32.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>177.5</td>\n",
       "      <td>1334.2</td>\n",
       "      <td>115.8</td>\n",
       "      <td>1349.6</td>\n",
       "      <td>100.4</td>\n",
       "      <td>1399.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>950</td>\n",
       "      <td>2000</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>582.0</td>\n",
       "      <td>2000.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2061.7</td>\n",
       "      <td>-61.7</td>\n",
       "      <td>2000.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2050.2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sqfeet  rent     F_0    R_0     F_1    R_1     F_2    R_2     F_3    R_3  \\\n",
       "0     750  1160  1418.0 -258.0  1272.5 -112.5  1180.0  -20.0  1195.4  -35.4   \n",
       "1     800  1200  1418.0 -218.0  1272.5  -72.5  1180.0   20.0  1195.4    4.6   \n",
       "2     850  1280  1418.0 -138.0  1272.5    7.5  1334.2  -54.2  1349.6  -69.6   \n",
       "3     900  1450  1418.0   32.0  1272.5  177.5  1334.2  115.8  1349.6  100.4   \n",
       "4     950  2000  1418.0  582.0  2000.0    0.0  2061.7  -61.7  2000.0    0.0   \n",
       "\n",
       "      F_4  \n",
       "0  1161.9  \n",
       "1  1161.9  \n",
       "2  1316.1  \n",
       "3  1399.8  \n",
       "4  2050.2  "
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "t = add_improvement(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.43.0 (0)\n",
       " -->\n",
       "<!-- Title: Tree Pages: 1 -->\n",
       "<svg width=\"264pt\" height=\"135pt\"\n",
       " viewBox=\"0.00 0.00 263.50 135.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 131)\">\n",
       "<title>Tree</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-131 259.5,-131 259.5,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M185.5,-127C185.5,-127 75.5,-127 75.5,-127 69.5,-127 63.5,-121 63.5,-115 63.5,-115 63.5,-86 63.5,-86 63.5,-80 69.5,-74 75.5,-74 75.5,-74 185.5,-74 185.5,-74 191.5,-74 197.5,-80 197.5,-86 197.5,-86 197.5,-115 197.5,-115 197.5,-121 191.5,-127 185.5,-127\"/>\n",
       "<text text-anchor=\"middle\" x=\"130.5\" y=\"-111.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">sqfeet &lt;= 925.0</text>\n",
       "<text text-anchor=\"middle\" x=\"130.5\" y=\"-96.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 5</text>\n",
       "<text text-anchor=\"middle\" x=\"130.5\" y=\"-81.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = 0.02</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M113,-38C113,-38 12,-38 12,-38 6,-38 0,-32 0,-26 0,-26 0,-12 0,-12 0,-6 6,0 12,0 12,0 113,0 113,0 119,0 125,-6 125,-12 125,-12 125,-26 125,-26 125,-32 119,-38 113,-38\"/>\n",
       "<text text-anchor=\"middle\" x=\"62.5\" y=\"-22.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 4</text>\n",
       "<text text-anchor=\"middle\" x=\"62.5\" y=\"-7.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = 12.575</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M108.61,-73.91C101,-65.01 92.46,-55.03 84.82,-46.09\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"87.26,-43.56 78.1,-38.24 81.94,-48.11 87.26,-43.56\"/>\n",
       "<text text-anchor=\"middle\" x=\"76.16\" y=\"-59.46\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">True</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M243.5,-38C243.5,-38 155.5,-38 155.5,-38 149.5,-38 143.5,-32 143.5,-26 143.5,-26 143.5,-12 143.5,-12 143.5,-6 149.5,0 155.5,0 155.5,0 243.5,0 243.5,0 249.5,0 255.5,-6 255.5,-12 255.5,-12 255.5,-26 255.5,-26 255.5,-32 249.5,-38 243.5,-38\"/>\n",
       "<text text-anchor=\"middle\" x=\"199.5\" y=\"-22.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 1</text>\n",
       "<text text-anchor=\"middle\" x=\"199.5\" y=\"-7.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = &#45;50.2</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M152.71,-73.91C160.51,-64.92 169.28,-54.82 177.09,-45.82\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"179.76,-48.09 183.67,-38.24 174.47,-43.5 179.76,-48.09\"/>\n",
       "<text text-anchor=\"middle\" x=\"185.43\" y=\"-59.48\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">False</text>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.sources.Source at 0x7eff5e737b20>"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "scrolled": true
   },
   "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>sqfeet</th>\n",
       "      <th>rent</th>\n",
       "      <th>F_0</th>\n",
       "      <th>R_0</th>\n",
       "      <th>F_1</th>\n",
       "      <th>R_1</th>\n",
       "      <th>F_2</th>\n",
       "      <th>R_2</th>\n",
       "      <th>F_3</th>\n",
       "      <th>R_3</th>\n",
       "      <th>F_4</th>\n",
       "      <th>R_4</th>\n",
       "      <th>F_5</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>750</td>\n",
       "      <td>1160</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-258.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>-112.5</td>\n",
       "      <td>1180.0</td>\n",
       "      <td>-20.0</td>\n",
       "      <td>1195.4</td>\n",
       "      <td>-35.4</td>\n",
       "      <td>1161.9</td>\n",
       "      <td>-1.9</td>\n",
       "      <td>1174.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>800</td>\n",
       "      <td>1200</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-218.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>-72.5</td>\n",
       "      <td>1180.0</td>\n",
       "      <td>20.0</td>\n",
       "      <td>1195.4</td>\n",
       "      <td>4.6</td>\n",
       "      <td>1161.9</td>\n",
       "      <td>38.1</td>\n",
       "      <td>1174.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>850</td>\n",
       "      <td>1280</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>-138.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>7.5</td>\n",
       "      <td>1334.2</td>\n",
       "      <td>-54.2</td>\n",
       "      <td>1349.6</td>\n",
       "      <td>-69.6</td>\n",
       "      <td>1316.1</td>\n",
       "      <td>-36.1</td>\n",
       "      <td>1328.7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>900</td>\n",
       "      <td>1450</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>32.0</td>\n",
       "      <td>1272.5</td>\n",
       "      <td>177.5</td>\n",
       "      <td>1334.2</td>\n",
       "      <td>115.8</td>\n",
       "      <td>1349.6</td>\n",
       "      <td>100.4</td>\n",
       "      <td>1399.8</td>\n",
       "      <td>50.2</td>\n",
       "      <td>1412.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>950</td>\n",
       "      <td>2000</td>\n",
       "      <td>1418.0</td>\n",
       "      <td>582.0</td>\n",
       "      <td>2000.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2061.7</td>\n",
       "      <td>-61.7</td>\n",
       "      <td>2000.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2050.2</td>\n",
       "      <td>-50.2</td>\n",
       "      <td>2000.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sqfeet  rent     F_0    R_0     F_1    R_1     F_2    R_2     F_3    R_3  \\\n",
       "0     750  1160  1418.0 -258.0  1272.5 -112.5  1180.0  -20.0  1195.4  -35.4   \n",
       "1     800  1200  1418.0 -218.0  1272.5  -72.5  1180.0   20.0  1195.4    4.6   \n",
       "2     850  1280  1418.0 -138.0  1272.5    7.5  1334.2  -54.2  1349.6  -69.6   \n",
       "3     900  1450  1418.0   32.0  1272.5  177.5  1334.2  115.8  1349.6  100.4   \n",
       "4     950  2000  1418.0  582.0  2000.0    0.0  2061.7  -61.7  2000.0    0.0   \n",
       "\n",
       "      F_4   R_4     F_5  \n",
       "0  1161.9  -1.9  1174.5  \n",
       "1  1161.9  38.1  1174.5  \n",
       "2  1316.1 -36.1  1328.7  \n",
       "3  1399.8  50.2  1412.3  \n",
       "4  2050.2 -50.2  2000.0  "
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "t = add_improvement(6)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Incremental shrinkage</div>\n",
    "\n",
    "<p>i.e., adding a <i>learning rate</i> $\\eta > 0$:</p>\n",
    "\n",
    "$$F_M(x) = f_0(x) + \\eta \\sum_{i=1}^M \\Delta_i(x)$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gradient_boosting(X, y, M, eta=1):\n",
    "    base = y.mean()\n",
    "    f0  = lambda x: base\n",
    "    rs = [None] * M\n",
    "    F = lambda x: f0(x)\n",
    "\n",
    "    for i in range(1, M+1):\n",
    "        fval = [np.round(F(x), 1) for x in X['sqfeet']]\n",
    "        \n",
    "        residual = round(y - fval, 1)\n",
    "        rs[i-1] = tree.DecisionTreeRegressor(max_depth=1)\n",
    "        rs[i-1].fit(X, residual)\n",
    "        \n",
    "        \n",
    "        #deltafunc = lambda x: rs[i-1].predict([[x]])[0]\n",
    "        F = lambda x: f0(x) + eta * sum([rs[j-1].predict([[x]])[0]\n",
    "                                         for j in range(1, i)])\n",
    "        \n",
    "\n",
    "    return np.vectorize(lambda x: F(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">A sanity check</div>\n",
    "<p>Let's use $\\eta = 1$</p>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAD4CAYAAAAAczaOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAXNUlEQVR4nO3dbZBc1X3n8e9PM5JgBBiMBhfRAzNxRCrA+iEoKpKUs7ZxAnE5hiSbXVHKwlZS0YZlU7Z3sxsTquzkhaocx1lXeAEp7ZrCuGSIUnEMb0jMerfMbi1YJTtgEA/WsGPkMYpGYxJbw5iZfvjnxT0ttUY9j+qZe6fP71PVNd3/e3vmf6+u/n363HPuVURgZmZ5WFd2AmZmtnpc9M3MMuKib2aWERd9M7OMuOibmWWkv+wEFrJ58+YYGhoqOw0zszXlG9/4xkREDM6OV77oDw0Ncfjw4bLTMDNbUyS92inu7h0zs4y46JuZZcRF38wsIy76ZmYZcdE3M8uIi76ZWUZc9M3MMlL5cfpmZivpB1M1vvD0d5ipN8tO5Ry/d+MO1vd1t23uom9mWftfL5/gM1/5NgBSycnM8h/e9xOs7+vu73TRN7OsTdeKFv7/+/j7+bFLLyw5m5XnPn0zy1qtWdw9sL+vYs38FeKib2ZZq6W+/A1d7juvqjy20sxsDvVmUfT7XfTNzHpfrVF076x3946ZWe+rNYqW/vp1eZTDPLbSzGwO9UbQt06sW+eWPgCStkn635JelHRE0kdS/K2SnpB0NP28rO09d0sakfSypJva4tdLei4tu1eq2qhYM8tNrdGkv0oFf/QAfHkIvriu+Dl6oKu/fjEt/TrwnyPip4AbgLskXQN8HPhqROwAvppek5btBq4Fbgbuk9SaXnA/sBfYkR43d3FbzMyWrNaI6ozcGT0Ah/bC1KtAFD8P7e1q4V9wSyPieER8Mz0/BbwIbAFuAT6fVvs8cGt6fgvwSERMR8QoMALsknQlcElEPBURATzU9h4zs1LUGs3qjNF/9h5oTJ0da0wV8S5Z0sebpCHg3cDXgbdFxHEoPhiAK9JqW4Dvtr1tLMW2pOez453+zl5JhyUdPnny5FJSNDNbknqzWZ3hmlPHlhZfhkVvqaSLgL8GPhoRP5xv1Q6xmCd+bjBif0TsjIidg4Pn3MzdzKxrZuoV6t4Z2L60+DIsakslraco+Aci4kspfCJ12ZB+jqf4GLCt7e1bgddSfGuHuJlZaYqWfkW6d965D/oGzo71DRTxLlnM6B0BnwNejIj/1rboMeCO9PwO4NG2+G5JGyUNU5ywPZS6gE5JuiH9ztvb3mNmVopao9n1yxcv2/Ae2LUfBq4CVPzctb+Id8lirrL588C/BZ6T9EyK/SHwKeCgpN8GjgG/ARARRyQdBF6gGPlzV0Q00vvuBB4ELgQeTw8zs9LUGlGtIZvDe7pa5GdbsOhHxP+lc388wI1zvGcfcM73kYg4DFy3lATNzFZSvdFkQ39FWvqrIJ8tNTProHIt/RXmom9mWatUn/4qyGdLzcw6cNE3M8tIvRnZXFYZXPTNLHMz9QrNyF0F+WypmVkHbumbmWXEffpmZhmpN4L+TO6aBS76Zpa5WqPJhn5375iZZaG4c1Y+pTCfLTUz66DeCPfpm5nlYqbR9OgdM7NcFEM28ymF+WypmdkszWbQaEZ1bqKyClz0zSxbtWYTwC19M7Mc1BrFbbrdp29mloF6o2jpe8immVkGZlLRX+87Z5mZ9b56q3vHd84yM+t9p4u+T+SamfW+VveOh2yamWWgnoZsbnBL38ys99XqRfeO75xlZpaBM5Oz3L1jZtbzanXPyDUzy0a9mbp3PGTTzKz3eXKWmVlGzkzOyqcU5rOlZmaz1E+39N29Y2bW82Z8wTUzs3y0unc8OcvMLAM1X4bBzCwftaYvuGZmlo0zk7Pc0jcz63mtC6752jtmZhnwPXI7kPSApHFJz7fF3iXpaUnPSDosaVfbsrsljUh6WdJNbfHrJT2Xlt0rKZ+9bGaV1DqR68lZZ3sQuHlW7NPAH0fEu4BPpNdIugbYDVyb3nOfpL70nvuBvcCO9Jj9O83MVlWt0aRvnVjna++cERFPAq/PDgOXpOdvAV5Lz28BHomI6YgYBUaAXZKuBC6JiKciIoCHgFu7kL+Z2bLVG5HVxdYA+pf5vo8CfyfpMxQfHD+X4luAp9vWG0uxWno+O96RpL0U3wrYvn37MlM0M5tfrRFZTcyC5Z/IvRP4WERsAz4GfC7FO31kxjzxjiJif0TsjIidg4ODy0zRzGx+tUYzq4lZsPyifwfwpfT8r4DWidwxYFvbelspun7G0vPZcTOz0tSbzawmZsHyi/5rwL9Mz98PHE3PHwN2S9ooaZjihO2hiDgOnJJ0Qxq1czvw6HnkbWZ23mbqkV3RX7BPX9LDwHuBzZLGgE8CvwP8uaR+4E1S/3tEHJF0EHgBqAN3RUQj/ao7KUYCXQg8nh5mZqWpN/Pr3lmw6EfEbXMsun6O9fcB+zrEDwPXLSk7M7MVVGu4e8fMLBu1DIdsuuibWbZqjSYbMro/Lrjom1nGcpyc5aJvZtlyn76ZWUZc9M3MMlJvRlaXVQYXfTPL2Ey9mdUNVMBF38wyVm/6gmtmZtnwBdfMzDJSDNnMqwzmtbVmZm1mGk029Lulb2aWhXqj6Za+mVku6o38Lq2c19aambWZaTQ9Tt/MLBfF5Ky8ymBeW2tmljSbQaMZHrJpZpaDWrMJ4Ja+mVkOao0AcJ++mVkO6o2ipe8hm2ZmGZhJRX+975xlZtb76q3uHd85y8ys99UaPpFrZpaN1olcD9k0M8tAPQ3Z9PX0zcwyUKu3Wvp5lcG8ttbMLDkzOcvdO2ZmPa9W94lcM7Ns1JutGbl5lcG8ttbMLGlNzvLoHTOzDJyZnJVXGcxra83MktOTs3yPXDOz3lfzBdfMzPLR6t7x5CwzswzUfCLXzCwfNQ/Z7EzSA5LGJT0/K/57kl6WdETSp9vid0saSctuaotfL+m5tOxeSXl9vJpZpZyZnJVXKVrMR9yDwM3tAUnvA24B3hER1wKfSfFrgN3Atek990nqS2+7H9gL7EiPs36nmdlqqvseuZ1FxJPA67PCdwKfiojptM54it8CPBIR0xExCowAuyRdCVwSEU9FRAAPAbd2aRvMzJbMl1ZemquB90j6uqSvSfqZFN8CfLdtvbEU25Kez453JGmvpMOSDp88eXKZKZqZze30OH0P2VyUfuAy4AbgvwAHUx99p4/MmCfeUUTsj4idEbFzcHBwmSmamc2t1mjSt06s8+0SF2UM+FIUDgFNYHOKb2tbbyvwWopv7RA3MytFvRH0Z1bwYflF/8vA+wEkXQ1sACaAx4DdkjZKGqY4YXsoIo4DpyTdkL4R3A48er7Jm5kt10yjmd3ELCi6aeYl6WHgvcBmSWPAJ4EHgAfSMM4Z4I50gvaIpIPAC0AduCsiGulX3UkxEuhC4PH0MDMrRb0R2Z3EhUUU/Yi4bY5FvznH+vuAfR3ih4HrlpSdmdkKqTeb2Q3XBM/INbNMzdTDRd/MLBdFSz+/7h0XfTPLUq3RpN8tfTOzPNQ8ZNPMLB+1RpMN/fmVwPy22MwMT84yM8vKTMNDNs3MslF30Tczy0e9GR6yaWaWi5m6h2yamWWj3owsL7iW3xabmdGanOXuHTOzLNQbvvaOmVk2iiGbbumbmWWh3mjSn9n9ccFF38wyVXP3jplZPmru3jEzy0cxOSu/EpjfFptZ9prNoNHM8x65Lvpmlp1aswnglr6ZWQ5qjQBwn76ZWQ7qDbf0zcyyMZOKvi+4ZmaWgXqre8d3zjIz6301d++Yma2Q0QPw5SH44rri5+iBsjM6fSI3xyGb/WUnYGY9bPQAHNoLjani9dSrxWuA4T2lpdVq6ft6+mZm3fTsPWcKfktjqoiXqH66pZ9fCcxvi81s9UwdW1p8lZyZnJVf946LvpmtnIHtS4uvklrdJ3LNzLrvnfugb+DsWN9AES9RvdmakZtfCcxvi81s9QzvgV37YeAqQMXPXftLPYkL7ZOz8uve8egdM1tZw3tKL/KztU7kevSOmVkGahm39F30zSw7p4u+75F7LkkPSBqX9HyHZb8vKSRtbovdLWlE0suSbmqLXy/pubTsXkn5fcSaWSXU3L0zrweBm2cHJW0DfhE41ha7BtgNXJvec5+kvrT4fmAvsCM9zvmdZmaroZ5x986CJ3Ij4klJQx0WfRb4r8CjbbFbgEciYhoYlTQC7JL0HeCSiHgKQNJDwK3A4+eVvZmd443pOtNpHLp19oMf1YA8h2wua/SOpA8D34uIZ2f10mwBnm57PZZitfR8dtzMuuiVk5Pc9NknT49Dt/ldsN5Ff0GSBoB7gF/qtLhDLOaJz/U39lJ0BbF9e7kz98zWkr8/9k/Um8HHPnA1lw6sLzudSrvyLRdw8QX57aPltPTfDgwDrVb+VuCbknZRtOC3ta27FXgtxbd2iHcUEfuB/QA7d+50k8VskY6On2JD3zruet/bs7yYmC1syUdFRDwXEVdExFBEDFEU9J+OiH8AHgN2S9ooaZjihO2hiDgOnJJ0Qxq1cztnnwswsy44emKSHx/c5IJvc1rMkM2HgaeAn5Q0Jum351o3Io4AB4EXgL8F7oqIRlp8J/A/gBHgFXwS16zrjo6fYsfbLi47DauwxYzeuW2B5UOzXu8DzrmaUkQcBq5bYn5mtkhTM3XG/vFH/Mb12xZe2bLl74BmPeKV8TeIgB1XXFR2KlZhLvpmPeLo+CkAd+/YvFz0zXrE0fFJ1veJqy4fWHhly5aLvlmPOHriFMObN2U5y9QWz0eHWY84Oj7prh1bkIu+WQ94s9bg2OtTPolrC3LRN+sBI+OTaeSOW/o2Pxd9sx4wMj4JwNVvc0vf5ueib9YDjo6fon+duOryTWWnYhXnom/WA759YpKhzZvY0O//0jY/HyFmPWBkfNJdO7YoLvpma9ybtQavfv8NfsIncW0RlnXnLLMyPPrM9xideKPsNCrnn6ZqNH3NHVskF31bE96sNfjII8+UnUZlXbSxn3dvv7TsNGwNcNG3NeHkqWkAPvVr/4J/8zO+dHAns+5XbdaRi76tCROTRdEfvHiji5vZefCJXFsTJiZnANh80caSMzFb21z0bU1otfQ3X+yib3Y+XPRtTZhIffqXb9pQcibA6AH48hB8cV3xc/RA2RmZLZr79G1NmJic5uIL+rlgfV+5iYwegEN7oTFVvJ56tXgNMLynvLzMFsktfVsTJiZnGKxCf/6z95wp+C2NqSJutga46NuacHJyuhoncaeOLS1uVjEu+rYmTExOs/niCvTnD2xfWtysYlz0bU2YOFWRlv4790HfrBuP9w0UcbM1wEXfKm+63uCHb9arUfSH98Cu/TBwFaDi5679Polra4ZH71jlfb9qE7OG97jI25rllr5V3umJWRdVoE/fbI1z0bfK82xcs+5x0bfKmzhVdO9UYpy+2Rrnom+Vd/J0946Lvtn5ctG3ypuYnGbThj4u3FDyJRjMeoCLvlXexOSM+/PNusRF3yqvMhOzzHqAi75V3sTktIdrmnWJi75V3kRVLrZm1gNc9K3Sao0m/zhVc9E365IFi76kBySNS3q+Lfankl6S9C1JfyPp0rZld0sakfSypJva4tdLei4tu1e+u3V1VPhOUK+/kS7B4BO5Zl2xmJb+g8DNs2JPANdFxDuAbwN3A0i6BtgNXJvec5+k1ji7+4G9wI70mP07rQytO0FNvQrEmTtBVaTwn0y3SRx0n75ZVyxY9CPiSeD1WbGvREQ9vXwa2Jqe3wI8EhHTETEKjAC7JF0JXBIRT0VEAA8Bt3ZpG+x8VPxOUBOemGXWVd3o0/8t4PH0fAvw3bZlYym2JT2fHe9I0l5JhyUdPnnyZBdStDlV/E5QE1W7wqbZGndeRV/SPUAdaPUFdOqnj3niHUXE/ojYGRE7BwcHzydFW0jF7wTli62Zddeyi76kO4APAXtSlw0ULfhtbattBV5L8a0d4la2it8JauLUNBesX8cmX4LBrCuWVfQl3Qz8AfDhiGjvEH4M2C1po6RhihO2hyLiOHBK0g1p1M7twKPnmbt1Q8XvBNUao+/BXmbdseCdsyQ9DLwX2CxpDPgkxWidjcAT6T/j0xHxuxFxRNJB4AWKbp+7IqKRftWdFCOBLqQ4B/A4Vg0VvhPUxOSM+/PNumjBoh8Rt3UIf26e9fcB5/QNRMRh4LolZWfZm5icZutlAwuvaGaL0pszcis82ciWZmJymsGLPUbfrFt678borclGrbHnU6/S+PrvMHLiFBOb/1W5udmSRBQzct29Y9Y9vVf0O0w26mv+iE0vfYKbXto2x5usyra5e8esa3qv6M8xqWjLhgkO/vufXeVk7Hz194l3bHlL2WmY9YzeK/oD29N1ZM6mge3sGn5rCQmZmVVH753IrfhkIzOzMvVe0a/4ZCMzszL1XvcOVHqykZlZmXqvpW9mZnNy0Tczy4iLvplZRlz0zcwy4qJvZpYRnbn/STVJOgmcO9tqcTYDE11Mp1uc19I4r6VxXkvTq3ldFRHn3Hqw8kX/fEg6HBE7y85jNue1NM5raZzX0uSWl7t3zMwy4qJvZpaRXi/6+8tOYA7Oa2mc19I4r6XJKq+e7tM3M7Oz9XpL38zM2rjom5llZM0WfUk/KemZtscPJX1U0h9J+l5b/INt77lb0oiklyXdtMp5/WVb7DuSnknrD0n6Uduyv1iJvNLf+pikI5Kel/SwpAskvVXSE5KOpp+Xta2/4vtrnrz+VNJLkr4l6W8kXZrWLXt/lXp8zZNXFY6vj6Scjkj6aIpV4fjqlFcVjq9Oea388RURa/4B9AH/AFwF/BHw+x3WuQZ4FtgIDAOvAH2rldes+J8Bn0jPh4DnV2EfbQFGgQvT64PAvwM+DXw8xT4O/Mlq7q958voloD/F/qQtr7L3V6nH11x5VeD4ug54HhiguGT7/wR2VOD4miuvso+vufJa8eNrzbb0Z7kReCUi5pu5ewvwSERMR8QoMALsWu28JAn418DDK/y3O+kHLpTUT3GwvUaxXz6fln8euDU9X839dU5eEfGViKin5U8DW1foby8pr3nWLXV/tRaUeHz9FPB0REylf7evAb9K+cdXx7wqcHzNtb/m0rX91StFfzdnH+T/MX1te6Dt6+QW4Ltt64yl2GrmBfAe4EREHG2LDUv6e0lfk/SelUgkIr4HfAY4BhwHfhARXwHeFhHH0zrHgSvSW1Zlf82TV7vfAh5ve13m/oISj69F7K9Sji+KVusvSLpc0gDwQWAbJR9f8+TVbtWPrwXyWtHja80XfUkbgA8Df5VC9wNvB95F8Z/iz1qrdnj7io1X7ZBXy22c/UFwHNgeEe8G/hPwRUmXrEA+l1G0FoaBHwM2SfrN+d7SIdb1/bVQXpLuAerAgRQqe3+Venwt4t+xlOMrIl6k6CZ5Avhbiq6I+jxvWZX9tVBeZR1f8+S14sfXmi/6wC8D34yIEwARcSIiGhHRBP47Z74CjXH2J/xW5v+63tW8ANLX8V8D/rIVS1/Xvp+ef4Oir+7qFcjnA8BoRJyMiBrwJeDngBOSrkz5XQmMp/VXa3/NlReS7gA+BOyJ1LFZ9v6qwPE13/4q8/giIj4XET8dEb8AvA4cpfzja668yj6+Oua1GsdXLxT9s1o2rQMs+VWKr1EAjwG7JW2UNExx0uTQauWVfAB4KSLG2vIdlNSXnv94yuv/r0A+x4AbJA2kft8bgRcp9ssdaZ07gEfT89XaXx3zknQz8AfAhyNiqrVy2furAsfXXP+OUO7xhaQr0s/tFB8+D1P+8dUxrwocX3PltfLH1/mehS7zQXES6/vAW9piXwCeA76VdtSVbcvuofjkfhn45dXMK8UfBH53VuzXgSMUX+++CfzKCub1x8BL6UD6AsVIgMuBr1K0fr4KvLWE/dUprxGKPsxn0uMvKrK/qnB8nZNXRY6v/wO8kP7WjSlWheOrU15VOL465bXix5cvw2BmlpFe6N4xM7NFctE3M8uIi76ZWUZc9M3MMuKib2aWERd9M7OMuOibmWXknwGxvjes8JVirwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "F = gradient_boosting(data[['sqfeet']], data['rent'], 5, 1)\n",
    "\n",
    "plt.plot(x, list(map(F, x)))\n",
    "plt.plot(data['sqfeet'], data['rent'], 'o', color='orange')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">How do we evaluate our results</div>\n",
    "\n",
    "<ul>\n",
    "    <li>Using a <i>loss function</i></li>\n",
    "    <li>In this case, $\\mathrm{MSE}$:\n",
    "        $$ L(\\mathbf x, \\mathbf y, F_m) = \\mathrm{MSE}(\\mathbf x, \\mathbf y, F_m)\n",
    "         = \\frac{1}{n} \\sum_{i=1}^n \\left(y_i - F_m(x_i) \\right)^2 $$\n",
    "        where $\\mathbf x$ and $\\mathbf y$ gather all observations and labels</li>\n",
    "    <li>(we'll see that this is a suitable choice among various possibilities)</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1559.2202222222172"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import mean_squared_error\n",
    "\n",
    "mean_squared_error(data['rent'], F(data['sqfeet']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Hyperparameters</div>\n",
    "\n",
    "<ul>\n",
    "    <li>How do we choose $M$ and $\\eta$?</li>\n",
    "    <li>Evluating our loss function over a grid</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [],
   "source": [
    "Ms = [1, 2, 3, 4]\n",
    "etas = [.6, .7, .8, .9]\n",
    "\n",
    "def get_mse(X, y, M, eta):\n",
    "    F = gradient_boosting(X, y, M, eta)\n",
    "    return mean_squared_error(F(X), y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYwAAAD8CAYAAABkbJM/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABILUlEQVR4nO3deXiU9bnw8e+dyUpWMgmEsGcBBBQECogLytIAYghhEahHe9yrp6fntOfteq5Tz9L3nPZ9W9/aVlu3qrVhEQIEJLIImoqIgIKCrGERSEggQEggQEh+7x/PzDAJk4VkMjNJ7s915WLym+eZ58445s7z224xxqCUUko1JcjfASillGofNGEopZRqFk0YSimlmkUThlJKqWbRhKGUUqpZNGEopZRqliYThoj0FpFNIrJXRPaIyPcc7fEisl5EDjr+7ep2zk9E5JCI7BeRDLf2kSLypeO5F0REHO1hIrLY0b5VRPq1wc+qlFKqFZpzh3EN+IEx5hZgLPCsiAwGfgy8b4xJB953fI/juXnAEGAK8KKI2Byv9RLwJJDu+JriaH8MOGeMSQOeB37phZ9NKaWUFzWZMIwxxcaYzxyPK4C9QE9gBvCm47A3gSzH4xnAImPMFWPMEeAQMFpEegAxxpgtxlot+Fa9c5yvtRSY6Lz7UEopFRiCb+ZgR1fR7cBWoLsxphispCIi3RyH9QQ+cTvthKOt2vG4frvznOOO17omIuWAHThT7/pPYt2hEBkZOXLQoEE3E37AqqiooKKigh49eiAi7NsHIjBwYN3jjDEUFxcTHR1NdHS0T2O8evUqZWVlREREEBcX59NrK6W8Z8eOHWeMMYktObfZCUNEooBlwD8ZYy40cgPg6QnTSHtj59RtMOZl4GWAUaNGme3btzcVdrvw5Zdfkpuby3e+8x26devG3/89rF0Lnn68F154geTkZGbPnu3zODdt2kRBQQGzZs1i6NChPr++Uqr1RORYS89t1iwpEQnBShZ/NcbkOppLHN1MOP4tdbSfAHq7nd4LKHK09/LQXuccEQkGYoGzN/vDtFd2ux2AsrIywLqzKC6GCxduPDYhIYHTp0/7MjyX8ePH06tXL959913Ky8v9EoNSyn+aM0tKgNeAvcaY37g9lQc84nj8CLDSrX2eY+ZTf6zB7U8d3VcVIjLW8ZoP1zvH+VqzgY2mE+2KGB8fD8DZs1aOdHZFHThw47EJCQmUlZVRW1vrq/BcgoKCmDlzJrW1tSxfvtwvMSil/Kc5dxh3An8HTBCRnY6vacD/AJNF5CAw2fE9xpg9wBLgK+A94FljTI3jtb4DvIo1EF4I5DvaXwPsInII+D6OGVedRXh4OJGRkXXuMMBzwkhMTKSmpobz58/7LkA38fHxTJ06lWPHjvHxxx/7JQallH80OYZhjPkIz2MMABMbOOcXwC88tG8Hbuj8NsZcBuY0FUtHZrfbXQkjNRWCgmD//huPS0hIAOD06dOuOxNfGzZsGAcPHmTTpk2kpKSQnJzslziUUr6lK70DRHx8vKtLKiwM+vXznDASE63JDWfOnLnxSR8REaZPn05kZCS5ublcvXrVb7EopXxHE0aAsNvtVFZWcuXKFcDqlvKUMMLDw4mKivJrwgCIiIhg5syZlJWVsW7dOr/GopTyDU0YAcI5U8p94PvAAfA0ruzPmVLu+vfvz7hx49ixYwf79u3zdzhKqTamCSNAeJpae+kSFBXdeGxCQgJnzpwhECaSTZgwgaSkJPLy8qioqPB3OEqpNqQJI0B07Wrt3ehMGAMGWO0NjWNcuXKFyspKX4XXIJvNRnZ2NtXV1axcuTIgkphSqm1owggQISEhxMbG3rAWo7GZUv4ex3BKTEwkIyODwsJCtm7d6u9wlFJtRBNGAHGfWpucDFFRTU+tDRQjR45kwIABbNiwgZKSEn+Ho5RqA5owAkh8fDxlZWUYYxCxuqU8JYzo6GhCQ0MD5g4DrKm2mZmZhIeHk5uby7Vr1/wdklLKyzRhBBC73c7ly5epqqoCrIThabW3iJCYmBhQCQMgMjKSrKwsSktL2bBhg7/DUUp5mSaMAOJcue0+U+roUbh8+cZjA2VqbX1paWmMHj2arVu3cujQIX+Ho5TyIk0YAcTT1FpjwNPv3YSEBCorK7nsKZv42aRJk0hMTGTlypVcvHjR3+EopbxEE0YAiYuLIygo6IZNCAN1i5CGhISEMGvWLKqqqli1apVOtVWqg9CEEUBsNhtxcXGuqbWNrcUIxJlS7rp3787EiRPZv38/O3bs8Hc4Sikv0IQRYNyn1kZFWdNrPQ18d+3aFZvNFpB3GE5jx44lJSWFtWvXBnScSqnm0YQRYJy71jq7cRrahDAoKAi73R7Qv4hFhKysLEJCQsjNzaWmpqbpk5RSAUsTRoCx2+1UV1e79mVyJgxPwwCBOlPKXXR0NJmZmRQXF7Np0yZ/h6OUagVNGAHG00ypc+fA041EQkIC58+fD/hFcoMGDWLEiBFs3ryZo0eP+jscpVQLacIIMJ4SBjQ88G2McR0byDIyMrDb7Sxfvty1MFEp1b40mTBE5HURKRWR3W5ti93qex8VkZ2O9n4iUuX23B/dzhkpIl+KyCEReUFExNEe5ni9QyKyVUT6ef/HbD9iYmIIDg6+YaZUQ/W9ITCn1tYXGhpKdnY2lZWVvPvuuzrVVql2qDl3GG8AU9wbjDEPGmOGG2OGA8uAXLenC53PGWOedmt/CXgSSHd8OV/zMeCcMSYNeB74ZUt+kI5CRFx7SoFVqjU01PMdhvNuJNDHMZySk5O599572bNnD1988YW/w1FK3aQmE4YxpgA46+k5x13CXGBhY68hIj2AGGPMFmP9afkWkOV4egbwpuPxUmCi8+6js7Lb7a47DJsN0tI8J4yQkBDi4uLaxR2G05133knfvn1Zs2aN62dUSrUPrR3DuBsoMcYcdGvrLyKfi8iHInK3o60ncMLtmBOONudzxwGMMdeAcsDeyrjaNefU2lpHfdaGptYC9OzZkwMHDnDq1CkfRthyQUFBzJw5ExFh+fLlrp9RKRX4Wpsw5lP37qIY6GOMuR34PpAjIjGApzsGZyd2Y8/VISJPish2EdneXrphWsJut1NbW8v58+cBaxyjsBA8TYbKyMggIiKCnJwcLly44NtAWyg2Npbp06dz4sQJCgoK/B2OUqqZWpwwRCQYyAYWO9uMMVeMMWWOxzuAQmAA1h1FL7fTewHOatUngN5urxlLA11gxpiXjTGjjDGjnAO+HZFzbMK9+l51tbVzbX3R0dHMnz+fK1eusHDhQq5everDSFtu6NCh3HbbbRQUFHD8+HF/h6OUaobW3GFMAvYZY1xdTSKSKCI2x+MUrMHtw8aYYqBCRMY6xiceBlY6TssDHnE8ng1sNJ18Cs3NTK0FSEpKYtasWZSUlJCbm9tuunmmTZtGbGwsubm5XLlyxd/hKKWa0JxptQuBLcBAETkhIo85nprHjYPd9wBfiMgurAHsp40xzruF7wCvAoew7jzyHe2vAXYROYTVjfXjVvw8HUKXLl0ICwtrdsIAGDBgABkZGezfv5/169f7IMrWCwsLY+bMmZSXl5Ofn9/0CUopvwpu6gBjzPwG2r/toW0Z1jRbT8dvB4Z6aL8MzGkqjs5EROrMlLLbra/GEgbAmDFjOHv2LJ988gl2u51Ro0b5INrW6dOnD3fffTcFBQWkpaUxdOgNHxGlVIDQld4Byn0tBjRc37u+jIwM0tPTWbNmTbupeDd+/Hh69erFu+++S3l5ub/DUUo1QBNGgLLb7XX2iRo40PNq7/qCgoKYNWsW3bp145133qG0tLSNI20951Tb2tpanWqrVADThBGgnAPf586dA6yEUVwMzZk5GxYWxvz58wkNDSUnJ4fKysq2DNUr4uPjmTp1KseOHePjjz/2dzhKKQ80YQSo+Ph44MaZUs25ywBrrcP8+fO5dOkSixYtorq6ui3C9Kphw4YxePBgNm3aRFFRUdMnKKV8ShNGgLrZqbWeJCcnk52dzcmTJ1m+fHnAb/gnIkyfPp3IyEhyc3PbzZoSpToLTRgBKjw8nMjISFfCSE2FoKCbSxhg1aKYPHkye/fu5f3332+DSL0rIiKCmTNnUlZWxrp16/wdjlLKjSaMAObcUwogLMzauba5XVLu7rjjDkaOHMnmzZv5/PPPvRtkG+jfvz/jxo1jx44d7Nu3z9/hKKUcNGEEMLvdXmdqbWObEDZGRJg6dSopKSmsXr2aI0eOeDHKtjFhwgSSkpLIy8tzlatVSvmXJowAFh8fT2VlpWvbDOfU2pbMOrXZbMyZMwe73c6SJUsCfkt0m81GdnY21dXVrFy5MuDHX5TqDDRhBLD6mxAOGACXLsHJky17vfDwcBYsWIDNZiMnJ4eLFy96K9Q2kZiYSEZGBoWFhWzdutXf4SjV6WnCCGDemClVX1xcHPPmzaOiooLFixe7FgYGqpEjRzJgwAA2bNhASUmJv8NRqlPThBHAWrsWoyG9evUiKyuL48ePB3x3j4iQmZlJeHg4ubm5AZ/glOrINGEEsJCQEGJiYlxdUsnJEBXVujsMpyFDhjBhwgR2797NBx980PoXbEORkZFkZWVRWlrKhg0b/B2OUp2WJowA5z5TSqT5mxA2x1133cXw4cMpKCjgiy++8M6LtpG0tDRGjx7N1q1b282mikp1NJowApz7WgzwbsJwrqzu168feXl5HDt2zDsv3EYmTZpEYmIiK1euDPgBe6U6Ik0YAc5ut1NVVcWlS5cAaxzj2DGoqvLO69tsNubOnUtcXByLFy+uk5wCTUhICLNmzaKqqopVq1YF9NiLUh2RJowA52mmlDFQWOi9a0RERLBgwQIAcnJyqPJWNmoD3bt3Z9KkSezfv58dO3b4OxylOhVNGAGu/loMb0yt9SQ+Pp558+Zx/vx5Fi9eTE1NjXcv4EVjxowhJSWFtWvXBvwCRKU6Ek0YAS4uLg4Rcd1hDBhgtXs7YYBVLjUzM5Njx44FdJePiJCVlUVISAi5ubkBndyU6kiaTBgi8rqIlIrIbre250TkpIjsdHxNc3vuJyJySET2i0iGW/tIEfnS8dwLIiKO9jARWexo3yoi/bz8M7ZrNpuNrl27uu4woqKs6bVtkTAAbrvtNsaPH8+uXbv46KOP2uYiXhAdHU1mZibFxcVs2rTJ3+Eo1Sk05w7jDWCKh/bnjTHDHV9rAERkMDAPGOI450URsTmOfwl4Ekh3fDlf8zHgnDEmDXge+GULf5YOy1ubEDbX+PHjufXWW9m4cSO7d+9u+gQ/GTRoECNGjGDz5s0cPXrU3+Eo1eE1mTCMMQVAc6fOzAAWGWOuGGOOAIeA0SLSA4gxxmwxVj/HW0CW2zlvOh4vBSY67z6UJT4+nrKyMlcXkTNhtFWPkXN1de/evVmxYgXHjx9vmwt5QUZGBna7neXLlwf0YL1SHUFrxjD+QUS+cHRZdXW09QTcf7uccLT1dDyu317nHGPMNaAcsHu6oIg8KSLbRWT76dOnWxF6+2K326murnbV5h44EM6fh7Yc7w0ODmbevHnExMSwaNEiV23xQBMaGkp2djaVlZWsXr06YMddlOoIWpowXgJSgeFAMfBrR7unOwPTSHtj59zYaMzLxphRxphRiYmJNxVwe1Z/am1bDny769KlCwsWLKC2tpacnBwuX77cthdsoeTkZO69916++uordu3a5e9wlOqwWpQwjDElxpgaY0wt8Aow2vHUCaC326G9gCJHey8P7XXOEZFgIJbmd4F1Cg1tQtjWCQMgISGBuXPncvbsWd55552AnZF055130rdvX/Lz8wN68aFS7VmLEoZjTMJpJuAcGc0D5jlmPvXHGtz+1BhTDFSIyFjH+MTDwEq3cx5xPJ4NbDTar1BHbGwsNpvNlTD69YPQUN8kDLBKpk6fPp3Dhw+zZs2agOz2CQoKYubMmYgIy5cvp7YlVaaUUo1qzrTahcAWYKCInBCRx4BfOabIfgHcB/wzgDFmD7AE+Ap4D3jWGOP8k/Q7wKtYA+GFQL6j/TXALiKHgO8DP/bWD9dRiAh2u931l7PNBmlprd/m/Gbcfvvt3HXXXXz22Wds2bLFdxe+CbGxsUyfPp0TJ05QUFDg73CU6nCCmzrAGDPfQ/NrjRz/C+AXHtq3A0M9tF8G5jQVR2cXHx9fZ1XzwIGwd69vY5gwYQJnz55l/fr1dO3alVtuucW3ATTD0KFDOXjwIAUFBaSmptK7d++mT1JKNYuu9G4nnHcYzq6WAQOs/aR8WU/IucK6Z8+e5ObmUlRU1PRJfjBt2jRiY2PJzc111UNXSrWeJox2Ij4+ntraWsrLywHrDqO6Go4c8W0cISEhzJs3j8jISBYuXOiKJ5CEhYWRnZ1NeXk5+fn5TZ+glGoWTRjtRFvU926pqKgoFixYQHV1NTk5OQH5V3zv3r25++672bVrV0CvVleqPdGE0U40lDB8OfDtrlu3bsyZM4fTp0+zdOnSgJyVNH78eHr16sW7774bkHdCSrU3mjDaicjISEJDQ10zpex268sfdxhOqampTJs2jUOHDvHee+/5L5AGOKfa1tbW6lRbpbxAE0Y74Zxa674JoTfLtbbUqFGjuOOOO9i2bRtbt271bzAexMfHM3XqVI4dO8bHH3/s73CUatc0YbQjvt61trkmTZrEwIEDWbt2LQf81UfWiGHDhjF48GA2bdoUsDO7lGoPNGG0I/Hx8ZSXl3PNMZd24EA4dQouXPBvXEFBQWRnZ5OUlMTSpUs5deqUfwOqR0SYPn06UVFR5ObmcvXqVX+HpFS7pAmjHbHb7RhjXDvH+nvg211oaCjz588nIiKCnJwcKioq/B1SHREREWRlZVFWVsa6dev8HY5S7ZImjHakfn1vX+1a21zR0dHMnz+fK1eusHDhwoD7S75///6MGzeOHTt2sG/fPn+Ho1S7owmjHam/a21aGgQFBU7CAEhKSmLWrFmcOnWK3NzcgJuZNGHCBHr06EFeXl7A3QUpFeg0YbQjERERdOnSxZUwwsKsnWsDKWEADBgwgIyMDPbv38/69ev9HU4dNpuN7OxsqqurWblyZUDuvKtUoNKE0c6471oLMHIk5OVZX4FkzJgxfOMb3+CTTz5h+/bt/g6njoSEBDIyMigsLAzIqcBKBSpNGO1M/am1L74It94K2dnw5z/7MTAPpkyZQnp6OmvWrOHQoUP+DqeOkSNHMmDAADZs2EBJSYm/w1GqXdCE0c7Ex8dTUVHhGlBOSICNG2HiRHj0UfjlLyFQelmCgoKYNWsW3bp145133qG0tNTfIbmICJmZmYSHh5Obm+uaqqyUapgmjHam/kwpgKgoWLUK5s+HH/8YfvADCJSx5rCwMObPn09oaCg5OTlUVlb6OySXyMhIsrKyKC0tZcOGDf4OR6mApwmjnam/CaFTaCi8/Tb84z/C88/DI49Y258HgtjYWObPn8/FixdZtGgR1YESGJCWlsbo0aPZunVrwHWbKRVoNGG0M/Wn1roLCoL/9//gF7+wkkdmJly86OMAG5CcnMysWbM4efIkK1asCKjZSZMmTSIxMZEVK1ZwMVDeMKUCUHNqer8uIqUistut7f+IyD4R+UJElotInKO9n4hUichOx9cf3c4Z6agDfkhEXhARcbSHichiR/tWEenn/R+z4wgJCSEmJqZOl5Q7EfjpT+GVV2DdOmtsw0Nu8YtBgwYxefJkvvrqK95//31/h+MSEhLCrFmzuHz5MqtWrQqoZKZUIGnOHcYbwJR6beuBocaY24ADwE/cnis0xgx3fD3t1v4S8CSQ7vhyvuZjwDljTBrwPPDLm/4pOpn4+HiPdxjuHn8cli2DnTvhrrvg6699E1tT7rjjDkaMGMHmzZv5/PPP/R2OS/fu3Zk0aRL79+9nx44d/g5HqYDUZMIwxhQAZ+u1rTPGOKeVfAL0auw1RKQHEGOM2WKsP9/eArIcT88A3nQ8XgpMdN59KM/qT61tSFYWrF0LRUVw553w1VdtH1tTRIRp06aRkpLC6tWrOeLrGrONGDNmDCkpKaxdu5YzZ874OxylAo43xjAeBdwLJ/cXkc9F5EMRudvR1hM44XbMCUeb87njAI4kVA7YPV1IRJ4Uke0isv306dNeCL19stvtVFVVUVVV1eSx48dDQQFcu2bdaWzZ4oMAm2Cz2ZgzZw52u50lS5YEzC9nESErK4uQkBByc3Opqanxd0hKBZRWJQwR+RlwDfiro6kY6GOMuR34PpAjIjGApzsGZ0dxY8/VbTTmZWPMKGPMqMTExNaE3q41NvDtybBhsHmzVaFv4kRYs6Yto2ue8PBwFixYgM1mIycnJ2AGm6Ojo8nMzKS4uJhNmzb5OxylAkqLE4aIPAJMB77l6GbCGHPFGFPmeLwDKAQGYN1RuHdb9QKclWxOAL0drxkMxFKvC0zV1dDU2sakpMBHH8Ett1izp/7yl7aKrvni4uKYN28eFRUVLF68OGAWzw0aNMg1znL06FF/h6NUwGhRwhCRKcCPgExjzCW39kQRsTkep2ANbh82xhQDFSIy1jE+8TCw0nFaHvCI4/FsYKPRaSqN6tq1KyJyUwkDoHt32LTJ6qZ6+GH49a/bKMCb0KtXL7Kysjh+/Dh5eXkBM0MpIyMDu93O8uXLm9X1p1Rn0JxptQuBLcBAETkhIo8BvweigfX1ps/eA3whIruwBrCfNsY47xa+A7wKHMK683COe7wG2EXkEFY31o+986N1XDabjbi4uAan1jYmJsbqkpozB/7lX+CHP/T/ViJDhgxhwoQJfPnll3z44Yf+DcYhNDSU7OxsKisrWb16dcAkMqX8KbipA4wx8z00v9bAscuAZQ08tx0Y6qH9MjCnqThUXc2dKeVJWBgsXAiJifB//g+cPm2t2whu8tPQdu666y7Onj3Lhx9+SHx8PLfddpv/gnFITk7mvvvu4/3332fXrl0MHz7c3yEp5Ve60rudcq7FaOlfvjYb/P738Nxz8MYbMHMmXLrU1Fltx1l3u1+/fuTl5XHs2DH/BeNm3Lhx9O3bl/z8/Bbd0SnVkWjCaKfsdjvV1dWt2sxPBH7+c3jpJXj3XfjmN8FRLtwvbDYbc+fOJS4ujsWLFwfEL+igoCBmzpyJiLB8+fKAqyColC9pwminWjJTqiFPPw1LlsC2bXD33XDyZKtfssUiIiJYsGABADk5OQEx4BwbG8v06dM5ceIEBQUF/g5HKb/RhNFOedrmvDVmz4b8fGsLkXHj/Fv2NT4+ngcffJDz58+zZMmSgFhAN3ToUG677TYKCgo4fvy4v8NRyi80YbRTMTEx2Gw2r9xhOE2YAB98AJcvW1uJfPqp1176pvXt25fMzEyOHj0aMBsCTps2jdjYWHJzc7ly5Yq/w1HK5zRhtFNBQUHN2oTwZo0YYa0Kj4mxEsi6dV59+Zty2223MX78eHbt2sVHH33kv0AcwsLCyM7Opry8nPz8/KZPUKqD0YTRjtnt9jYZGE5Ls5JGWhrcf781Bddfxo8fz6233srGjRvZvXt30ye0sd69e3P33Xeza9eugIhHKV/ShNGOxcfHc/bs2TaZudOjB3z4oTWesWABvPCC1y/RLM7a271792bFihUBMX4wfvx4evXqxbvvvkt5ebm/w1HKZzRhtGN2u52amhouXLjQJq8fG2ttj56VBd/7HvzsZ/5ZFR4cHMyDDz5ITEwMixYt4pw/5/5yfaptbW2tTrVVnYomjHbMm1NrGxIeDu+8YxVk+t//G5580toq3dciIyNZsGABtbW15OTkcPnyZd8H4SY+Pp6pU6dy7NgxPv74Y7/GopSvaMJox3yRMMDaMuTll+Ff/xVefdXah8ofyyMSEhKYO3cuZ8+e5Z133vH7dNthw4YxePBgNm3aRFFRUdMnKNXOacJoxyIjIwkNDW3zhAHWqvD//E9rLGPlSpgyBc6fb/PL3qB///5Mnz6dw4cPs2bNGr9Ot3VuZxIVFUVubi5Xr171WyxK+YImjHZMRLDb7Rw/ftxnv6y++13IybEq940fD8XFPrlsHbfffjt33nknn332GVv8XEIwIiKCrKwsysrKWOfPOchK+YAmjHZu+PDhFBcX8+KLL1JYWOiTa86bZ+09VVhoLfA7eNAnl61j4sSJDB48mPXr17N3717fB+Cmf//+jBs3jh07drBv3z6/xqJUW9KE0c6NHj2aRx99lJCQEN5++23y8vJ8MiA8ebJVjKmiwkoan33W5pesw1l/u2fPnuTm5vp9DGHChAn06NGDvLw8Kioq/BqLUm1FE0YH0Lt3b5566inuuusudu7cyYsvvsh+H2wG9Y1vWGVfu3SBe++FjRvb/JJ1hISEMG/ePCIjI1m4cKFf10TYbDays7Oprq5m5cqVAbGViVLepgmjgwgODmbixIk8/vjjdOnShUWLFpGbm8ulNi5yMXCgtSq8b1+YOhWWLm3Ty90gKiqKBQsWUF1dzcKFC/26x1NCQgIZGRkUFhaydetWv8WhVFvRhNHBJCcn88QTT3DvvfeyZ88e/vCHP7Bnz542/Yu3Z08oKLDuOObOtepr+FK3bt2YM2cOpaWlLF261K8L6UaOHMmAAQPYsGEDJSUlfotDqbbQnJrer4tIqYjsdmuLF5H1InLQ8W9Xt+d+IiKHRGS/iGS4tY8UkS8dz70gIuJoDxORxY72rSLSz8s/Y6djs9kYP348Tz31FHFxcSxdupQlS5a0ad96167WRoX33w/PPGNV8vNlr0xqairTpk3j0KFDvPfee767cD3OrUzCw8PJzc3lmj9WOSrVRppzh/EGMKVe24+B940x6cD7ju8RkcHAPGCI45wXRcTmOOcl4Ekg3fHlfM3HgHPGmDTgeeCXLf1hVF3dunXjscceY/LkyRw6dIgXX3yRXbt2tdndRpcusHw5fPvb8O//biUOX66tGzVqFGPHjmXbtm1+7RKKjIwkKyuL0tJSNmzY4Lc4lPK2JhOGMaYAqL8l6gzgTcfjN4Est/ZFxpgrxpgjwCFgtIj0AGKMMVuM9dvqrXrnOF9rKTDRefehWi8oKIhx48bx9NNP061bN1asWEFOTk6bDRAHB8Prr8MPfwh//KM1BdeXwwqTJ09m4MCBrF27lgMHDvjuwvWkpaUxevRotm7dyqFDh/wWh1Le1NIxjO7GmGIAx7/dHO09AfftRE842no6Htdvr3OOMeYaUA7YPV1URJ4Uke0isv306dMtDL1zstvtfPvb33btf/Tiiy+yffv2NrnbEIFf/hJ+/WtrEHzqVGij/RFvEBQURHZ2NklJSSxdupRTp0755sIeTJ482ZWkL1686Lc4lPIWbw96e7ozMI20N3bOjY3GvGyMGWWMGZWYmNjCEDsvEWH06NE888wzru2533rrrTapqQHw/e/DW2/B3/5mTbv11RhwaGgo8+fPJzw8nIULF/ptXURwcDDZ2dlcvnw5YKoGKtUaLU0YJY5uJhz/ljraTwC93Y7rBRQ52nt5aK9zjogEA7Hc2AWmvCguLo6HHnqIBx54gOLiYl566SW2bNnSJrOL/u7vIC8P9u2zFvgdPuz1S3gUHR3NggULqKqqYuHChX7b56l79+5MmjSJ/fv3s2PHDr/EoJS3tDRh5AGPOB4/Aqx0a5/nmPnUH2tw+1NHt1WFiIx1jE88XO8c52vNBjYa/VOszYkII0aM4JlnniElJYV169bx5z//mbbo6ps61VrUd+6clTR27fL6JTxKSkpi9uzZnDp1itzcXL9Ntx0zZgypqamsXbuWM2fO+CUGpbyhOdNqFwJbgIEickJEHgP+B5gsIgeByY7vMcbsAZYAXwHvAc8aY5zzZL4DvIo1EF4IOIsivwbYReQQ8H0cM66Ub8TExDBv3jyys7MpKyvjT3/6E3/729+8vnX42LHWqvDgYLjnHquany8MGDCAjIwM9u/f77cZSyLCjBkzCAkJITc31+/bsivVUtJe/5gfNWqU2b59u7/D6FAuXrxIfn4+e/bsISkpiRkzZpCUlOTVaxw/DhkZVtfUwoUwc6ZXX75Ba9asYdu2bdx///2MGjXKNxetZ9++fSxevJg777yTSZMm+SUGpURkhzGmRf8T6Epv5RIZGcns2bOZO3cuFRUVvPLKK2zatMmri89697YGwW+/HWbPtgoy+cKUKVNIS0tjzZo1fpvmOmjQIEaMGMHmzZs5evSoX2JQqjU0Yagb3HLLLTz77LPceuutFBQU8PLLL3Py5Emvvb7dDhs2WHcaTzwBv/hF268KDwoKYvbs2SQmJrJ06VJKS0ubPqkNZGRkYLfbWb58OVX+KFuoVCtowlAeOQsDLViwgCtXrvDaa6+xbt06qqurvfL6kZFW5b6HHrJKv37ve9DWY9JhYWEsWLCAkJAQcnJyqKysbNsLehAaGkp2djaVlZWsXr1ap9qqdkUThmpUeno6zzzzDCNGjGDLli388Y9/5NixY1557ZAQePNNa73G734H3/oWtPXs19jYWObPn8/FixdZtGiR1xLgzUhOTua+++7jq6++Ypevpowp5QWaMFSTwsLCmD59Og8//DDGGN544w3WrFnjla3Eg4Lg//5fa2X4okUwfbpVlKktJScnk52dzcmTJ1mxYoVf/sofN24cffv2JT8/v80WTirlbZowVLP179+fp59+mjFjxrBt2zZeeuklr5SFFbH2nnr9dWu9xoQJ0NY7v9xyyy1MnjyZr776io2+rvyENaYyc+ZMRITly5f7dUt2pZpLE4a6KaGhoUyZMqVOWdiVK1d6pSzs3/+9tdvt7t1w113Q1hOJ7rjjDkaMGMFHH33E559/3rYX8yA2Npbp06dz4sQJCgoKfH59pW6WJgzVIu5lYXft2uW1srAPPADr10NpqbUq/MsvvRBsA0SEadOmkZKSwurVqzly5EjbXawBQ4cO5bbbbqOgoIDjx483fYJSfqQJQ7WYsyzsE0884SoLu2zZslaXhb3rLquCH1irwj/6yAvBNsBmszFnzhzsdjtLlizxy9Yd06ZNIzY2ltzcXL+WmFWqKZowVKv16NHDVRb2q6++8kpZ2FtvtWqFd+sGkyfDqlVeDLie8PBw5s+fT1BQEDk5OW1eB72+sLAwsrOzKS8vJz8/v+kTlPITTRjKK9qiLGy/ftbdxdCh1hYif/6z9+Ktr2vXrsybN48LFy6waNEin5dW7d27N/fccw+7du1i9+7dTZ+glB9owlBe5aks7M6dO1t8t5GYeH3m1KOPwq9+1Xarwnv37k1WVhbHjx8nLy/P59Nt77nnHledkraqiKhUa2jCUF5XvyzsypUrW1UWNjoaVq+2yr3+6EfwL//SdqvChw4dyn333ceXX37Jh77aUtfBOdW2trZWp9qqgKQJQ7UZb5aFDQ2Fv/4Vvvtd+M1v4JFHoK0Wad99990MGzaMDz/8kC+++KJtLtKA+Ph41/v18ccf+/TaSjVFE4ZqU57Kwr755pstWt0cFAS//S3813/B22/DjBnQFqWyRYQHHniAvn37kpeX57WtUJpr2LBhDB48mE2bNlFUVNT0CUr5iCYM5RPuZWFPnTrV4rKwIvCzn8HLL8PatTBpEpSVeT9em83Ggw8+SFxcHIsXL/bp9h0iwvTp04mKiiI3N9dv5WWVqk8ThvIZb5aFfeIJWLoUPv8c7r7bKszkbRERESxYsACAnJwcn25H7twtuKysjLVr1/rsuko1RhOG8jlvlYWdOdO6yzh5EsaNg717vR9rfHw8Dz74IOfPn2fJkiU+La/av39/xo0bx2effca+fft8dl2lGtLihCEiA0Vkp9vXBRH5JxF5TkROurVPczvnJyJySET2i0iGW/tIEfnS8dwLIiKt/cFUYBMRbr31Vp599lkGDRrExo0befXVVzl16tRNvc748VZ98Opqa4X4J594P9a+ffuSmZnJ0aNHfV7DYsKECfTo0YO8vLxWrWlRyhtanDCMMfuNMcONMcOBkcAlYLnj6eedzxlj1gCIyGBgHjAEmAK8KCI2x/EvAU8C6Y6vKS2NS7UvnsrCbty48aYWzg0fDh9/DF27Wus12mKx9G233cY999zDzp07+agt9yqpx2azkZ2dTXV1NStXrtSCS8qvvNUlNREoNMY0Np1kBrDIGHPFGHMEOASMFpEeQIwxZoux/m94C8jyUlyqnXAvC/u3v/2Nl19+mRMnTjT7/JQUayuRQYMgM9OaReVt9957L0OHDmXjxo3s2bPH+xdoQEJCAhkZGRQWFrJ161afXVep+ryVMOYBC92+/wcR+UJEXheRro62noD70OQJR1tPx+P67TcQkSdFZLuIbG/JQKkKbPXLwr7++us3VRa2e3f44ANrEPzv/s5ar+FNIsKMGTPo3bs3y5cvv6mE1lojR45kwIABbNiwgZKSEp9dVyl3rU4YIhIKZALvOJpeAlKB4UAx8GvnoR5ON42039hozMvGmFHGmFGJiYmtCVsFsNaUhY2JgTVrYNYs+MEPrJXh3uzFCQ4O5sEHHyQmJoaFCxdy7tw57714I0SEzMxMwsPDyc3N9fleV0qBd+4wpgKfGWNKAIwxJcaYGmNMLfAKMNpx3Amgt9t5vYAiR3svD+2qE/NUFvbdd99t1vbf4eGweDE8/bS199Rjj4E3f79GRkayYMECamtrWbhwoVeKRzX3ullZWZSWlrJhwwafXFMpd95IGPNx645yjEk4zQScW2/mAfNEJExE+mMNbn9qjCkGKkRkrGN21MPASi/EpToAZ1nYsWPHsn379maXhbXZ4MUX4ec/t3a5zc4Gb+5anpCQwNy5cykrK+Odd97x2XTbtLQ0Ro8ezdatWzl06JBPrqmUU6sShoh0ASYDuW7Nv3JMkf0CuA/4ZwBjzB5gCfAV8B7wrDHG+X/Zd4BXsQbCCwEtCqBcQkNDycjIuOmysCLw3HPwhz9Ymxd+85vgzR6k/v37M336dA4fPsyaNWt8NoNp8uTJdOvWjRUrVnCxLfZGUaoB0l6n6Y0aNcps377d32EoH7t27RoffvghmzdvJjIykunTpzNw4MAmz3vnHXjoIRgwAN57D3p6nFbRMhs2bGDz5s1MnjyZcePGee+FG1FSUsIrr7xCWloaDz74ILp0STWXiOwwxoxqybm60lu1K+5lYSMjI11lYZv6S3vOHGt9xtGjVq1wL5Qfd5k4cSKDBw9m/fr1PluR3b17dyZNmsT+/fvZsWOHT66plCYM1S7VLwv74osvsnv37ka7hSZMsKbdXrpkrQrfts07sYgIWVlZ9OzZk2XLlvlsh9kxY8aQmprK2rVr/VKLXHU+mjBUu1W/LOyyZctYvHhxo1tojBxpLfCLioL77oP1670TS0hICPPmzSMyMpKFCxf6pGKec11ISEgIubm5Pt3nSnVOmjBUu+deFrawsLDJsrDp6dZWIqmpcP/9sGiRd+KIiopiwYIFXL16lYULFzZrCnBrRUdHk5mZSXFxMZs2bWrz66nOTROG6hA8lYX961//2uBf+j16WJsW3nEHLFgAv/udd+Lo1q0bc+bMobS0lGXLlvmkzOqgQYMYMWIEmzdv5ujRo21+PdV5acJQHYp7Wdivv/6aF198kW3btnm824iLs2ZMzZgB//iP8K//6p1V4WlpaUydOpWDBw/6rJZFRkYGdrud5cuX+7Ruh+pcNGGoDqd+Wdg1a9Y0WBY2IsKacvvYY/CLX8BTT3lnVfg3vvENxo4dy6effuqTDQNDQ0PJzs6msrLS51uwq85DE4bqsJxlYTMzMxstCxscDK+8Aj/9qfXvnDngjd0+Jk+ezMCBA1m7di0HDhxo/Qs2ITk5mfvuu4+vvvqKXbt2tfn1VOejCUN1aCLC7bff3mRZWBHrDuO3v4UVK2DKFGjtRKegoCCys7Pp3r07y5Ytu+niUC0xbtw4+vbtS35+vk/rkKvOQVd6q07DGMPu3bvJz8/n6tWrjB8/nnHjxmGz2eocl5MDjzwCQ4ZYi/169GjgBZvpwoULvPrqq4gIjz/+ONHR0a17wSaUl5fz0ksvce3aNfr37096ejrp6el07dq16ZNVh9eald6aMFSnc/HiRfLz89mzZw9JSUnMmDGDpKSkOsesXWttkd6tG6xbB2lprbvmqVOneP3110lISODb3/42oaGhrXvBJpSUlPD5559z8OBB151GQkIC6enpDBgwgN69e9+QKFXnoAlDqRbYu3cv7777LlVVVdx5553cc889BAcHu57/9FOYNs3a+TY/H0aMaN31Dhw4wKJFixgwYABz584lKMg3PcJlZWUcPHiQgwcPcvToUWprawkLCyM1NdV19xEZGemTWJT/acJQqoWqqqpYu3Ytu3btIjExkczMTHr1ul6eZd8+yMiwdrldscLaXqQ1tm7dynvvvccdd9zBN7/5zda9WAtcuXKFw4cPuxJIZWUlAD179nQljx49euhmhh2YJgylWungwYOsXr2aiooKxo4dy3333UdISAgAJ09aSePgQfjrX2H27JZfxxhDfn4+27Zt4/7772fUqBb9f+sVxhhOnTrFgQMHOHjwICdPngSsFetpaWkMGDCAlJQUwsLC/Baj8j5NGEp5wZUrV1i/fj07duwgPj6eBx54gH79+gFw9iw88ABs2WIVZnr66ZZfx1mpr7CwkG9961ukpqZ65wdopYsXL3Lo0CEOHjzIoUOHuHLlCkFBQfTt29c19mG32/0dpmolTRhKedGRI0dYtWoV586dY9SoUUyaNImwsDAuXYIHH7SKMT33HPzbv1nTcVviypUrvP7665SXl/Poo4/SrVs3r/4MrVVTU8Px48ddXVfOacjx8fGurqu+ffvWGfNR7YMmDKW87OrVq2zatIlPPvmE2NhYpk+fTlpaGtXV8MQT8Oab8Mwz8MIL1qB4S5SXl/Pqq69is9l4/PHHiYqK8u4P4UXnzp1zJY8jR45QU1NDaGgoKSkprgTS1tOFlXdowlCqjRw/fpy8vDzOnDnD8OHD+eY3v0l4eAQ//jH86lfWqvC//AVa2s1fVFTEn//8Z7p3784jjzziGjcJZNXV1Rw5csQ19nHhwgUAkpKSXF1XycnJPpsFpm6O3xKGiBwFKoAa4JoxZpSIxAOLgX7AUWCuMeac4/ifAI85jv9HY8xaR/tI4A0gAlgDfM80EZgmDOUr9cvC3n///QwaNIhf/xr+5V+smVPLl0NMTMtef+/evSxZsoTBgwcze/bsdjVDyRhDaWkpBw8e5MCBA5w4cQJjDF26dCEtLY309HTS0tIIDw/3d6jKwd8JY5Qx5oxb26+As8aY/xGRHwNdjTE/EpHBwEJgNJAMbAAGGGNqRORT4HvAJ1gJ4wVjTH5j19aEoXytuLiYlStXUlJSwtChQ5kyZQrLlkXy6KMwbBisWQPdu7fstTdv3syGDRu46667mDhxoncD96FLly5RWFjoGjivqqpCROjTp4+r6yoxMbFdJcWOJtASxn7gXmNMsYj0AD4wxgx03F1gjPlvx3Frgeew7kI2GWMGOdrnO85/qrFra8JQ/lBTU8NHH31EQUEB4eHhTJ06lWPHhjBnjtCzp7UqvH//m39dYwyrV6/ms88+IzMzk9tvv937wftYbW0tJ06ccI19lJSUANamkM7k0a9fv3bRDdeR+DNhHAHOAQb4kzHmZRE5b4yJczvmnDGmq4j8HvjEGPO2o/01IB8rYfyPMWaSo/1u4EfGmOkervck8CRAnz59Rh47dqzFsSvVGqWlpaxcuZKioiIGDhxIUtL9ZGdHExZm1dgYNuzmX7OmpoacnByOHj3KQw89RP+WZJ4AVl5eXmfgvLq6muDg4DoD57Gxsf4Os8PzZ8JINsYUiUg3YD3wXSCvgYTxB2BLvYSxBvga+O96CeOHxpgHGru23mEof6utreWTTz5h06ZNBAcHM3RoBk89NYyKCmHVKrjnnpt/zcuXL/Paa69RWVnJY489RkJCgvcDDwDXrl3j6NGjroHz8+fPA1bFQufAea9evXTgvA0ExCwpEXkOqASeQLukVCdSVlZGXl4eX3/9NT17pvLSS9PZsyeORYsgK+vmX+/cuXO8+uqrhIWF8fjjj9OlSxevxxxIjDGcOXPGdffx9ddfU1tbS3h4eJ2B847+PviKXxKGiEQCQcaYCsfj9cB/ABOBMrdB73hjzA9FZAiQw/VB7/eBdMeg9zasu5OtWHcdvzPGrGns+powVCAxxrBt2zY2bNgACDt3TmLZslH86U/C44/f/OsdP36cN998k+TkZB5++OFOtUDu8uXLdQbOL168iIjQq1cvV9dV9+7ddeC8hfyVMFKA5Y5vg4EcY8wvRMQOLAH6YHU3zTHGnHWc8zPgUeAa8E/OmVAiMorr02rzge/qtFrVHp0/f55Vq1Zx+PBhLlzoyxtvZPKDH8Tzk5/c/Krw3bt3s2zZMm699VZmzpzZKX9BGmMoKipydV0VFxcDEBMT49rvqn///m2+XXxHEhBdUr6mCUMFKmMMO3fuZO3atVRV1bB+/QS+8Y0xPP98EDfbJV9QUMCmTZsYP3489957b5vE255UVFS49rsqLCzk6tWr2Gw2+vXr5xr70EJRjdOEoVQAqqioYNWq1Rw8eIATJ3pSXT2Dl19O5Gb+GDbGsHLlSnbt2sXMmTO57bbb2i7gdqampoZjx465xj7KysqA64Wi0tPT6dOnjxaKqkcThlIBylkWNjc3n2vXrnLy5D08//ydxMY2/5dYTU0Nf/nLXzhx4gQPP/wwffr0acOI26+zZ8+6uq6OHTtGTU1NnUJRaWlpAb1fl69owlAqwF28eJE//CGfqqo9lJcn8cQTmdxyS/OLhV+6dInXXnuNqqoqHn/8ceLj49sw2vbv6tWrHD58mAMHDnDo0CEqKioASE5OdnVdddZCUZowlGon3nprL19+uYYuXS4yfPhdPPDAPc2eAVVWVsZrr71Gly5deOyxx4iIiGjjaDsGZ6EoZ9fViRMngOuFotLT00lNTe00haI0YSjVjmzcWMUf/7iOIUN2Eh2dwNy5M+qUhW3MsWPHeOutt+jTpw8PPfSQ9s+3gHuhqMLCQi5fvtypCkVpwlCqnfnyS3j88UPcddcqYmIqGDt2DBMmTGjWvkq7du1ixYoVDB8+nMzMzE7ZreIttbW1HD9+3DX24V4oyjltt6MVitKEoVQ7dPQoTJt2hfT09YwYsYOuXbuSmZnpKgvbmE2bNlFQUMCECRO4++672zzWzuL8+fOu5HH06FGuXbtGSEiIa+C8IxSK0oShVDtVWgrTpsG5c0d59NE8rl2rWxa2IcYYcnNz2b17N7Nnz2bIkCE+jLpz6KiFojRhKNWOVVRAdjZ8+OFVfv7zTVy7VrcsbEOuXbvGW2+9RVFREd/+9rebPQ6ibp57oaiDBw9y/PjxdlsoShOGUu3clSvwyCOweDH8r/91nD598igru14WtqEZURcvXuS1117j6tWrPP7448TFxfk28E6qqqrKNXDe3gpFacJQqgOorYXvfQ9+/3t4+OFrPPTQh2zZUrcsrCdnzpzh1VdfJSYmhkcffbRd/JXbkdTW1nLy5ElX15WzUFRsbKyr6yqQCkVpwlCqgzAG/uu/4N/+zRrb+N3vilm3zioLO2TIEKZOnUpkZOQN5x05coS3336bfv36sWDBAp1u60cXLlxwdV0dPnzYVSiqf//+rgTiz0JRmjCU6mD+9Cd45hkYPRry8mrYu3czH374oass7JAhQ27o7vjss89YtWoVI0eO5P777w/I7pDOxlkoyplAzp07B1wvFJWenk7v3r19OnCuCUOpDig3F+bPh7Q0WLsWQkPrloW9//77b5jiuWHDBjZv3szkyZMZN26cnyJXnhhjKCsrc3Vd+atQlCYMpTqoDz6AGTMgNtZKGgMHXi8La7PZyMjIYPjw4a67CWMM77zzDnv37mXixImkpKTQrVu3DrXwrKO4fPkyhw8fdt19OAtF9ezZ09V11RaFojRhKNWB7dwJU6ZAdTWsWQNjxtQtC5uamsr06dNdM6Sqq6t5++23+frrrwEICgqie/fuJCcn06NHD5KTk+nWrZuOcwQQZ6EoZ/IoKioCIDo62tV1lZKS4pVCUZowlOrgCgshIwOKi2HZMiuBGGPYvn0769evR0SYNGkSo0aNQkQwxlBeXk5RURFFRUUUFxdTVFTE5cuXAbDZbCQlJbkSSHJyMomJie1uEVpHVVlZ6UoengpFpaent3jHYk0YSnUCJSVWoti9G954A771LavdvSxs3759eeCBBzxunmeM4dy5czckkatXrwIQHBxMjx496iQRu92uScTPampq+Prrr11jH85CUXa73dV1dTOFovxV07s38BaQBNQCLxtjfisizwFPAKcdh/7UGLPGcc5PgMeAGuAfjTFrHe0juV7Tew3wPa3prdSNysshK8sa2/jNb+Cf/9lqdy8LW1NTw3333cfYsWOb/GXvHIh1TyLFxcVUV1cDEBISUieBJCcnEx8frzOw/Ojs2bOuu4+jR4/edKEofyWMHkAPY8xnIhIN7ACygLlApTHm/9Y7fjCwEBgNJAMbgAHGmBoR+RT4HvAJVsJ4wRiT39j1NWGozuryZevuIjcXfvQj+O//Bufv74qKClavXs2BAwcIDg4mKiqKyMhI15f79+6PIyIiXEmgtraWM2fOuO5AioqKOHXqFNeuXQMgLCzshiQSFxenScQPnIWinAmkfqGo9PR0kpOT6/y3CYguKRFZCfweuBPPCeMnAMaY/3Z8vxZ4DjgKbDLGDHK0zwfuNcY81dj1NGGozqymBp591lqv8eij1r/OiVDGGPbv38/XX3/NxYsXuXjxIpWVla7Hnv6fDwoKajCxREZG0qVLF65evcqFCxcoKyujuLiYkpISampqAAgPD68zqJ6cnExsbKwmER8yxlBSUuLqunIWioqMjHQlj9TUVMLDw1ucMLwy105E+gG3A1uxEsY/iMjDwHbgB8aYc0BPrDsIpxOOtmrH4/rtSqkG2Gzw0kvQvTv8x3/AmTOwaBFERICIMGjQII9biRhjqKqqciUQ90RSWVnJpUuXqKys5MyZM1RWVroSQn1dunQhPj7etd1FdXU1p0+f5siRI66E5EwiPXv2dCWR6OhoTSJtRERISkoiKSmJe+65p06hqH379rFz585Wj0e1OmGISBSwDPgnY8wFEXkJ+E/AOP79NfAo4OlTYhpp93StJ4EnAfr06dPa0JVq10Tg3/8dunWD734XvvlNyMuDrl0bO0fo0qVLsxaHGWO4evVqg8nF+dj5vXPw3Mm5zuDw4cOuNpvNRlRUFHFxcSQmJroG1p13NKGhoZpQvCQyMpJhw4YxbNiwOoWiWqNVCUNEQrCSxV+NMbkAxpgSt+dfAVY7vj0B9HY7vRdQ5Gjv5aH9BsaYl4GXweqSak3sSnUUzz4LiYnw0ENwzz3WAr/k5Na/rogQFhZGWFhYs0qWVldXe0wozm6s8vJy1/fl5eUcO3bshtew2WxERkYSHR3d5NiL+7iLapyzBG3fvn1b9TotThhi/Zd6DdhrjPmNW3sPY0yx49uZwG7H4zwgR0R+gzXonQ586hj0rhCRsVhdWg8Dv2tpXEp1RnPnQnw8zJwJ48bBunUwYIBvYwgJCSEuLq5ZW6xXVVVx7Ngxvv76a4qLi+t0gV24cIFLly5hs9kwxlBdXd3guEuXLl2aPbCv04NbrzWzpO4C/gZ8iTWtFuCnwHxgOFa30lHgKWcCEZGfYXVPXcPqwsp3tI/i+rTafOC7Oq1WqZu3fbu1y60x8NvfwpAhkJIC7aGq6OXLlzl16pRrZlZRUZFrsz6AmJgY4uPjiYqKIiIiguDgYC5fvnzDHY1zNld9ERERrgQSFRVVJ9nUTzIdeSuVgJgl5WuaMJTy7MABa4HfkSPX2xITITXVSh6pqXUfJyVBoP7xXVVV5Zre6/z3/Pnzruftdnud2VlJSUkATY63OB9fuXLF43XDwsIanDFWP7m0t3EXTRhKqTouX4Y9e6wtRQ4frvvv8eNWsSan8PDryaP+v/36Wc8HkkuXLt2wWt1ZbxtwDaa7J5GGihe5j7s0lVwuXbrk8TWCg4ObnVwCYdxFE4ZSqtmuXoVjx+omEffH7r8XRaBnT8/JJDXVGjcJhD+uKysrb0gilZWVgDV470wizq/u3bvfdLdTbW2tx2TiPh3Zvb2xcZfGkovz3y5durTJBpGaMJRSXmEMlJY2nExOnap7fExMw8mkd+/riwl9/3MYKioq6qxWLyoqct0lBAUF0a1btzpJxJs7+DrXuzRnOnJzx12aGtRvbglYTRhKKZ+4eNEaG/HU1XXkiLUFu1NwMPTt63ncxB8D8cYYLly4UCeB1N/Bt3v37jfs4NvW28A717s0N7k0NO4SGhrarOSSkJCgCUMp5V81NXDypOdkUlgIbhOeAGsgvqFk0qOHbwbijTGcP3/+hu4s5y/l4ODgG7aBT0hI8OsU3WvXrjU7uXgad3nuuec0YSilAtu5c1YC8ZRMGhqI9zQY379/2w7EG2M4e/bsDTv4OleyO3fwrb8NvL8Hsz2pra29YXxl+PDhmjCUUu2XcyDe07jJ4cNWV5iTcyC+oZlddrv3B+Jra2s9bgPvHHsIDQ29YQffrl27BmQS0TEMpVSH5RyIbyiZFBfXPT4mxvMgfEoK9OnjvYF45zbw7uMhp06dqrODrzOJOP8NhG3gNWEopTqtS5c8d3UdPmwNxLvviWizWQPxDS1ibO1AfE1NDadPn66TREpKSqh19LdFRETcsA18TEyMT5OIJgyllPLAORDvKZkUFsLZs3WPT0jwPAifmtrygfhr165RWlpapzurpKTEtU4jMjLyhiQS3YZTyDRhKKVUC5w/73kQ/vBh+PrrGwfi+/f3nExudiC+urqakpKSOjOzTp8+7UoiUVFRdcZDkpOTiYyM9MrPrAlDKaW87OpVK2k0tIjRfSAeGl8R35yB+KtXr7o2X3QmkTNnzriej4mJqZNAevTo0ay6JvVpwlBKKR8yBk6f9jwIX1h440B8dHTD4yaNDcRfuXLlhh18z7r1o8XFxd3QnRXexK2OJgyllAogly41viLe00B8Q4sYY2Lqvvbly5dv2PLEfQff+Pj4OkmkR48ehIWFuZ5vTcLouJu+K6WUn3TpYtUiGTLkxudqaqCoyHMyeeedhgfiryeRcFJT+5OS0p877rAG4i9dulRnG/jjx4+ze/dut9dIcCWP1tCEoZRSPmSzWRsz9u4N99574/POgfj64yZbtsDixZ4H4lNSupCamkpKSiqpqZCRAYmJFzl37vrMrCNHjvDFF1+0KnZNGEopFUDi4mDECOurvurqhlfEf/BB/YH4SHr2TCclJd11h9KrVxXwXItj04ShlFLtREgIpKVZX/W5D8TX7+pat87qBrOqYLecJgyllOoARKBbN+vrjjtufN45ED90aMuvETCVfEVkiojsF5FDIvJjf8ejlFIdiXMgvjUCImGIiA34AzAVGAzMF5HB/o1KKaWUu4BIGMBo4JAx5rAx5iqwCJjh55iUUkq5CZQxjJ7AcbfvTwBj6h8kIk8CTzq+vSIiu+sf00klAGeaPKpz0PfiOn0vrtP34rqBLT0xUBKGp11WbliCbox5GXgZQES2t3S1Ykej78V1+l5cp+/FdfpeXCciLd4iI1C6pE4Avd2+7wUU+SkWpZRSHgRKwtgGpItIfxEJBeYBeX6OSSmllJuA6JIyxlwTkX8A1gI24HVjzJ4mTnu57SNrN/S9uE7fi+v0vbhO34vrWvxetNvdapVSSvlWoHRJKaWUCnCaMJRSSjVLQCcMEXldREobWm8hIveKSLmI7HR8/ZuvY/QVEektIptEZK+I7BGR73k4RkTkBcf2Kl+IiIf9Ltu/Zr4XneKzISLhIvKpiOxyvBf/7uGYzvK5aM570Sk+F2DtoCEin4vIag/PtegzERCD3o14A/g98FYjx/zNGDPdN+H41TXgB8aYz0QkGtghIuuNMV+5HTMVSHd8jQFewsMCyA6gOe8FdI7PxhVggjGmUkRCgI9EJN8Y84nbMZ3lc9Gc9wI6x+cC4HvAXiDGw3Mt+kwE9B2GMaYAONvkgZ2AMabYGPOZ43EF1gehZ73DZgBvGcsnQJyItK7EVgBq5nvRKTj+W1c6vg1xfNWfydJZPhfNeS86BRHpBdwPvNrAIS36TAR0wmimOxy3oPki0sq9GNsHEekH3A5srfeUpy1WOvQv0kbeC+gknw1H18NOoBRYb4zptJ+LZrwX0Dk+F/8P+CFQ28DzLfpMtPeE8RnQ1xgzDPgdsMK/4bQ9EYkClgH/ZIy5UP9pD6d02L+wmngvOs1nwxhTY4wZjrVDwmgRqV/xoNN8LprxXnT4z4WITAdKjTE7GjvMQ1uTn4l2nTCMMRect6DGmDVAiIgk+DmsNuPol10G/NUYk+vhkE6zxUpT70Vn+2wAGGPOAx8AU+o91Wk+F04NvRed5HNxJ5ApIkexdv6eICJv1zumRZ+Jdp0wRCRJRMTxeDTWz1Pm36jahuPnfA3Ya4z5TQOH5QEPO2ZAjAXKjTHFPgvSR5rzXnSWz4aIJIpInONxBDAJ2FfvsM7yuWjyvegMnwtjzE+MMb2MMf2wtlnaaIx5qN5hLfpMBPQsKRFZCNwLJIjICeDnWANZGGP+CMwGviMi14AqYJ7puEvX7wT+DvjS0UcL8FOgD7jejzXANOAQcAn4e9+H6RPNeS86y2ejB/CmWEXIgoAlxpjVIvI0dLrPRXPei87yubiBNz4TujWIUkqpZmnXXVJKKaV8RxOGUkqpZtGEoZRSqlk0YSillGoWTRhKKaWaRROGUkqpZtGEoZRSqln+P7zzOJO93gpXAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "result = [[get_mse(data[['sqfeet']], data['rent'], M, eta)\n",
    "           for M in Ms] for eta in etas]\n",
    "\n",
    "for r, eta in zip(result, etas):\n",
    "    plt.plot(Ms, r, label=eta, color='blue' if eta==0.8 else 'gray')\n",
    "plt.ylim(0, 20000)\n",
    "plt.xlim(1.5, 4)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Stochastic gradient boosting</div>\n",
    "\n",
    "<p>Don't use all data at each iteration:</p>\n",
    "<ul>\n",
    "    <li>subsample rows before creating each tree</li>\n",
    "    <li>subsample columns before creating each tree</li>\n",
    "    <li>subsample columns before considering each split</li>\n",
    "</ul>\n",
    " \n",
    "<p><i>Aggressive</i> subsampling (e.g., 50% of data) often proves\n",
    "    to be effective</p>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Summing up</div>\n",
    "\n",
    "$$ F_M(x) = f_0(x) + \\eta \\sum_{i=1}^M \\Delta_i(x) $$\n",
    "\n",
    "<ul>\n",
    "    <li>at each iteration $m$ we learn residuals $y_i - F_{m-1}(x_i)$</li>\n",
    "    <li>thus we use both <i>sign</i> and <i>magnitude</i></li>\n",
    "    <li>risk: chasing outliers!</li>\n",
    "    <li>possible solution: just learn $\\mathrm{sign} \\left( y_i - F_{m-1}(x_i) \\right)$</li>\n",
    "    <li>hint: don't evaluate using MSE, use MAE instead:\n",
    "        $$ \\mathrm{MAE}(\\mathbf x, \\mathbf y, F_M) =\n",
    "        \\frac{1}{n} \\sum_{i=1}^n \\left|y_i - F_{m-1}(x_i) \\right|$$</li>\n",
    "    <li>note: when learning regression tree stumps, choose splits according\n",
    "        to squared error minimization (for sake of efficiency)</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">A note on MSE</div>\n",
    "<ul>\n",
    "    <li>consider $L(\\mathbf x, \\mathbf y, F_M) = \\frac{1}{n}\\sum_i \\left( y_i - F_M(x_i) \\right)^2$</li>\n",
    "    <li>let $\\hat y_i := F_M(x_i)$, and note that $n$ is fixed</li>\n",
    "    <li>$L(\\mathbf x, \\mathbf y, F_M) \\propto \\sum_i \\left( y_i - \\hat y_i \\right)^2$</li>\n",
    "    <li>for each $k$ we have $\\frac{\\partial}{\\partial \\hat y_k}L(\\mathbf y, \\hat {\\mathbf y}) \\propto -2(y_k - \\hat y_k)$</li>\n",
    "    <li>thus $\\nabla L(\\mathbf y, \\hat {\\mathbf y}) \\propto -2(\\mathbf y - \\hat {\\mathbf y})$</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">A note on MAE</div>\n",
    "<ul>\n",
    "    <li>consider $L(\\mathbf x, \\mathbf y, F_M) = \\frac{1}{n}\\sum_i \\left| y_i - F_M(x_i) \\right|$</li>\n",
    "    <li>$L(\\mathbf x, \\mathbf y, F_M) \\propto \\sum_i \\left| y_i - \\hat y_i \\right|$</li>\n",
    "    <li>for each $k$ we have $\\frac{\\partial}{\\partial \\hat y_k}L(\\mathbf y, \\hat {\\mathbf y}) \\propto -\\mathrm{sign}(y_k - \\hat y_k)$</li>\n",
    "    <li>thus $\\nabla L(\\mathbf y, \\hat {\\mathbf y}) \\propto - \\mathrm{sign}(\\mathbf y - \\hat {\\mathbf y})$</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Why «gradient» boosting?</div>\n",
    "<ul>\n",
    "    <li>At each iteration of gradient boosting $F_m(\\mathbf x) = F_{m-1}(\\mathbf x) + \\eta \\Delta_m(\\mathbf x)$</li>\n",
    "    <li>Let $\\hat{\\mathbf y}_m := F_m(\\mathbf x)$, so that $\\hat{\\mathbf y}_m = \\hat{\\mathbf y}_{m-1} + \\eta \\Delta_m(\\mathbf x)$</li>\n",
    "    <li>Let $\\mathbf r_{m-1}$ denote the target residuals that we approximate via $\\Delta_m(\\mathbf x)$</li>\n",
    "    <li>Using this approximation we have $\\hat{\\mathbf y}_m = \\hat{\\mathbf y}_{m-1} + \\eta \\mathbf r_{m-1}$...</li>\n",
    "    <li>...that is, $\\hat{\\mathbf y}_t = \\hat{\\mathbf y}_{t-1} - \\eta (-\\mathbf r_{t-1})$</li>\n",
    "    <li>Compare this with the gradient descent update $\\mathbf x_t = \\mathbf x_{t-1} - \\eta \\nabla L(\\mathbf x_{t-1})$</li>\n",
    "</ul>\n",
    "\n",
    "$$\\mathbf r_t(\\mathbf x) = - \\nabla L(\\mathbf x_t) \\propto\n",
    "\\begin{cases}\n",
    "(\\mathbf y - \\hat {\\mathbf y}) & \\text{when chasing residuals,}\\\\\n",
    "\\mathrm{sign}(\\mathbf y - \\hat {\\mathbf y}) & \\text{when chasing sign of residuals.}\n",
    "\\end{cases}\n",
    "$$\n",
    "\n",
    "<p>Thus at each iteration the next improvement is chosen implicitly optimizing\n",
    "    via gradient descent either MSE or MAE.</p>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Gradient boosting in practice</div>\n",
    "\n",
    "<ul>\n",
    "    <li><a href=\"https://github.com/dmlc/xgboost\">XGBoost</a>\n",
    "        is a popular implementation of gradient boosting</li>\n",
    "    <li>it provides portability and scalability (e.g., it\n",
    "        runs on Hadoop and Spark)</li>\n",
    "    <li>it proved successful in several Kaggle competitions</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"header\">Sources</div>\n",
    "\n",
    "<p>The analysed experiments are from T. Parr and J. Howard, <a href=\"https://explained.ai/gradient-boosting/\">How\n",
    "    to explain gradient boosting</a>.</p>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.11"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": false,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": false,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": true,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
