Skip to content

Instantly share code, notes, and snippets.

@sharow
Created May 25, 2016 13:34
Show Gist options
  • Save sharow/c95b09fe8bc53c9c8ac684a658674510 to your computer and use it in GitHub Desktop.
Save sharow/c95b09fe8bc53c9c8ac684a658674510 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"{'divide': 'warn', 'invalid': 'warn', 'over': 'warn', 'under': 'ignore'}"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%matplotlib inline\n",
"\n",
"# Machine Learning by Andrew Ng\n",
"# https://class.coursera.org/ml-005/lecture\n",
"# Logistic Regression with One Variable (Week 1)\n",
"# https://d396qusza40orc.cloudfront.net/ml/docs/slides/Lecture6.pdf\n",
"\n",
"import random\n",
"import math\n",
"import numpy as np\n",
"from functools import partial\n",
"\n",
"import matplotlib\n",
"import matplotlib.pyplot as plt\n",
"\n",
"np.seterr('ignore')"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def sigmoid(z):\n",
" return 1. / (1 + np.exp(-z))\n",
"\n",
"def make_h(theta):\n",
" def h(x):\n",
" return sigmoid(np.dot(theta.T, x))\n",
" return h\n",
"\n",
"\n",
"def gradient_descent(data, alpha=0.001, max_iteration=300):\n",
" epsilon = 0.0005\n",
" theta = np.zeros(data.shape[1] - 1)\n",
" temp = theta.copy()\n",
" m = data.shape[0]\n",
" print(data.shape)\n",
" #samples = list(zip(data_x, data_y))\n",
" r = []\n",
" y = data[:,-1].T\n",
" samples = data[:,:-1].T\n",
" for i in range(max_iteration):\n",
" h = make_h(theta.copy())\n",
" hx = h(samples)\n",
" #cost = np.array([-np.log(x) if np.isclose(yy, 1) else -np.log(1 - x) for x, yy in zip(hx, y)])\n",
" for j,_ in enumerate(theta):\n",
" temp[j] = theta[j] - alpha * np.sum((hx - y) * samples[j]) / m\n",
" r.append(temp.copy())\n",
" #print(temp)\n",
" if all(np.isclose(temp, theta, rtol=epsilon)):\n",
" print('local minimum found. iteration:', i)\n",
" break\n",
" theta = temp.copy()\n",
" else:\n",
" print('giveup! local minimum not found.')\n",
" return r"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def gen_feature(x, y):\n",
" return np.vstack([np.ones(x.shape), x, y, x**2, y**2, x*y, x**3, y**3, x**4, y**4])\n",
"\n",
"def gen_datasets(N=4, dist=4):\n",
" x = np.array([random.random() * dist for _ in range(N)])\n",
" y = np.array([random.random() * dist for _ in range(N)])\n",
" dx = 2\n",
" dy = 2\n",
" z = [1 if (np.sqrt((x-dx)*(x-dx)+(y-dy)*(y-dy))) > 1 else 0 for x,y in zip(x, y)]\n",
" #z = [1 if x*y > 1.5 else 0 for x,y in zip(x, y)]\n",
" datasets = np.vstack([gen_feature(x, y), z])\n",
" return datasets.T"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(240, 11)\n",
"local minimum found. iteration: 2213\n",
"[ 3.65195462 1.97034109 1.52421939 0.25664173 -0.09306913 -3.33140552\n",
" -1.63056589 -1.35911616 0.61435219 0.61223779]\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAegAAAFwCAYAAABzZegiAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnX+8VVWd9z9fLtik3RtTkcK9hsio6YyKD1IpTuI0GqCj\nU5NlGUo5qYiYj8ao/PCC4K+0shBQGxsV7Zc+M2UKps8YMahDSCL6QEhG5L0XiRm9cYWeR4L1/LHP\nvnffc/c5Z/9ae6+19uf9et0X58c+56zF3nt91vfH+i5RSoEQQgghZjGo6AYQQgghZCAUaEIIIcRA\nKNCEEEKIgVCgCSGEEAOhQBNCCCEGQoEmhBBCDCSyQIvIIBH5pYg8GvLeASLyfRHZIiLPicgHsm0m\nIYQQUi7iWNBfBrCxxnsXAXhDKXUEgDsAfDVtwwghhJAyE0mgRaQNwGQA/1zjkHMA3F95/AiAj6Vv\nGiGEEFJeolrQ3wAwE0CtsmOtAF4DAKXUPgDdIvKe9M0jhBBCyklDgRaRMwHsUEqtByCVvwGHhTxn\nDVFCCCEkIYMjHDMewNkiMhnAOwE0i8gDSqkLAse8BuBQAF0i0gSgRSn1ZvUXiQhFmxBCSOlQSoUZ\nt3WROJtliMipAK5WSp1d9fplAP5KKXWZiJwH4O+VUueFfF6pDc/HbaM1zFtyN+ZddknRzYjOrh5g\n0RJg6hTgvmXAjMuAluaah1vXv5i43D+X+wY40L/OLmDS2cCKR4HWEQPeNqJ/q1YDY47vP0bs6gHW\nvwh89JRUX21E/zQix52YSKATr4MWkfkiclbl6b0A3iciWwBcCeDapN9LcqSl2RPnSWd7/9YRZ0KI\nJnb1eBPkFY96/+7qKbpF4Yw53pvQ++3zJ/hjji+2XQ4TS6CVUj/3rWelVLtS6rHK4/+nlPq0UuoI\npdRHlFK/1dBWkjW2DAyEuIovcjMu8yznGZf1F0GTaGnua19nV1+7ObHXBiuJZciEcWOLbkJ0EgwM\nVvUvAS73z+W+AXX6t2r1wGt6V4/3ugmsf7G/yPkiuP7FfocZc/40ed2M6Z9hxIpBp/4xx2PQVqEx\nnkSIMQQnoi3NA5+TgdQbG3w3d8S8FeKRewyaWM5HTxl4Y7U0U5yJW9AtG59asebRo+1xxzsCLWhC\niPs0yJImVYSt8PAtaHrdYkMLmhBCwmAyZHzCYs30uuUOBZoQ4i42ZUmbBCc1RkCBJiQtpmcKl5mI\nWdIkACc1xkCBJiQtLOBgLnTLxseUSQ0nvhRoQlLDTGHiEqZMajjxpUATR8l79s2yqYRkCye+FGji\nKHnPvplU4yZ0sxZLySe+FGjiJnnOvplU4y50sxZLySe+LFRC9GFCOdE8ClSY0E+ij5jbspKMcKhM\nKwuVEPMo2vrIa/ZtSlIN0UPJ3ayFYUo2eYFQoIk+ikzyoNuZZEXJ3ayFwYkvBTozmEwSTlHWB2ff\nZmD7fcGJXrHYfv2khAKdFUW7c31Mu6CLsj44+zYDU+6LpHCiVyy2Xz8poUBnhSlr9ky6oE21Pkyb\nxLiMKfdFUjjRKxbbr5+UMIs7a0zY1s6UrFNTs5sdyg61BhPuC2Ivll8/zOI2AVOSSUzJOjXV+ij5\nrDx3TLkviJ2U+PqhQGdF1u7cNG7YEl/QkTFlEuM6poY5iB2U/PqhQGdF1skkSWPJJb+gI8NJTD4w\nyYqkoeTXD2PQJpMklmxq3NckGIPOH16XpMQkjUFToE3H8uQII6FY5A8nRaTEMEnMReiG1YOpyWsu\nw8S8fOFSQiegQJsKY8nENZiYlx8m1UMgiaFAm0rJkyOIBoq2qugRyg96LJyAAm0qdMOSrCnSqqJH\nKH/osbAeCjTJjqItNFKfIq0qeoTyhx4L66FAk+xg3Mt8klhVWUy86BHKF3ossqcAA4QCTbKDca/8\niTtoJLGqOPGyD3ossqeA+4ACXTSuuYUZ98qXMccD180FOrd7z/1BY/TogddQUquKEy/7cNFjUfRY\nWcB9QIEuGtesE8a98qWlGZh1DTDjSmDzK5XKcxcA9z0w8BpKY1Vx4kWKxoSxMuf7oKFAi8g7RGSN\niLwgIi+JSHvIMReKyO9F5JeVvy/qaa6DuGSdMO5VDK3DgZsXAOd+Dph0hifOYddQGquKEy9SNCaM\nlTnfB5FKfYrIgUqpPSLSBOAZAFcopX4ReP9CAGOVUlc0+B6W+qyFCyU9WUKzGPyJ0aQzgKlfAh7+\nHnDUEdl/P8t0EhMoaqxMcR9oLfWplNpTefgOAIMBhKl67B8nFVyxTlyMe5lO74YqFwArnvTE+bo5\nfTHpLGDCEUlDlrHjWmNlHvHpAu6DSAItIoNE5AUArwN4Sim1NuSwT4rIehH5oYi0JW5R0YkAeUO3\nMEnD+hf7Ys4zLvMs50V3ADfdmt01xIkXSUNWseN6Y2Ue8ekC7oNYu1mJSAuAHwG4XCm1MfD6nwN4\nSym1V0QuAfBppdTHQj7f2MVdNnca3cIkLbyGiOkk2Tq3mkbXeRa/oYnctpsUkevhifHXa7w/CMAb\nSqmhIe+p9ku/1Pt8wrixmDDuxIFfYvB/NMkQCgsh5SGP2LEhuTwr1z6PlWvX9T6ff9e39Qi0iLwP\nwF6l1B9E5J0AfgrgFqXU8sAxhyilXq88/gSAmUqpk0O+K3qSmCH/0UQjtbwlY08ATj6Jwk2IK+Rh\ndBls2OlMEhsO4Gcish7AGgA/VUotF5H5InJW5ZgrROTlSpz6cgBT4zakH64kTZH61Fo2cfJJxa93\ndJWy5XiQ4skjz8bRXJ7YLu5UP8YYNAkjzFtS5GzYZdc77y+SN3ncT4bfs7nFoNMQSaAN/48mGVNP\niC1c72gFBrsCicFwbE6M1nXQmdLIvcYlHeWhnluqyDCHCRWLdFJ02U662e3EhFKbJSN/geYJJj61\nFv4/+1zx8aSiRUwnRed4cKC3E9cnrgaSv4t79c/oXiP1McGV5qob2BT3vav/v2WAK2xiY1cMmieY\nmIwpIqaDJJMfXRMmjgP2wYlVIuyKQZd9CRVjcGbjcu3pJDkeOlzSHAfsw9GlTCZTTAy67CeYMbj+\nmDZhYaJif7KOPXKgtxOXJ65ZUWssS0gxMWim6dNVFMRll7JLZOWSNiHHgBAd1BjL5AcPWxSDJh6M\nwfXBCYvZ8PwQEo2Qe0VOOc2SGDTxYAyuPy4va4qCaW7+6nbQJa0Xk88/iUeGYxkFugg44A2k7BMW\nk/MSGHvUj8nnn8Qjw7GsOBd3meNQZe57GIxBe9CNXG54/u3HmRg0B2XiwwlLH8xLKDc8/3ZTYyyz\nLwbNsnHEpyzLmhrFGYty8zP+aQZlD/O4QK2xLCHFxqDLnhhEykW9OGOReQmMfxYP81JICMUKNGeM\npEzU8xqFJWKNPcHbOCSIDsuW3qziYSIeCYExaELyJmqcMe97hPFPQrRgTy1un3ozRsbEiKvE8Rrl\nadnSm0WIcRQn0PUSgxgTIy6SJM6YR56G6fFPTthJSTGzUAljYsRFksQZ87BsTY9/csJOSorZtbgZ\nEyNlhnkafdhcxIPr/EuPfTHoRjAmRsqO6ZZtXNK4qm1ekkkPAEmImQJtekyMkDxwrYBLGqGyecLO\nkJ29FJz/YKZAu2Y5EEKSC5ULE3bTPABMvItGwd4PMwXaNcuBEOKRRKhcmLCb5gGg2z0aBXs/zE4S\nI4S4hc3JXkkxNdmvjOciKSkTlt1LEiOEuIULruokmOoBMM3tbipB78dNXwU6tw98X1NogAJNCMkH\nU4VKN6aG7Exzu5tI9aRy1jXAjCv7RFpzaIAubkIIKRumut2zJu0a9LDPd24HbroVmPVPkUMDSV3c\nFGhCCCkbZSmeomsiEjMmzRg0IcQcuIzHbEx1u2eNjizsHEMDFGhCSPZwGQ8xhSyT4XJOdKRAE0Ky\nh9WziClkafHmnOjYMAYtIu8AsArAAQAGA3hEKTW/6pgDADwAYCyA/wLwGaXU70K+izFoQsoEN7wh\nRWJIMlzSGPTgRgcopf6fiJymlNojIk0AnhGRFUqpXwQOuwjAG0qpI0TkMwC+CuC8uI0hhDhEteUS\ncVDci82pfnYIjkr1eeIQ9SxeC+LtsbK4ReRAeNb0NKXU2sDrTwBoV0qtqYj460qpYSGfd9+CLkt2\nJOkPz3t/KpbK3hmnAy0HAbt2Y9CiH2L/jE97z+ugjj0m1U/LSxsjH0sxJ3mgzYIGABEZBGAdgNEA\nFgfFuUIrgNcAQCm1T0S6ReQ9Sqk34jbIevzkmDCXCnEX/7yPPQE4+STvNf+8OyzUtaxdWf8CVEWc\nfcHd95cfhDyzHmr8OK1tiirw8tLGuta68+LNSaXxxLWgWwD8CMDlSqmNgddfBnCGUqqr8vzXAMYp\npd6s+rz7FjTAGrdlZVcP8LU7gL17gSFDgKuv9F53IEGqnpCltXhNJMwKd06wDYnPlgGtFrSPUmqX\niKwEMBFA8Ap+DcChALoqLu6WanH2mbfk7t7HE8aNxYRxJ8Zts/kE0/pXPMqLvSy0NAMXX+Sd97Mm\nAz09xk/QtnZsx9w7n0Tnzia0DtuH6y8fjVFtA6JThYjwK/hTpOOOjDeMRSKsv3urRNt6wQ5m2ttg\nTFhk8a9c+zxWrl2X+nuiZHG/D8BepdQfROSdAH4K4Bal1PLAMZcB+Cul1GUich6Av1dKDUgSowVN\njEDXjR4874vvAh5bbnT28isdqzHp4o34TcfXARwEYDcOb7sKy1edg1GjsmtzVKGtZh+Oi3RcEzbE\n/u60ol5tYVst1rZk2lts8Wsr9SkixwK4H96a6UEAfqCUulFE5gNYq5R6rLIUaxmAEwD8N4DzlFK/\nDfku9wXa4ouoNOg4R9W5BtWubgPOfbWb+sJrn8L3lt8JT5x9duO882fh/ge/EPl7GwlwVKHNi3qC\nnlS4g4JtlVjbZkzY1t4KrMVtCha5YYxG9/9j1je6316gv1A/+xyw7oXcB5KwmHG12/aM0x7Az1d+\nfcBxp552FZ58+oIBr9cTYtNEOClh4h1XtK0Ra1uNCVss/gAUaOIWeQweOm70Aido1aLcKG584ef/\nBd9/6CaEWdCzH5wy4PgiRLj58eXYPf5k7B86tPe1Qd3dOOiZZ9Fz5mTtv59GsI0XahuNCVrQ+qBA\nk1jovBktvdGDxBXkarZu7cLk01fgN6/eAj8G3Tb6Gnz7qY9j+KiPZ9fQEDZtinbckF3dOO6b12PD\nl2/A3pahA5434uijUza0imrBjiLWxgu1Ldhq8YMCTVxFh5Vr6Y2eVpCBgW7qjq3b8a25a7GzS2HY\nCMH0BVPQNmpkqnZGEd8j9hwQ+fuaeroxYsls7JgyEwcvuw1dl92Ifc2NxXnLgW/XfT+teKcRawp1\nAmy0+CtQoIl76LJyLbrR04pyWNw4C1d1PRGOI75ROaDrtzj27FF46dGteHvEYZl8Zy0BTyLcQbGm\nUJNqKNAuYpGQZI6lVm5aTBTkWmKsQ4jDSGpBJ6FatOOKdRyhpuu7PFCgXcRFkYo66SjR5CRrUU4j\nyGFinJcQh+GLsy/K1c91k0awfbGOKtQUaXehQGeBiaLgQDJTP1ycdCQgjShnaSWbJsjVtKx+HLuP\nH99PjJt6unHQi89g1yln5tqWpGJNobYMDTpgj0DfeYd5Ihhsh4niYeG6v7q4NumISJainJUgmyTG\nNhEU6yyFmiJtABp0wB6BXv0zM0XQxzTxMK09WaF70mGIN6RoUaYg6yWuUEeJUVOkDSDjcdcegd7w\nvPmiY4rFaqpFn5Y8zn+B/3cU5XLii3UcoaY1bTAZ6oBdAg2YI4LVmDR50GEFFm1Z5imcOZ/LoDDn\nKcoUZLOIKtS0pnMiyZhHC9oQEQziqsUapOg+5j1B0DwRpCiTWsQVaoq0JuKOeVGOjzmO2SPQJseg\ni7Yu88LUCVJSap03f6OKjPuZlQubouw+UWPUFGnNxBnzouhATNG3R6BNzuIuE6aGGJIQdrN87Q7v\nPX+rxwwmgllYyxTlchLFmrZepE03cLIe82KIvj0CbfI66LLgmgUNDOzT2BOAk09KPVgktZbTuLAp\nym7ivEgXHT6L0rasx7yIok+BJtEw+SZKS4Yz5KKtZYqyuzQSaidE2qTJv64xjxY0yRzT3VBJyWhg\nSCLMWVnLFOXykIVIGynQgHnhMx1jnrMxaAq0uyJZFClnyLSWSRE4KdImWtA6cDaLmwLttpu5CBJO\nePIWZooyqSaNSBvn6ua4VhMKtG2UZaZpIBRmYhLOiDQ9gzWhQNuIabEax0kbX6Ybm+girUgbIdCk\nJkkFepCOxjjJqtXebDDIrh7v9STs6vEs5xWPev9WfzfJjL3YjL3YDHXsMb1/jXgFf+oV5304LrbF\nvGmTJ8r+HyH18K+RsO0/gcaTw+rlgMQNKNBRGXO855L2hdR3UY85Pv53BWMzrSO8f4PfTVLji3JQ\nmKOQVJh9UQ4KMyFxiHLNhO0FHidMQ+yCLu44ZBU3ZqxGG4wvE9vZcuDbdHU7BmPQecG4caFs7diO\nuXc+ic6dTWgdtg8LLj8Do9qGU5iJM0SJRxufMEb6kVSga29GSgZSHTdm5nWubO3YjtMv/ile7bgF\nwEEAduO5DVdhxT3HYFTbMAoz6Udn5zYsXXofdu7cj2HDBmHatKlobR2p7XNZccSeA7DlwLexaVNt\nkX4Ffxog0urYY3pFmrgBBToq1Wv6/LgxRTo35t75ZECcAeAg/Kbj62h/aBbuf/DUSN9BYS4HnZ3b\nMH36InR0zIc/mXv55XYsXjyjrtgm/VzW+CIdxj4c128vaZIjOYcnmSQWlfUv9hdjX6TXv1hsu0pE\n584m9Imzz0HY3tXU8LNps7IBJn/ZxNKl9wVEFgAOQkfHfCxdep+Wz+miVlY3UDthjBndGskyWTgC\ntKCjEjY7amlmUleODB/WDWA3+ov0bgwfsa/u54LCHIegMJeNot28adm5cz/CJnPe69l/Tge0og0k\n6D3NocgUBZoYj28RzLt8DNZsvha/ebUvBn346Gsxb8Gk0M+lFWagvOJsgps3DcOGDULYZM57PfvP\n6SRuLBrw7hkmi2mipdkTZz9ZWGOIky5uYiz+OmbAc90dNulULH9qEs47fxZOPe0qnHf+LCx/ahJG\njeqfTV/tzo6Kv44ZKLc72zQ3bxKmTZuKtrZ2eGILALvR1taOadOmavmcLupdg7Wuba6L1kyORaZo\nQRPjqLdkatSoEbj/wS+Efi6LspxlFeUgJrl5k9LaOhKLF8/A0qW3B9z0jT0AST+nm3pWNMmRnJOF\nKdA24nChk6DFHAfGmbPDRDdvElpbR2LhwvbcPqeLRrHoV2qsi6abWwP1koWLyOIWkTYReVpENorI\nSyJyRcgxp4pIt4j8svI3J/OWkj5yziTMgyRlOYE+d3bSetlAMnHu7NyGOXPm45JL2jFnznx0dm6L\n/R2mYpqbl3jUy+iuxgg3d9b7F5jAR08ZaClrTBZuWElMRA4BcIhSar2IvAvAOgDnKKV+FTjmVABX\nK6XObvBd9lcSMwVHtqtMWgEMKM5qDkuiamuzK4mqEbZncbtIrRKg9SqLFWpBc3/oXrRVElNKvQ7g\n9crjt0RkE4BWAL+qOjT2j5MUtDQDx3xwYCahRa7uotzZQDqXdu0kqtuNco2mwTQ3L6lPrWzuQsl5\nSZKLxDqjInIYgDEA1oS8/REReQFAF4CZSinWnNPJrh5g/QbgrMnAPfcCV1/pve7PUA0mrTADxcaa\nXUiiIuGY7jkISxartSZaHXsM9hZtRee4JMlFIgt0xb39CIAvK6Xeqnp7HYCRSqk9IjIJwI8AHJld\nM0k/fFfR1VcCzz4H/Hw1cMttwJAhfUK9arWRVrStVnMQHUlUpgtDGTB9/Xe9ZDFj4f4FqYgk0CIy\nGJ44L1NK/bj6/aBgK6VWiMgSEXmPUuqN6mPnLbm79/GEcWMxYdyJiRpeaoKZhCef5InxY8uB+XO9\n9w20om23moNMmzYVL7/cPiAGPW3ajETfZ7owlIUyhC5ypcT7F6xc+zxWrl2X+nsibTcpIg8A+C+l\n1FU13j9YKbWj8vhDAH6olDos5DgmiWXNrh7ga3cAe/d6z30r2pAboIgkMED/8qksLd45c+bjiSe+\ngmqLfOJECkOeXHJJO9atmz/g9bFj23H33QNfL4J6iWLAwH2iC00Uc3g5aFy0JYmJyHgA5wN4qRJj\nVgBmARgJQCml7gHwKRGZBmAvgD8C+EzchpAEBF3dPT1enOesyUW3qpekVjNg/rrmLJOo8opp041e\nH1vWf8eJQxcK9y9ITZQs7mcA1N0uSCm1GMDirBpFIuK7uoG+OM8993px6YlnFNq0vGPNgL1FR/IQ\nBrrRG5N16EIHSeLQLFhiL2ZNDctO3IX9/kzUj+u0jvCs6XUvaK0PW4+kBUcAO8U5i4IleRQGcaG+\ntm78Mp8TJ96OsWPbMXHi7dZPYGregy4WEXEQwxbOlRy/QljYwv4wVq0G9uwZmHQx9oRC4jwuu7TD\nyMoqzaP+M5eGRaM067/jjjWkEMplQZs+awxmOnZ2Nc54HHO8Zy37+DfZySflKs7Vu07FIWmpTqB4\nl3aWVqkvDHffPR8LF7ZnbrX1udGDmBdfJTkRd6whhVCuu9OGGtbBhf1Tp9S/YQy4yYLCXAaXdhDd\nVmmW9b5ZX5sMIM5YQwqhXC5uG0rPxV3YX2ClniJc2oAZ4gzoTe7KOqnL1G0USYGwiIjxRFoHndmP\nmbIOurOrT9BaRxTdmj6SFJcvYNOMNGubATfEGdC7aQbXRpNaZLJpBjeyyJWk66DdcHHHiS1XzxoL\nynYOpd5eo2EEb6rWEX3eAY19SuPSBtwRZ0Bv1i+TuohW4o41pBDccHFHzUg0vfRc3IX9OW8ensal\nDaA3GSwJpomzj66sX1uKZhBz2Ifj8EoNK3oALCJiBW7c7VGTpVybNea4eXjaeLOL4qwTJnURQtyK\nQZsaW7acopLBgHKKsw9Lc5IwasWggfA4dKH1uPPE4Nrf2mpxW8MTTwLPremfkQgYcXJyQdPFSXEu\njtIUzSCZUCtJrDQ4WHzFjbO5q8cTZwBorritv3aH99zfH9l1Mr44s4g3AxTntNCKJiQiNiyjjYkb\nAr3+xT4h9k8OAJz0YatPTiwyvDhdEmebBY4bXCTH5vNOUlBgXQgduCHQQRdu8OSULQ6dwcWZVpx9\nTBFnmwWudilRroWuhwnnnROEgnCs+IobWdw+Jq9xzoNdPcBNXwUe/m7//kesN56FOKfJ1vbJyq1t\n+w5OXAudjKLPuz9BeOKJr2DdOq/gzPTpi1KVaiURKKAuhG7cEWgHT04s/P7PugZ45N+AqRdUlp1t\nj1Rv3ARx3rQp25iz7QLHDS6SUfR5L3qCYARFbEzk2jJauCTQDp6cWPj9f/VVT5zvewD41CeBm271\nntf5f8hKnNPgu7azxHaB41roZBR93oueIASRlzbm/psAitmYKMe6EHlhx0gVBQdPTiz8/o85viLO\nnwDO/SxwxWXe8xo3RpbibELcOYjtAqezlKjLFH3ei54gVFPIGmgDdtpzAbcKlRCPzu3AjCuBOdcC\nC28BFt0BtA4fcJgJ4gxk79oOwmSdclLkede5iQoQb7OMwouUsHgUgOSFSijQruG7kj71Sc+Cfvh7\nwCP/Gjp73YvNqbO1TYs7E2ICOicI1gh0ATvtmQoFmnisWg2MHu25tf0bY+oFXmw64O43RZwBCjQh\nUaknzgDMEWhuZ9mPcm83SfrwY9DBbPaqGHRwP+ekpE0K83FJnDs7t2HOnPm45JJ2zJkzn8tqSK7U\nLPPpSkZ1Ef0oGAq0azS4MUyKO7sE174SY3Elo7qIfhQMBdo16twYWVUJA9KJs49L1jPXvhLT6HVv\nu5JR7Uo/YuBGqU8SmSzizmlxMTHMpLWvhAzAlRrVrvQjIrSgS0IWSWE+WVjPrlFr7WtX18uMSZNM\naJQgVhdXyiC70o+IUKBLQBZJYUA2dbZdtJ6B8OIYTU3TsX37QsakiXbq7gPtShlkV/oRAwp0ScjK\neibhVFf9Gj78Auzbdw0A3+RhTJrkR78Sn66UQXalHzGgQNtAiuUFWbm2s7KeXaa1dSQWLmzH3XfP\nx4gRf4U+cfZhTJokY8uBb8f+TO/6Z1fKILvSjxhQoG0g4fKCrFzbWeKiezsM0+oxE/tJHH8m1sLR\nwgZSLC8wxXouG0Vv2EDKQ934M7EanllbiLm8wDTr2XX3djV+THrp0tsD9Zi5ExXRT2FbTJLMoUDb\nQvXygggWdFbWc1aUxb3t48ekCWlEvc01asWf67m3C93BimRGQxe3iLSJyNMislFEXhKRK2oc9y0R\n2SIi60VkTPZNLTExlxdkbT3TvU2IPqKUiQ2LPwN0b7tOlBj0nwBcpZQ6BsBJAKaLyAeDB4jIJACj\nlVJHALgEwF2Zt7QoTCjQnmB5AZdVEVso+yYjWZaJreneNmEcKxNh/98JaCjQSqnXlVLrK4/fArAJ\nQGvVYecAeKByzBoA7xaRg1O3zgRMKNAeY3lBGutZHv8PoLvvonoFf8Kg7h40P7488XcCxcSfyz7o\n2wI3GalfJjZJ9bBQ9/aY44Hr5gKd273n/jg2ejRFWgfVupGQWFncInIYgDEA1lS91QrgtcDzTgwU\ncTuxsEB7UutZjR+Dptl39or0oO4evH/2D7B7/Mmp25Rn/NmlQd/1iQY3GUm+JC+We7ulGZh1DTDj\nSmDzFm8cm3rBgK1oSUZU60ZCIp9hEXkXgEcAfLliSfd7O+QjKux75i25u/fxhHFjMWHciVGbkJxV\nq72LMCiqu3o8F3GURe5JC7Sn/d2YpI49D23GvhsvR9PsO7Fv5oU4+LZ/QdeNi7F/6NBsGpgTtQf9\n241P2gomCx100B5s3vwH7NjxDXh92Y2XX27H4sXuZINzkxFvSd7LL7cHrllvSd7Eqy6J9T0Ns7db\nhwM3LwTO/Sxw37f79o032NiwlZVrn8fKteuAwU2ebiQkkkCLyGB44rxMKfXjkEM6ABwaeN4GIHTa\nMO+yeBddJvjuBv9iDCZdRSFBBnUmv5uA1LHnoc3YN/NCHDDqTPzX1h9bJ86AvYO+b/kHB2pgLoD/\nqjy3Z6KM1qI3AAAgAElEQVQRlT7rMXi+ylXQpdaSvD1tw7Nxb/vs6gEe+VdPnKd+CXj4uxRnTUwY\ndyImHHWUN96veBTzE4p01LvgOwA2KqW+WeP9RwFcAAAi8hEA3UqpHYlapIM0buo0BdotdI+juwdN\nt92PzVt/jPfethyDuruLblFsdFfx0uV2DrP8gQUA7gscZf5EIw4s6OIRLBO7cGF7Qw9J7Oxtfxyb\negGw4klPnIMxaZIt1bqRkIZnWUTGAzgfwEsi8gI81/UsACMBKKXUPUqp5SIyWUR+De9O+0LiFuki\nqZu6Xga1Tvd4TDJZWtXd47m3b7wce4e+E9tvvAHDZ1+P7TfeYJUlXctlOG3ajNTfHWblZuV2rmX5\nA0FBdsu6ZEGXcGolh9WioXt7/Yt9MWd/PFt0B3DTrcDNC8w2GmykWjcSIkqFhoq1ICJKbXg+t9/r\nR+8Mcko8N7Ulv5vFphjy+H9AjR8DDG3uLe85qLsbBz3zLHrOnJz4e4vYYrJe4Yc0zJnjJZ1Vu2Qn\nTkzvdq713cAt8Cxpb6LhUgyahFMvezvMepaXNjYuTpJzTgzpQ447EUqpsFytupRjlXvQ3RB0O+sW\n6aJ+NyHqzL8e8Nr+oUNTiXNR6KripTO+HWb5H3LILBx55CDs3t1O67IkJNm5KhJhIuz4blC2Uw6B\nTuum1vW7nNFah86kpnB371UU5BISJzkskvVMrKQ8Lm4Tqbawq5/HIKt9n32y3MGqCBe3LsJi0HQ7\nk6zwrefM3dukUOjitpGg2ztFjDprcSa1YVIT0U1c65m4CwW6aHLK8ibZwV2qskNXMp+NNIo911pa\nRevZXSjQRZO0CAohlqNzyVqt3zN9MlAa65n5N5FwZ0GljaQpgmIAHVu34brPL8Q/nrYA131+ITq2\n1i7YoS0zlVhLnnW4Ta/PXjrr2YRNiCyAAl0kCbaRNIWOrdtw6el3YcVD1+D5lQuw4qFrcOnpd4WK\ndJyCC6Q85FmS1YZNOeKW9bQaG6ssFgAFukhibCNpGovnLkPHqzeg34D36g1YPHdZkc0iFqG7JGsQ\nk+uzJ7GencjcDubfTJ1CcQ6BAk0SsbNTIXTA68pv2R6xmzzrcOc5GUhCqaxnn+r8G0tCe3lS3NW5\navXAE7Krh5uHW8KwVkHogDei9lI/xqFJEH/J2sSJt2Ps2HZMnHi7tgQxUzflaFRzO1frOc8x2fL8\nm7worlBJhkU6CqfgjERd66DrFSvxY9B9bu7daBt9PeZ95+/wv+55Gjs7FYa1CqYvmIK2Ud6A61LB\nEmIfpmVxNypKAuQs0HmOySXL4k5aqKTYSmJFbWCRNWkv7JQXaxECDXgivXjuMuzsUhg2QvAPF/8N\n5n3xJwNE+66nLkXbqJEUaEIC1LOeC6sa5sqYbBh2CjTgZfD5RTpS7JtZOGku7JQCX5RAV3Pd5xdi\nxUPXoLpO9aTzb8XND87Bpk3eKxRpUnaMs56DuDImG0RSgS42Q8KlJIE0GYmOLDlolDjG5VaE9GFM\n7DmIS2OyAxQn0K4lCaS9sFMuOdBVVahWJmlYkZIkiWOElI1Gru3CcG1MdoDiBNriIh0DyOLCTiHw\numbVtaoX1SpS8g8X/w3aRl+Pfpmyo6/H9AVTej979NHM5iblJcq1X5j17NKY7AjFx6BdIG1GYgbZ\nk3nGoevFmqcvmNIvcSyYxe3DZDFSVpImhgEWl/Uk3G6yUMJEOE5FsHozVwOWHDRhQz+Rrhdrbhs1\nEjc/OKfu9x19NLBp09sUaVIq0ri2Kc7lxIwyOmXH4JKfYTN6xpoJiUca13ZusHiUcVCgHWEIjtJ6\nMwdn+NMXTGkYa24EY9GkbBhvPXOHKeNgDNohdMWhgYGx6OoiJWGx5kZwXTQpA1Fc28bEnlmoRAuM\nQRPtBGPRUWLNjfBi0Vm0jNiCaeU2dZPUte2Te+y5pRk45oN9hUp8cXa4DKfJ0MXtEDrd3PUGkbTQ\n1V0OOju3Yfr0RXjiia9g3br5eOKJr2D69EXo7By4h7gL1KsWBtR3bRe2neSuHmD9BuCsycA993rP\n6eouDAo0iUXWhRT8wYsi7T5Ll96Hjo756LeHeMd8LF16X4Gt0ksa13bu+EJ89ZXAtTO91265Dfja\nHXR1FwQF2kFss6JZArQc7Ny5H6HL83buL6I5Wmm0jSRgmGsb6L/cs6UZuPgi4LHlwJjjKM4FQYF2\njDxubF3lCGlFu82wYYMQujxvmFvDUKPruJFruzCCyz2DlQ03/orlPguCWdwOshebASC3jO6sYFZ3\neuIkYeWdsOXHoPvc3LvR1taOxYtnOJMoFjXubEzWdhh57gvt4/j+0PZuN0m0oHPJFaBXpBsJdFJh\ncT2DOI4AFiWWLp+DRuIM1C7nCRSYGFZNEWJZxKQgRyjQpB95WNEAchfppMJSButtzhwvM7q6RvrE\nibdj4cL2xMeSaDSKOzcSZ8AA67lIHF6Dbed+0EQbum90ncuugNpxvKSZwGXIII6ThFWmhK08iCLO\ntaA4V0i55a6LUKAdR2fSyZEYrCVhrN7Sq6TCUgZBipOEVZaErTyImhRmXNa2aaTYctdVGt6NInKv\niOwQkdCRWEROFZFuEfll5S9deSkSjQiF7fO66fMU6aTCUgZBmjZtKtra2tGvRnpbO6ZNm5rqWFKb\nKHFnoLY4F5q1bRLBmHPrCO/fYF3wktIwBi0ipwB4C8ADSqkBAUcRORXA1Uqpsxv+GGPQ2REjqSKP\nhDFAXzwa6ItJMwZdH5OzuF0ji6QwgNYzAGZx1/pclCQxERkJ4Cd1BPorSqm/i/A9FOgsiZhUoTth\nDNCX1Q2EizSzuEmRRBVnoL71THHOkQInAUUL9CMAOgB0AZiplAr121CgNdDZ1VfYvnVEzcN0W9FA\nviJNSFFkJc4AredcKXApV5FZ3OsAjFRKnQDgTgA/yuA7SRRiJFXo3i/aR1eVMdbsLg+dndswZ858\nXHJJO+bMmW/UZhoUZ4tpae6LbXd2WbHOOrUFHXLsVgBjlVJvhLyn2i/9Uu/zCePGYsK4E+O1mHgk\nmA3m5eoG9MSjAVrSrmNyrkDUhLB6cWeAru3Cieh1TMPKtc9j5dp1vc/n3/VtrS7uw+AJ9LEh7x2s\nlNpRefwhAD9USh1W43vo4s6KhPEUijQxGVMLqFCcHaGgYihJXdwNq02IyHcBTADwXhH5HYB2AAcA\nUEqpewB8SkSmAdgL4I8APhO3ESQBYSLc0tww2WEIjuoVaV0cicF4BX9CEzZoEemjj/ZEesuBbxcq\n0o2SzpiUFh8T16vHEed6cElVwVR7GX13t8Fu7oYCrZT6XIP3FwNYnFmLiHaG4CjsfWmjVivadZEO\nc8W+/HKfK7bR+yScvvXq/S3ootarxxVnxp0NJridJtAn0gYv5XKnSgOJje4ZvT9YuZg41qh0aBlK\ni+rApAIqFGfHCG6n6RPB61gkegsqE2PxXd1CSzoRjVyxJrpqTSYYDjj8cMHhh8/B7t0tldBA/l6H\nrMTZh+JMkkCBLjEuijSQT/JYI1esaa5ak6mduf3FQsIBWYoz484kDRwtSo4/s3fB3Z2ny7uRK9Yk\nV63pmBQO0CHOtJ5JUmhBE2csaSA/l3dr60gsXjwDS5feHsjS7nPFNnqf9JEmHJBlpjzFmZhGpHXQ\nmf0Y10EbTR5rpAH966QBrpU2mWpR3bPnLaxaNQ9x1z5nWdSE4kx0UmSpT+IIeQ0out3dQJ/Le8uB\nb7M8qEH4ovrEE1/BunVeUZLNm/+AQw6ZhbjhgCxc4/71EQyRNKJRQhhAcSbZQBc36Ucea6SBfNzd\nQPHrpctCVFdzmKju2PENfPSjczBmTLxwQNpM+ahWs0+jKmEAK4WRbKFAkwFQpEkc4hRlqSWqu3e3\n4Otfj1fKM02mfBxxjrqUihnbJGvo4iah5LX7VR7uboAub53EcTX3iWqQZMvPkmbK6xRnWs8kS9wX\n6FWrB27DuKvHe53UxRfpPJZgHYnBaMKGXIQa4LaVWRLH1Zzl8jM/U37ixNsxdmw7Jk68vW6CWNx4\nM8WZREaTzrjv4h5zfO1tGUlD8lqCBeTr8gaATZvyK2ziMnFczWmXn4XFuqPscpUk3gxQnElENOlM\nOZZZFbTFmEvktQQLyGcZlo+/HAugUCclrz2ck/xO0FPS/GfbsHjuMuzsVBjWKpi+YAraRg38HMWZ\nJKKOziRdZlUOgQZy2aTbdRqJtDz+H1DjxwBDA5Of7h7IM+uhzvzrWL/lizSgT6g7tvYN2O84SHDu\nl6fglPccoeW3XCePrTXj7hUdtJo7tm7DpaffhY5Xb0CvuI++Hnc9dWmvSHds3YYlcxdhZ2cTRrfu\nx7wFH8eoUeFjBcWZhFJDZ7TtB+0Eu3q8Gc2KR2lBp6CRu1uNH4Om2Xdi342XeyLd3dP3PCa+9aLL\n5R02YP96w/W47t5LcXDbSCOtaZP3l25tHRnJ1ZyGqLHuoNXsu7QXz10WONfe5zpevQGL596Kmx+c\nU7kevomOV28FcBDWYjd+8Z/XYvlTkwaINMWZhKJBZ9xPEgvGAlpH9G3SXR3QJ5GoW7t7aDP23Xg5\nmmbfCfy2q79YJ0RXlnfYgL3jtRvw0/uXATAv2zuswMf06YvQ2bmt6KblRpQM8KDVHIw37+xUCBX3\nLs+DuGTuol5x9t/7zau3YN7cn/b7BMWZhKJJZ9wX6HqbdJNENBTpmRfigFFnYt/MC1OJs09QpLMS\n6noDdt4bb0TBpA0liqJeBnhwQhWWCDasVRAq7iMETdiAnZ1NCLsetnc19T6jOJOaaNIZ9wXawk26\nbWAIjgpfhtXdg6bb7sfbWx9H0233A93ZeCr8pVhANtZ0vQHbx6S109xfuvayqj1HDAcw0GoOMn3B\nFLSNvh79xH30NbhiwTgcicEY3bofYdfD8BH7AFCcSQM06Ux5ksSINnqTxw49tHYMOgNL2ieLLO8o\nSUPVFLkBR9wEqTIQd+lUb1Jgl8L7R/wBMxacjr8ZdSgAYOvWLkw+fQV+8+ot8K+Hw0d7MejD3+oG\nQHEmyWEWN6nPqtXeWr3gLG9Xj+eCycCbsBebIatewP7zz84kizsKaYU6OGAPG1F72U3w+JtnLMOb\nOxX+fJjgny6+qGGSVlaJXXktZbKBsCSwONRaRrV1axfmzf0ptnc1YfiIfZi34OMUZ5IJFGhSn2AS\nQ/VC+owy2vNcK+2T15rpMIv74EO9rO9aS7OyFlWTs7jzIK0wA9HXOAMFuLU1T6JJcVCgSWNyKtii\nS6jrrbPefOZJAPQJ9XWfX4gVD12DahfzpPNvxQWz5/S+EnR/R3VLl114G5G3MAMFxZxzmESTYuB+\n0KQxLc2eOE862/tX001fN8s7Bf46697Es0qMW40foyXTO0icrG9fUKIkdnH5VG2qM7OdFmegL/N3\n0RKv4AXF2Txy3tuBAl0mqhfSa1wLrkWkG6yzzjrTO0icrG/AE5c/O0SFfyawbpfLpwaSlTADFomz\nT06TaJIQv+a2P3b6Xo4xx2v5OQp0WSigYEtQpDMT6gjrrHVY0+HLdK7H9AVTBhzri8p1i6bg4EOr\nPlO1cxOXT3n4ohzcbSqtMDdhQ79JWyMKF2cg10k0SUDOXo5iSn0y8SF/6i2k13ge/MEusx2xqtZZ\n11rCVV0qFEgXn24bNRJ3PXUpFs+9NZD1fSkALz4dtgFD26iRuPfn3me2bfEyv8/98iXY0zYc2ON9\nb5ydoFwki/hyNXGtZsAgcQ4O+L4QRBEAJpjlR9DLseJRrV6O/JPEVv+MsZWSkjp5rHpddYx11mHZ\n3s2PL8fu8Sdj/9Chva8N6u7GQc88i54zJzdsTpK11ED/HbR2dGzD7V+8u1TLp3SIMpBMmIGCxDlM\nUJ940vt34hl9r0UVWSaY5UeCZFt7srg/cy4vmpKTVKiz2C0rKNSDursxfPb12H7jDdg/dOiA542o\nl9l984Nzan2sH5s2eSL98De99dUfeM9gJ7O4qyuxZSnMgGXiDOgRVG6rq5+E580egeZ2jwTFrJn2\nCW5lqbo/gOGzr8fvZ16F99/29cjiDAD/eNoCPL9ywYDXTzxtLv756bmx2xW0rH1M3FUrCroF2cc6\nYQ6iQ1C5ra5eEoYS7NlukjM7gkBsujJQ5inUwfi0DP0d/nvmZBwz6ihs3Lo5sjgDwczuqvjxiNj3\nIYCBIrZp00ChM1Www2qV6xJloH+WvpXiDGQfy+S2uvoJE2GNezvkn4nC7R5JAF1rpqNwJAbjyO4/\n4n23LcPmrT/GwbfNxqDubjQ/vhyDurv7Heu/HiROZncSgtnM1Rt3VP/lRb3fr26rLoJWc1xxHrT4\nIWDX7v7irHEda12yzNhutEoj5/W7JBuKqSTG7EISQu5u76oks193v4mDZy/Bzn+6AO/76uORYtNx\n63nrIsw9rgud4luPpO5sH3lpoyfOi54qPpkq6xh0I9crk8gKxZ4YNEt9kjrkKdK1ks66nlmHPeOP\nx8Gzl2DHzBtjx6ZJtqRxZwP9vTNDcJQZyVRFLIsyod8lRZtAi8i9AM4CsEMpFbqQVES+BWASPF/f\nVKXU+hrHUaBJJIpMIvPZ+tvf4ahR52Dz1h/j/x42sbB2lJW0wgzUiTeXNZmqrP0uGJ21uP8FwMdr\n/rDIJACjlVJHALgEwF1xG0FINVqqkMWhuwd/cdtDeHvr43jfbcswpPsZbXW+SX+C/89J4sw+NcXZ\n9mpdSePJtve7hDQUaKXUagBv1jnkHAAPVI5dA+DdInJwNs0jZWYIjiomiSwYmz5sBJpvvAJHzb4L\nR3b/EYC+DTnKTpbCXFeccy55mzlJ6kFn0W8mmuVOFlncrQBeCzzvrLxGSH0i3vC+UOdlTcsz6/tX\nJ6ts0iHPrB+wIQeFOj1ZCTPQ32oOXUZVr+StLSSpB51Fv3PeKIJETBITkZEAfhIWgxaRxwDcpJR6\ntvL8fwOYqZR6IeRYxqBJHwkyS/3YNFBsfDpIsPCJrv2oXSOL+HI1xqxvzosi4slMNEtEkYVKOgAc\nGnjeBqCr1sHzltzd+3jCuLGYMO7E2t/MAvBuE7QEIt7w1ZtvAMULddjGHADFuppqbwOFOQVFFSXJ\ncaMIm1m59nmsXLsu9fdEtaAPg2dBHxvy3mQA05VSZ4rIRwDcoZT6SI3viWdBc+1eOUhhCZiQ7R1G\n0KoGyi3WOqxln9KKc1HjIi3oROhcZvVdABMAvBfADgDtAA4AoJRS91SOuRPARHjLrL6glPplje/y\ndrOKYxHzgnCbjM6vqUINDBRrwG3B1mUpBymlMPsU5VmkwZQYewqVBHezinqCuXbPTWrd8GNPAE4+\nKfYAZGJ8OgwXres8RBkIKTpC8oMhx8TYI9D+ftBRLSZa0O5S64Z/9jlg3QuJZ+q2CLWPjRa2DkFu\ntJ1oqa1mYjX2CPSG56NbxHSplJcMJma2CbVPmGD75C3ctZaRabGQq2qj+8/3f+5vgZaDKMzEWuwR\n6DgWNF0q7hLl3GYU2rBVqKupJ9xh1BLzuGu3dbmrQ/FFeuaFaLr2G9g/49MUZ2I99gh0khg0cY9G\n3hENoQ1XhDoqtQQ9V8FNgDzxcwyZdCX2rrgDQ1o5ESf2Y49Ax83iJu5SS4RzCG2UTaxtwN8OctCi\nH6Jp6hXMOSHOYI9As5JYPFx384e5sXPsM4W6eHozs03Zq5mQjNG5mxUpEpfr39baXeejpwwckFua\ntUxIqjfkKGTnrJJSvanFkPV77K+TTUiG0IK2AReXmj3xJPDcGuDqK/uspa/dAZz0YWDiGYU2zQSr\nutGSI5vhWmZSNmhBu0yw/u3UKfaLs+GYYFWr8WPQNPtOoLviVahkN6vxY3JvS1YMsJh1ijO3RiQO\nQAvaBly0oAGr+lWIVR1ccnTb/f23wLSE6slNbhYzaygQg2CSmKu4PtBYVsY1KNRADmL92y4cMOpM\nvL31ceAw8/9/fIxwY1s0ASRuQ4F2FZezuC0fQLWLtWUWtBGiXI1lE0DiJhRoYhcOegYyFewaZS9N\nEunC3NdRsXwCSNyBAk3swjbPQMz2Vos1EE+wTc3iNl6UfRycABJ7oUATopOUW2OGCTZgdnGUsOx1\nYwW5GtsmgGWlJOeJAp2WklwoJAVhLlMgsaVWS7SB/IW71lIyawSZ2ElJPB0U6LSU5ELJjSwmPCZO\nmsKSjjKOddYT7nr4op5k3bZ2ITbxXBIzKEGuAAU6C0pwoeRGFhMe0yZN9a4PA7KF92KzuRavaeeS\nmIUB909DUkwyWUksC1ixKzv8OsqLlng3X5LBOIvvyIqgoLSO6GvXrp7aNcVzxlhxBsw6l8QsDLl/\nGhJ3X4SwanYxoQUdhBZ09mQxMzZhdl1r9vzsc8C6F2gZRsWEc0nMwTbPShyNCPRFTjmNFnQq6llI\nJBlRZ8b16iabMruu3mHLr+l84IH9B5f1L3IHplqYci6JOfj3iy07mMXxsga9RgmhQPvYdqGYTpwJ\nTy3X0ejR5k6a/Db7VnXQ3aVpa0yr4QSYhJHj1rKZEHeS6Qt6QujiJnqIm1AR5jpa/6LZmb8MiUSH\nWdzEdpK44yvHyA8eZhZ3Pzgg2IeN8Ukb2wzw/iAkLkmNDsagQ4ibcUeKxcb4pI1t9uH9QUg84rrj\nq8OmCXBXoLmswx5sjE/a2OYgvD8I6aNeompSwgQ9Ju66uH1sdUGWCRvdrTa2OQzeH4RoX+7FQiVh\n2OyCLBO2ZXICdra5Gt4fhHgY6lFyV6Btd0ESohPeH4T0x8BKku4KNNc1E1Ib3h/60BHPJPox0KPk\nfgyaEELyxLbylcTYGDQFmhBCsoZFbOxCc9InBZpEx5UMZEJMhhnypILWLG4RmSgivxKRV0TkmpD3\nLxSR34vILyt/X4zbEJIjLFJBiF4MjGcS+2go0CIyCMCdAD4O4C8BfFZEPhhy6PeVUv+j8vedjNtJ\nssRPCLpuLrB5y8DYC5NZCEkOM+RJRkSxoD8EYItSaptSai+A7wM4J+S42OY7KZCWZuCK6cC5nwU+\n9cmBOzIRQpLBDHmSEVEEuhXAa4HnHZXXqvmkiKwXkR+KSFsmrSP62NUDPPKvwMPfA66bA2x+hZmm\nhGSBC0Vs8oDL0RoSRaDDLOPqzLJHARymlBoD4N8B3J+2YblQ1gsk6II76gjg5gXAuZ8DPvUJijMh\nJB+YC9OQwRGO6QDwgcDzNgBdwQOUUm8Gnn4bwK21vmzekrt7H0845hhMGCQDZ5Z5ZRn7F0jY2jeX\nCbrgdvUAj/wb8PB3gW8t8cQ6S5FmxjghJIxgeU3HlqOtXPs8Vq5dl/p7Gi6zEpEmAJsBfAzAdgC/\nAPBZpdSmwDGHKKVerzz+BICZSqmTQ75LqdU/a7wQPM+F/mVer5jH/3OZijZwMkJIfEqwHE3bMiul\n1D4AlwN4EsD/gZetvUlE5ovIWZXDrhCRl0XkhcqxU2t+YZRi5HkWLjew/mpu5JHMYmgRei3QZUdI\nPLgcrS75FypZ8Wj02VIeM6syW9B5UoJZMgBeT4REpUTeNXu2m4w6W8pjZsX1ivlQpllymT0yhMSB\ny9Eakr9ARxHDvISTF4h+yjYJKtNkBCjvSgiSHi5Ha0ixtbhrJdAw2cYdynQuS+Sy66WMfSYkJtws\ng5CiKdNkJIiOuLvt/5e2t59kij0xaEJcpawuOx1xd9sz4m1vPzECCrTtmBADNKENpDh0xN1NXJ4X\n5zo3sf3EOijQtmPCTN2ENpBi0JkEaFpGfNzr3LT2E+ugQNuOCTN1E9pAikHnSgjTMuLjXuemtZ9Y\nB5PEXMGEQiAmtIG4QZTs8FWrgT17gJNP6nttVw/w7HPAgQfqi/1Huc6Z3U4CMEmszJgwUzehDcQd\noljmY44HnlsDfO0O73rb1eM9fm6NvvBK1OucNRZIBphvQbu6XCGrfhU9U1+1Ghg9Grjvgb7f7NwO\n3HRr9jtjEVKNL8p793rPhwwBrr5Sz3VX9L1GrMVdC9rVBKSs+lX0TH3M8Z4YT72gb9C67wFg1jW0\nFoh+WpqBiy8CHlvu/V18kT6xLPpeI6XDfAsacHcDAlf65Uo/iH3kaUETkhD3K4m5moDkSr9c6Qex\nB1+cAU+Ugf7PixZpV8NzJDbuurgBdxOQXOmXK/0gZtGoMMj6F4GTPtwnxi3N3uOTPmyG29nV8BzJ\nDfMF2tXdkFzplyv9IObRSOA+egow8Yz+FmpLs/eaCRYq6wM0hlUI62K+i9tVN5Er/XKlH8RMXMhv\nYPinNiXJjHc/Bk0IKSc2Cxx3+mqMC5OwBrgdgyakEXSVuYnN+Q26wj+uxbZZs7wmFGjiBq4NWsT+\n/AZd66Zdi23bPAnTDF3cReKaq6poSuAqKxW8P+pjs+vfhzHoutCCLhJafdlCV5lbfPSUgeewpZni\nDLhjdbI6W10o0EXimquqaFwZtAiph+2u/yCchNWFLm4TcMFVVTQlcZURQte/fdDFbSu0+rKBrjJS\nFly2Orkaox8U6CJxyVVVNC4PWoSUBebl9IMCXSS0+ohuaJEQm2BeTj8o0EVCq4/ohhYJsQ2uxujF\nDIHmLJ+kgddPbWiRENtgXk4vZgg0Z/kkDbx+6kOLhNgC83L6YYZAmzzLp3VmPiZfPyZgm0XCe668\nMC+nH2YINGDuLJ/WmR2Yev0UjY0WCe+58pJVXo4jkzxzBNrUWT6ts/TkcbOYev0UjY0WCe85khZH\nJnmRBFpEJorIr0TkFRG5JuT9A0Tk+yKyRUSeE5EPxGqF6bN8Wmfp0H2z5Hn92DYzt3WlgO33nG3X\nSRJM7qMjk7yGAi0igwDcCeDjAP4SwGdF5INVh10E4A2l1BEA7gDw1Vit0DnLz+IiimidrVzrdhnT\nxP3TfbNkdP1E6p+lM3Prrs2YHhHj+pfxdWJc/4BM+6ilf7ZP8hDNgv4QgC1KqW1Kqb0Avg/gnKpj\nzgFwf+XxIwA+FqsVOmf5aS+iGNbZyrXr0rfXYFL1T+fNktH1E6l/ls7Mrbo2E3hEjOtfxteJcf0D\nMk2RX7cAAATsSURBVO2jlv45EPaKItCtAF4LPO+ovBZ6jFJqH4BuEXlPJi1MS9qLyMYYnok4cLP0\n4sDM3GhcuefKcJ2Y2kfTw6YRiSLQYTtwVG+BVX2MhBxTHGkuIltjeCbhyM3Si0uTDRNx5Z4rw3Vi\nah8dmeQ13G5SRD4CYJ5SamLl+bUAlFLq1sAxKyrHrBGRJgDblVLvD/kuc0SbEEIIyYkk200OjnDM\nWgB/ISIjAWwHcB6Az1Yd8xMAFwJYA+BcAE9n1UBCCCGkjDQUaKXUPhG5HMCT8Fzi9yqlNonIfABr\nlVKPAbgXwDIR2QLgv+GJOCGEEEIS0tDFTQghhJD80VJJTHthk4KJ0L8LReT3IvLLyt8Xi2hnEkTk\nXhHZISIb6hzzrcq5Wy8iY/JsX1oa9U9EThWR7sC5m5N3G5MiIm0i8rSIbBSRl0TkihrHWXn+ovTP\n8vP3DhFZIyIvVPrXHnKMtWNnxP5ZO3YCXt2QSrsfDXkv/rlTSmX6B0/0fw1gJIAhANYD+GDVMdMA\nLKk8/gyA72fdDl1/Eft3IYBvFd3WhP07BcAYABtqvD8JwOOVxx8G8J9Ftznj/p0K4NGi25mwb4cA\nGFN5/C4Am0OuTWvPX8T+WXv+Ku0/sPJvE4D/BPChqvetHTsj9s/asbPS/v8J4MGwazDJudNhQesv\nbFIsUfoHhC9PMx6l1GoAb9Y55BwAD1SOXQPg3SJycB5ty4II/QPsPXevK6XWVx6/BWATBtYssPb8\nRewfYOn5AwCl1J7Kw3fAyxGqjkHaPHZG6R9g6fkTkTYAkwH8c41DYp87HQJtd2GTxkTpHwB8suJC\n/GHlxLlCdf87Ed5/m/lIxQ33uIgcU3RjkiAih8HzFKypesuJ81enf4DF56/iIn0BwOsAnlJKra06\nxOaxM0r/AHvHzm8AmInaNUBinzsdAm1/YZP6ROnfowAOU0qNAfDv6Js1uUCU/tvMOgAjlVInwKtB\n/6OC2xMbEXkXvBn6lyuWZr+3Qz5i1flr0D+rz59San+l7W0APhwywbB57IzSPyvHThE5E8COiodH\nEH6fxT53OgS6A0Aw+N0GoKvqmNcAHAoAlcImLUqpRm5HU2jYP6XUmxX3NwB8G8DYnNqWBx2onLsK\nYefXWpRSb/luOKXUCgBDLLNQBsMTr2VKqR+HHGL1+WvUP9vPn49SaheAlQAmVr1l89jZS63+WTx2\njgdwtoj8BsD3AJwmIg9UHRP73OkQ6N7CJiJyALw10dUZbX5hE6BOYRNDadg/ETkk8PQcABtzbF8W\n1JoBAl5fLwB6q8x1K6V25NWwjKjZv2A8VkQ+BG8p4ht5NSwDvgNgo1LqmzXet/381e2fzedPRN4n\nIu+uPH4ngL8F8Kuqw6wdO6P0z9axUyk1Syn1AaXU4fA04Wml1AVVh8U+d1EqicVCOV7YJGL/rhCR\nswHsBfAGgKmFNTgmIvJdABMAvFdEfgegHcAB8Mq73qOUWi4ik0Xk1wB2A/hCca2NT6P+AfiUiEyD\nd+7+CC/b0gpEZDyA8wG8VInzKQCz4K04sP78RekfLD5/AIYDuF+8LX4HAfhB5Xw5MXYiWv+sHTvD\nSHvuWKiEEEIIMRAthUoIIYQQkg4KNCGEEGIgFGhCCCHEQCjQhBBCiIFQoAkhhBADoUATQgghBkKB\nJoQQQgyEAk0IIYQYyP8HhLpua040qSAAAAAASUVORK5CYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7f1af3aee470>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"dist = 4\n",
"N = 240\n",
"datasets = gen_datasets(N, dist)\n",
"plt.figure(figsize=(8, 6), dpi=50)\n",
"alpha = 0.05\n",
"gda_spotting = gradient_descent(datasets, alpha=alpha, max_iteration=6000)\n",
"theta = gda_spotting[-1]\n",
"print(theta)\n",
"for d in datasets:\n",
" x = d[1]\n",
" y = d[2]\n",
" z = d[-1]\n",
" if np.isclose(z, 1.0):\n",
" plt.plot(x, y, 'rx')\n",
" else:\n",
" plt.plot(x, y, 'bo')\n",
"\n",
"def prob(X, Y):\n",
" samples = datasets[:,1:-1]\n",
" h = make_h(theta)\n",
" for ax, ay in zip(X, Y):\n",
" yield h(gen_feature(ax, ay))\n",
"delta = 0.02\n",
"X, Y = np.meshgrid(np.arange(0.0, dist+0.01, delta), np.arange(0.0, dist+0.01, delta))\n",
"Z = np.array(list(prob(X, Y)))\n",
"plt.contourf(X, Y, Z, 3, alpha=0.2)\n",
"plt.show()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment