Skip to content

Instantly share code, notes, and snippets.

@jupp0r
Last active April 13, 2017 06:52
Show Gist options
  • Save jupp0r/5b5cd269bc5b39b30a76cdf2b25b7546 to your computer and use it in GitHub Desktop.
Save jupp0r/5b5cd269bc5b39b30a76cdf2b25b7546 to your computer and use it in GitHub Desktop.
coursera_machine_learning_python
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Exercise 1 - Linear Regression\n",
"## Warmup Exercise\n",
"As a warm-up exercise, we should produce a 5x5 identity matrix."
]
},
{
"cell_type": "code",
"execution_count": 411,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 1., 0., 0., 0., 0.],\n",
" [ 0., 1., 0., 0., 0.],\n",
" [ 0., 0., 1., 0., 0.],\n",
" [ 0., 0., 0., 1., 0.],\n",
" [ 0., 0., 0., 0., 1.]])"
]
},
"execution_count": 411,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"np.identity(5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Reading input data\n",
"Let's first read the input data into two variables and print them"
]
},
{
"cell_type": "code",
"execution_count": 412,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 5.5277, 9.1302],\n",
" [ 8.5186, 13.662 ],\n",
" [ 7.0032, 11.854 ],\n",
" [ 5.8598, 6.8233],\n",
" [ 8.3829, 11.886 ],\n",
" [ 7.4764, 4.3483],\n",
" [ 8.5781, 12. ],\n",
" [ 6.4862, 6.5987],\n",
" [ 5.0546, 3.8166]])"
]
},
"execution_count": 412,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ex1data1 = np.genfromtxt('ex1data1.txt', delimiter=',')\n",
"ex1data1[1:10]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Visualizing the input data\n",
"We'll be using ggplot to visualize data."
]
},
{
"cell_type": "code",
"execution_count": 413,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7f0f4ab46b90>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<ggplot: (8731478533733)>"
]
},
"execution_count": 413,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from ggplot import *\n",
"ggplot(pd.DataFrame({\"x\": ex1data1[:,0], \"y\": ex1data1[:,1]}), aes(x=\"x\", y=\"y\")) + geom_point() + xlab('population') + ylab('revenue')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Cost and gradient descent"
]
},
{
"cell_type": "code",
"execution_count": 414,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# separate features from predictions\n",
"x = ex1data1[:,0]\n",
"y = ex1data1[:,1]\n",
"# number of training samples\n",
"m = y.shape[0]\n",
"# add a column of ones to the input data\n",
"x = np.c_[np.ones(m), x]\n",
"# initialize theta to zero\n",
"theta = np.zeros((2,1))\n",
"\n",
"# number of gradient descent iterations\n",
"iterations = 1500\n",
"alpha = 0.01"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Defining the cost function\n",
"As a first step, let's define the cost function $$ J(\\theta)=\\frac{1}{2m}\\sum_{i=1}^{m}\\left(h_{\\theta}(x^{(i)})-y^{(i)}\\right)^2 $$ for the linear model $$ h_{\\theta}(x) = \\theta^T\\,x $$"
]
},
{
"cell_type": "code",
"execution_count": 415,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"32.072733877455654"
]
},
"execution_count": 415,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def compute_cost(x, y, theta):\n",
" # number of samples\n",
" m = y.shape[0]\n",
" j = 0\n",
" # define the hypothesis\n",
" def h(x, theta):\n",
" hx = theta.transpose().dot(x.transpose()).transpose()[:,0]\n",
" return hx\n",
" j = 1./(2.*m)*sum((h(x, theta) - y)**2)\n",
" return j\n",
"\n",
"compute_cost(x, y, theta)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Given this, we can run some tests ported from the original exercise code. The test tests the cost function against $$ \\theta = \\begin{pmatrix}0\\\\0\\end{pmatrix} $$ and $$ \\theta = \\begin{pmatrix}-1\\\\2\\end{pmatrix} $$"
]
},
{
"cell_type": "code",
"execution_count": 416,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"With theta = [0 ; 0]\n",
"Cost computed = 32.0727338775\n",
"Expected cost value (approx) 32.07\n",
"With theta = [-1 ; 2]\n",
"Cost computed = 54.242455082\n",
"Expected cost value (approx) 54.24\n"
]
}
],
"source": [
"# test the cost function\n",
"j = compute_cost(x, y, theta)\n",
"print('With theta = [0 ; 0]\\nCost computed = ' + str(j))\n",
"print('Expected cost value (approx) 32.07')\n",
"\n",
"# some more tests\n",
"j = compute_cost(x, y, np.array([[-1],[2]]))\n",
"print('With theta = [-1 ; 2]\\nCost computed = ' + str(j))\n",
"print('Expected cost value (approx) 54.24')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Gradient descent\n",
"Given the cost function, we can implement gradient descent"
]
},
{
"cell_type": "code",
"execution_count": 417,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Theta found by gradient descent:\n",
"[[-3.63029144]\n",
" [ 1.16636235]]\n",
"Expected theta values (approx)\n",
"\n",
"[[-3.6303], [1.1664]]\n"
]
}
],
"source": [
"def gradient_descent(x, y, theta, alpha, num_iters):\n",
" m = x.shape[0]\n",
" cost_history = np.zeros(num_iters, dtype=np.float)\n",
" for iter in range(num_iters):\n",
" step = np.zeros(theta.shape)\n",
" for j in range(m):\n",
" diff = alpha*(1./m)*(x[[j],:].dot(theta) - y[j])[0][0] * x[[j],:].transpose()\n",
" step = step + diff\n",
" cost_history[iter] = compute_cost(x, y, theta)\n",
" theta = theta - step\n",
" return theta, cost_history\n",
"\n",
"theta, _ = gradient_descent(x, y, np.zeros((2,1)), alpha, iterations)\n",
"print('Theta found by gradient descent:')\n",
"print(theta)\n",
"print('Expected theta values (approx)\\n')\n",
"print('[[-3.6303], [1.1664]]')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's plot the linear fit:"
]
},
{
"cell_type": "code",
"execution_count": 418,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAuwAAAIqCAYAAAB/kR9VAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAMTQAADE0B0s6tTgAAIABJREFUeJzs3Xt8k/Xd//F30qQtPQXSBrHg1HtzZgqTzeMPFVCYRREB\np3e1Og4ZHipz6pynloOKx22i41brHEadiqJs4GlaAaH1tk6dOr3RxanzSCZNG2hLj2mT3x9IS205\npE1yXWlfz8djf3iFtO+Wz8I733yv67JEIpGIAAAAAJiS1egAAAAAAHaPwg4AAACYGIUdAAAAMDEK\nOwAAAGBiFHYAAADAxCjsAAAAgIlR2AEAAAATsxkdQJIeeeQRbd++XRaLRWlpaZoyZYr2339/1dbW\nas2aNWpqalJ6erpmzJghl8tldFwAAAAgYSxmuHFSS0uL0tPTJUn//Oc/tXHjRhUXF+vhhx/W2LFj\ndcQRR+iDDz7Q//7v/+rCCy80OC0AAACQOKbYErOzrEs7yrvFYlFjY6P8fr/GjBkjSTrssMNUX1+v\nYDBoVEwAAAAg4UyxJUaSVq9erU8//VQWi0XnnXee6urqlJ2dLau16z2Fw+FQXV2dnE6ngUkBAACA\nxDFNYZ85c6Yk6d1339XatWt10kkn6du7dXb97+XLl/f6debNmxe/kAAAAECCmaaw73TEEUfo2Wef\n1YwZM7R9+3aFw+HOVfb6+no5HI49Pj8cDqu9vT0RUZOCxWLp8cZnsLLZdow789GF+ejCfPSOGenC\njPTEfHRhPnpiPrqz2Wzddo5E9dwYZ4laS0uLQqGQsrOzJe046TQjI0OZmZnaf//99d5772ns2LF6\n//33lZOT07kdZncr6W1tbaqpqUlYfrPLyMhQU1OT0TFMIS8vT5KYj10wH12Yj94xI12YkZ6Yjy7M\nR0/MR3d5eXlKTU3t03NNUdifeuqpznekmZmZKioqkiSdfvrpWrNmjV555RWlpaVpxowZRkYFAAAA\nEs7wwj506FBdcMEFvT6Wl5fHnnQAAAAMaqa4rCMAAACA3lHYAQAAABOjsAMAAAAmRmEHAAAATIzC\nDgAAAJgYhR0AAAAwMQo7AAAAYGIUdgAAAMDEKOwAAACAiVHYAQAAABOjsAMAAAAmRmEHAAAATIzC\nDgAAAJgYhR0AAAAwMQo7AAAAYGIUdgAAAMDEKOwAAACAiVHYAQAAABOjsAMAAAAmRmEHAAAATIzC\nDgAAAJgYhR0AAAAwMQo7AAAAYGIUdgAAAMDEKOwAAACAiVHYAQAAABOjsAMAAAAmRmEHAAAATIzC\nDgAAAJgYhR0AAAAwMQo7AAAAYGKWSCQSMTpELDU2NioUChkdwzSsVqvC4bDRMUzBZrNJktrb2w1O\nYh7MRxfmo3fMSBdmpCfmowvz0RPz0Z3NZlNWVlbfnhvjLIaz2+2qq6szOoZpZGRkqKmpyegYppCX\nlydJqq+vNziJeTAfXZiP3jEjXZiRnpiPLsxHT8xHdztnpC/YEgMAAACYGIUdAAAAMDEKOwAAAGBi\nFHYAAADAxCjsAAAAgIlR2AEAAAATo7ADAAAAJkZhBwAAAEyMwg4AAACYGIUdAAAAMDEKOwAAAGBi\nFHYAAADAxCjsAAAAgIlR2AEAAAATo7ADAAAAJkZhBwAAAEyMwg4AAACYGIUdAAAAMDEKOwAAAGBi\nFHYAAADAxCjsAAAAgIlR2AEAAAATo7ADAAAAJkZhBwAAAEyMwg4AAACYGIUdAAAAMDEKOwAAAGBi\nFHYAAADAxCjsAAAAgInZjA7Q3t6uVatWKRAIyG63KzMzU1OnTpXT6dSDDz6ouro6paenS5LGjh2r\n4447zuDEAAAAQOIYXtgl6cgjj9QhhxwiSXrjjTf0zDPPaM6cObJYLDr11FN16KGHGpwQAAAAMIbh\nW2JsNltnWZekUaNGadu2bZ3/HYlEjIgFAAAAmIIpVth39frrr8vtdnf+97p167Rhwwa5XC5NmjRJ\nw4YNMzAdAAAAkFiWiImWsCsrK/XRRx9p1qxZstvtqq+vV05OjqQdW2XefPNNzZ8/X5K0fPnyXr+G\nx+NRe3t7wjKbndVqVTgcNjqGKdhsO96fMh9dmI8uzEfvmJEuzEhPzEcX5qMn5qM7m80mq7Vvm1sM\n3xKz06uvviqfz6fzzz9fdrtdkjrLuiQdc8wx2rp1q5qbm42KCAAAACScKbbEVFVVadOmTZo9e7bS\n0tIkSeFwWE1NTcrKypIkffDBB8rKytKQIUMkSfPmzev1a7W1tammpiYxwZNARkaGmpqajI5hCnl5\neZLEfOyC+ejCfPSOGenCjPTEfHRhPnpiPrrLy8tTampqn55reGGvr6/XSy+9JKfTqYceekjSjo8M\nZs2apRUrVqijo0OSlJmZqXPPPdfApAAAAEDiGV7Yc3JydP311/f62IUXXpjYMAAAAIDJmGYPOwAA\nAICeKOwAAACAiVHYAQAAABOjsAMAAAAmRmEHAAAATIzCDgAAgKgEg0FVVVUpGAwaHWVQoLADAABg\nn5WVlamgoEBFRUUqKChQWVmZ0ZEGPAo7AAAA9kkwGJTX65Xf71coFJLf75fX62WlPc4o7AAAANgn\nPp9PgUCg27FAICCfz2dQosGBwg4AAIB94na75XK5uh1zuVxyu90GJRocKOwAAADYJ06nUx6PR/n5\n+bLb7crPz5fH45HT6TQ62oBmMzoAAAAAkkdxcbEKCwvl8/nkdrsp6wlAYQcAAEBUnE6nxo0bZ3SM\nQYMtMQAAAICJUdgBAAAAE6OwAwAAACZGYQcAAABMjMIOAAAAmBiFHQAAADAxCjsAAABgYhR2AAAA\nwMQo7AAAAICJUdgBAAAAE6OwAwAAACZGYQcAAABMjMIOAAAAmBiFHQAADCjBYFBVVVUKBoNGRwFi\ngsIOAAAGjLKyMhUUFKioqEgFBQUqKyszOhLQbxR2AAAwIASDQXm9Xvn9foVCIfn9fnm9XlbakfQo\n7AAAYEDw+XwKBALdjgUCAfl8PoMSAbFBYQcAAAOC2+2Wy+XqdszlcsntdhuUCIgNm9EBYi0UCikj\nI8PoGKZhtVr5fXyjra1Nkvh97IL56MJ89I4Z6cKM9GS2+cjIyNBFF12kP/7xj9qyZYv2228/XXDB\nBRo1alTcvzfz0ZPZ5sNobW1tSk1N7dNzLZFIJBLjPIZqa2tTTU2N0TFMIyMjQ01NTUbHMIW8vDxJ\nYj52wXx0YT56x4x0YUZ6Mut8BINB+Xw+ud1uOZ3OhHxP5qMns86HUfLy8vpc2AfcCjsAABjcnE6n\nxo0bZ3SMga2jQ5aGBkWGDjU6yaDAHnYAAADsM/u77yrvjDM09Fe/MjrKoEFhBwAAwF5Ztm2T47rr\nlHvmmWo9+WRtveceoyMNGmyJAQAAwO6Fwxry1FPKuflmhX74QwXWrVPHwQcbnWpQobADAACgV7YP\nPpCjpEQpmzer7rbb1HLqqZLFYnSsQYctMQAAAHEWDAZVVVWVNHddtTQ0KGfxYuVNm6a2Y45RoKJC\nLaedRlk3CCvsAAAAcVRWViav16tAICCXyyWPx6Pi4mKjY/UuElH6M8/IccMNav/ud1Xz4otqP+QQ\no1MNeqywAwAAxEkwGJTX65Xf71coFJLf75fX6zXlSrvt44+VW1gox/XXq37hQtU++SRl3SQo7AAA\nAHHi8/kUCAS6HQsEAvL5fAYl6snS1KTsW29VXkGBQm63qisq1DxzJttfTIQtMQAAAHHidrvlcrnk\n9/s7j7lcLrndbgNTfSMSUfqLLypn8WKF999fNc88o/bDDzc6FXrBCjsAAECcOJ1OeTwe5efny263\nKz8/Xx6PR06n09BcKZ99JuesWXJcfbUarrxSNatXU9ZNjBV2AACAOCouLlZhYaF8Pp/cbrexZb2l\nRVn33quse+9V81lnaeuyZYoMG2ZcHuwTCjsAAECcOZ1OjRs3ztAMaS+/LMfChQrn5Kh21SqFxo41\nNA/2HYUdAABgAEvZvFk5ixcrrapK9ddco6bzz5dSUoyOhSiwhx0AAGAgamtT1t13yzVxoiLZ2aqu\nrFTT7NmU9STECjsAAMAAk/q//ytHaalktyv42GNqO+YYoyOhH1hhBwAASIBgMKiqqqq43jTJumWL\nhs6fL+fPf66m889X4MUXKesDAIUdAAAgzsrKylRQUKCioiIVFBSorKwstt+gvV2Zf/yjhk+YIEmq\nrqhQ4wUXSDY2UwwEFHYAAIA4CgaD8nq98vv9CoVC8vv98nq9MVtpT33zTbmmTFHGo48quHy5tt1z\nj8IjRsTka8McKOwAAABx5PP5FAgEuh0LBALy+Xz9+rrWmhoNveIKOYuK1DxjhgJr16rthBP69TVh\nThR2AACAOHK73XK5XN2OuVwuud3uvn3Bjg5lPPywho8fL0tDgwIbN2r7L34hpabGIC3MiMIOAAAQ\nR06nUx6PR/n5+bLb7crPz5fH4+nTHU/t//iH8qZNU9b992vr3Xdr6/Ll6hg5Mg6pYSaciQAAABBn\nxcXFKiwslM/nk9vtjrqsW7ZuVc5tt2nIqlXaPn++tl9yiZSeHqe0MBsKOwAAQAI4nU6NGzcuuieF\nwxry1FPKuekmhcaOVWD9enUcdFBc8sG8KOwAAAAmZHv/fQ0tKZHV71fdb36jlilTJIvF6FgwAHvY\nAQAATMTS0KCcRYuUd8YZaj3uOAUqKtRy6qmU9UGMFXYAAAAziEQ0ZM0a5dx4o9oPOUQ15eVq/973\njE4FE6CwAwAAGMz20UdylJTI9sknqrv+erWccQYr6ujElhgAAACDWBoblX3zzXJNmaLQ4YeruqJC\nLdOnU9bRjeEr7O3t7Vq1apUCgYDsdrsyMzM1depUOZ1ONTY2avXq1QoGg7LZbJo6daoOPPBAoyMD\nAAD0TySi9BdeUM7ixeoYOVKBZ59V+2GHGZ0KJmV4YZekI488Uocccogk6Y033tAzzzyjOXPmaO3a\ntRo1apTOP/98bd68WStXrtTll18uq5UPBgAAQHJK+fRTORYulP2991RfWqrms8+W6DbYA8Onw2az\ndZZ1SRo1apS2bdsmSfrggw901FFHSZJGjhyp7OxsffbZZ0bEBAAA6J/mZmX/7ndyTZ6sjgMOUHVl\npZoLCynr2CtTrLDv6vXXX5fb7VZTU5PC4bCysrI6Hxs6dKjq6uokScuXL+/1+R6PR3l5eQnJmgys\nVqsyMjKMjmEKNtuOcWc+ujAfXZiP3jEjXZiRnpiPLnubD8tf/yrbFVcokpurjvXrZT/qKOUmMqAB\nmI/uds5IX5jqLV1lZaWCwaAmTZrU6+ORSCTBiQAAAPrh889lO+ss2ebOVceVV6r9lVcU+Wb3ALCv\nTLPC/uqrr8rn82n27Nmy2+2y2+2yWq3avn175yp7XV2dHA6HJGnevHm9fp22tjbV1NQkLLfZZWRk\nqKmpyegYprBz1YP56MJ8dGE+eseMdGFGemI+uvSYj9ZWZf3hD8patkwtZ5yh+spKhXNzpa1bDUyZ\nWMxHd3l5eUpNTe3Tc01R2KuqqrRp0ybNnj1baWlpnccPO+ww/f3vf9fEiRO1efNmNTQ06KCDDjIu\nKAAAwF6kVlZqaGmpImlpCj7+uNqOPtroSEhyhhf2+vp6vfTSS3I6nXrooYck7djjM2/ePE2ePFmr\nV6/WsmXLZLPZdOaZZ3KFGAAAYE6bN2vYZZcpbcMGNVx1lRrnzJH6sW8Z2MnwKcrJydH111/f62NZ\nWVn62c9+lthAAAAA0QiFZL3rLqUsWaL2yZNVXVGh8IgRRqfCAGJ4YQcAAEhWqa+/LkdJiVIiEbWv\nWqVtY8YYHQkDEPtLAAAAomQNBDT0ssvkPP98NZ95pkJ//7siJ51kdCwMUBR2AACAfdXRoYyHHtLw\n8eNlaWpSYONGbZ8/X+rj1T+AfcGWGAAAgH1gf+cdOUpKZK2v19Z771UrK+pIEFbYAQAA9sASDMpx\n9dXKPftstZxyiqrXr6esI6FYYQcAAOhNOKyMlSuVffPNCv3oRwqsW6cO7gcDA1DYAQAAvsW2aZOG\nlpTI+vXXqvvd79RSUCBZLEbHwiDFlhgAAIBvWOrrlbNwofKmT1fr//t/CmzcqJYpUyjrMBQr7AAA\nAJGIhqxerZwbb1T7oYeqprxc7d/7ntGpAEkUdgAAMMjZ/vUvOUpKZPv0U9XdcINazjiDFXWYClti\nAADAoGRpbFTOTTcp79RTFRozRtUVFWqZPp2yDtNhhR0AAAwukYjS//pXORYvVvsBB6jmuefU/oMf\nGJ0K2C0KOwAAGDRS/v1vORYulP3//k/1Cxeq+ayzWFGH6bElBgAADHzNzcr+7W/l+slP1HHggaqu\nrFTz2WdT1pEUWGEHAAADWtratXIsWqRwbq5qV69W6Ic/NDoSEBUKOwAAGJBSvvxSOYsWKe2NN1R/\n3XVqKiqSrGwuQPJhagEAwMDS2qqsZcvkOvlkhXNzVf3KK2o6/3zKOpIWK+wAAGDASKuslKO0VJH0\ndNWuWKHQ0UcbHQnoNwo7AABIetb//EeOG25Q2saNarj6ajXOmiXZqDkYGPhsCAAAJK9QSJn33afh\nEycqYrerurJSjR4PZR0DCtMMAACSUurf/iZHSYkUiSj44INqGzfO6EhAXFDYAQBAUrEGAspZskTp\nL76ohiuuUOO8eZLdbnQsIG7YEgMAAJJDR4cyHnxQw8ePl6WlRdUbN6qxuJiy/i3BYFBVVVUKBoNG\nR0GMsMIOAABMz/7WW3KUlMja2KitZWVqnTjR6EimVFZWJq/Xq0AgIJfLJY/Ho+LiYqNjoZ9YYQcA\nAKZlCQbluPpq5RYWquXUU1W9fj1lfTeCwaC8Xq/8fr9CoZD8fr+8Xi8r7QMAhR0AAJhPOKyMFSs0\nfPx4pWzZosDLL2v75ZdLaWlGJzMtn8+nQCDQ7VggEJDP5zMoEWKFLTEAAMBUbJs2aeh118laXa1t\nS5eq9ZRTjI6UFNxut1wul/x+f+cxl8slt9ttYCrEAivsQJxx8g8A7BtLXZ1yFixQ3vTpaj3hBAU2\nbqSsR8HpdMrj8Sg/P192u135+fnyeDxyOp1GR0M/scIOxBEn/wDAPohENOQvf1HOkiUK/eAHCrz0\nkjq++12jUyWl4uJiFRYWyufzye12U9YHCAo7ECe7nvwjqfPkn8LCQl5AAeAbtg8/lKO0VLZPP1Xd\nkiVqOf10yWIxOlZSczqdGsdNpAYUtsQAccLJPwCwe5bGRuUsWaK8005T6IgjVF1RoZZp0yjrQC8s\nkUgkYnSIWGpsbFQoFDI6hmlYrVaFw2GjY5iCzbbjA6X29vaEfL9gMKgJEyboq6++6jw2atQoVVRU\nmGaFnfnokuj5SBbMSBdmpKc+zUckIvvTT2tIaanCBx2kpt/+VuHDDotPwARiPnri9aM7m82mrKys\nvj03xlkMZ7fbVVdXZ3QM08jIyFBTU5PRMUwhLy9PklRfX5+Q75eenq45c+Z028M+Z84cpaenm+bv\nhPnokuj5SBbMSBdmpKdo5yPlk0/kWLBA9g8+UN3ChWr+6U93rKgPgBljPnri9aO7nTPSFwOusANm\nwsk/ACBZmpuVtWyZMu+/X03nnqut992niMNhdCwgaVDYgTjj5B8Ag1naSy/JsWiRwnl5ql2zRqEx\nYxLyfYPBIIslGDAo7AAAIOZSvvhCjkWLlPrmm6ovLVXTOedI1sRc64JL6mKg4SoxAAAgdlpblXXX\nXXKdfLI6XC5Vv/KKmoqKElbWd72kbigU6rykLjevQzJjhR0AAMREWkWFHKWlCmdmqnblSoWOPDLh\nGfZ0SV22JyJZscIOAAD6xer3a9iFF2rYxRdr+89/rpq//tWQsi5JbrdbLper2zGXyyW3221IHiAW\nKOwAAKBvQiFllpVp+MSJiqSnq7qyUk1z50opKYZFcjqd8ng8ys/Pl91uV35+vjweDyeeIqmxJQYA\nAEQt9bXXlL1ggcKRiIJ/+pPajjvO6EiduKQuBhoKOwAA2GfW6mrlLFmi9PJytV5zjbbOmiXZ7UbH\n6oFL6mIgYUsMAADYu/Z2ZXq9Gj5hgixtbareuFGtl15qyrIODDSssAMAgD2yv/WWhl53nSxNTdp6\n331qnTDB6EjAoMIKOwAA6JU1GJTj179WbmGhmqdOVfX69ZR1wACssAMAgO7CYWWsWKGcW29V6zHH\nKLBhgzoOOMDoVMCgRWEHAACd7O+9J0dJiaw1Ndp6111q/clPjI4EDHpsiQEAALLU1clRWqrcmTPV\nOmGCqjdsoKwDJsEKOwAAg1kkoiGrVinnppsUOvxwBdauVcd//ZfRqQDsgsIOAMAgZfP55Cgpke3z\nz1V3881qmTpVsliMjgXgW9gSAwDAIGPZvl05N9ygvKlTFfrxj1VdWamW00+nrAMmxQo7AACDRSSi\n9GefleOGG9R+8MGq+etf1X7ooUanArAXFHYAAAaBlI8/1tAFC2Tz+VS/aJGaZ85kRR1IEmyJAQBg\nALM0Nyv7ttvkKihQ6PvfV3VlpZrPPJOyDiQRVtgBABiIIhGlv/SSchYtUnj4cNU8/bTaR482OhWA\nPqCwAwAwwKR8/rkcCxfK/vbbaigtVVNhoWTlQ3UgWfH/XgDAgBEMBlVVVaVgMGh0FGO0tCjrzjvl\nmjRJHSNGqLqyUk3nnktZB5IcK+wAgAGhrKxMXq9XgUBALpdLHo9HxcXFRsdKmLQNG+RYsEDh7GzV\nPvWUQj/6kdGRAMQIb7kBAEkvGAzK6/XK7/crFArJ7/fL6/UOipV26+bNGnbBBRo2f762X3CBap5/\nnrIODDAUdgBA0vP5fAoEAt2OBQIB+Xw+gxIlQFubsu69V8NPOkmRjAxVV1Soac4cKSXF6GQAYowt\nMQCApOd2u+VyueT3+zuPuVwuud1uA1PFT2pVlRwlJVJKioKPPKK2Y481OhKAOGKFHQCQ9JxOpzwe\nj/Lz82W325Wfny+PxyOn02l0tJiybtmiob/4hZxz56rp3HMVePFFyjowCBi+wv7CCy/oww8/1LZt\n23TxxRdrxIgRkqQ777xTdrtdNtuOiCeeeKIOP/xwI6MCAEysuLhYhYWF8vl8crvdA6ust7cr86GH\nlP2736n1pJNUvXGjwvvvb3QqAAlieGE/7LDDdPzxx8vr9XY7brFYdPbZZ2u//fYzKBkAINk4nU6N\nGzfO6BgxZf/73zX0uuuk1lYF779fbePHGx0JQIIZXtgPPPDA3T4WiUQSmAQAAPOw1tYq+5ZbNOSZ\nZ7T90ku1/aKLpLQ0o2MBMIDhhX1PVq9eLUkaOXKkJk2apMzMzM7Hli9f3utzPB6P8vLyEpIvGVit\nVmVkZBgdwxR2bq9iProwH12Yj94xI10SNiPhsKwPPKCUhQsVOeEEtb/zjtIPOkjp8f2ufcJ8dOE1\npCfmo7udM9Kn58YwR0zNnTtXDodD4XBY69ev15o1a3TeeecZHQsAgLixvP22Ui69VJaaGrV7vYqc\ndprRkQCYgGkLu8PhkLTj3dlxxx2nu+++u9vj8+bN6/V5bW1tqqmpiXu+ZJGRkaGmpiajY5jCzlUP\n5qML89GF+egdM9IlnjNi2bZNOb/5jYasXKnG4mI1zJ8vDRkimXwemY8uvIb0xHx0l5eXp9TU1D49\n15SXdWxra1NLS0vnf//f//1f59VjAADJJRgMqqqqalDcdTRqkYiGPPmkho8fr5QvvlBg3To1/PrX\nO8o6AHzD8BX2Z599Vh999JG2b9+uRx99VKmpqfrZz36mlStXdp50OmzYMM2cOdPgpACAaJWVlcnr\n9SoQCMjlcsnj8ai4uNjoWKZg++c/5Sgpke3LL1V3221qOfVUyWIxOhYAEzK8sE+bNq3X4xdffHGC\nkwAAYikYDMrr9XbefdTv98vr9aqwsHBgXSM9SpaGBmXfcYcyHnlEjR6Pgo8+qsguF1UAgG8z5ZYY\nAEDy8/l8CgQC3Y4FAgH5fD6DEhksElH6009r+IQJsm/apJoXXlBDaSllHcBe9WmF/b333lNlZaVq\na2t10UUXacSIEfr444+13377KTs7O9YZAQBJyO12y+Vyda6wS5LL5ZLb7TYwlTFsH38sR2mpbP/6\nl+oXLVLzjBlsfwGwz6JaYW9tbdXZZ5+tH/3oR/rlL3+pG2+8sfOF+Oqrr9bNN98cl5AAgOTjdDrl\n8XiUn58vu92u/Px8eTyeQbUdxtLUpOxbb1VeQYFChx6q6ooKNc+cSVkHEJWoCntpaanWrVunRx55\nRFu2bOl2J9JTTz1V5eXlMQ8IAEhexcXFKi8v14oVK1ReXj54TjiNRJT+4otyTZyotNdeU83TT6v+\nxhsVyckxOhmAJBTVlpjHH39cN910k4qKitTR0dHtsYMPPlifffZZLLMBAAYAp9OpcePGGR0jYVI+\n+0yOhQtl/8c/VF9aqub//m/JyiljAPouqleQ2tpa/eAHP+j1sXA4rNbW1piEAgAg6bS0KGvpUrkm\nT1ZHfr6qKyvVfM45lHUA/RbVq8jBBx+s1157rdfH3njjDR166KExCQUAQDJJe/llDZ80Selr16p2\n1SrV3X67IsOGGR0LwAARVWGfNWuWbrvtNj322GNqa2uTJFksFm3YsEF33nmnPB5PXEICAGBGKZs3\na9i8eRr2i19o+4UXqua55xQaO9boWAAGmKgK+9VXX62pU6fqZz/7WedZ/ieccIImT56sKVOm6NJL\nL41LSAAATKWtTVl33y3XxImKZGerurJSTbNnSykpRicDMABFddJpSkqKnnjiCc2fP1/l5eWqrq5W\nbm6upkyZogkTJsQrIwAAppH66qtylJRIdruCjz2mtmOOMToSgAGuTzdOOvHEE3XiiSfGOgsAAOb1\nn/8o5Zpr5Hz+eTVceaUaPR7J1qd/RgEgKpy6DiAhgsGgqqqqFAwGjY4CRKe9XZl//KPsY8ZIkYiq\nKyrUeOGFlHUACRPVq43VapVlL3dn+/b12QGgrKxMXq9XgUBALpdLHo9n8NxAB0kt9c035bjuOikU\nUvuTTypy8skK19QYHQvAIBNVYV+0aFGPwl5bW6uXXnpJra2tmjNnTiyzARgAgsGgvF6v/H6/JMnv\n98vr9apsF5e1AAAgAElEQVSwsHBQ3aIeycVaW6ucm25S+nPPafsvf6ntF12kvPx8o2MBGKSiKuzX\nX399r8c7Ojo0bdo0ORyOWGQCMID4fD4FAoFuxwKBgHw+36C6++VAFQwG5fP55Ha7B8YbsI4OZTz2\nmHJuv12txx2nwIYN6hg1yuhUAAa5mOxhT0lJ0SWXXKK77rorFl8OwADidrvlcrm6HXO5XHK73QYl\nQqyUlZWpoKBARUVFKigoUFlZmdGR+sX+7rvKmzZNWffdp63LlmnrAw9Q1gGYQsxOOm1tbeVkMgA9\nOJ1OeTwe5efny263Kz8/Xx6PZ2Csxg5iu251CoVCnVudkvHfAcvWrXJce61yzzxTrZMmqXr9erVO\nmmR0LADoFNWWmC+++KLHsba2Nm3atEnXXnutjjrqqJgFAzBwFBcXq7CwcGBtnRjkBsRWp3BYQ556\nSjk33aTQEUcosG6dOg4+2OhUANBDVIX9oIMO6vUqMZFIRN/97nd1zz33xCwYgIHF6XQmT5HDXu3c\n6rTzZGIpubY62d5/X47SUqVs3qy6229Xy6mnSnu5ChoAGCWqwu71ensU9vT0dB144IE6+uijlcIt\nmQFgUNi51enbl+s0+6cnloYGZf/ud8p89FFt//nPtf3yyxXJyDA6FgDsUVSFncs2AgB2SqqtTpGI\nhjz9tHJuvFHt//VfCrzwgtq//32jUwHAPuE2bQCAPkuGrU62jz6So6REto8/Vv2iRWqeMYPtLwCS\nStSF/eGHH9bjjz+uL774Qi0tLd0es1gs+uSTT2IWDgCAvrI0NSnrrruU9cADajzvPAUfeECRnByj\nYwFA1KIq7EuWLNHixYs1evRojR07VmlpafHKBQBA30QiSn/hBeUsXqxwfr4Czzyj9sMPNzoVAPRZ\nVIX9gQce0GWXXaY777wzXnkAAOizlE8/lWPRItn/8Q/VL1ig5rPPlqwxu+UIABgiqlex2tpaTZs2\nLV5ZAADom+ZmZd9xh1yTJ6tj5EhVV1aqubCQsg5gQIjqlWzChAl6991345UFAICopa1fr+GTJilt\n/XrV/vnPqrvtNkWGDTM6FgDETFRbYu666y6deeaZys3N1WmnndbrJbysrGYAABIg5auvlLN4sdJe\ne031116rpvPOk7gfCIABKKrC/v1vrlk7d+7cXh+3WCxqb2/vfyoAAHanrU1Zf/iDspYtU8vpp6u6\nslLhvDyjUwFA3ERV2BctWtTjTqcAACRK6iuvyFFaKqWmKrhihdqOPtroSAAQd1EV9uuvvz5OMQAA\n2D3r118r58Yblf7yy2r49a/VOGeOZOPefwAGB0skEon05Ynbt29XbW2t8vPzZbfbY52rzxobGxUK\nhYyOYRpWq1XhcNjoGKZg++Yfd7ZtdWE+ujAfvTN8RtrblXb//Uq/7TaFCgrUvGSJIiNGGBKFGenJ\n8PkwEeajJ+ajO5vNpqysrL49N9onPPfcc1q0aFHn1WLefPNN/fjHP9a8efN08sknq6ioqE9BYsVu\nt6uurs7QDGaSkZGhpqYmo2OYQt43e1zr6+sNTmIezEcX5qN3Rs5I6htvyFFSIoVCql2+XG0nnLDj\nAYPyMCM98RrShfnoifnoLq8f59pEdUmXNWvWaPr06crLy9Ptt9+uXRfnDz74YD388MN9DgIA0QgG\ng6qqqlIwGDQ6CmLMWlOjoZdfLud556l55kwF1q7tKusAMAhFVdhvuOEGzZ07Vy+99JIuv/zybo+N\nHj1amzZtimk4AOhNWVmZCgoKVFRUpIKCApWVlRkdCbHQ0aGMhx/W8PHjZWlsVGDjRm2fP19KTTUs\nEm8MAZhBVIX9n//8pwoLCyWpx9Vihg0bptra2tglAzAg9bcABYNBeb1e+f1+hUIh+f1+eb1eClWS\ns//jH8qbNk1Z99+vrffco61//KM6Ro40NNO33xguXbrU0DwABq+oCntOTo5qamp6feyzzz6Ty+WK\nSSgAya+3Yh6LlXGfz6dAINDtWCAQkM/n63dmJJ5l61Y5rrlGuWedpZbJk1W9fr1aTzrJ6Fi9vjG8\n5557WJgCYIioCvtPfvIT3Xrrrdq2bVvnMYvFotbWVt1999069dRTYx4QwN6Z7WP73op5rFbG3W53\nj8UBl8slt9sdyx8B8RYOa8jKlRo+frxS/H4F1q3T9l/9SkpPNzqZpN7fGG7ZsoWtnwAMEVVhv/nm\nm/X111/r0EMP1bx582SxWHTbbbdp7Nix+uqrr7hOO2AAs+3n3l0xf/PNN2OyMu50OuXxeDovKZuf\nny+PxyOn0xnLHwNxZHv/feXNnKnsO+5Q3W9/q+Cf/qSOgw4yOlY3vb0x3G+//TR69GiDEgEYzKIq\n7AcddJDefvttnX766Vq7dq1SUlJUWVmp4447Tq+//rry8/PjlRNAL8y4n3t3W1YkxWxlvLi4WOXl\n5VqxYoXKy8tVXFzc98BIGEt9vXIWLVLeGWeo9bjjFNi4US1TpkgmvIN2b28M58+fr9zcXKOjARiE\nor4O+6hRo/TAAw/EIwuAKO1pP/e4ceMMybRzZdLv93cec7lcOvroo+XxeOT1ehUIBORyufq1Mu50\nOg37GRGlSERDVq9WzpIlaj/kENWUl6v9e98zOtVeFRcXq7CwUD6fT263W9///veNjgRgkIqqsC9b\ntkznnnsuJ5cCJrG7cmzkfu6dK5O9FfNvFyC2sQx8tn/9S47SUtk++UR111+vljPOMOWK+u7wxhCA\nGUS1JebKK6/UyJEjdfrpp+upp55Sa2trvHIB2Adm3c+9py0rOwuQ0RkRX5bGRmXffLPyTj1VocMP\nV3VFhVqmT0+qsg4AZhHVCvuXX36pxx57TI8++qgKCwuVk5Ojs88+W7NmzdKJJ54Yr4wA9sCsq9as\nTA5SkYjS//pXORYvVvuoUap59lm1H3aY0akAIKlFtcI+YsQIXXnllXrnnXf07rvv6sILL1R5ebkm\nTJiggw46SAsXLoxXTgB7wKo1zCDl00/l/NnP5LjuOtVfdZVq//IXyjoAxEBUhX1XY8aM0W9+8xt9\n/vnnevbZZ9XR0aFbbrklltkAAMmguVnZv/udXJMnq+OAA1RdWanmwkLJ2ud/YgAAu4j6KjG7qqio\n0KOPPqpVq1aprq5ORx11VKxyAQCSQNr69XIsWKCw06nav/xFoSOOMDoSAAw4URd2n8+nRx55RI89\n9pi++OILfec739Ell1yiWbNm6dBDD41HRgCAyaR8+aVyFi9W2uuvq/7aa9VUVCSlpBgdCwAGpKgK\n+1FHHaV33nlH2dnZ+ulPf6pZs2ZpwoQJ8coGADCb1lZl/eEPylq2TM3Tp6u6slJhbiYEAHEVVWHf\nb7/9tGLFCk2fPl3p6enxygQAMKHUykoNLS1VJC1NtY8/rtDRRxsdCQAGhagK+/PPPx+vHAAAk7L+\n5z9y3HCD0jZuVMOvf63GOXMkW79OgQIARCHqU/gbGxu1bNkynXXWWTrppJP00UcfSZKeeOIJ+Xy+\nmAcEABgkFFLa3Xdr+IQJithsqq6oUOO8eZR1AEiwqG+cNHHiRH311Vdyu93atGmTGhoaJEkbNmzQ\nunXrtHz58rgEBQAkTurrr8tRUiJrJKLggw+q7fjjjY4EAINWVCvsV155pdLS0vTRRx/prbfeUiQS\n6XxswoQJqqysjHlAAEDiWAMBDb3sMjnPP1/NP/2pGiorKesAYLCoVtjXrl2r+++/X9/5znfU0dHR\n7bGRI0dq8+bNMQ0HAEiQjg5lPPKIcm6/Xa0nnKDAxo3qGDlSGampUnu70ekAYFCLqrC3tbUpOzu7\n18fq6upkt9tjEgoAkDj2t9/esf2loUFb771XrSedZHQkAMAuotoS88Mf/lB//vOfe33shRde0JFH\nHhmTUACA+LMEg3JcfbVy//u/1VJQoOr16ynrAGBCUa2wX3XVVTrrrLMkSUVFRZKkDz74QE8//bQe\neOABPfPMM7FPCACIrXBYGStXKvvmmxX68Y8VWL9eHQceaHQqAMBuRFXYzzzzTN1777269tpr5fV6\nJUmzZs1Sdna27r77bk2ZMiUuIQEAsWHbtElDS0pk3bJFdXfcoZZTTpEsFqNjAQD2YJ8Le1tbmwoL\nC3XFFVdo8+bNeu2111RdXa3c3FyNGzdut3vbAQDGs9TXK/u3v1XGihVqvOACbb/sMkWGDDE6FgBg\nH+xzYU9NTdW6det02WWXKTMzU5MnT45nLgBALEQiGvKXvyhnyRK1H3qoasrL1f697xmdCgAQhai2\nxBx//PH629/+pokTJ8YswAsvvKAPP/xQ27Zt08UXX6wRI0ZIkmpra7VmzRo1NTUpPT1dM2bMkMvl\nitn3BYCBzvbhh3KUlsr26aequ+EGtZxxBttfACAJRXWVmDvuuEMPPPCA7r77bn311Vfq6OhQOBzu\n9r9oHXbYYfJ4PBo6dGi3488995yOOuooXXrppTr++OO1evXqqL82AAxGlsZG5dx0k/JOO02hMWNU\nXVGhlunT41LWg8GgqqqqFAwGY/61AQA7RFXYx4wZo08++USXXXaZDjzwQKWmpsput3f+LzU1NeoA\nBx54oHJycroda2xslN/v15gxYyTtKPX19fX8gwAAexKJKP255zR8wgTZ33pLNc89p/rFixXJyorL\ntysrK1NBQYGKiopUUFCgsrKyuHwfABjsotoSs2jRIlkS8HFqXV2dsrOzZbV2vZ9wOByqq6uT0+mM\n+/cHgGST8u9/y7Fggezvv6/6BQvUfNZZcd3+EgwG5fV65ff7JUl+v19er1eFhYW8TgNAjEVV2K+/\n/vo4xdi7SCTS7b+XL1/e65/zeDzKy8tLRKSkYLValZGRYXQMU7DZdow789GF+eiStPPR3KyU3/xG\n1jvvVHjWLHWsXKnMYcOUGaMvv7sZef/99xUIBLodCwQC+s9//qPvf//7Mfru5pK0MxJHvIZ0YT56\nYj662zkjfXpuDHPEjMPhUENDg8LhcOcqe319vRwOh8HJAMA8LM89J9uvfqXI8OFqf/llRX7844R9\n79GjR2vEiBH68ssvO4/tt99+Gj16dMIyAMBgYcrCnpmZqf3331/vvfeexo4dq/fff185OTndPmad\nN29er89ta2tTTU1NoqKaXkZGhpqamoyOYQo7Vz2Yjy7MR5dkmo+UL79UzqJFSnvjDdVdd52aiook\nq1WKQ/Y9zcjs2bPl9XoVCATkcrk0Z84cRSKRpPgd9kUyzUii8BrShfnoifnoLi8vr0/ne0omKOzP\nPvusPvroI23fvl2PPvqoUlNT9ctf/lKnn3661qxZo1deeUVpaWmaMWOG0VEBwFitrcq67z5l/c//\nqHnGDFW/8orCBu4XLy4uVmFhoXw+n9xuN3vXASBODC/s06ZN6/V4Xl7eblfRAWCwSauslKO0VJEh\nQ1T7xBMKHXWU0ZEkSU6nU+PGjTM6BgAMaIYXdgDA7ln9fjluuEFpFRVquOoqNc6eLfXjxCUAQPKJ\n6jrsAIAECYWUed99Gj5xoiKpqaqurFTjz39OWQeAQYhXfgAwmdS//U2OkhIpElHwoYfUxpYTABjU\nKOwAYBLWQEA5S5Yo/cUX1XDFFWqcN0+y242OBQAwGFtiAMBoHR3KePBBDR8/XpaWFlVv2KDG4mLK\nOgBAEivsAGAo+1tvyVFSIuv27dpaVqbWiRONjgQAMBlW2IG9CAaDqqqqUjAYNDoKBhBLMCjHVVcp\nt7BQLVOmqHr9eso6AKBXFHZgD8rKylRQUKCioiIVFBSorKzM6EhIduGwMlas0H4nnqiU6moFXn5Z\n26+4QkpPNzpZwvFmGAD2DYUd2I1gMCiv1yu/369QKCS/3y+v10u5QJ/ZNm1S3vTpyvr977X1zjsV\nfPhhdXznO0bHMgRvhgFg31HYgd3w+XwKBALdjgUCAfl8PoMSIVlZ6uqUs2CB8qZPV+sJJyiwcaNa\nTznF6FiG4c0wAESHwg7shtvtlsvl6nbM5XLJ7XYblAhJJxLRkFWrNHzCBNk++USBl15SwzXXKDJk\niNHJDMWbYQCIDoUd2A2n0ymPx6P8/HzZ7Xbl5+fL4/HI6XQaHQ1JwObzKfess5Rz662qW7JEwRUr\n1PHd7xodyxR4MwwA0eGyjsAeFBcXq7CwUD6fT263m7KOvbI0Nip76VJlPPSQmmbPVvDhhxXJyjI6\nlqnsfDPs9XoVCATkcrl4MwwAe0BhB/bC6XRqHLeGx95EIkp/7jk5rr9e7QceqJrnn1c7K8a7xZth\nANh3FHYA6KeUTz6RY8EC2T/4QPULF6r5pz+VLBajY5keb4YBYN+whx0A+sjS3Kzs22+X65RT1P7d\n76q6slLNZ51FWQcAxBQr7ADQB2kvvSTHokUK5+Wpds0ahcaMMToSAGCAorADQBRSvvhCjkWLlPrm\nm6ovLVXTOedIVj6sBADED//KAMC+aG1V1l13yXXyyepwuVT9yitqKiqirAMA4o4VdgDYi7SKCjlK\nSxXOzFTtypUKHXmk0ZEAAIMIhR0AdsO6ebMcN9ygtFdeUcNVV6lx9mwpJcXoWACAQYbPcgHg20Ih\nZZaVafhJJymSnq7qyko1ejymLevBYFBVVVUKBoNGRwEAxAEr7ACwi9TXXpOjpESyWBT805/Udtxx\nRkfao7Kysh53DC0uLjY6FgAghlhhBwBJ+vprpcyZI+fs2WoqLFSgvNz0ZT0YDMrr9crv9ysUCsnv\n98vr9bLSDgADDIUdwODW3q5Mr1f2MWOkUEjVGzeq8eKLJbvd6GR75fP5FAgEuh0LBALy+XwGJQIA\nxANbYgAMWva33tLQ666TpalJ7Y8/rsjkyQrX1PT4c8FgUD6fT263W06n04CkvXO73XK5XPL7/Z3H\nXC6X3G63gakAALHGCjuAQccaDMrx618rt7BQzVOnqnr9ekUmT+71z5aVlamgoEBFRUUqKChQWVlZ\ngtPuntPplMfjUX5+vux2u/Lz8+XxeEz1pgIA0H+ssAMYPMJhZTz+uHJuuUWtxxyjwIYN6jjggN3+\n8V33iEvq3CNeWFhomlJcXFyswsJCU34CAACIDQo7gEHB/t57O67+Ul2t1y66SI7zz99rud3THvFx\n48bFM25UnE6nqfIAAGKLLTEABjTLtm1ylJQod+ZMvZqZqR+Ewzpp6dJ92t6yc4/4rtgjDgBINAo7\ngIEpEtGQp57S8PHjlfLZZ/p41Sqd/+9/69//+c8+XwKRPeIAADNgSwyAAcf2z3/KUVoq2+efq+6W\nW9Qydaree+21Pm1vYY84AMBolkgkEjE6RCw1NjYqFAoZHcM0rFarwuGw0TFMwWbb8f60vb3d4CTm\nMeDmo6FB6bffrjSvV63z5qnl6qulrCxJO04gnTBhgr766qvOPz5q1ChVVFTI6XQyH7sx4GakH5iR\nnpiPLsxHT8xHdzabTVnf/JsU9XNjnMVwdrtddXV1RscwjYyMDDU1NRkdwxTy8vIkSfX19XH5+ma9\nVveexHs+EvY7iUSU/swzctx4o9oPPliB559X+6GH7njsm58vPT1dc+bMkdfrVSAQkMvl0pw5c5Se\nnq6mpqa4z0ey4jWkCzPSE/PRhfnoifnobueM9MWAK+yAEcrKyroVQY/Ho+LiYqNjGSpRv5OUjz/W\n0AULZPP5VL9okZpnzpQsll7/LNtbAADJiJNOgX7a9Vrd+3oy40CXiN+JpblZ2bfeKldBgUKHHKLq\nyko1n3nmbsv6TjsvgWhkWQ8Gg6qqqhrUMwIA2HcUdqCf9nSt7sEqrr+TSETp5eVyTZyotKoq1Tz9\ntOqXLFEkJ6f/XzsBzHznVACAOVHYgX7iWt09xet3kvL553LOni3HlVdq++WXq+bpp9U+enS/vmYi\n8WkMAKAvKOxAPzmdTp1zzjnKzc2VzWbjWt2Kw/XLW1qUdeedck2apI4RI1RdWammc8+VrMn1Esan\nMQCAvuCkU6CfysrK9MQTT6iurk4Oh0PnnHNO0pxwGgwG9fbbb8flBMxYneCZtmGDHAsWKJydrdon\nn9SWgw4y5KTRWFzxZucnD36/v/PYYP80BgCwd8m1PAWYzK5bHNrb21VbW6snnngiKbY4lJWVacKE\nCXvcS93fkyP7c4KndfNmDbvgAg275BJtv+AC1Tz/vJa9/nrC9n/v+rPHat85d04FAPTFgLtxUltb\nm2pqaoyOYRpcA7XLzuufxnI+qqqqVFRU1O1mXXa7XStWrNjj3TN3J1HXLQ8GgyooKOi20pufn6/y\n8vLO72vYpSrb2pT1xz8q66671HLaaapfsEBhl2ufMvfHrvOx68+em5urpqambtdW7u/3TaZr9vMa\n0iUeryHJjvnownz0xHx0l5eXp9TU1D49lxV2oB9ieXJlIq8esre91H05OTIWlypMffVVuU45RUP+\n8hcFH31U237/e4W/+f0mav/3t3/2r7/+useNUPr7fc1waUkAQPKgsAP9EKstDom+esje3mhEW477\n+2bDumWLhv7iF3LOnaumc89V4MUX1XbssVFljpXefvZvY985ACCRKOxAPxUXF6u8vFwrVqxQeXl5\nn7aNJPrqITvfaIwaNarXNxrRlON+vdlob1fm8uUaPmGCLB0dqq6oUONFF0l2+24zx3v/d28/e3Z2\ntkaMGMG+cwCAIbhKDBADO7c49JURVw8pLi7W3Llze71KzM5y/O097L2V1D292djT78T+5psaWlIi\nS0uLgvffr7bx4/cpcyyuPLMnu/vZ4/19AQDYHU46HeA44aOL2U8IMuIkz73Nx76cHBntyaDW2lpl\n33KLhjz9tLb/8pfaftFFUlpa/3+Yfvr2fCTTiaHxxGtIF7O/hhiB+ejCfPTEfHTXn5NOWWEHTCIR\nq8fR2pdPDvZ5Nb6jQxkrVijnttvUeuyxCmzYoI4DDohj+v7p76cmAADECoUdMJFkLYl7e7Nhf/dd\nOUpKZA0GtfX3v1fr5MkGJQUAIPlQ2AHERG9vNizbtinn9ts15Mkn1XjxxWr4xS+kIUMMSggAQHLi\nKjGACcXimuaGikQ05MknNXz8eKV88YUCa9eq4aqrKOsAAPQBK+yAyRh2h9EYsX3wgRylpbJ9+aXq\nbr1VLaedJlksRscCACBpscIOmEiib6AUS5aGBuUsXizXtGkKHXmkqisq1DJ1KmUdAIB+orADJpLo\nGyjFRCSi9Kef1vAJE2R//30FXnhB9QsWKJKZaXQyAAAGBAo7BpXa2lpT7w2P5g6jZmD7+GPlFhbK\nsXix6hcuVO1TT6k6L8/Uv2MAAJINhR2DxtKlS3XssceqqKhIBQUFKisrMzpSDzuvaZ6fny+73a78\n/Pzd3mHUSJamJmXfeqtcBQUKud2qrqxU88yZKrvvPhUUFJj6dwwAQLLhTqcDHHcZ2yEYDOq0007T\nl19+2XlsT3fjNFqi7rIZ9XxEIkovL1fOokUKjxihbbfcovbRoyVFf8dTs+Euhb3jNaQLM9IT89GF\n+eiJ+eiuP3c6ZYUdg4LP59PXX3/d7ZgZ9obv7vKNO69pbqaim/L553LOmiXHVVep4Ve/Us2aNZ1l\nXUrS/fcAACQBCjsGBbfbrREjRnQ7ZvTe8LKysuTYPtLSoqylS+WaNEkd+fk7tr+cc45k7f7yYYb9\n90l//XoAAHpBYceg4HQ6dckll2jUqFGm2Bu+u8s3/vvf/+5z4YxHWU17+WUNnzRJ6WvXqvapp1R3\n++2KDBvW6581ev990rwBigPeqADAwMYe9gGO/WNd8vLyVFtbq1dffTXue8P3pqqqSkVFRQqFQp3H\nrFarnE6n6urqor5hUl9vtrS7+UjZvFk5ixcrrapK9ddco6bzz5dSUvYpS6L233/7e/Z3/3yy7j+N\n9422eA3pkqwzEk/MRxfmoyfmozv2sAP7KDc31xR7w91ut9LT07sdi0QiqqmpifqGSTG92VJbm7Lu\nvluuiRMVyc5WdWWlmmbP3ueyLhmz/36w7p9P5httAQD2nc3oAHtz5513ym63y2bbEfXEE0/U4Ycf\nbnAqJDMjVoC/7cEHH1RDQ0O3Y9/+sGtn4Rw3btwev9aeyurenrur1FdflaOkRLLbFXzsMbUdc8w+\nPzcW+vP3snP//K4r7Eafo5AIsfq7BwCYm+kLu8Vi0dlnn6399tvP6CgYAJYuXar/+Z//idv2gX0R\nDAb1pz/9aa9/bl8LZ3/LqnXLFuXceKPS161Tw5VXqtHjkWyJfWno77aOnfvnv/01jP4kJd4G6xsV\nABhskmJLzADbZg+D1NbW6t577zV8+4DP59O2bdt6HB8yZIhGjBgR9QmbfT7Zs71daWVlGj5hgtpa\nW/XXO+7Ql2edlfCyHqttHcXFxSovL9eKFStUXl6e8DdiRjD6RF8AQGKYfoVdklavXi1JGjlypCZN\nmqTMzEyDEyEZbdq0abfXYk/k9gG3263hw4d3WxW1Wq0qLi7W3Llz+7QtpLi4WIWFhfv83NQ335Tj\nuutkbW/Xw9OmacHGjQqsW2fIpw6x3Naxc//8YBLt3z0AIPmY/ioxdXV1cjgcCofDWr9+vaqrq3Xe\needp+fLlvf55j8ej9vb2BKc0L6vVqnA4bHQMU6irq9NRRx2lL774ovPYqFGj9MYbbyg3NzehWZYu\nXap77rlHW7Zs0dChQ3XxxRdrwYIFMf8+tbW12rRpk0aPHr3jZ6yuVkppqax//rM6rr1WtbNn6+jj\nj+92B9hE/05qa2t17LHHGppBUud5Mrx+dMdrSBdmpCfmowvz0RPz0Z3NZpPV2rfNLabfEuNwOCTt\n+Es/7rjjupUtIBq5ubmaP39+57XYR40apfnz5ye8rEvSr371K73xxht6/vnn9e6778alrC9dulTH\nHnuspk6dqv93zDF6ubBQ9jFjZKmrU+iddxS++mpt+te/enzqsGXLFm3atCnmeXYnNze32zXyjfx7\nAQDAjEy9wt7W1qZwONx5+buqqip9+OGHmjt37h6fwzVQu3AN1C47r5H7r3/9a8BvH9j1uuRHSbpX\nkhhVqxwAACAASURBVCslRVq2TKkzZnT+uZaWFp144on9un55LDMb+ffCNZR7x2tIF2akJ+ajC/PR\nE/PRXX+uw27qPeyNjY1auXJl50mnw4YN08yZMw1OhWQ3GPY5+3w+/f/27j06qvrc//hnJhNCJjcy\nuTDGVEVam1JUbEURDqCABg3HI16KAgWNlmVC9SDWIlYErfVoLdRqm5xaT7gsi6C1Qau2UbygApr2\np60CjRarFRlCQgZyISCTzPz+oDOTYSaTSUjYO5n3ay2WZM/eO98ZH/Z68uT5fr9tdXUqkzRX0k8l\nrbBYVJGbq47v3Eyrq8TD/xcAAHrC1Al7Zmambr75ZqOHAQQYXQWOiderMX//u3Z4vaqWdJakTyTl\n5eZGXO4v1kmL/eK9AwAwAJk6YQfMpK+3gO8Ntu3bNeSuu2R1ufT0lVfqjs2bVb9vn/K6qJx3Vd3u\nD+8dAICBytQ97D1BD3so+seCjqe/sGNPuJ9Rvd6RWJqblfbww0r57W/VcuONalmwQD67vcuqeCzx\nYfb33lvoP42MZ0gQMRKO+AgiPsIRH6GOp4fd9KvEAGYQba1wQ/l8St6wQbkTJyrx739X/Z/+pOa7\n7pLPbpcUrJxHSqzdbrfefvvtLjcoMu17BwAgTtASA8TAjFvA2/7xD2XcdZdsn3yipnvu0aH/+i/J\nYunyOrfbrYceekgbN25UQ0NDoMWlsz52M753AADiCRV2IAq3260tW7ZIkmm2gLe0tirtgQeUPXWq\nPCNGqG7TJh264oqYkvXy8nJdcsklevLJJ1VbWyuPxyOXy6Vf/OIXuuSSSzRz5kwVFhaqvLw8cI1/\nJZnjfe/+z7Krij4AAAhFD/sAR/9YUHf7CyNNtDR0C3ifT4P/+EelL10qb16eDjzwgNq++c2YL4/U\ni96ZSD3qx7NKTH+YtEr/aWQ8Q4KIkXDERxDxEY74CEUPO9DL3G63Kioq5HK5AlXoiooKSeq0J7wv\nJXz6qRzf/a4yFi1S8w9+oH2Vld1K1qXIveididSjfmw/fKwV884+SyrtAADEhoQdiMA0Ey0PHVLa\nz36mnClT1J6fr7o339ShGTMka/f/6TqdTqWnp4cdz83NDTveVY96eXm5CgsLI7bQHMs0nyUAAP0U\nCTsQgX+iZUcneqJl0quvKnfyZCW99poann1WjQ8+KF9mpqTu94OXl5drxowZ2r9/v6xWq6xWq5xO\np2644Qa9+uqruvXWW2PuUe9uxbyvP0t64wEAAx2rxAAR+CdaHtt3fSJaYRK++ELpS5cqaetWNd15\np1pnzZISEgKvd7cfvGOC7ZeVlaVnnnlGeXl5eu+99zRjxoyY+/OjVcwjbb7Ul59lf+iNBwDgeDHp\ndIBjwkdQdna2GhoatHnz5pgnTh7PRMtuO3JEqb/+tVIffVSH//M/1fSjH8mblRU2nu5uYrRlyxbN\nnDlTHo8ncCwxMVHXXnutXn/9de3du7dbyW5PN1Lq7c+ytzd0YsJYZDxDgoiRcMRHEPERjvgIxaRT\nIAYrVqzQ+eefH1PftV+0jYd606C33lLOlClKfu45udeu1YEVK8KSdaln/eCRWlKysrK0ceNGffHF\nF92eCNrTZR57+7OkNx4AEC9I2BEX3G63ysrKtGvXLlOtVGKtrdWQ0lJl3nijto8fr4/WrtWR0aM7\nPb8n/eCREuwpU6aEVYG6k+yWlJSoqqpKa9euVVVVlSFtKGaYZwAAwIlAwo64UFNTo9ra2pBjhlZj\nPR6lPP64cidO1M6dOzU6NVXn/fa3Kiwqilr572l1+9gEe9GiRced7J6o3z5E+/5m2cwKAIC+RA/7\nAEf/2FFut1uXXXaZdu3aFTjWWb9zX/etD6quVsbixVJbm7648079xz33GNIPXl5erlWrVnW7h91s\neuv/F/2nkfEMCSJGwhEfQcRHOOIjFD3sQBccDodKS0uVn58ftRrbnfXFu8u6b5+G3HabHLNm6dCV\nV6r+lVf0/zIyetSH3RvV7ZKSEm3atMnQtpbeYHSlHwCAvkbCjrixcOFCVVdXd5qgxrK+eI/W/G5v\nl33VKuVOmCBLc7Pq33hDLfPnS4MGGd6HTbILAID5kbAjrmRlZXWaoHa16khPqu+J77+v7GnTlPqb\n32j/L3+p/U88ofaTTw683td92GwqBABA/8fGScC/+avdHfvJ/dXuYzcfcrlcgQT+9NNPD7uXZf9+\npT/4oJKffVYt8+erpaREGjw44vctKSmJedOi7mBTIQAABgYq7MC/Rat2R6q+NzQ0qKioSMuXLw8e\n9HqVvG6dcidMUILLpfqNG9Vy223S4MFRq9293ZoSS3sPAADoH6iwAx10Vu12Op3KyMgIm/3f1NSk\nRx55RJK0aOpUDbnrLln37FHjww/rcGGhZLFIOvHV7mjtPWPHju2z7wsAAHofFXbgGMdWu8vLyzVj\nxgy53W5ZreH/ZFK9Xp1RVqbsyy/Xl2PGqP6NN3R46tRAsm5EtdvoyawAAKD3kLADUXRMtr1er7xe\nb8jrMyXVSPrql1/qlQcfVPPixfLZ7SHndDWZtS+wqRAAAAMHLTFAFJGSbavVqgKvV7+U9HVJt0l6\ny+lU1eTJEe8RbTJrX+qryawAAODEosKOuNOdpQ6PbS1JkfSo3a73bTbVDB6skQkJeisvT8U33thp\nQmxktZt11gEA6P+osCOurFixQo899ljMkz/9yXbF//2f/qOuTisktQ0ZogMrV2q806nHY6xeU+0G\nAAA9ZfH5fD6jB9Gbjhw5EraSRzyz2+1qbW01ehimYLFYdP7552vXrl2BY3l5eaqqqoqaQCd8+qns\nixYp8cMPte+HP5T1+usDE0r7O+IjKDs7W5J4fhyDGAkiRsIRH0HERzjiI1R2drYGDRrUo2tpiUHc\n2LZtm2pra0OORZ38eeiQ0h5+WDlTpsg6fLj2b90q6w03DJhkHQAA9A+0xCBujBw5Uk6nM6TC3tnk\nz6SNG5WxZIm8DocaKivlOeusEzlUAACAACrsiBtZWVkqLS2NOvkzYdcuZRYXK/O//1stpaXa94c/\nRE3WuzOBtTeuAwAA8YcKO+LKwoULNW3atPDJn19+qdRf/1qpjz2mQ5dfrro335Q3KyvqvXq6e+mJ\n3vUUAAD0bwNu0unBgwfl8XiMHoZpWK3WsM1+4pXNdvTn07a2ttDjb7yh5DvukAYPVuvPfqb288/v\n8l5ut1sTJ07UF198ETiWn5+vTZs2RZ3A2tPr+grxEdRZfMQ7YiSIGAlHfAQRH+GIj1A2m02pqak9\nu7aXx2K4xMRENTY2Gj0M02CGdpB/Bn9TU5MkybpnjzLuvVdJb7yh5jvu0MG5cyWbTYrh83rvvfe0\nd+/ekGN79+7Ve++9p7Fjx/b6dX2F+Ag6Nj5wFDESRIyEIz6CiI9wxEcof4z0BD3siD8ej1L+93+V\ne+GF8tlsqtu0SQdvvPFosh6jYzdUkmLbvbSn1wEAgPhFwo64Ynn3XeVMnSr7unVyV1TowC9/Ke/Q\nod2+T093LzVy11MAANA/DbgedjZOCsWvo4Kys7OVsHixDg4erF1XX62/f/LJce866na7e7R7aU+v\n623ERxCbnkRGjAQRI+GIjyDiIxzxEYqNk4AYtf/P/+hhq1WXTJummTNnqrCwUOXl5ZJ6ttSiw+HQ\n2LFju5109/Q6AAAQfwbcpFMgmoaGBlVUVMjlckmSXC6XKioq1NraqnXr1rHUIgAAMB0q7Igr27Zt\nU319fcixuro6rVmzRi6XSx6PJ5DER6u0d6zG+//+z3/+k82QAABAr6PCjrgycuRI5eTkBCrskpSR\nkRGWZNfW1qqmpibiUosdNz5KTk6Wz+fTwYMHA687nU4q9AAAoNdQYUdcycrKClul5Tvf+U7Ec51O\nZ9gxt9sdaKnxeDxqampSc3OzvF5v4E8sFXoAAIBYkbAj7pSUlKiqqkpr165VVVWVJk2aFPG82tra\nsGM1NTVhLTWR1NfXq6am5rjHCgAAQMKOuNRxlZaCgoKwarrT6Yy4mVGkjY8iYTMkAADQW0jYEfe6\ns5nRseemp6crLS1NVqs18IfNkAAAQG9i46QBjk0Lgrra1KI7mxl1PFc62irjdDpVW1sb82ZIZtg8\nifgIYtOTyIiRIGIkHPERRHyEIz5CHc/GSawSA/ybv02mJ+f6/3766afHdH3HlWZY9x0AAERDSwzQ\nB6LtmnrsSjOsKgMAAKIhYQd6WXl5uQoLCzVz5kwVFhaqvLw85PVIK82wqgwAAOgMCTvQi2Kpnkda\naYZVZQAAQGdI2IEYRGtx6SiW6nl3VqXpq3ECAID+g0mnQBeWL1+u1atXq7GxUbm5uVEniPqr5y6X\nK3AsUvW8pKREM2bM6NVVYpjICgDAwESFHYhi+fLleuSRR9TQ0KC2trYuJ4j6q+dOp1MJCQlyOp1R\n13T3b950vJjICgDAwEXCDnTC7XZrzZo18nq9Icfr6uq6nCBqsVhC/tvXmMgKAMDARcIOdKKmpkYH\nDhwIO56RkdHpBFF/pXvPnj1qb2/Xnj17Tkilm4msAAAMXCTsQCcKCgqUm5sbcsxqtWry5MmdXtPd\nSndvTRLty4msAADAWCTsQBSTJk2S0+mUzWaT3W5XSkqKKisrI66vLnWv0t3Veu3dVVJSoqqqKq1d\nu1ZVVVVMOAUAYIAgYUfcilbdXr58uS666CKtW7dOFotF06dPV3p6upqbm6NO6oy10t1Xk0R7cyIr\nAAAwB5Z1RFyKtgSif2UY/2TTPXv26LXXXlNjY2PIPerq6vTss8/qqquuCkmQY1myMVrrzNixY3v7\n7QIAgH6MCjviTrTqttvt1urVq8NWhmlsbFRGRkbIMa/Xq/vvvz9iO0tXlW4miQIAgFiRsCPuRKtu\n19TUhFXSpaMrw8ydO1d5eXmy2WyyWq3yer0xrc0eCZNEAQBArEjYEXeiVbc7Wxlm7ty5uv3221VV\nVaW7775bVmvoP52erHne2STR3lo5BgAADAwk7Ig7HavbNptNWVlZuvbaa+VwOCK+tmDBAt1+++2B\na6+66qqwpL6n7SzHts709soxAACg/0tYtmzZMqMHEU1DQ4Oeeuopbd68WR988IFOOeUUpaSkdHp+\ne3u7WltbT+AIzS0xMVEej8foYZiC3W6XJLW2tmr06NFqbm7WRx99pMbGRn366adqb2/X6NGjNXr0\naF199dW68MIL9YMf/EDnnHOO3n//faWkpCg5OVnJyclqb2/Xzp07dfjwYTmdThUXF2vChAnHNT63\n263bb79dLpdLXq9Xzc3N2rlzp66++molJyf3xkcQpi/iw+12h3xe/UXH+EAQz5AgYiQc8RFEfIQj\nPkLZ7XYlJCT06FrTV9hfeOEFnXvuubrllls0btw4VVZWGj0kDABut1vr1q3Tvn37Ivah+yvf69ev\nj1jx7os1z7u76ZIZ8RsCAAB6n6kT9oMHD8rlcunMM8+UJI0YMUJNTU309uK4xZIcd7VWem+ved7f\nV47pq7XlAQCId6ZO2BsbG5WWlhYywS8jIyPiKh5Ad8SSHJ/oind/XzlmIPyGAAAAM+p3Gyf5fD5J\n0hNPPBHx9eLiYmVnZ5/IIZma1WoN9NXFO5vtaLhnZ2crOztbt9xyi371q19p7969Gjp0qObPn68z\nzjgjcP64cePkdDq1a9euwLGhQ4dq3LhxysrK6pMxLlmyRKWlpdq2bZtGjhzZZ9/Hrzfjw4jPqzd1\njA8E8QwJIkbCER9BxEc44iOUP0Z6wtQV9oyMDDU3N4dsYtPU1BS2gQ3QEwsXLlR1dbVefPFFVVdX\na+HChSGvZ2VlqbS0VPn5+UpMTFR+fr7mz5/f58lnVlaWJk6c2C+S3I6M+rwAABjoLD5/ydqkVq1a\npVGjRmnUqFHavn27Nm/erHnz5nV6/pEjR7Rv374TOEJzs9vtzFj/N3/Vo7vx4Xa7VVNTo4KCgn7T\nnhKrvoiP/vp59TQ+BjqeIUHESDjiI4j4CEd8hMrOztagQYN6dK3pW2KmTZumDRs26K233lJSUpKu\nuOIKo4eEOOOfXIrY8HkBANC7TJ+wZ2dn66abbjJ6GAAAAIAhTN3DDgAAAMQ7EnYAAADAxEjYAQAA\nABMjYUdcc7vd2rJlC7txAgAA0yJhR9wqLy9XYWGhZs6cqcLCQpWXlxs9JAAAgDAk7IhLbrdbFRUV\ncrlc8ng8crlcqqiooNIOAABMh4Qdcammpkb19fUhx+rr61VTU2PQiAAAACIjYUdcKigoUE5OTsix\nnJwcFRQUGDQiAACAyEjYEZccDoeKi4uVl5enxMRE5eXlqbi4WA6Hw+ihAQAAhDD9TqdAXykpKdGM\nGTNUU1OjgoICknUAAGBKVNgR1xwOh8aOHStJLO8IAABMiYQdcY/lHQEAgJmRsCOusbwjAAAwOxJ2\nxDWjl3dkp1UAANAVEnbENSOXd6QVBwAAxIKEHXHNqOUdacUBAACxYllHxD0jlneM1orjX7UGAABA\nosIOSAou73ii1mJnp1UAABArEnbAAOy0CgAAYkVLDGAQdloFAACxIGEHDNRxp1UAAIBIaIkBAAAA\nTIyEHQAAADAxEnYAAADAxEjYAQAAABMjYQcAAABMjIQdAAAAMDESdgAAAMDESNgBAAAAEyNhBwAA\nAEyMhB0AAAAwMYvP5/MZPYjedPDgQXk8HqOHYRpWq1Ver9foYZiCzWZTQ0ODPvzwQ40YMUIOh8Po\nIRmO+Aiy2WySpLa2NoNHYi7ESBAxEo74CCI+whEfoWw2m1JTU3t2bS+PxXCJiYlqbGw0ehimYbfb\n1draavQwTGHNmjUqKytTbW2tcnJyVFxcrJKSEqOHZSjiIyg7O1uS1NTUZPBIzIUYCSJGwhEfQcRH\nOOIjlD9GeoKWGMQFt9utsrIy7dq1Sx6PRy6XSxUVFXK73UYPDQAAICoSdsSFmpoa1dbWhhyrr69X\nTU2NQSMCAACIDQk74kJBQYGcTmfIsZycHBUUFBg0IgAAgNiQsCMuOBwOlZaWKj8/X4mJicrLy1Nx\ncTETTwEAgOkNuEmnQGcWLlyouXPnavPmzSooKCBZBwAA/QIJO+JKVlaWxo4da/QwAAAAYkZLDAAA\nAGBiJOwAAACAiZGwAwAAACZGwg4AAACYGAk7AAAAYGIk7AAAAICJkbADAAAAJkbCDgAAAJgYCTsA\nAABgYiTsAAAAgImRsAMAAAAmRsIOAAAAmBgJOwAAAGBiJOwAAACAiZGwAwAAACZGwg4AAACYGAk7\nAAAAYGIk7AAAAICJkbADAAAAJkbCDgAAAJgYCTsAAABgYiTsAAAAgImRsAMAAAAmZjN6AJ154403\nVF1drfT0dElSbm6urrzySoNHBQAAAJxYpk3YJemss87S1KlTjR4GAAAAYBhaYgAAAAATM3WFfceO\nHfrss8+UnJysCRMmaNiwYUYPCQAAADihLD6fz2fEN37iiSfkdrsjvnbzzTfLarXKbrfLarXq888/\n1/r16zVv3jxlZGQEro+kuLhYbW1tfTbu/sZqtcrr9Ro9DFOw2Y7+fEp8BBEfQcRHZMRIEDESjvgI\nIj7CER+hbDabrNaeNbcYVmG/6aabYj73lFNOkdPplMvlCiTskdTV1amioqJb90b88P+QR3wgEuID\nXSFGEA3xga4cT4yYtiWmqakpsEJMQ0OD9u7dq9zc3MDrkd5sZ1V3AAAAoL8ybcL+6quvas+ePbJa\nrbJarSoqKlJWVpbRwwIAAABOKNMm7NOnTzd6CAAAAIDhWNYRAAAAMDESdgAAAMDEDFvWEQAAAEDX\nTNvD3l0NDQ3asGGDWltbNXjwYF1xxRXKyckxelgwiZ///OdKTEwMrJM7fvx4ffOb3zR4VDDSH//4\nR3300Uc6cOCAbr75ZjmdTkk8S3BUZ/HBswTS0bXWf/e736m+vl6JiYlKSUlRUVGRHA6HDh48qMrK\nSrndbtlsNhUVFenUU081esg4gaLFx8qVK9XY2KjBgwdLkkaNGqUxY8Z0ec8Bk7C/8MILOvfcc3X2\n2Wdrx44dqqys1Lx584weFkzCYrHommuu0dChQ40eCkxixIgRGjdunCoqKkKO8yyB1Hl88CyB37e/\n/W197WtfkyRVV1fr+eef1/XXX69XXnlF+fn5mj17tnbv3q3169drwYIFPd4wB/1TZ/FhsVh06aWX\n6utf/3q37jcgoufgwYNyuVw688wzJR190DY1NXW6kyriE91f6OjUU08N7PXgx7MEfpHiw49nCWw2\nWyAZk6T8/HwdOHBAkrRjxw6de+65kqSTTz5ZaWlp+uyzz4wYJgwSLT6knj1DBkSFvbGxUWlpaSE/\nvWZkZKixsVEOh8PAkcFMKisrJR19gE6ePFkpKSkGjwhmw7MEseBZgmO9++67KigoUGtrq7xer1JT\nUwOvDRkyRI2NjQaODkbzx4ffxo0b9frrrysnJ0eTJ09WZmZml/cYEAl7JFRA0NENN9ygjIwMeb1e\nvfrqq9qwYYNmzZpl9LDQD/AsQUc8S3CsN998U263W3PmzJHH4wl7nWdIfOsYH5J05ZVXBn57V11d\nrbVr12r+/Pld3mdAtMRkZGSoublZXq83cKypqUkZGRkGjgpm4o8Fq9WqMWPG6PPPPzd4RDAjniXo\nCs8SdLR582bV1NRo9uzZSkxMlN1ul9VqVUtLS+CcxsZGniFx6tj4kBTSanfeeedp//79OnToUJf3\nGhAJe0pKik466SR98MEHkqTt27crPT2dX2FDknTkyBEdPnw48PWHH34YWPEB6IhnCaLhWYKOtmzZ\nom3btmnOnDlKSkoKHB8xYoT+8pe/SJJ2796t5uZmnXbaaQaNEkaJFB9erzfkh7kdO3YoNTVVycnJ\nXd5vwKzDvm/fPm3YsEGHDh1SUlKSrrjiCuXm5ho9LJjA/v37tX79+sCvJTMzMzV16lQNGTLE4JHB\nSH/4wx/0j3/8Qy0tLbLb7Ro0aJBuvfVWniWQFDk+vvvd7/IsgaSjv3lbsWKFHA6HBg0aJOnoRMOb\nbrpJLS0tqqys1P79+2Wz2XTZZZeRsMeZzuJjzpw5WrVqldrb2yUdLRIVFhbGtOrUgEnYAQAAgIFo\nQLTEAAAAAAMVCTsAAABgYiTsAAAAgImRsAMAAAAmRsIOAAAAmBgJOwAAAGBiJOwAgDBWq1X33Xdf\nt69bvXq1Vq5cGfF4QkICO4MCQA+QsAMAes2qVasiJuzTpk3T1q1bddJJJxkwKgDo32xGDwAAMPBl\nZWUpKyvL6GEAQL9EhR0ADLBs2TJZrVZt27ZNkyZNUkpKivLy8rR06dKQ8z7++GNNnz5dmZmZstvt\nuuCCC1RVVdWje61atUpWqzWsLcV/fTSffPKJ5syZo9NPP112u13Dhw9XaWmpDhw4EDjnoosu0qZN\nm7R582ZZrVZZrVZNmjSp0+/d1tamu+++W8OGDVNSUpKGDRumJUuWqK2tLXDOv/71L1mtVj3++ONa\nunSp8vLylJmZqcsvv1y7d++O4ZMGgP6PhB0ADGCxWCRJ06dP18UXX6znnntOs2bN0o9//ONA7/ie\nPXs0btw4ffjhhyorK9MzzzyjzMxMFRUVhSTtsdzLf57/3GPHEul4Ry6XS1/5ylf06KOP6uWXX9bS\npUv12muvqaioKHBOeXm5zjnnHJ111ll699139c4776isrKzT7zFnzhz99Kc/1fXXX68XX3xRxcXF\neuihh3T99deHff8HH3xQn3zyiVauXKlHH31UW7du1ezZs6OOGQAGClpiAMAgFotF8+bN0x133CFJ\nmjJlihobG7V8+XItWLBAy5cvV2Njo6qrqzVs2DBJ0qWXXqoRI0boRz/6kQoLC2O+V3p6+nGNdfz4\n8Ro/fnzg6wsuuEDDhw/XhAkT9Le//U1nn322CgoKlJ6ervb2do0ePTrq/bZv365169bp3nvv1ZIl\nSwJjtlqtuueee3TnnXdq5MiRgfNPO+00Pfnkk4Gv6+rq9MMf/lC1tbVyOp3H9d4AwOyosAOAga65\n5pqQr6+99lq1tLRo27ZteuuttzRmzJhAsi4dXb3luuuu01//+le1tLTEfK/j5fF49MADD+gb3/iG\n7Ha7EhMTAwn8Rx991O37vfnmm7JYLJo1a1bI8dmzZ8vn82nTpk0hxy+77LKQr88880xJYtUZAHGB\nhB0ADDR06NCIX+/evVtutzviqipOp1M+n0/79+/v8l4+n69Xer3vvPNO3XfffZozZ45eeukl/fnP\nf1ZlZaV8Pp8OHz7c7fu53W5JCnt//mq5/3U/h8MR8nVSUpIk9eh7A0B/Q0sMABho7969Ou2000K+\nlqSTTz5ZDodDtbW1Ydfs2bNHFoslLImNdi9JGjx4sCTpyJEjIdc1NDR0Oc7169dr7ty5Wrx4ceBY\nc3Nzl9d1xj/22trakN8g+N8vK8oAQBAVdgAw0NNPPx3y9VNPPaXU1FSNHDlSEydO1DvvvBPS9uH1\nerV+/Xp961vfUkpKSpf3SktLC/SCn3rqqfL5fCEtMu3t7Xr55Ze7HGdra6tsttAaT0VFRdhE0qSk\nJB06dKjL+02cOFE+n0/r1q0LOf7kk0/KYrFowoQJXd4DAOIFFXYAMIjP59NvfvObwCTNP/3pT6qo\nqNC9996r9PR03XbbbVq9erUuvvhiLVu2TGlpaSorK9POnTv10ksvdetekjR69GgNHz5cd9xxh9rb\n25WUlKSysjJ9+eWXXY516tSpWr16tUaOHKmvfvWr+v3vf6+tW7eGnTdixAiVl5fr6aef1vDhw5WW\nlqYzzjgj4nnXXXedli1bJo/Ho7Fjx2rLli26//77NXPmzJAJp9E+PwCIByTsAGAQi8Wi5557Tt//\n/vd1//33KyMjQ0uWLNHdd98t6Wh/99tvv61FixaptLRUX375pUaNGqWXXnpJF198cbfuJUkJCQl6\n/vnnNX/+fN1www1yOBxasGCBzj///JDlH/3361g9f+yxxyQpcL+ioiKtW7dO5513Xsh1ixYtQJX5\nwQAAAKxJREFU0scff6zvfe97amlp0cSJE/Xaa69FfP9r1qzR8OHDtXLlSv3kJz9RXl6eFi9erHvu\nuSdsLJ19fgAQDyw+ShQAcMLde++9uu++++TxeLrctOhE3gsAYD482QEAAAATI2EHAIP0ZksH7SEA\nMHDREgMAAACYGBV2AAAAwMRI2AEAAAATI2EHAAAATIyEHQAAADAxEnYAAADAxEjYAQAAABMjYQcA\nAABM7P8D9L//rLsQtScAAAAASUVORK5CYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7f0f4c682650>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<ggplot: (8731481279349)>"
]
},
"execution_count": 418,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"predictions = [ theta[0] + theta[1]*x for x in ex1data1[:,0] ]\n",
"ggplot(pd.DataFrame({\"x\": ex1data1[:,0], \"y\": ex1data1[:,1], \"predictions\": predictions}), aes(x=\"x\", y=\"y\")) \\\n",
" + geom_point() \\\n",
" + geom_line(aes(x=\"x\", y=\"predictions\"), color='red') \\\n",
" + xlab('population') \\\n",
" + ylab('revenue')"
]
},
{
"cell_type": "code",
"execution_count": 419,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"For population = 35,000, we predict a profit of\n",
"4519.7678677\n",
"For population = 70,000, we predict a profit of\n",
"45342.4501294\n"
]
}
],
"source": [
"# Predict values for population sizes of 35,000 and 70,000\n",
"predict1 = np.dot([1, 3.5], theta)[0]\n",
"print('For population = 35,000, we predict a profit of')\n",
"print(predict1*10000)\n",
"predict2 = np.dot([1, 7], theta)[0]\n",
"print('For population = 70,000, we predict a profit of')\n",
"print(predict2*10000)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Linear regression with multiple variables\n",
"We can use the same solutions for performing linear regression on more than one variable.\n",
"## Reading input data\n",
"Let's read the input data and define x and y accordingly:"
]
},
{
"cell_type": "code",
"execution_count": 420,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"First 10 examples from the dataset:\n",
"('x:', array([[ 2.10400000e+03, 3.00000000e+00],\n",
" [ 1.60000000e+03, 3.00000000e+00],\n",
" [ 2.40000000e+03, 3.00000000e+00],\n",
" [ 1.41600000e+03, 2.00000000e+00],\n",
" [ 3.00000000e+03, 4.00000000e+00],\n",
" [ 1.98500000e+03, 4.00000000e+00],\n",
" [ 1.53400000e+03, 3.00000000e+00],\n",
" [ 1.42700000e+03, 3.00000000e+00],\n",
" [ 1.38000000e+03, 3.00000000e+00],\n",
" [ 1.49400000e+03, 3.00000000e+00]]), 'y:', array([ 399900., 329900., 369000., 232000., 539900., 299900.,\n",
" 314900., 198999., 212000., 242500.]))\n"
]
}
],
"source": [
"ex1data2 = np.genfromtxt('ex1data2.txt', delimiter=',')\n",
"x = ex1data2[:, [0,1]]\n",
"y = ex1data2[:, 2]\n",
"m = y.shape[0]\n",
"print('First 10 examples from the dataset:');\n",
"print(\"x:\", x[range(10),:], \"y:\", y[range(10)])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Feature scaling"
]
},
{
"cell_type": "code",
"execution_count": 421,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"('final theta', array([[ 334302.06399328],\n",
" [ 99411.44947359],\n",
" [ 3267.01285407]]), 'final cost', 2106213044.7604921)\n"
]
},
{
"data": {
"image/png": "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\nv0sZOHCgKzIy0vXXv/7Vdfbs2XyvJyYm5tuWlZXlGj58uKtu3bquX3/9Nc9rObP6xz/+kWf7ihUr\nXJGRka6BAwfm2d6hQwdXVFSUa9y4ca4LFy7kbl+0aJErMjLS9eijj17RzwXAP7CUBYBRSUlJklTg\nEpZL+eKLL5Samqp+/frphhtuyN1ut9v18MMPy+Vy5S5d+KPmzZvnO2N72223yeVyaefOnbnbOnfu\nrICAAC1ZsiTPvj/88IP279+vTp065Z5R3r17t7Zv366+ffvmu0NIw4YNFRcXp6+++kpnz57N81pQ\nUJAeeOCBfBmXLl0ql8ulESNGqHTp0rnbw8PDNXjwYLn+dL3+l19+qcTERN19992qVq1antduueUW\n1atXT0uXLs33Oddff72GDBmSZ1vv3r3lcrm0Y8eO3G2LFi1Senq6Ro4cqerVq+c7jtPplCS5XC7N\nnz9ftWvX1tChQ/PsU6FCBQ0fPlynTp0qcjnHiRMnJEmVKlXK95rL5dLLL7+sqVOn5v7z9ttv59vP\nZrNp7NixCgsLy/da5cqV822z2+3q27evsrOztXHjxnyvBwQEaOzYsXm2dezYUQ0aNNC3336rY8eO\n5XvPxIkTFRAQkPv77t27y+Fw5Pn3DAD+jKUsACxnz549stlsatq0ab7XoqKiVKZMmQLX/9apUyff\ntpwvBCkpKbnbypUrp7Zt22r16tX67bffcvf5+OOPZbPZ1L1799x9t2/fLklKTEzU1KlT8x3/999/\nV3Z2tg4dOpS75EOSqlatmm95iSTt3btXkgq8DWBB23KWt+zbt6/Az09PT1dycrKSk5NVvnz53O1R\nUVH59s35Oc+cOZO7LadItm7dOt/+f7R//36lpKSoSpUqBeY4ePCgXC6X9u/fr3bt2hV6rEvJzs7W\nK6+8krucx+VyqUqVKrrzzjvz7Vu/fv0Cj5GRkaF33nlHy5Yt04EDB5SWlpb7ms1m0/Hjx/O9p0qV\nKgV+cYyJidHOnTu1Z8+ePIW/bNmy+b4ABAQE6JprrskzWwD4M8sV82XLlmnv3r1KTk7WqFGjCjz7\n8WcLFizQkSNHdObMGU2YMEGlSpXKfe2XX37RkiVLdOHCBZUtW1a9e/fOt6YUgOc4nU4dOHBAv/32\nW4FnZAuSc/Y5Z91wQccs6CLGgs6g5pzVzMrKyrO9e/fuWrVqlZYuXaphw4bJ5XJp2bJlqlixolq0\naJG7X86dYlatWqVVq1YVmMdms+ncuXN5toWHhxe4b85dRgp6vaCf9/Tp05f8G4I/f/4fi3lxZ5Ez\n64LOYP85h3TxS9OlLoq02Wx5inBBcn7GggpyQEBAnmMX9MUsx6XmO3bsWK1Zs0a1atVS9+7dFR4e\nroCAAB09elSLFy9WRkZGvvdUqFCh0Kx//tuQP/5Nx5/z//nfMwD4I8sV87p166p169aaOXNmsd8T\nGxurrl27asqUKfle+/DDD9WjRw9Vr15dX3/9tZYtW6a+ffu6MzKAQjRu3FibNm3Sxo0b1bx582K9\nJ6f45Cx7+LMTJ05cshwVV1xcnMLCwrRkyRINGzZMGzdu1LFjxzR06NA8F2CWLl1aNptNkydP1l/+\n8pdiH7+gizil/yvMJ0+ezFcuC/p5cz5/1qxZeb4wuEvOiYrjx49f8otQTg7p4heaZ5999oo/r0qV\nKqpYsaISExP166+/6rrrrrviY/3Zjh07tGbNGrVr105vvPFGntc+/fRTLVq0qMD3nTp1qsDtOX8e\nV/vvGgDksNwa82rVqhX4179Hjx7V22+/rWnTpumNN97IcwuvmjVrKiwsLN/azKNHj8put+eepYuJ\nidG+ffvy3WoNgOf06tVLdrtdCxYsKPI+5TlnM6OiouRyuQq8Bd+ePXuUkpJy1U8JDQ4OVqdOnbRn\nzx79/PPP+uSTT/ItY5Gk6OhouVwubdu27ao+L0fOEpOtW7fme62gbQ0aNHDr51/q+OvWrSt0v1q1\naiksLEw7duzI97+1lytn3f+0adOu6jh/lvO3KG3bts332pYtWy75Zeno0aP67bff8m3/7rvvJBW8\nLAgAroTlinlBzp8/ryVLlugvf/mL7rrrLg0aNEgrVqwoci3f6dOn8/zVbnBwsIKDg1kDCJSg6tWr\na8iQIUpKStLdd99d4IV0KSkpeuaZZ7Rs2TJJUkJCgkqXLq0FCxbo8OHDuftlZ2drypQpstls6tmz\n51Vn69Gjh1wulz744AOtWLFCNWvWzFf4o6OjFR0drQ8//FBffvllvmNcuHAht8AVR+fOnWWz2TRj\nxow8SyROnjypd999N195TEhIUEREhKZNm6bvv/8+3/HS09ML3F5ct912m0JCQjRjxgzt378/z2su\nlyv34t2AgAD1799fBw4c0AsvvKDs7Ox8x/r++++Vnp5e5GeOHDlSVatW1fz58/XKK68UeLIkNTX1\nspeFRERESLpYwv9o27ZtWrBgwSXfl5WVpZdffjnPthUrVmjHjh2KjY0t1pJKACgOyy1lKciRI0d0\n6tQpvffee3m2JyUlXfZ68as90wPg8j300EM6f/685s6dq06dOqlVq1aqVauWbDabDh48qK+//lrn\nz5/Xq6++Kuni0oFJkybpb3/7m3r37p3nPuY//fSTOnTo4JZi3qJFC1WsWFHvvPOOsrKyNHz48AL3\ne/7553XnnXdq9OjRio2NVZ06dWS325WYmKhvv/1W5cuX16efflqsz6xVq5aGDRumN998U927d9ct\nt9yirKwsLVu2TPXr19fq1avz3Ls7KChIL730kkaOHKl+/fqpdevWuvHGG3XhwgUdPXpUmzdvVuPG\njTV9+vQrmoHT6dSTTz6pv/3tb+rVq5cSEhJUtWpV/f7779q0aZNuu+223Icx3Xfffdq1a5emT5+u\nL774QjExMSpXrpwSExO1a9cuHTp0SOvWrVNwcHChn1m2bFnNnDlTo0eP1tSpUzVv3jy1atVKlStX\n1vnz55WYmKh169bp3Llz6tixY7F/loYNG6p+/fr69NNP9fvvv6tBgwY6cuSIVq1apfj4eH322WcF\nvi8yMlLr16/XgAED1LRpUx09elSfffaZSpcurUcffbT4wwSAIvhEMXe5XKpUqdIl/08zx5/PNJUr\nV07Jycm5v09PT1dGRgYXfwIlLCAgQI8++qi6d++u+fPn69tvv9WGDRskSdddd5169Oih/v3751ky\n0LVrV1WqVElvvPGGli9frvT0dN1www0aP358vtsAShf/+7/UUoVLvWaz2dS1a1e9/fbbub8uyPXX\nX69FixZp5syZWrlypd5//305HA5de+21iouLU7du3YqdRZLGjx+vypUra/bs2ZozZ44qVaqkgQMH\nqlWrVlq9enW+Czejo6P10UcfacaMGVq7dq02bdqkkJAQXXvtterVq1e+LymXO4suXbqoatWqmj59\nur755hudPXtWTqdTjRs3VlxcXO5+QUFBmjlzpubNm6ePP/5Yy5Yt04ULF1SxYkVFRkbqnnvuueSF\nlH92ww03aPHixVq8eLGWL1+u9evXKzk5WcHBwapSpYp69uyp2267TQ0bNizwZyiI3W7XtGnT9Nxz\nz2n9+vXasWOHatWqpWeeeUYVK1bUihUrCnxv2bJl9eqrr+rpp5/W/PnzlZGRoRYtWmj8+PGqXbt2\n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\niYiIiIiswP8BycXz/Jx1vyoAAAAASUVORK5CYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7f0f4acd9050>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<ggplot: (8731481279393)>"
]
},
"execution_count": 421,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def normalize_features(x):\n",
" n = x.shape[1]\n",
" mu = np.zeros(n)\n",
" sigma = np.zeros(n)\n",
" for j in range(n):\n",
" mu[j] = np.mean(x[:,j])\n",
" sigma[j] = np.std(x[:,j])\n",
" x_norm = (x - mu) / (sigma);\n",
" return (x_norm, mu, sigma)\n",
"\n",
"(x_normalized, mu, sigma) = normalize_features(x)\n",
"# add intercept term to x\n",
"x_normalized = np.c_[np.ones(m), x_normalized]\n",
"\n",
"alpha = 0.01\n",
"num_iters = 400\n",
"theta = np.zeros((x_normalized.shape[1],1))\n",
"[theta, history] = gradient_descent(x_normalized, y, theta, alpha, num_iters)\n",
"print('final theta', theta, 'final cost', history[-1])\n",
"ggplot(pd.DataFrame({\"x\": range(num_iters), \"y\": history}), aes(x=\"x\", y=\"y\")) + geom_line() + xlab('Number of iterations') + ylab('Cost J') + ggtitle('Convergence Graph')\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Predictions\n",
"Lets use our trained model to predict some housing prices:"
]
},
{
"cell_type": "code",
"execution_count": 422,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"('Predicted price of a 1650 sq-ft, 3 br house ', '286003.880774')\n"
]
}
],
"source": [
"def predict(area_in_sq_ft, bedrooms_total, theta, mu, sigma):\n",
" # normalize\n",
" normalized_features = np.array([1, (area_in_sq_ft - mu[0])/sigma[0], (bedrooms_total - mu[1]/sigma[1])])\n",
" return normalized_features.dot(theta)[0]\n",
"\n",
"predicted_price = predict(1650, 3, theta, mu, sigma)\n",
"\n",
"print('Predicted price of a 1650 sq-ft, 3 br house ', str(predicted_price))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Normal Equations\n",
"Finally, we can analytically find a $ \\theta $ minimizing the cost function $ J(\\theta) $ by computing $$ \\theta = (X^T\\,X)^{-1}X^T y $$ It is not necessary for solving the normal equation to normalize $X$ and thus the resulting theta will be differently scaled to the one we computed before using gradient descent on a normalized $X$."
]
},
{
"cell_type": "code",
"execution_count": 423,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 89597.9095428 139.21067402 -8738.01911233]\n",
"('Predicted price of a 1650 sq-ft, 3 br house ', '293081.464335')\n"
]
}
],
"source": [
"def compute_theta_via_normal_equations(x, y):\n",
" return np.linalg.inv(x.transpose().dot(x)).dot(x.transpose()).dot(y)\n",
"\n",
"def predict_without_normalization(area_in_sq_ft, bedrooms_total, theta):\n",
" return np.array([1, area_in_sq_ft, bedrooms_total]).dot(theta)\n",
"\n",
"# extend the input data with an intercept term (1 column vector)\n",
"x_ = np.c_[np.ones(m), x]\n",
"\n",
"theta = compute_theta_via_normal_equations(x_, y)\n",
"print(theta)\n",
"predicted_price = predict_without_normalization(1650., 3., theta)\n",
"print('Predicted price of a 1650 sq-ft, 3 br house ', str(predicted_price))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tensorflow\n",
"Let's now see how we train a linear regression model using tensorflow."
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>area_in_sq_ft</th>\n",
" <th>bedrooms_total</th>\n",
" <th>price</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>2104</td>\n",
" <td>3</td>\n",
" <td>399900</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1600</td>\n",
" <td>3</td>\n",
" <td>329900</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2400</td>\n",
" <td>3</td>\n",
" <td>369000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1416</td>\n",
" <td>2</td>\n",
" <td>232000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>3000</td>\n",
" <td>4</td>\n",
" <td>539900</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" area_in_sq_ft bedrooms_total price\n",
"0 2104 3 399900\n",
"1 1600 3 329900\n",
"2 2400 3 369000\n",
"3 1416 2 232000\n",
"4 3000 4 539900"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"('Predicted price of a 1650 sq-ft, 3 br house ', '293083.0')\n"
]
}
],
"source": [
"import tensorflow as tf\n",
"import pandas as pd\n",
"import numpy as np\n",
"from IPython.display import display\n",
"from tempfile import mkdtemp\n",
"\n",
"tf.logging.set_verbosity(tf.logging.ERROR)\n",
"\n",
"COLUMNS=[\"area_in_sq_ft\", \"bedrooms_total\", \"price\"]\n",
"FEATURE_COLUMNS=COLUMNS[0:2]\n",
"# read data into pandas dataframe\n",
"data = pd.read_csv(\"ex1data2.txt\", sep=',', names=COLUMNS)\n",
"\n",
"# print the first 5 data entries\n",
"display(data[0:5])\n",
"\n",
"# normalize data\n",
"means = {}\n",
"stds = {}\n",
"\n",
"def normalize(x):\n",
" mean = np.mean(x)\n",
" std = np.std(x)\n",
" return [(x - mean)/std, mean, std]\n",
"\n",
"for col in FEATURE_COLUMNS:\n",
" [data[col], means[col], stds[col]] = normalize(data[col]) \n",
"\n",
"# define the input reading function, it returns a pair of feature tensors(x) and the label tensor(y)\n",
"def input_data():\n",
" features = {k: tf.constant(data[k].values, shape=[data[k].size,1]) for k in [\"area_in_sq_ft\", \"bedrooms_total\"]}\n",
" label = tf.constant(data[\"price\"].values, shape=[data[\"price\"].size,1])\n",
" return [features, label]\n",
"\n",
"# create feature columns for the model\n",
"area = tf.contrib.layers.real_valued_column(\"area_in_sq_ft\")\n",
"bedrooms = tf.contrib.layers.real_valued_column(\"bedrooms_total\")\n",
"\n",
"m = tf.contrib.learn.LinearRegressor(feature_columns=[area, bedrooms],\n",
" optimizer=tf.train.GradientDescentOptimizer(\n",
" learning_rate=0.1))\n",
"m.fit(input_fn=input_data, steps=100)\n",
"\n",
"def input_predict():\n",
" return {\"area_in_sq_ft\": tf.constant([(1650.0-means[\"area_in_sq_ft\"])/stds[\"area_in_sq_ft\"]], shape=[1,1]),\n",
" \"bedrooms_total\": tf.constant([(3.0-means[\"bedrooms_total\"])/stds[\"bedrooms_total\"]], shape=[1,1])}\n",
"\n",
"for x in m.predict_scores(input_fn=input_predict):\n",
" print('Predicted price of a 1650 sq-ft, 3 br house ', str(x))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.9"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment