{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Linear Models\n", "\n", "There's a few linear models out there that we felt were generally useful. This\n", "document will highlight some of them. \n", "\n", "## LOWESS\n", "\n", "Lowess stands for LOcally WEighted regreSSion and has historically \n", "been used for smoothing but you can also use it\n", "for machine learning where you're interested in interpolating. Here's \n", "a demo; " ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAsMAAAEICAYAAAC6S/moAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nOzdeXxU5fXH8c/JBmFLQNaEJSiLsqgg4oIrLrhVqdqqrVZbra2tdrO02NpqrVaqrdZW+7O2drG21VYtdccFlcUVBARBENkDSFjCmpDt+f1xZ2ASZiYzyczczMz3/XrNK7PcufckN5Azzz3Pecw5h4iIiIhINsrxOwAREREREb8oGRYRERGRrKVkWERERESylpJhEREREclaSoZFREREJGspGRYRERGRrKVkWEQygpldZ2afmtkuMzuomW2vMrNZrTzeiWa2NMrrZWbmzCyvNcdp68zsFDNb14r3P2hmP0lkTIH93mpmjyZ6vyKSeZQMi0gjZrbKzKoCSeU2M3vOzPr5HVc0ZpYP3AOc6Zzr5JzbkuxjOudmOueGhsSwysxOT/Zxm0pEYp8q4WJ1zn3dOfdzv2ISEVEyLCLhfMY51wnoA3wK/M7PYGIYXe0FtAc+TEE4acfMcv2OIZ1l+ui+SLZTMiwiETnnqoEngGHB58ysnZn9yszWBMoSHjSzwkj7MLOvmtkSM9tpZovNbHTg+clm9knI858Nec9VZjbbzO41sy3ArZGOa2ZDgGC5QqWZTQ9XomBmr5vZNc19z2b2NzO7MXC/NLCfbwYeH2JmW80sJ7Q8wMz+DvQHngmMqP8gZJdfDMS82cx+HOW4EX+uZva8mf06ZNvHzOzPZnYY8CBwXOC4lYHX/2pm/xd4327gVDM718zmmdkOM1trZreG7C/487rWzNab2QYz+36T2H4TeG194H67CN9H2PPaTKy3h7z/q2a2PPBzftrMSkJec2b2dTP72MwqzewBM7Mop7PAzB4JxPKhmY0J2VeJmT1pZhVmttLMvhXy2q1m9oSZPWpmO4CrzKzIzB4O/GzKzex2fcgQyQxKhkUkIjPrAFwCvB3y9BRgCHAkMAgoBX4a4f2fA24FvgR0Ac4HgiUMnwAnAkXAz4BHzaxPyNuPAVbgjfreEem4zrllwPDAe4qdc+Nb/A173gBOCdw/ORDDSSGPZzrnGkLf4Jy7AlhDYETdOXdXyMsnAEOB04CfBpLCcKL9XL8CXGFm483si8BY4NvOuSXA14G3AsctDtnfF/B+bp2BWcBuvPNQDJwLXGdmE5vEcCowGDgT+KHtL/v4MXBsILYjAse/OcL3Efa8NhMrAGY2HrgT+DzeVYnVwGNNNjsPOBo4PLDdhAhxgPf79ljge34auD9wnBzgGWAB3s/5NOA7Zha6rwvwPggWA/8A/grU4Z2bUYGfUbMfrkQkDTjndNNNN9323YBVwC6gEqgF1gMjA68ZXlJ1SMj2xwErI+xrGl7SFstx5wMXBO5fBawJeS3qcYEywAF54R4HnnsduCZk/7MixHEIsA1vsOBB4GvAusBrfwO+F7h/SvD5kJ/b6SGPgzH0DXnuXeDSMMds9ucKXASsBTYDJ4Q8f8D3gpe4PdLMz/s3wL1NYj005PW7gIcD9z8Bzgl5bQKwKtzPIYbzGi7W2wP3HwbuCnmtU+B3sCzw2DX53v8NTI5w3FuBV0IeDwOqAvePCf39Cjx3E/CXkPfOCHmtF7AXKAx57jLgtWT/e9RNN92Sf1MdlIiEM9E590rgMvAFwBtmNgxoADoAc0OuThsQ6XJxP7xE6gBm9iXge3iJGHiJT/eQTdaG3O8R53FbzDn3SaC04Ei8Ec6fA1eb2VC8keHfxrnLjSH39+B9n03F8v09g1e7vdQ5F8uEudCfH2Z2DN7o8wigAGgH/CfKe1YDIwP3SwKPQ18rIYwYzms0JcD7wQfOuV3mlcmU4n3YgNh+nkFNt20fKJ0ZAJQESzUCcoGZIY9DfxYDgHxgQ8j5yWmyjYikKZVJiEhEzrl659xTQD3e5f7NQBUw3DlXHLgVOW+yXThr8UZaGzGzAcAfgeuBg5x3yXwRXgK47/Ah9+M97u7A1w4hz/WO+s029gZwMVDgnCsPPL4S6Io30hmOi/B8LGL5/u4AlgB9zOyyGI7b9Pl/4pUK9HPOFeGNejettw3tGtIf76oAga8DIry2TwzntbmfUaPjmFlH4CCgvJn3xWst3qh7ccits3PunJBtXJPt9wLdQ7bv4pwbjoikPSXDIhKReS7ASwKXOK9W9o/AvWbWM7BNaZNay1B/Ar5vZkcF9jUokDB1xEs2KgL7+DLeiGVY8R7XOVeBl0Bdbma5ZvYVwiTlUbyBl9DNCDx+PfB4lnOuPsJ7PgUOjuMYofFG/f7M7CTgy3g1v1cCvzOz0pDj9jWzgmYO0xnY6pyrNrOxeDXFTf3EzDqY2fDA8R4PPP8v4GYz62Fm3fFqmcP18G3uvDYX67+AL5vZkYEJer8A3nHOrWrme4vXu8BOM/uheZMwc81shJkdHW5j59wG4CXg12bWxbwJlIeY2ckJjktEfKBkWETCecbMdgE78EYkr3TOBduW/RBYDrwdmGn/Ct4EsQM45/4TeP8/gZ3AVKCbc24x8GvgLbwEaSQwu5mYYj5uwFeBSXgT9oYDbzaz/1Bv4CWPwWR4Ft4o84yI7/Amft0c6HLw/SjbRRL2+zOzLsAjwPXOuXLn3Ey82tq/BDopTMdrKbfRzDZH2f83gNvMbCdeMvvvMNu8EYjhVeBXzrmXAs/fDswBPgAW4pUy3N70zTGc16ixOudeAX4CPAlswPsAc2mU76lFAh9ozsMrhVmJNzL/J7xJf5F8Ca+8ZDFeTfkTeJP8gguw7Ep0nCKSGuZca67siYhIujOzMrykMN85V+dvNCIiqaWRYRERERHJWkqGRURERCRrqUxCRERERLKWRoZFREREJGv5tuhG9+7dXVlZmV+HFxEREZEsMXfu3M3OuR7hXvMtGS4rK2POnDl+HV5EREREsoSZrY70msokRERERCRrKRkWERERkaylZFhEREREspaSYRERERHJWkqGRURERCRr+dZNQkREJBNMnVfO3dOWsr6yipLiQiZNGMrEUaV+hyUiMVIyLCIi0kJT55Vz01MLqaqtB6C8soqbnloIoIRYJE2oTEJERKSF7p62dF8iHFRVW8/d05b6FJGIxEvJsIiISAutr6yK63kRaXtUJiHSBrWmBtGv+kXVTUo2KikupDxM4ltSXOhDNCLSEhoZFmljgjWI5ZVVOLwaxO8+Pp+yyc8xbsp0ps4rj+u9Nz21MOp7khVzKo4r4rdJE4ZSmJ/b6LnC/FwmTRjqU0QiEi8lwyIpMHVeOeOmTGdgDAltuBpEF/jaXJLpV/2i6iYlW00cVcqdF46ktLgQA0qLC7nzwpG6KiKSRlQmIZJk8c42b67WMJhkxvPeZNcvqm5SstnEUaVKfkXSmJJhkSSLNmoa7g9opBrEUJGSTL/qF5s7bjz1xKo9FhGRVFIyLJJk8Y6aTpowtNFIcjiRkttw701W/WJo0lpUmE9+rlFb7/a9HjxuPCPj6tkq6SJRH9r04U/Ef0qGRZIs3tHa4B/Cu6ctpbyyCmN/zTAcmNw2/WN60VGlvPZRRcL/uDZNfnfX1O1LfiurasnPMbp2yKdyT22j446bMj3mkfF4R9FFUiXa739LP7Tpw59I26BkWCTJWjJaG1qDGG3kKNwf0yfnlid8Ak/T41RW1R6wTW2Do0NBHvN+emaj5+MZGY+0bXllFQMnP6eRM/FFLL//LfnQpg9/Im1Ds8mwmfUDHgF64Q1QPeScu6/JNqcA/wNWBp56yjl3W2JDFUlPoSO9LRmtjTY5J9F/TCMl3uGOE04wmQ3dT44Z9c4dsG24kfFo9dKhLdtAI2eSOvH+/jcn+O8j0u+6Jp6KpFYsI8N1wI3OuffNrDMw18xeds4tbrLdTOfceYkPUST9NU1og63WWlvKEG89cryjzMHEM9Y/ziXFhQfsJ1wiHGlkPJZ6aY2cSSqE/ls58Dc4vFgmqjb999HS/YhI4jSbDDvnNgAbAvd3mtkSoBRomgyLSAwSWScYTz1yc8eNNsocS4eLYIIbaRQt14wG56Im/01H0SMlIRo5k2SKJWFtKtaJqs2NMmvBDpHUi6tm2MzKgFHAO2FePs7MFgDrge875z4M8/5rgWsB+vfvH2+sIimXjJneiSxtaK4eublyhdDjRhtlvveSIw84Tn6O0al93gET5r77+Pyw+2lwjpVTzt0XV6SR8dBR9HFTpmupW0m5WMoiIv3+hxPrKHOpauJFfBFzMmxmnYAnge8453Y0efl9YIBzbpeZnQNMBQY33Ydz7iHgIYAxY8bEeuVJxBfJmumdyAUqotUjN42/ne2he34lB+Vtp73tpX1ODe2sBhrgul+8wllFOeyuL2BPQ3v2NBSypa4LW+uL6FnUJa6651h6Djf9uU76zwJ+9syHByQWqWwVJxIU7d+iQVwfjGMdZS4tLmT25PHxhioiCRBTMmxm+XiJ8D+cc081fT00OXbOPW9mvzez7s65zYkLVSS1kjXTO9ELY+wbSa3dAds/gh0vw7wlFM19i0f6b6FH3jZ65G2jY251i/ZfWdeJZX/tzdiDBjN7wnAoGg7FI6FLt7DbN5fAhvu51jY4tu3xZuiH+9ChPqySSpH+jbYkYY1llDnS1Rz9voukRizdJAx4GFjinLsnwja9gU+dc87MxgI5wJaERiqSYslaYjgho51Vn8Lmt7zbtnmwYwnsWbf/9ZwC+uX05NPabizYM4SKumIq6rpSUduVrfVFVDW0o6qhHTUuH4cBkEsD7XP20il3L4W2h4PydtAtr5IeedvoW7CJss2LqN81nVy31zuG5UDxEdBjHPQ4AXqdCu17NpvAxvLzC/3QoaVuJdUSeUUinlFm9R0W8UcsI8PjgCuAhWYWLAb8EdAfwDn3IHAxcJ2Z1QFVwKXOhZlCLpJGkrW0cdyjnc7B9kWwaYaX/Fa8CbsDXQxz8qFoJPQ8FYqGQdFh0GUYdBrIlXfNCBt/cCJbpH+gwT/Q5VsPfG+/4gJmfmMAVH4A2+Z78XzyZ1h2v7dBtzFQcjYTB0xk4g9PBbMD9hHLZDzQJDnxT2uvSMTSWjDcKLP6Dov4w/zKWceMGePmzJnjy7FFYhGu1q8wPzfhC1qEVb0ZNr4MG6bBxpegakMggD7Q/Tjofrz3tdtoyG3fovgjTU4rLS6MONHHYN8kuH0aar3EeMM0WP8CbHkbXAN0GgQDLoGyy6Ho0KhxhaMaSklHsfx+R/p/ZODk52L/dycicTGzuc65MeFe0wp0IhGktF7VOS+hXPdfL6HcOhdwUNANep8OfSZAr/HQcQBT56/n7v8tZX3lNkqK34y5TVnT+KNdCo60IEDYUfGcfDjoaO824mbYuwXW/hfWPA6L74QP7/DKKA75KvS/+IC4mi5tGxpHOKqplLasNa0Fk3U1SkSi08iwiF9cg1dmsPYp77Z7lVeH2/046D3BS4C7HQU5ufvekujR6kiJZcKOU/UprHwEPvkT7FwG7Q6Cwd+EId+E9j2bjSNcvL6N1ovEoDWju/r9FkmeaCPDSoZFUsk52PwmrPqHN3pavdEbWe19BvS7EErPh/Y9Ir49WmlDoksKEjoC6xxsegM+uhfKn/ZKOw7+Cgz/EXSIfZ+p/P4l8yXjKkNrf0d15UMkOVQmIeK3ncth5d9h1aOwawXkFkLJOdDvIu9rQVFMu0lWh4twEtrFwQx6neLdtn8EH/0alj8EnzwMg6+DYZOhsFezu0nl9y+ZLVmdG1rbiULdU0RST8mwSLLs3QKrH/eS4C1vA+a1HxvxEy8Jzu+8b9NYR4Myoqaw6FA45o/eqPCin8Oy33lJ8Ygfw9BvR5wQCBny/UubkKzODeqNLZJ+lAyLxCimhLV+L6x/zkuA1z/ndVooGg5HToGyL0KHvmH3G+sIVUatyNZpIBz7Z29UeN4kmD8ZPv4DjL4H+k0M+5aM+v7FV8m8yqDRXZH0omRYJAZRE9YjS7w64JV/hzX/hppt0L4XDL4eBl4BXY8M2283KJ4RqowcdeoyBE7+H2x8BeZ+B2Z+FvpOhDG/O+DDQ0Z+/+ILXWUQkSAlwyIxCJew9rI1bH37n7B29v464L6f9RLg3qdDTmz/vOIdocrYUafep8PZ8+Cj38DCW+DZYd6I+uCve102AuL5/jUZSSLRVQYRCVIyLBKDYGJanLuD84pncmHxdEZ3XEqDM+g4Hkb81OsGEVIHHCuNUIXIyYdhk6D/RfDu12HON73ey8f8GTr2i2tXWtpWotFVBhEJUjIs0pz6vXyhz3ucXDCNUzrPoSCnjo+qBnDnhqt4p+Espn7xkrBvi3VUUiNUYXQ6GE6dBp/8Ed7/Hjw/EsbcDwMvj3kXWtpWmpMOV1l0dUMk+ZQMi4TjGmDTTK8f8Jr/cEePSirquvK3Lefx323jWVw9kML8PO68cGTYt8czKqkRqgjMYNC10Os0ePsqeOsK+PRVLynO69js29WGTdKdrm6IpIaSYZEg56ByAaz6J6z+F+xZ5yVdfSdC2RW8ufFQ/vrSJ6yvrqK0mYQ13lHJdBih8k3nQ+C012HRbV4rti3vwgn/gaJhUd+m8hNJd7q6IZIaSoZFdq2C1f/0RoG3L6bO5fLGztHMqLmSMeOu5DNHDQbgghK4YPSAmHapUckEy8mFw38GPU+EN78ILx4Nx/0V+n8u4ltUfiLpTv+PiKSGkmHJTnvWecshr37Ma4sGbCk8mvs3fJOpW49nW723Ity/p35CfU6HsKMw0Wr5NCqZJL1Ph7Pnw8yLYdbnvYU7Rt7mJctNqPxE0p3+HxFJDXPO+XLgMWPGuDlz5vhybMlSOz+BtU/B2idhyzvec0UjoOwLMOAyxt2/IuwfntLiQmZPHt/ouaa1fAD5OUan9nlU7qmlqDCf3TV11Nbv//dVmJ/LnReOVDKWCPV7Yc4N3gS7knNh3D8hv0vcu9HkJAlqi78L4f6f0f8jIi1jZnOdc2PCvaaRYclczsH2xfsT4MoF3vPdjoIj7vCWRO6y/5L5+soPw+4m3CXJcLV8tQ2ObXtqAaisqiU/x+jaIZ/KPbVt5o9rxshtB2P/AN1GeUnxyyfCyc/G1X5Nk5MkqK3+LujqhkhqKBmWzNJQB5vf8pZCXjcVdiz1nu9+PIz6tdcLuFNZ2LfGc0kylpq92gZHh4I85v30zLi+BYmRGQy+DjoNglkXw0vHeglxt1ExvV2TkySoLf8uaHKtSPIpGZb0V70ZNrzoJcAbpnnLIVse9DwJhnzL6wbRoaTZ3cQz4SpS4tyUJrqkQJ8z4IxZ8Pq58MqJcOJT0Kf5DyCanCRB+l0QyW5KhiX91NfAlrdhw8uw8ZVA/a+D9j2h9HwoPRd6nwkFRXHtNp5LkuES53A00SVFikfCmW/D62fDG+fBcX+HAeEXQwlq7kpAW6whleTQRDWR7KZkWNo+1wCVi7wFFza8DJvegPo9YDnQbay3FHLpuV4tsOW06lCxXpJsmjhHmjCnNl4p1KEETn8D3jgfZl8Ge7fAkG9E3DzalYC2WkMqyaE2fCLZTd0kpO2p3wtb53grwFXMgorZUFvpvdZ5CPQ+w2ux1esUKCg+4O1+jehpJLFteHrucrrN+xIndHiLB7Z9ldLjb4l4HiKds3FTpsfcWUQyQ7r8+02XOEXammjdJJQMi/9qtnu9foPJ75Z3oWGv91qXQ6HHCd6t16nQsX/UXTXXikh/SDJb8PzX1NZwb/9fc37xDH696csccvLP4zrPAyc/R7j/GQ1YOeXchMUraay+Bio/gOqNUF0BtTu8qxMdB3qrJhZ0Tfgh1WpNpOXUWk3ajrrdsHWeN/IbvAU7PlgedBsNQ64PJMDjoH2PuHYfbVY4oEvfGW7/+c/lu2tupMEZN/b8C394y2DUwzHvRzWkElZNJax+HDa8ABtfhbpdkbftfhwMuMxbJbGwd0IO35a7XoikMyXDkjy1u2D7ItgSmvgu8WqAAQpL4aAxMOCLXuLb/RjI69iqQ0abFa4/JJkv9PzXk8v31n6PBnL4Wtc/w8IyGPmTmPYTroY0P8fYU1PHwMnP6apCmmrxlaGqT2HpvbDs91C3EzoOgLLLvXKtDv28D+15naGqHHat9P7fW/MfmPsteP87cPBX4PCftzopVtcLkeRQMiyt11ALO5ZB5ULvj0Dw664V+7dp3xO6HQ39LvYS4G5HQWGfhIcSbURPf0gyX9Pz30Au31/7HQoL8jh74U+BBhh5S7P7iTRBMrioiq4qpJ8WTYqs3wsf/gKW3AUNNdDvczDsB9B1lNfnuqn23aHrEdBvIoy42Vv05+M/wMe/95Z+H/4jOPR73qIxLaArFiLJoZphiV3dbtj5sZf47lwG25fA9oWw4yMvIQawXG9Vt6IRXrurohFe8ltYGv6PR4JFq6m7e9rSsH9Ics1ocE6jfRkg4vn/7DAm1twCK/7qdR8ZeWtcv4+aUJf+4j6Hm9+Gd672EtoBX/B+Z7oMbtnBdyyD+T+Adf/zBgVOfDKu1RKDVDMs0nKqGZbY1VXB7tWwa/n+pHfnMu9+VXnjbTv09xLeknOgaCQUj/AmvLVw1CMRmusVHK43cH3gA6FG+9Jf1PPvHgZyYNFt3u/o8B/FvF9dVUh/MZ9D1wALb4VFt0OHvnDK81BydusO3mUInDQV1v4X3roSXhwN4x6D3qfFtRstzyySHEqGs019dSDZXQW7A7ddK/ffr/608fYFXaHzUO8/7S5DvdZmnYdA50GQ1yHl4cciUq/gpn9Icsz2JcJBqiFOfxF7RVsOHPNH73L3gh9DwUEw+Gsx7VOXp9NfTOewdge8eTmUPwMDr4Qxv4X8LokLot9noWgYzLwQXjsTxvw+5t/BIC3PLJJ4SoYzSV0VVK33RnD3BL5WrYc95bBnjZf0Vm9s/J6cfG+Et2MZlJ7nfe04EDoN9JLfdgf58Z0kTegfkoGTnwu7jUb70ktck6IsB479s7dk93vXeR/2Bny+2WNoUYb01+w53LncW7Bl5zI46ncw5JvJKe3qMhTOfAdmXwrvfR1ogMHXtWhXahUpkhjNJsNm1g94BOgFOOAh59x9TbYx4D7gHGAPcJVz7v3Eh5uFXIPXzqd6E+zd5H2t3hQ+6a3ZduD7cztAYYk3+7n03ECyG7h1KoP2fSAnN7XfUxuh0b70F++kqGDysHX7l3ls8GpGzr6cnIJi6HNm1OPo8nT6i3oOKxfC9DPA1cH4l72e5smU38mrG571OXjvG97/80O+GdcutEqiSOI0O4HOzPoAfZxz75tZZ2AuMNE5tzhkm3OAG/CS4WOA+5xzx0Tbb9ZOoHMN3qW4vVtgb8X+5HZfolvROOndWwGu/sD9WC607w0dSr1kt7B0//3Q5/K7pGTiWlsWafREk1HSXzyTopqe7y45u/j3oJsYVLiRvDOmQ/djUxKztDFb5sBrEyC3PYx/FYoOTd2x62u8hLj8aRj7Rxh0Tcxv1aROkfi0agKdc24DsCFwf6eZLQFKgcUhm10APOK8zPptMys2sz6B92am+r3eSGzNNqjZCnu37r8f6XFtYPtgn92m8jp7Lcja9/RGbg8a691v13P/8+167P+apSO68Yhl9ESjfekrnoltTftM72joxBUrbuO/g39I39fPgdNnQvHwpMUqbVDFbHjtbGjXHU57BTodnNrj5xbACf+BGRd4ZTudDobesSWymtQpkjhx1QybWRkwCninyUulwNqQx+sCzzVKhs3sWuBagP79oy+rmzSuAWp3Qu12b4Q2+LVm+4HP1W6P/HpDTZSDGBQUQ0G3wK2r959c6ON23aB9r8bJbZ4uzydacwttaDJKeoun1CVcklBR15XLlt/GzNE/8SY0nTHbKx+SzLd1Hrx+jtfv/LRXvc4Rfsgt8DpLvHw8zLrYqyeOoYWbyrxEEifmZNjMOgFPAt9xzu1oycGccw8BD4FXJtGSfbTKrlXw9MDmt7McyOvilRgUFHlfC3t7Ex/yu0B+4LnQhLddSKKbX6RR2zZCoyeZLZ6JbZGSh4aOA+HUafDySV5ydOab3r9tyVw7lnmlEfnFMP4V/xLhoIIiOPkZmHYMvHEeTHjb+1sShSZ1iiROTMmwmeXjJcL/cM49FWaTciC0g3jfwHNtS7vuXsP90IQ2v2h/wht8Lq9T1tfZZgqNnmS2eEpdoiYPxaVw0lNegjTzIjjlBW/ETjLP7rXeZDnwJsu1YPGLpOh0MJz4FEw/Dd78Epz8dNS/QyrzEkmcWCbQGfA3YKtz7jsRtjkXuJ79E+h+65wbG22/WTuBTlJKk+QkVLOtqFb8Dd6+Cg7+MhzzsD4UZ5raHfDSOK/V5GmvQbfRfkd0oKW/hbnf9tq7Db3e72hEMkZrV6AbB1wBLDSz+YHnfgT0B3DOPQg8j5cIL8drrfbl1gYtkggaPZFQzdaIH3wl7FrhrVLX6RAY8ePUBSfJ1VAHsy7xlo8/9cW2mQgDDLkBNkyDed+HnidB18P9jkgk4zU7MpwsGhkWkTbJOXjrClj1Dzj+n1B2md8RSWs5B3Ouh49/D2MfgkFf9Tui6Ko3wfOHe4seTXivza72KZJOoo0M56Q6GBGRNs3MK5HoeZJXMrFplt8RSWstu99LhA/7fttPhMHrMHTcI7B9Mcz/od/RiGQ8JcOS9qbOK2fclOkMnPwc46ZMZ+q8tjd3U9JMbjs48b9ev+8ZF8COj/2OSFrq09fg/e9C6flwxBS/o4ldnzNhyLdg2QNeP2QRSRolw5LWghPkyiurcOxfVEMJsbRau25wyvNeq8UZn/GWRZf0snuNVyfceTAc//f0a3l5xB3QsT+8cw3UV/sdjUjGUjIsaS3aohoirdb5EDjxSdj5Ccy+DBrCLI0ubUboVaJTp7zItmnne0nkSVO9tpnpJr8THP2gN+lv0R1+RyOSseJagU6krdGiGpJI4VuvnQRH/x7evRbm/wBG/9rvMCVE8JyVV1ZhQHBK+Nc73UPX6gW83fdhju2SxgtRlJwFZZfD4ikw4PNQPDLips22DhSRsJQMS1rTohqSKE17UiKMgjMAACAASURBVAdLbgAmjvoqVC6Ej+7xkpGDr1Li0QY0PWfBRHhi8Wtc0u1lfvfpJTy2pozZJ/kXY0KMvhc2vAjvfg3OmOWV7jQR/fdXv5ci0ahMQtLapAlDKcxvXAeoJUmlJZotuRl9D/Q+Hd79GjNm/0+16m1AuHM2sKCcO0of4J1dw/nNp1/IjKtE7bvDkXfB5re8ln9hqGRMpOWUDEtamziqlDsvHElpcSEGlBYXanU5aZFmS25y8mDc49ChPyNWXEVXNjTarqq2nhv/vUBdTVKo6TkrsFruH/BLalw+3147iXpyM+cq0cFXQrejYd4PoHbnAS+rZEyk5ZQMS9qbOKqU2ZPHs3LKucyePF6JsLRIpKSp0fPtusHJz5BHDX8su51CazzDv945jRSnUNNzdlOfPzO8cAXfX/sdNtZ2Jz/H2FNTlxkfUCwHxvwOqjfCotsPeDmm318RCUvJsIgIcZTcFB3Kz7bczGHtV/Krfveyv1K1MV2iTr7Qc3Zml7f4cvdneLjiAl7deQzFhflgsG1PbeZ8QOl+DBx8FSy994De1yoZE2k5JcMiIsRXcnPiyV/iV5u+wrnFs/lmz39H3KcuUSdX8JyNPmgHd/W9j4/2DqHHCfewasq5dGyXR2194w8qGfEB5Yg7Iac9vP+9Rk+rZEyk5dRNQkQkYOKo0piSh4mjSpnqbmXa3FXc2OtRllUP5OUdYw/YLtIlanWiSJyJR/RkYsX9UGkUn/0ch3Y+GMjgGtrC3jDiZm+Z5k9fh16n7Hsp1t9fEWlMI8MiIi0wcXRfJnz5GXIOGs3vD76H4R0bX36PdIlaqyYm2MJbYfObMPYP0HnQvqczuoZ2yA3QoS/MmwSuwe9oRNKekmERkZbKK4QT/0t+QQceP2wKh3ata/YStVpgJdDGV+DDO+GQq6HsskYvZXQNbV4hHH47bJ0Da/7jdzQiaU9lEiIirdGxH5zwJJ2mj+fFsf8HJz8HObkRN8/Yy/epVvUpvHk5FB0GR/32gJeDH0Qythyl7HL46New4EfQ97OQW+B3RCJpS8mwiEhr9TwBxjzgLdm84CYYdVfETbVqYgK4BnjrCqjdDuNfgbwOYTfL6BranFxvIY7Xz4blD8LQb/kdkUjaUpmEiEgiDPoqDP4GLLkbVv0z4mYZffk+BabOK+fB/7sWNr7MlE3fYOrKrn6H5J8+E6DXeK/vcO2uA16eOq+ccVOmZ0afZZEkUjIsIpIoR/0Gep4E71wNW+eG3UQtsFpu6rxyHn/hca4p+gvPVJ7Ig+WnZvfkQzOvdnhvBXz8QKOXNFFTJHbmXPiG8ck2ZswYN2fOHF+OLSKSNNUV8OIYoAEmzIHCXn5HlDHOumsqf+p5LfUul/M+vo+dDR0B7wPF7MnjfY7OR6+dDVvfg/NXQn5nAMZNmR62HCfrf1aStcxsrnNuTLjXNDIsIpJI7XvASVNh7xaYdRHU1/gdUWZwju92/iU987Zxw5of7EuEQZMPGfkz7/dt2e/2PaWJmiKxUzIsIpJo3UbBsX+BitkwVxObEmLZA0woeptfbrySD6qGNHop6ycfdh8LJefBkl9BzXYgw/ssiySYkmERkWQYcAkMuwmW/wE+ftDvaNLb1nkw70Y2djqNf26/qNFLmnwYcPitULMNlnpt5jRRUyR2SoZFRBIsOIv/kMeO5c2qY2h47wbYNMPvsNJT7U6YfQm060HvMx/jzgsP1+TDcLodBX0v8HoP11RqoqZIHDSBTkQkgYKz+IOrzHXO2c3/Bt9IaYcq2p03FzoO8DnCNPPml2D1P+C017xOHRLZtvnwwigY8VM4/Gd+RyPSpmgCnYhIijRdbnlnQ0euWXUztbXVMOOzULfHx+jSzIq/waq/w4hblAjHouuR0O8iWPob2LvV72hE0oaSYRGRBAo3W3/F3r7csPr73sjdO1eDT1fk0sr2xfDeN6DnKTD8x35Hkz5G3gK1O+Cje/yORCRtKBkWEUmgSLP1l+WeBEfeCasfgyWRl2sWvGRu5oVez9zj/+EtPSyxKR4J/T8PS++D6s1+RyOSFpQMi4gkULhZ/Pk5xp6aOgY+MpyXd5+Km38TlD/vU4RtnHPw9ldg53IY9zh0KPE7ovQz8hao2w0f/crvSETSgpJhEZEEajqLv7gwHwy27anFYdyw4pssqT6Y2pmXQuVCv8Ntez66B9Y+CUf+Enqd7Hc06aloGAy4FJbdr9FhkRg0mwyb2Z/NbJOZLYrw+ilmtt3M5gduP018mCIi6WPiqFJmTx7Pyinn0rFdHrX1+2uEq117rl55M5U1BfD6ObCn3MdI25hNM2iY90Om7zmJgX8byrgp05k6Tz+fFhlxszc6vPQ+vyMRafNiGRn+K3BWM9vMdM4dGbjd1vqwREQyQ7gJdRtqe3DlilugphJeP9frpZvt9qyn+rWLWbW3DzesuB6HUV5ZxU1PLVRC3BJFw7zOEst+6/2eiUhEzSbDzrkZgHq0iIi0QKQJddvbD4cTnoDti2DW56ChNsWRtSENtTD78zTU7uTaVT9id0OHfS9V1dZz97SlPgaXxkbc7E1GXHa/35GItGmJqhk+zswWmNkLZjY80kZmdq2ZzTGzORUVFQk6tIhI2xV1WdySCXD0g7BhmtdGLFtbrs37AVTM5gdrv8Xyvf0PeDnc6LrEoOuRUHIefHQv1O7yOxqRNisRyfD7wADn3BHA74CpkTZ0zj3knBvjnBvTo0ePBBxaRKRta3ZZ3EHXwPCb4ZM/wYe/8DVWX6z8u7dIxNBvM88mhN0kx4yBk59TDXFLjPgx1GyF5Q/6HYlImxXTcsxmVgY865wbEcO2q4AxzrmoU1i1HLOISIBz8NaXYNWjcNzfYeDlfkeUGptmwfTToMcJcOqLTF2wqdFS1uEU5uc2/jAhzZt+hte55PyVkBe+bEck0yV1OWYz621mFrg/NrDPLa3dr4hI1jCDYx6GXqfCO1+B9S/6HVHy7VoBMz8LHcvgxCcgJ/+AUfRc709LI6ohboHhN0P1p97VBxE5QCyt1f4FvAUMNbN1Zna1mX3dzL4e2ORiYJGZLQB+C1zqYhluFhGR/XIL4MSnoGi4t/rappl+R5Q8NZXw+nng6uHkZ6Gg676XQtvSNUT4U6Ia4jj1Ohl6nOitfFi/1+9oRNqcWLpJXOac6+Ocy3fO9XXOPeyce9A592Dg9fudc8Odc0c45451zr2Z/LBFRDJQQTGcOg069vdarm2d63dEiVdfzebnz6J2+8dctmQS436/NmIdcKROHJGelyhG3Ax71sHKR/yORKTN0Qp0IiJtSfueMP4VaNcNXpsA2z7wO6LEaahn/fOfpfued/jemu/y1u7Do/YSjtqJQ+LT+wy2tT+C8jdvYdDkpzUZUSSEkmERkbamQ18vIc5pD9PHw7YFfkfUes7BnG9QsvNFbi2/lme2719qOVIdcLOdOCRmU+ev58cfT6Q0bwOfKX5DC5qIhIipm0QyqJuEiEgzdi6HV0+Fuj1w2qte39h05BzMnwxL7uKBTZ/j7o1XHrCJASunnJv62LLEuCnTKa/cwwuDb6DA6jhj2QM0kEtpcSGzJ4/3OzyRpEtqNwkREUmSzoPgtNchryO8Oh42v+N3RPELSYQZ/A3+Wf218JuBLt0nkTfp0Pjdpks5pP06zi56M+R5keymZFhEpC3rfAic/obXceHV8bD+Bb8jip1zsOCmfYkwY+5n0oRDD6gDDtKl++QJTjp8cftxLK/uy/U9H8do0GREEZQMi4i0fZ0GwhmzocsQeON8b9W2tq6hHuZ+Gxb/EgZfB2PuB7NGdcDhqI9wcgQnIzaQywObPs9hhas4u+tcTUYUQcmwiIjvps4rZ9yU6dGXHC7s7Y0Q9zzJW63ug1vBNaQ81pjUV8PsS2HZ72Dod/clwkHBXsIHLqnh0aX7xAv9EPJM5cmU1/XhjsFTmXhkid+hifguz+8ARESy2dR55Y2WIA6WCgAHdk3I7wKnPA/vfg0W/QwqF8Bxj0B+51SHHdnerTBjIlTMhNH3wKHfjbhpSXEh5WESX126T46Jo0r3/04t/xTevRY2vgx9zvQ3MBGfaWRYRMRHd09bui8RDopaKpDbDo79C4z+DZQ/Ay8dB9s/SkGkMdj6Prx4FGx5B8Y9FjURBvUR9tXAK70Wfot+7tV2i2QxJcMiIj6KVBIQtVTADA79trdaXfVGeHE0fPx//iY1nzwMLx0Prg5OnwEDLmn2Leoj7KPcAjjsh1AxCzbN8DsaEV+pz7CIiI+8/q/hE9/S4kImTRgaPTncsx7e/jJsfAlKzoOxf4AOKawDrd4Ec74Fax6H3mfA8f+A9j1Sd3xpuboqeHogFI+E8S/7HY1IUqnPsIhIGxWuVCCovLKKSf9ZwKjbXoo8ua5DCZz6Ahx1n1f/+exQWHw31NckN3DnYMUj8OxhsO6/cPjtcMoLSoTTSV4hHPZ92PgKbH7b72hEfKNkWETER821GqttcGzbU4sjSh9ey4Gh34JzP4Rep8L8H8DzI2HNf7wWZ4n26Wvwyknw9pVQdBicPR9G/Bhywif10oYN+jq0OwgW3eF3JCK+UTIsIuKz5lqNhYo6ua7zIXDy017HCcuBWZ+HZw+Fj//gLencGg11sP5FeOVUb/GPXSvg6Ae9+uCiw1q3b/FPfiev/d36Z2HrPL+jEfGFkmERkTYi1pZizfbhLTkbzlkEJzwBBcXw3tfhyR4w61JY+xTUbI8toPq9UPEWzJsE/+sPr58NO5Z4nSzO/wQGf81LuiW9Dbke8ovgQ40OS3ZSn2ERkTZi0oShjXoORxJT0pyTC/0vgn4Xej1/V/0L1j7pTXQD6DwYuh0FHQdCQZGXDDXUehPi9lbA9kWwZQ407AXLg5JzYOCXoPQ8r71bHKbOK+fuaUtZX1lFSSyTAiW1CopgyA3w4e1Q+SEUD/c7IpGUUjcJEZE2JDRxLCrMZ3dNHbX1+/+fLszPbXn7sYY6r43W5jdh61yvL3DVeq8dWpDlQMFB0OkQ6DEOehwPPU6C9t1b/P00TfBb9T1IclRvhqfLoO9EOP5Rv6MRSbho3SSUDIuItGFJH1V1DuqroKYScvKhoFurJ8KFxpxjRn2YvzOlxYXMnjy+VceRBJs3CT66B85bCp0H+R2NSEJFS4ZVJiEi0oY1WkK3GS1KnM0gr4N3S4CmI8HhEmGIoe5ZUu/QG2HZ/fDhnXDsw35HI5IymvkgIpIBgkloeWVV9DZsSRZueelwYp0sKClU2BsO+SqsfAR2r/Y7GpGUUTIsIpIBwiWhUduwJUksI76F+blMmjA0BdFI3A6b5F0tWHyX35GIpIySYRGRDBApCU11OUKkEd9cMwyvVliT59qwjv1g4FXwycPeUt8iWUDJsIhIBoiUhKa6HCHc8tKF+bn8+vNHsHLKucyePF6JcFs3/CZw9eo7LFlDE+hERDJAuB7F8ZQjJKprRfA96iucXpqe/0cPv4yByx+Cw26ETgf7HZ5IUqm1mohIGmmatJx6aA9e+6hiX19iM6jcUxtXEqpewNkt3PkfULiN6UOuIbfsEjjubz5GJ5IY0VqrqUxCRCRNhOsY8ejba/Y9rqyqpbq2gXsvOTKucoS2MvlO/BHu/K+u6srj28+HVY/C9sU+RSaSGkqGRUTSRCxty1qSxLaVyXfij0jn+VdrJ0JuB/jgpymOSCS1VDMsIpImYk1Og9vFWgdcUlxIeZh9xzr5Lumr5ElSRTr/hZ17ewtxLPqZt3x3t6N8iE4k+TQyLCKSJmJNTkuKC+NahCNSB4hYJt+1lcU+pOWinv/Dvuct0b3gZp+iE0m+ZpNhM/uzmW0ys0URXjcz+62ZLTezD8xsdOLDFBGRcElLU8EkJp464ImjSrnzwpGUFhfG3QtY9cbpL+r5z+8CwybDhhdh00y/QxVJima7SZjZScAu4BHn3Igwr58D3ACcAxwD3OecO6a5A6ubhIhI/KJ1kwgtURg4+Tki/e9u0OpyhmAc4S6vB4+xcsq5Ldq3tDF1e+DpQ6DzIDh9hrdCnUiaidZNotmaYefcDDMri7LJBXiJsgPeNrNiM+vjnNvQomhFRCSiiaNKY0pgI9WBAo3KGYL7jEe4Vlzhji8ZIq8DjPgJzPkmbJgGJWf5HZFIQiWiZrgUWBvyeF3guQOY2bVmNsfM5lRUVCTg0CIiEk4sJRUtLWdorqtFPIt9iD+mzitn3JTpDJz8HOOmTG++xvuQa6BjGSz4Mfi0PoFIsqR0Ap1z7iHn3Bjn3JgePXqk8tAiIlmlaR1oJC1pnxbtPfHUG4s/WjTpMbcARt4K296HtU+kKlSRlEhEMlwO9At53DfwnIiI+GjiqFJmTx7PyinnUhqhbKEl5QyR3lNaXBjXYh/ijxZPeiy7HIpGwPzJUL83iRGKpFYikuGngS8FukocC2xXvbCISNvSmvZpydyXpF6LF1nJyYVRv4JdK2DZA0mITMQfzU6gM7N/AacA3c1sHXALkA/gnHsQeB6vk8RyYA/w5WQFKyIiLRMcrY11cYxoC2nEuy9pW1q1yErJBOgzARb9HA6+EtodlIQIRVKr2dZqyaLWaiIibVO4bhGF+bmqBc4QrT6/lYvghSNgyA1w1G+SGKlI4kRrraYV6EREpBEtpJHZWrPICgDFI+Dgq71SiR0fJzVWkVRotkxCRESyS4trSiVtxNqvOqLDb4PVj8H734NTnklcYCI+0MiwiIg0Eql2NMcs9r60ktaa7UNc2BtG/hTWPwvlz/sTpEiCKBkWEZFGIi3YUe9c7H1pJW3F3Id4yLegy1CY+221WpO0pmRYREQaaVpTmmsHLtuhGuLMFXPNeG4BjL4Pdi2Hj+5NYYQiiaVkWEREDhC6YEdDhK5DqiHOTHHVjJdMgL4XwIe3wx5dKZD0pGRYRCRLNVsXGhCphrglq9dJ2xf3+R59LzTUwfvfTWJUIsmjZFhEJAvFXBeKVpzLNnGf704DYcRPYM1/oPy5FEQoklhKhkVEslA8vYRb3ZdW0kqLzvdhk6BoGLz3DajbnbJYRRJBfYZFRLJQvL2EW92XVtJK3Oc7twCO/gO8ciJ8cAuM/lXyghNJMI0Mi4hkIdUBS8L1PAEGXQtLfwNb5/kdjUjMlAyLiGQh1QFLUhw5Bdp1h3e+AvU1fkcjEhMlwyIiWUh1wJIUBV1h7B9g23z48Bd+RyMSE9UMi4hkKdUBS1L0vQDKLocP7/Dudxvld0QiUWlkWERERBLrqPu8com3r1S5hLR5SoZFREQksdp1g7EPQeVCWHir39GIRKVkWERERBKv72fgkKth8RT49HW/oxGJSMmwiIiIJMfo30DnwfDm5bB3i9/RiISlZFhERESSI78TjPsX7N0E71wDzvkdkcgBlAyLiIhI8nQbDUfcCeumwvIH/Y5G5ABKhkVERCS5Dv0u9DkL5n4HtrzndzQijSgZFhERkeSyHDj+USjsAzMvgurNfkckso+SYREREUm+dgfBCU9A9SZ48zJoqPc7IhFAybCIiIikykFj4OgHYOMr8MHNfkcjAmg5ZhEREUmlQ66GLe96/Ye7HAYHf8nviCTLaWRYREREUmvM/dBrPLx7DWya6Xc0kuWUDIuIiEhq5eTDiU9Ax4Ew87Owc7nfEUkWUzIsIiIiqVfQFU55zluI4/VzvIl1Ij6IKRk2s7PMbKmZLTezyWFev8rMKsxsfuB2TeJDFRERkYzSeRCc/AzsWQevnQW1O/yOSLJQs8mwmeUCDwBnA8OAy8xsWJhNH3fOHRm4/SnBcYqIiEgm6nE8nPgkVC6EN86H+mq/I5IsE8vI8FhguXNuhXOuBngMuCC5YYmIiEjWKDkbjnsENs2AWZ+H+hq/I5IsEksyXAqsDXm8LvBcUxeZ2Qdm9oSZ9UtIdCIiIpIdyi7zehCXPwOzLob6vX5HJFkiURPongHKnHOHAy8Dfwu3kZlda2ZzzGxORUVFgg4tIiIiGWHwdXD0772EeOZFKpmQlIglGS4HQkd6+wae28c5t8U5F/wI9yfgqHA7cs495Jwb45wb06NHj5bEKyIiIpls8HVw9IOw/jmYMRHqdvsdkWS4WJLh94DBZjbQzAqAS4GnQzcwsz4hD88HliQuRBEREckqg78Gx/wJNr4Mr54G1Zv9jkgyWLPJsHOuDrgemIaX5P7bOfehmd1mZucHNvuWmX1oZguAbwFXJStgERERyQKHXA0nPAmVC+CVE2D3ar8jkgxlzjlfDjxmzBg3Z84cX44tIiIiaWLTLHjjM5DbHk6aCt2P8TsiSUNmNtc5Nybca1qBTkRERGI2dV4546ZMZ+Dk5xg3ZTpT55U3/6bW6HkCnDELcgvhlZNh5aPJPZ5kHSXDIiIiEpOp88q56amFlFdW4YDyyipuemph8hPi4uFw1nvQ/Th46wqYNwka6pJ7TMkaSoZFREQkJndPW0pVbX2j56pq67l72tLkH7zdQTD+JRj8DVjyK3j1FNi9ttm3iTRHybCIiIhEFSyNKK+sCvv6+gjPJ1xOvrcwx/H/gG0L4IUjofzZ1BxbMpaSYREREYkotDQikpLiwhRGBJR9Ac6aCx37e5Pr3rkWanemNgbJGEqGRUREJKJwpRGhCvNzmTRhaAojCugyBM58Cw6bBJ/8CZ4fCRunpz4OSXtKhkVERCSiaCUQpcWF3HnhSCaOKk1hRCFy28Oou7xuEzkFMP00eOsqqK7wJx5JS0qGRUREJKJIJRClxYXMnjzev0Q4VI/j4ez5MOwmWP1PeHYofPwgNEQe0RYJUjIsIiIiEU2aMJTC/NxGz4WWRqS873AkeR3gyF/A2Qug65Hw3nWBCXbPg08LjEl6UDIsIiIiEU0cVcqdF46ktLgQo3FphG99h6MpOgzGvwonPAH11fDGuTD9dKh407+YpE3TcswiIiLSIpHarQVLKHxXXwPLH4JFt8HeCuh9Ooy4xVvVTrKKlmMWERGRhIs0uS5lfYebk1sAQ6+HC1bCqF9B5Qfwyonw0jhY86RqigVQMiwiIiItFGlyXcr7DjcnryMcdiOcvxKO+i1Ub4RZF8Mzg2HxXVC9ye8IxUdKhkVERKRFmptc1+bkdYChN8B5y+DEJ6FDX5j/Q5jaF2Zd4k22q6/xO0pJsTy/AxAREZH0FGyrdve0payvrKKkuJBJE4a2jXZr0eTkQr8Lvdv2xbD8j7Dyb7Dm31DQFfpdBAMuhZ4nQ45SpUynCXQiIiIi9TWw8SVY/Tismwp1u6B9T+j3Oeh7AfQ80VvkQ9JStAl0+rgjIiIiklsAped5t7oqWP88rH4MVjwMHz/gJcI9T4Y+E7xbl8PAzO+oJQGUDIuIiIiEyiuE/hd5t7rd8OkbsGEabJwG73/P26ZDX+h5KvQ4DrofB0UjVFKRpnTWRERERCLJ6wil53g3gN2rYcNLgeT4JVj19/3bHTTWS4y7HQ1dD4eOZWDqVdDWKRkWERGRpJk6rzz9JthF03EADPqqd3MOdq+CzW95t4o3YfEvwQX6F+d1guKRUHy4dysaDp0HQ2EflVi0IUqGRUREJCmCyzVX1XrJYXC5ZiBsQpx2ibMZdBro3cq+4D1XtxsqF3kLfARvqx+H5X/Y/768jtBpkJcYdx4MnQdBx/7QoT906OeVaUjKKBkWERGRpLh72tJ9iXBQVW09d09bekCSG2/i3GbldYTux3i3IOegqtxr47bz4/23ygVe5wpX13gf7Xp4SXHHftC+l3dr1xMKm9zPL9YIcwIoGRYREZGkiGe55ngS57Rj5k2469AX+pzZ+LWGWtizFnavhT1rYPeawOM1sPMTr/yiugII0wo3J99LjAu6Bm7FXoIcvF8QuJ9fDPmdILejl6zvu3XyFiLJ8rpmJcMiIiKSFCXFhZSHSXzDLdccT+KcUXLyodPB3i2ShnrYuxn2boLqT73lo6s/3X+/phJqtnlJdM1C737t9thjyC1snCTndvRKNXIKIKed9zW3XePHoc+Fey0nHyzP67Bhefsf9zypzZWBKBkWERGRhAmt+y0qzCc/16it3z+qaXglEOOmTG9UExxP4px1cnK9sojCXsDI2N7TUA91O/cnynW7vHrm4K1+d+PHTW/1VVC3Bxq2QUMN1O/1vjbsbfI4zuWrJ66FvL5x/wiSScmwiIiIJETTut/Kqlryc4yuHfLZtqcWY//F/qY1wZMmDG30XoDC/FwmTRia4u8iQ+Tk7i+VoCx5x3HOK/VomiS7OmioC3yt3f+4XY/kxdJCWo5ZREREEmLclOlhR3dLA6O74V7LNaPBOUqKCzn10B689lFF+nSTkLSh5ZhFREQk6VpS91sfGJQrr6ziybnl3HnhSCXAklLZPX1QREREEiZSfW9JcWFMtb/B7hEiqRRTMmxmZ5nZUjNbbmaTw7zezsweD7z+jpmVJTpQERERadsmTRhKYX5uo+eCdb/hXgsn47tHSJvTbJmEmeUCDwBnAOuA98zsaefc4pDNrga2OecGmdmlwC+BS5IRsIiIiLRNwfKGaKvIBV/LMdtXIhFK3SMk1WKpGR4LLHfOrQAws8eAC4DQZPgC4NbA/SeA+83MnF+z80RERMQXE0eVRqz5DX2taecJUPcI8UcsZRKlwNqQx+sCz4XdxjlXB2wHDkpEgCIiIpJ5Jo4q5c4LR1JaXIjhdZzQ5DnxQ0q7SZjZtcC1AP3790/loUVERKSNiTaKLJIqsYwMlwP9Qh73DTwXdhszywOKgC1Nd+Sce8g5N8Y5N6ZHj7bXdFlEREREskssyfB7wGAzG2hmBcClwNNNtnkauDJw/2JguuqFRURERKSta7ZMwjlXZ2bXA9OAXODPzrkPzew2YI5z7mngYeDvZrYc2IqXMIuIiIiItGkx1Qw7554Hnm/y3E9D7lcDn0tsaCIiIiIiyaUV6EREREQka5lfpb1mVgGs9uXg0B3Y7NOxJXl0XjOTzmvm0rnNTDqvmSudYBSQVQAAAwtJREFUz+0A51zY7g2+JcN+MrM5zrkxfschiaXzmpl0XjOXzm1m0nnNXJl6blUmISIiIiJZS8mwiIiIiGStbE2GH/I7AEkKndfMpPOauXRuM5POa+bKyHOblTXDIiIiIiKQvSPDIiIiIiJKhkVEREQke2VlMmxmnzOzD82swcwyrkVINjKzs8xsqZktN7PJfscjrWdmfzazTWa2yO9YJHHMrJ+ZvWZmiwP/D3/b75gkMcysvZm9a2YLAuf2Z37HJIljZrlmNs/MnvU7lkTLymQYWARcCMzwOxBpPTPLBR4AzgaGAZeZ2TB/o5IE+Ctwlt9BSMLVATc654YBxwLf1L/XjLEXGO+cOwI4EjjLzI71OSZJnG8DS/wOIhmyMhl2zi1xzi31Ow5JmLHAcufcCudcDfAYcIHPMUkrOedmAFv9jkMSyzm3wTn3fuD+Trw/rqX+RiWJ4Dy7Ag/zAzfN0s8AZtYXOBf4k9+xJENWJsOScUqBtSGP16E/riJtnpmVAaOAd/yNRBIlcCl9PrAJeNk5p3ObGX4D/ABo8DuQZMjYZNjMXjGzRWFuGjEUEfGZmXUCngS+45zb4Xc8khjOuXrn3JFAX2CsmY3wOyZpHTM7D9jknJvrdyzJkud3AMninDvd7xgkZcqBfiGP+waeE5E2yMzy8RLhfzjnnvI7Hkk851ylmb2GV/evSbDpbRxwvpmdA7QHupjZo865y32OK2EydmRYssp7wGAzG2hmBcClwNM+xyQiYZiZAQ8DS5xz9/gdjySOmfUws+LA/ULgDOAjf6OS1nLO3eSc6+ucK8P7+zo9kxJhyNJk2Mw+a2brgOOA58xsmt8xScs55+qA64FpeJNx/u2c+9DfqKS1zOxfwFvAUDNbZ2ZX+x2TJMQ44ApgvJnND9zO8TsoSYg+wGtm9gHeIMXLzrmMa8MlmUfLMYuIiIhI1srKkWEREREREVAyLCIiIiJZTMmwiIiIiGQtJcMiIiIikrWUDIuIiIhI1lIyLPL/7daBAAAAAIAgf+tBLooAgC0ZBgBgK33PRjFsvnRYAAAAAElFTkSuQmCC\n", "text/plain": [ "
\n", "\n", "![](_static/lowess-span-2.png)\n", "\n", "You may need to squint your eyes a bit to see it, but lower spans cause more \n", " jiggles and less smooth curves." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ProbWeightRegression\n", "\n", "> Note, this is a somewhat experimental feature. We found this feature to be plausibly useful but we've not seen it cause a big \"win\" yet. \n", "\n", "Let's say that you're interested in combining a few models for a regression task. \n", "You could put them together in an ensemble. Say we've got predictions $y_1, y_2, y_3$, each of which come from respectable models, then you may want to combine these together in another linear regression. This way the new, hopefully best, prediction $y_*$ is defined via;\n", "\n", "$$y^* = w_1 y_1 + w_2 y_2 + w_3 y_3$$ \n", "\n", "This can be a valid way of reweighing. But there's one issue:\n", "technically the weights $w_1, w_2, w_3$ can sum to a number that isn't one. Since that's \n", "numerically totally possible we need to be aware that we can end up in a strange situation. \n", "\n", "The `ProbWeightRegression` adresses this. It assumes that every input it receives is\n", "the output of a model and it will ensure that they are reweighed with a constraint in mind. For this usecase, it would optimise;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\\begin{equation} \\label{eq1}\n", "\\begin{split}\n", "\\text{min} & \\sum_i (y_i - (w_1 y_{1,i} + w_2 y_{2,i} + w_3 y_{3,i}))^2 \\\\\n", "\\text{subject to} & \\\\\n", "& \\text{ } w_1 + w_2 + w_3 = 1 \\\\ \n", "& \\text{ } w_1 \\geq 0, w_2 \\geq 0, w_3 \\geq 0\n", "\\end{split}\n", "\\end{equation}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The final positivity constraint is optional in our model. \n", "\n", "Here's an example usage." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from sklearn.datasets import make_regression\n", "import pandas as pd\n", "\n", "X, y = make_regression(n_samples=1000, n_features=10, random_state=42)\n", "df = pd.DataFrame(X)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We've turned the array into a dataframe so that we can apply the `ColumnSelector`." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from sklearn.pipeline import Pipeline, FeatureUnion\n", "from sklearn.linear_model import LinearRegression\n", "from sklearn.decomposition import PCA\n", "from sklearn.model_selection import GridSearchCV\n", "\n", "from sklego.meta import EstimatorTransformer\n", "from sklego.linear_model import ProbWeightRegression\n", "from sklego.preprocessing import ColumnSelector\n", "\n", "pipe = Pipeline([\n", " ('models', FeatureUnion([\n", " ('path1', Pipeline([\n", " ('select1', ColumnSelector([0,1,2,3,4])),\n", " ('pca', PCA(n_components=3)),\n", " ('linear', EstimatorTransformer(LinearRegression()))\n", " ])),\n", " ('path2', Pipeline([\n", " ('select2', ColumnSelector([5,6,7,8,9])),\n", " ('pca', PCA(n_components=2)),\n", " ('linear', EstimatorTransformer(LinearRegression()))\n", " ]))\n", " ])),\n", " ('prob_weight', ProbWeightRegression())\n", "])\n", "\n", "grid = GridSearchCV(estimator=pipe, param_grid={}, cv=3).fit(df, y)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "GridSearchCV(cv=3,\n", " estimator=Pipeline(steps=[('models',\n", " FeatureUnion(transformer_list=[('path1',\n", " Pipeline(steps=[('select1',\n", " ColumnSelector(columns=[0,\n", " 1,\n", " 2,\n", " 3,\n", " 4])),\n", " ('pca',\n", " PCA(n_components=3)),\n", " ('linear',\n", " EstimatorTransformer(estimator=LinearRegression()))])),\n", " ('path2',\n", " Pipeline(steps=[('select2',\n", " ColumnSelector(columns=[5,\n", " 6,\n", " 7,\n", " 8,\n", " 9])),\n", " ('pca',\n", " PCA(n_components=2)),\n", " ('linear',\n", " EstimatorTransformer(estimator=LinearRegression()))]))])),\n", " ('prob_weight',\n", " ProbWeightRegression())]),\n", " param_grid={})
FeatureUnion(transformer_list=[('path1',\n", " Pipeline(steps=[('select1',\n", " ColumnSelector(columns=[0, 1,\n", " 2, 3,\n", " 4])),\n", " ('pca', PCA(n_components=3)),\n", " ('linear',\n", " EstimatorTransformer(estimator=LinearRegression()))])),\n", " ('path2',\n", " Pipeline(steps=[('select2',\n", " ColumnSelector(columns=[5, 6,\n", " 7, 8,\n", " 9])),\n", " ('pca', PCA(n_components=2)),\n", " ('linear',\n", " EstimatorTransformer(estimator=LinearRegression()))]))])
ColumnSelector(columns=[0, 1, 2, 3, 4])
PCA(n_components=3)
EstimatorTransformer(estimator=LinearRegression())
LinearRegression()
ColumnSelector(columns=[5, 6, 7, 8, 9])
PCA(n_components=2)
EstimatorTransformer(estimator=LinearRegression())
LinearRegression()
ProbWeightRegression()