{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 1.0\n", "The first task is to write two versions of a function couting the occurence of the subsequence (2, 0, 1) in an array of 10000 random numbers. But first, a few standard imports." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import timeit\n", "import numpy as np\n", "import matplotlib.pyplot as plot" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def count_seq_loop(array, seq):\n", " \"\"\"Counts the occurences of a given sequence in a given array using a loop\n", " :param array: Array to search through\n", " :param seq: Sequence to look for\n", " \n", " :return: number. Number of occurences of seq in array\n", " \"\"\"\n", " if len(array) == 0 or len(seq) == 0:\n", " return 0\n", " res = 0\n", " for i in range(len(array) - 2):\n", " if array[i] == seq[0]:\n", " if (sum([1 if array[i + k] == seq[k] else 0 for k in range(len(seq))]) == len(seq)):\n", " res += 1\n", " return res\n", "\n", "def count_seq_vectorized(array, seq):\n", " \"\"\"Counts the occurences of a given sequence in a given array using vectorization\n", " :param array: Array to search through\n", " :param seq: Sequence to look for\n", " \n", " :return: number. Number of occurences of seq in array\n", " \"\"\"\n", " if len(array) == 0 or len(seq) == 0:\n", " return 0\n", " tvals = array[:-len(seq)] == seq[0]\n", " for i in range(1, len(seq)):\n", " tvals = np.logical_and(tvals,array[i:-(len(seq) - i)] == seq[i])\n", " return np.count_nonzero(tvals)\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us now generate a random sequence of integers to measure the performance of our functions." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "N = 10000\n", "seq = [0, 1, 2]\n", "data = np.random.choice(seq, N)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using timeit, we test our functions on the newly generated sequence." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "362\n" ] }, { "data": { "text/plain": [ "1.677986160000728" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(count_seq_loop(data, seq))\n", "timeit.timeit(\"count_seq_loop(data,seq)\", globals=globals(), number=100)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "362\n" ] }, { "data": { "text/plain": [ "0.016546916998777306" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(count_seq_vectorized(data, seq))\n", "timeit.timeit(\"count_seq_vectorized(data,seq)\", globals=globals(), number=100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 1.1\n", "We now want to create a set of 200 data points. First of all, to get to know Python's normal distribution, we make some sample draws and plot them." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX8AAAD8CAYAAACfF6SlAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAEg9JREFUeJzt3W2MXFd9x/HvzyFALaigzbZJk6yXShYitJTAKiXiDeJBDVFFCgU10YqHCrTiISpIvEmxRFskq7xCKgKBlhIB1YoH8VDcYhQFCA2okGYTJSGJm+JGcbJK2phEDUSmION/X8y43mxmvVnPnbkzc78faTVz7xzPOb7y/ub63P89k6pCktQtu9oegCRp/Ax/Seogw1+SOsjwl6QOMvwlqYMMf0nqIMNfkjrI8JekDjL8JamDntb2ALZyzjnn1MLCQtvDkKSpcsstt/ykqua2azex4b+wsMDa2lrbw5CkqZLkyFNp57SPJHWQ4S9JHWT4S1IHGf6S1EGGvyR1kOEvSR1k+EtSBxn+YnUVFhZg167e4+pq2yOSNGoTe5OXxmN1FZaX4dix3vaRI71tgKWl9sYlabQ88++4fftOBf9Jx4719kuaXUOHf5ILk9yQ5FCSu5K8d0CbVyR5LMlt/Z8PDtuvmnH//TvbL2k2NDHtcxx4f1XdmuTZwC1Jrq+quze1+15V/XED/alB8/O9qZ5B+yXNrqHP/Kvqoaq6tf/8Z8Ah4Pxh31fjsX8/7N79xH27d/f2S5pdjc75J1kALgZuGvDypUluT/LNJC9ssl+duaUlWFmBPXsg6T2urHixV5p1qapm3ih5FvAvwP6q+uqm134dOFFVjye5HPi7qto74D2WgWWA+fn5lx4ZNB8hSdpSkluqanG7do2c+Sc5G/gKsLo5+AGq6qdV9Xj/+UHg7CTnDGi3UlWLVbU4N7ftdxFIks5QE9U+AT4NHKqqj2zR5tx+O5Jc0u/3kWH7liSdmSaqfV4OvBn4UZLb+vs+AMwDVNUngTcC70pyHPg5cGU1Nd8kSdqxocO/qr4PZJs2HwM+NmxfkqRmeIevJHWQ4S9JHWT4TxBX15Q0Lq7qOSFcXVPSOHnmPyFcXVPSOBn+E8LVNSWNk+E/IbZaRXOaV9f0GoY0uQz/CTFrq2uevIZx5AhUnbqG4QeANBkM/wkxa6trDnsNw/81SKPV2KqeTVtcXKy1tbW2h6EztGtX74x/swROnDj9n91c+QS9/wVN84ehNC5jXdVT2myYaxhWPkmjZ/hrJIa5hmHlkzR6hr9GYphrGLNY+dQlXq+ZDoa/RmZpCe67rzfHf999T32+ftYqn7rEKq/pYfhr4sxa5VOXeL1meljtI6kxw1R5qRlW+0gaO6/XTA/DX1JjvF4zPQx/SY3xes30GDr8k1yY5IYkh5LcleS9A9okyUeTHE5yR5KXDNuvpMl0plVeGq8mvszlOPD+qro1ybOBW5JcX1V3b2jzWmBv/+cPgU/0HyVJLRj6zL+qHqqqW/vPfwYcAs7f1OwK4HPV80PgOUnOG7ZvSdKZaXTOP8kCcDFw06aXzgce2LC9zpM/IEiynGQtydrRo0ebHJokaYPGwj/Js4CvAO+rqp9ufnnAH3lSNXBVrVTVYlUtzs3NNTU0SdImjYR/krPpBf9qVX11QJN14MIN2xcADzbRtyRp55qo9gnwaeBQVX1ki2YHgLf0q35eBjxWVQ8N27ck6cw0Ue3zcuDNwI+S3Nbf9wFgHqCqPgkcBC4HDgPHgD9voF9J0hkaOvyr6vsMntPf2KaA9wzblySpGd7hK0kdZPhLUgcZ/pLUQYa/JHWQ4S9JHWT4S1IHGf6S1EGGvyR1kOEvSR1k+EtSBxn+ktRBhr8kdZDhL0kdZPhLUgcZ/pLUQYa/JHWQ4S9JHWT4S1IHNRL+Sa5N8nCSO7d4/RVJHktyW//ng030K0k6M018gTvAZ4CPAZ87TZvvVdUfN9SfJGkIjZz5V9WNwKNNvJckafTGOed/aZLbk3wzyQvH2K8kaZOmpn22cyuwp6oeT3I58I/A3s2NkiwDywDz8/NjGpokdc9Yzvyr6qdV9Xj/+UHg7CTnDGi3UlWLVbU4Nzc3jqFJUieNJfyTnJsk/eeX9Pt9ZBx9S5KerJFpnySfB14BnJNkHfgr4GyAqvok8EbgXUmOAz8HrqyqaqJvSdLONRL+VXXVNq9/jF4pqCRpAniHryR1kOEvqRNWV2FhAXbt6j2urrY9onaNq9RTklqzugrLy3DsWG/7yJHeNsDSUnvjapNn/pJm3r59p4L/pGPHevu7yvCXNPPuv39n+7vA8Jc087ZaMKDLCwkY/pJm3v79sHv3E/ft3t3b31WGv0bG6gpNiqUlWFmBPXsg6T2urHT3Yi9Y7aMRsbpCk2ZpyX97G3nmr5GwukKabIa/RsLqCmmyGf4aCasrpMlm+GskrK6QJpvhr5GwukKabFb7aGSsrpAml2f+ktRBhr8kdZDhL0kd1Ej4J7k2ycNJ7tzi9ST5aJLDSe5I8pIm+pUknZmmzvw/A1x2mtdfC+zt/ywDn2ioX0nSGWgk/KvqRuDR0zS5Avhc9fwQeE6S85roW5K0c+Oa8z8feGDD9np/nySpBeMK/wzYV09qlCwnWUuydvTo0TEMS5K6aVzhvw5cuGH7AuDBzY2qaqWqFqtqcW5u7ow7cx15STq9cYX/AeAt/aqflwGPVdVDo+jo5DryR45A1al15P0AkKRTmir1/DzwA+D5SdaTvD3JO5O8s9/kIHAvcBj4FPDuJvodxHXkJWl7jaztU1VXbfN6Ae9poq/tuI68JG1v5u7wdR15Sa2bgguPMxf+riM/Xabgd0TamSm58Dhz4e868tNjSn5HpJ2ZkguP6U3HT57FxcVaW1trexgaoYWFXuBvtmcP3HffuEcjNWTXrt7ZzGYJnDgx8u6T3FJVi9u1m7kzf00PL85rJk3JhUfDX62Zkt8RaWem5MKj4a/WTMnviLQzU3Lh0fBXa6bkd0STaNLLxJaWeheuTpzoPU7gP2q/wF2t8kvetWMny8ROVtScLBMD/zHtgGf+kqbLlJRSTjrDX9J0sUysEYa/pOlimVgjDH9J4zfMBVvLxBph+Esar2HX9bBMrBEu7yBpvFzXY6Rc3kHSZPKC7UQw/CWNlxdsJ4LhL2m8vGA7EQx/SePlBduJ0NQXuF+W5J4kh5NcM+D1tyU5muS2/s87muhX0pSagrVvhjbh6w8NvbZPkrOAjwOvAdaBm5McqKq7NzX9YlVdPWx/kjTxpmD9oSbO/C8BDlfVvVX1S+ALwBUNvK8kTacpWH+oifA/H3hgw/Z6f99mf5rkjiRfTnJhA/1K0mSagnLWJsI/A/ZtvnPsn4CFqnoR8C3gswPfKFlOspZk7ejRow0MTZJaMAXlrE2E/zqw8Uz+AuDBjQ2q6pGq+kV/81PASwe9UVWtVNViVS3Ozc01MDRJasEUlLM2Ef43A3uTPC/J04ErgQMbGyQ5b8Pm64BDDfQraVpNeCXM0KagnHXoap+qOp7kauA64Czg2qq6K8mHgLWqOgD8RZLXAceBR4G3DduvpCk1BZUwjZjwr6lzYTdJ4+XCbiPlwm6SJtMUVMJ0geEvabymoBKmCwx/SeM1BZUwXWD4aybMevHITJmCSpguGLraR2pbV4pHZsqEV8J0gWf+mnpTsIyKNHEMf009i0eknTP8NfUsHpF2zvDX1LN4RNo5w19Tz+IRaees9tFMsHhE2hnP/CWpgwx/SdPHu/qG5rSPpOniXX2N8Mxf0nTxrr5GGP6Spot39TXC8Jc02KTOq8/qXX1jPt6Gv6QnOzmvfuQIVJ2aV5+ED4BZvKuvhePdSPgnuSzJPUkOJ7lmwOvPSPLF/us3JVlool9JIzLJ8+qzeFdfC8d76O/wTXIW8B/Aa4B14Gbgqqq6e0ObdwMvqqp3JrkSeH1V/dnp3tfv8JVatGtX7wx0swROnBj/eGZdg8d7nN/hewlwuKrurapfAl8ArtjU5grgs/3nXwZelSQN9C1pFGZ1Xn1StXC8mwj/84EHNmyv9/cNbFNVx4HHgN9soG9JozCL8+qTrIXj3UT4DzqD3/z/l6fShiTLSdaSrB09erSBoUk6I7M4rz7JWjjeTcz5Xwr8dVX9UX/7LwGq6m83tLmu3+YHSZ4G/BcwV6fp3Dl/Sdq5cc753wzsTfK8JE8HrgQObGpzAHhr//kbge+cLvglSaM19No+VXU8ydXAdcBZwLVVdVeSDwFrVXUA+DTwD0kOA4/S+4CQJLWkkYXdquogcHDTvg9ueP6/wJua6EuSNDzv8JWkDjL8JamDDH9J6iDDX5I6yPCXpA4y/CWpgwx/Seogw1+SOsjwl6QOMvwlqYMMf0nqIMNfkjrI8JekDjL8JamDDH9J6iDDX5I6yPCXpA4y/CWpgwx/SeqgocI/yW8kuT7Jj/uPz92i3a+S3Nb/OTBMn5Kk4Q175n8N8O2q2gt8u789yM+r6sX9n9cN2ackaUjDhv8VwGf7zz8L/MmQ7ydJGoNhw/+3q+ohgP7jb23R7plJ1pL8MIkfEJLUsqdt1yDJt4BzB7y0bwf9zFfVg0l+F/hOkh9V1X8O6GsZWAaYn5/fwdtLknZi2/Cvqldv9VqS/05yXlU9lOQ84OEt3uPB/uO9Sb4LXAw8KfyragVYAVhcXKyn9DeQJO3YsNM+B4C39p+/Ffj65gZJnpvkGf3n5wAvB+4esl9J0hCGDf8PA69J8mPgNf1tkiwm+ft+mxcAa0luB24APlxVhr8ktWjbaZ/TqapHgFcN2L8GvKP//F+B3x+mH0lSs7zDV5I6yPCXpA4y/CWpgwx/Seogw1+SOsjwlzS7VldhYQF27eo9rq62PaKJMVSppyRNrNVVWF6GY8d620eO9LYBlpbaG9eE8Mxf0mzat+9U8J907Fhvvwx/STPq/vt3tr9jDH9Js2mrlYFdMRgw/CXNqv37YffuJ+7bvbu3X4a/pBm1tAQrK7BnDyS9x5UVL/b2We0jaXYtLRn2W/DMX5I6yPCXpA4y/CWpgwx/Seogw1+SOmio8E/ypiR3JTmRZPE07S5Lck+Sw0muGaZP6Yy5yJf0/4Y9878TeANw41YNkpwFfBx4LXARcFWSi4bsV9qZk4t8HTkCVacW+fIDQB01VPhX1aGqumebZpcAh6vq3qr6JfAF4Iph+pV2zEW+pCcYx5z/+cADG7bX+/uk8XGRL+kJtr3DN8m3gHMHvLSvqr7+FPrIgH21RV/LwDLAvIsvqUnz872pnkH7pQ7aNvyr6tVD9rEOXLhh+wLgwS36WgFWABYXFwd+QEhnZP/+J36xB7jIlzptHNM+NwN7kzwvydOBK4EDY+hXOsVFvqQnGLbU8/VJ1oFLgW8kua6//3eSHASoquPA1cB1wCHgS1V113DDls7A0hLcdx+cONF7NPjVYUOt6llVXwO+NmD/g8DlG7YPAgeH6UuS1Bzv8JWkDjL8JamDDH9J6iDDX5I6yPCXpA5K1WTeS5XkKDDglsyZdQ7wk7YH0TKPgccAPAbD/v33VNXcdo0mNvy7JslaVW25LHYXeAw8BuAxGNff32kfSeogw1+SOsjwnxwrbQ9gAngMPAbgMRjL3985f0nqIM/8JamDDP8JkuRNSe5KciJJZ6odklyW5J4kh5Nc0/Z42pDk2iQPJ7mz7bG0IcmFSW5Icqj/O/Detsc0bkmemeTfktzePwZ/M8r+DP/JcifwBuDGtgcyLknOAj4OvBa4CLgqyUXtjqoVnwEua3sQLToOvL+qXgC8DHhPB/8d/AJ4ZVX9AfBi4LIkLxtVZ4b/BKmqQ1V1T9vjGLNLgMNVdW9V/RL4AnBFy2Mau6q6EXi07XG0paoeqqpb+89/Ru+7Pzr1Xd/V83h/8+z+z8guyhr+atv5wAMbttfp2C+9nijJAnAxcFO7Ixm/JGcluQ14GLi+qkZ2DIb6MhftXJJvAecOeGlfVX193OOZABmwzxK0jkryLOArwPuq6qdtj2fcqupXwIuTPAf4WpLfq6qRXAcy/Mesql7d9hgmzDpw4YbtC4AHWxqLWpTkbHrBv1pVX217PG2qqv9J8l1614FGEv5O+6htNwN7kzwvydOBK4EDLY9JY5YkwKeBQ1X1kbbH04Ykc/0zfpL8GvBq4N9H1Z/hP0GSvD7JOnAp8I0k17U9plGrquPA1cB19C7yfamq7mp3VOOX5PPAD4DnJ1lP8va2xzRmLwfeDLwyyW39n8u3+0Mz5jzghiR30Dspur6q/nlUnXmHryR1kGf+ktRBhr8kdZDhL0kdZPhLUgcZ/pLUQYa/JHWQ4S9JHWT4S1IH/R9KID4PImud/AAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "n = 10\n", "id2 = np.identity(2)\n", "a = np.random.multivariate_normal([1.5, 0], id2, size = n)\n", "b = np.random.multivariate_normal([0, 1.5], id2, size = n)\n", "\n", "plot.scatter(*zip(*a), color = 'r')\n", "plot.scatter(*zip(*b), color = 'b')\n", "plot.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us now create two data sets of 100 points each by drawing 100 elements from a and b respectively and add some normally distributed noise to both of them. For this purpose, we define a function, as we will need to create another, similar dataset in a later task." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def create_sample_data(a, b, N, cov = 0.25 * np.identity(2)):\n", " \"\"\"Creates 2 dimensional sample data to train and test models on\n", " :param a: vector to draw the first N samples from\n", " :param b: vector to draw the second N samples from\n", " :param N: Number of samples to draw from a and b each\n", " :param cov_factor: covariance matrix for noise\n", " \n", " :returns: ndarray. 2N random samples of a and b with noise\n", " \"\"\"\n", " noise = np.random.multivariate_normal([0, 0], cov, size = 2 * N)\n", " return np.append(a[np.random.randint(0, len(a), size = N)],\n", " b[np.random.randint(0, len(b), size = N)],\n", " axis = 0) + noise" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "N = 100\n", "sample = create_sample_data(a, b, N)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot.scatter(*zip(*sample[:N]), color = 'r')\n", "plot.scatter(*zip(*sample[N:]), color = 'b')\n", "plot.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To create our dataset, we create the label column and append it to the sample data. However, for convenience and modularity we are going to use *labels* and *sample* instead of *data*." ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": true }, "outputs": [], "source": [ "labels = np.append(np.zeros(N), np.ones(N))\n", "data = np.concatenate((sample, np.matrix(labels).T), axis = 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 1.2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we have a data set on which we could use a learning algorithm. First, though, we have to implement one. We implement LLS using numpy.linalg.solve" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def prepend_ones(matrix):\n", " \"\"\"Adds a column of ones on the left of the given matrix\n", " :param matrix: matrix to append column to.\n", " \n", " :return: ndarray. given matrix with additional column of ones on the left.\n", " \"\"\"\n", " return np.append(np.ones((len(matrix), 1)), matrix, axis = 1)\n", " \n", "\n", "def lls(dataset, labels):\n", " \"\"\"Computes a multivariate linear function minimizing squared errors\n", " \n", " :param dataset: n times d numpy matrix containing n samples from d-dimensional domain of function to be learned \n", " :param labels: function values corresponding to sample data in dataset\n", " \n", " :return: ndarray. linear function minimizing squared errors shaped as vector of dimension d + 1\n", " \"\"\" \n", " X = prepend_ones(dataset)\n", " return np.linalg.solve(np.dot(X.T, X), np.dot(X.T, labels))\n", "\n", "def linear_function(alpha):\n", " \"\"\"Transforms vector into a multivariate linear function\n", " :param alpha: d + 1 dimensional vector\n", " \n", " :returns: function. linear function from d dimensional domain into the real numbers\n", " \"\"\"\n", " def func(x):\n", " if (len(np.shape(x)) == 1):\n", " return alpha[0] + np.dot(alpha[1:], x)\n", " else:\n", " X = prepend_ones(x)\n", " return np.dot(X, alpha)\n", " return func" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we have an algorithm, let us calculate the coefficient vector corresponding to our data" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "alpha = lls(sample, labels)\n", "lls_model = linear_function(alpha)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before we look at the result, we define a function to produce a contour plot to use in the future." ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import colorsys\n", "\n", "def generate_color_palette(count):\n", " \"\"\"Generates evenly distributed rgb colours\n", " \"\"\"\n", " def to_int_rgb(tup):\n", " return tuple([int(255 * x) for x in tup])\n", "\n", " return ['#%02x%02x%02x' % to_int_rgb(colorsys.hsv_to_rgb(*(x*1.0/count, 0.5, 0.5))) for x in range(count)]\n", "\n", "def plot_contour_2d_classification(data, labels, model, grid_delta = 0.1, title = \"\"):\n", " \"\"\"Plot contour of a 2d classifier\n", " :param data:\n", " :param labels:\n", " :param model: function expecting an array of d dimensional arrays returning a value\n", " \"\"\"\n", " overlap = 0.5\n", " x_range = (min(data[:, 0]) - overlap, max(data[:, 0]) + overlap)\n", " y_range = (min(data[:, 1]) - overlap, max(data[:, 1]) + overlap)\n", "\n", " x, y = np.meshgrid(np.arange(*x_range, grid_delta), np.arange(*y_range, grid_delta))\n", " \n", " z = np.zeros(np.shape(x))\n", " for i in range(np.shape(x)[1]):\n", " array = np.array([x[:, i], y[:, i]]).T\n", " z[:, i] = model(array)\n", " \n", " label_list = np.unique(labels)\n", " rgb_colors = generate_color_palette(len(label_list))\n", " rgba_colors = [color + \"44\" for color in rgb_colors]\n", " \n", " plot.rc('text', usetex=True)\n", " plot.figure()\n", " \n", " cp = plot.contourf(x, y, z, 1, colors = rgba_colors)\n", " \n", " np.shape(data)\n", " \n", " class_dict = dict()\n", " for i in range(len(label_list)):\n", " class_dict['Class ' + str(int(label_list[i]))] = plot.scatter(*zip(*(data[np.equal(labels, label_list[i]),:])),\n", " color = rgb_colors[i])\n", "\n", " plot.title(title, fontsize = 10, color = 'black')\n", " plot.xlabel(r'$x_1$')\n", " plot.ylabel(r'$x_2$')\n", " plot.legend(class_dict.values(), class_dict.keys())\n", " plot.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "At last, we use the previously defined plot function to visualize our model." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot_contour_2d_classification(sample, labels,\n", " lambda x: lls_model(x) > 0.5,\n", " grid_delta = 0.01,\n", " title = r'Hyperplane H: $\\alpha_0 + \\alpha_1 x_1 + \\alpha_2 x_2 = \\frac{1}{2}$')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 1.3\n", "Having obtained a working model, we now would like to measure its performance. One such measure involves the confusion matrix which we calculate as follows:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def conf_matrix(labels, predictions):\n", " \"\"\"Calculates the confusion matrix given the actual and predicted labels\n", " :param labels: actual labels\n", " :param predictions: predicted labels\n", " \n", " :return: ndarray. confusion matrix\n", " \"\"\"\n", " label_list = np.unique(labels)\n", " return np.array([[np.count_nonzero(np.logical_and(labels == label_list[i], predictions == label_list[j])) \n", " for j in range(len(label_list))]\n", " for i in range(len(label_list))])\n", "\n", "def accuracy(labels, predictions):\n", " \"\"\"Calculates the accuracy of a model given the actual and predicted labels\n", " \n", " :param labels: actual labels\n", " :param predictions: predicted labels\n", " \n", " :return: number. accuracy\n", " \"\"\"\n", " return np.trace(conf_matrix(labels, predictions)) / len(labels)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[100, 0],\n", " [ 10, 90]])" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "preds = np.array([1 if lls_model(sample[i]) > 0.5 else 0 for i in range(len(sample))])\n", "conf_matrix(labels, preds)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can calculate the accuracy." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.95" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "accuracy(labels, preds)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 1.4\n", "To get and idea of how our trained model generalizes, we test it on a sample of 10000 points created similarly to our training data." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Confusion matrix:\n", " [[9787 213]\n", " [1612 8388]]\n", "Accuracy:\n", " 0.90875\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "test_N = 10000\n", "test_sample = create_sample_data(a, b, test_N)\n", "test_labels = np.append(np.zeros(test_N), np.ones(test_N))\n", "test_preds = np.array([1 if x > 0.5 else 0 for x in lls_model(test_sample)])\n", "\n", "print(\"Confusion matrix:\\n\", conf_matrix(test_labels, test_preds))\n", "print(\"Accuracy:\\n\", accuracy(test_labels, test_preds))\n", "\n", "plot_contour_2d_classification(test_sample, test_labels,\n", " lambda x: lls_model(x) > 0.5,\n", " grid_delta = 0.01,\n", " title = r'Hyperplane H: $\\alpha_0 + \\alpha_1 x_1 + \\alpha_2 x_2 = \\frac{1}{2}$')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see, the model generalises quite well to non-training data. However, one has to remember that we are not working with real world, but simulated data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 1.5\n", "In this task, we test our linear classifier on the classical *Iris dataset*. First, we need to get a hold of it." ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import pandas as pd\n", "url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'\n", "\n", "iris_data_frame = pd.read_csv(url, header = None)\n", "iris_data = np.array(iris_data_frame)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We continue by training our linear classifier to classify *setosa* correctly, using only the first two features for now." ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": true }, "outputs": [], "source": [ "labels_setosa = np.array([0 if iris_data[i, 4] == 'Iris-setosa' else 1 for i in range(len(iris_data))])\n", "sample_setosa = iris_data[:, [0, 1, 2]].astype(np.float64)\n", "\n", "alpha_setosa_reduced = lls(sample_setosa[:, [0, 1]], labels_setosa)\n", "model_setosa_reduced = linear_function(alpha_setosa_reduced)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot_contour_2d_classification(sample_setosa[:, [0, 1]], labels_setosa,\n", " lambda x: model_setosa_reduced(x) > 0.5,\n", " grid_delta = 0.01,\n", " title = r'Hyperplane H: $\\alpha_0 + \\alpha_1 x_1 + \\alpha_2 x_2 = \\frac{1}{2}$')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And now, using all four features." ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Confusion matrix:\n", " [[ 50 0]\n", " [ 0 100]]\n", "Accuracy:\n", " 1.0\n" ] } ], "source": [ "alpha_setosa = lls(sample_setosa, labels_setosa)\n", "model_setosa = linear_function(alpha_setosa)\n", "preds_setosa = [1 if x > 0.5 else 0 for x in model_setosa(sample_setosa)]\n", "\n", "print(\"Confusion matrix:\\n\", conf_matrix(labels_setosa, preds_setosa))\n", "print(\"Accuracy:\\n\", accuracy(labels_setosa, preds_setosa))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lastly, we perform the same experiment for the class *versicolor*." ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "labels_versicolor = np.array([0 if iris_data[i, 4] == 'Iris-versicolor' else 1 for i in range(len(iris_data))])\n", "sample_versicolor = iris_data[:, [0, 1, 2]].astype(np.float64)\n", "\n", "alpha_versicolor_reduced = lls(sample_versicolor[:, [0, 1]], labels_versicolor)\n", "model_versicolor_reduced = linear_function(alpha_versicolor_reduced)\n", "\n", "plot_contour_2d_classification(sample_versicolor[:, [0, 1]], labels_versicolor,\n", " lambda x: model_versicolor_reduced(x) > 0.5,\n", " grid_delta = 0.01,\n", " title = r'Hyperplane H: $\\alpha_0 + \\alpha_1 x_1 + \\alpha_2 x_2 = \\frac{1}{2}$')" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Confusion matrix:\n", " [[19 31]\n", " [12 88]]\n", "Accuracy:\n", " 0.7133333333333334\n" ] } ], "source": [ "alpha_versicolor = lls(sample_versicolor, labels_versicolor)\n", "model_versicolor = linear_function(alpha_versicolor)\n", "preds_versicolor = [1 if x > 0.5 else 0 for x in model_versicolor(sample_versicolor)]\n", "\n", "print(\"Confusion matrix:\\n\", conf_matrix(labels_versicolor, preds_versicolor))\n", "print(\"Accuracy:\\n\", accuracy(labels_versicolor, preds_versicolor))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see, we could (almost) perfectly classify the *setosa* class, while the *versicolor* classifier only reached an accuracy of about 70%. This is most likely due to the small number of features. The ones we have do not suffice to distinguish between the classes *versicolor* and *virginica*. If there is a series of properties that can linearly separate those two, they are not captured by the features available to us." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 1.8" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get to know another classification technique, we want to implement and test the *k*-nearest neighbour algorithm." ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import scipy.spatial.distance as dist\n", "\n", "def nearNeigh(x, data, labels, k, measure = 'euclidean'):\n", " \"\"\"Calculates the mean label of the k nearest neighbors\n", " :param x: vector to predict label\n", " :param data: trainig set\n", " :param labels: labels of the vectors in the training set \n", " :param measure: distance measure\n", " \n", " :return: number. mean label of the k nearest neighbors\n", " \"\"\"\n", " if len(np.shape(x)) == 1: \n", " if (k >= len(data)):\n", " return sum(labels) / len(data)\n", " distances = dist.cdist(np.matrix(x), data, measure)\n", " kSmallestIdx = np.argpartition(distances[0, :], k)[0:k]\n", " return sum(labels[kSmallestIdx]) / k\n", " else: \n", " if (k >= len(data)):\n", " return np.full((len(x),), sum(labels) / len(data))\n", " distances = dist.cdist(x, data, measure)\n", " kSmallestIdx = np.argpartition(distances, k, axis = 1)[:, 0:k]\n", " return np.sum(labels[kSmallestIdx], axis = 1) / k" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def kTest(test, training, labels, k):\n", " \"\"\"Tests k nearest neighbor algorithm for a given k\n", " :param training: training set\n", " :param labels: labels corresponding to the training set\n", " :test: test set\n", " :k: parameter for k nearest neighbor algorithm\n", " \"\"\"\n", " preds = np.array([1 if x > 0.5 else 0 for x in nearNeigh(test, training, labels, k)])\n", " conf = conf_matrix(labels, preds)\n", " print(\"k = \", k)\n", " print(\"Confusion matrix: \\n\", conf)\n", " print(\"Accuracy: \", accuracy(labels, preds))\n", " plot_contour_2d_classification(training, labels,\n", " lambda x: nearNeigh(x, training, labels, k) > 0.5,\n", " grid_delta = 0.01,\n", " title = \"Contour plot for k = \" + str(k))" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "k = 1\n", "Confusion matrix: \n", " [[100 0]\n", " [ 0 100]]\n", "Accuracy: 1.0\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "k = 15\n", "Confusion matrix: \n", " [[98 2]\n", " [ 8 92]]\n", "Accuracy: 0.95\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "k = 30\n", "Confusion matrix: \n", " [[96 4]\n", " [ 8 92]]\n", "Accuracy: 0.94\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEUCAYAAAAmxTHXAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJztnW9wXNWZ5p8jWS3LSkxjYQyKqeA2oLFZV9lqOSUx40kgJlUuFwk2Aja7kyEDW6ZqF0/VEBZqKpAPi6e2YGCoGfIFb8IEQwUMRgqbTHlYHJMMZctbSMY1nsVl47QN8dhYRnbjlCzUUuvsB93bvn11/3bfP+f2fX5VLqtvd99+723pfc553/e8R0gpQQghJL00xW0AIYSQeKEQEEJIyqEQEEJIyqEQEEJIyqEQEEJIyqEQEEJIyqEQkFgRQjwlhHhHCPGGEOLRuO0xI4TICSGeqvG9W7Tr6o/qM23O94JmxwuGY0+pes9J9FAISGxojul3UsrbpZR3A9ju8/2+HGwYuNhwu5TybinlrsgMMiGE6AbwlHZ/FwkhurVj0I51CCFycdlH1IBCQGJBCJEFsF5KWXH+Usqiz9PcG6xVNeFkQzYyK2yQUh6UUha0hzkABQDrAbyjHXtfe0xSDIWAxEUPgD1WT2ghi3f0UIYWKnlHC3GMCCGyWuhkvXYs6/A+/edHhRD9+jHttTnT5+a0878ghPidxfPm88+xwfDaRwH06CEeO9us7DCd5516R+zaLOB3AHZqYtsB4Lz2dBHA8nrOT5LPvLgNIMSI5kB3Sil3aY57CzTBkFI+qDnWHinlY0KIbinlg27vs+AeAMtsZiAF7XP6ATwIoCIk5vObbTAipXxaCHG79ho725zsgBDiDQCPGUb0+vEcbEbxxhmW4dhBIUQewBtCiNjCVERdOCMgcTEMa2e2Fpcd+EEAt2s/685wDNYhF7v3WfG6QxjqPABocf3uGs/v1TYnOx7FbChnzvNSyoKUcrvVPzsDtM95A0A/Zu/hIu2prPaYpBgKAYkFzTHt0UbHACp5A2PMer322Atu7zOGP5xyEYs0W9bjsvh4OX8ttjnZsR3AN6HNSIxoYaUtVv8sXmtMZucxe017cFmMbof9zImkBIaGSGzooR4hhJ64PKiFUt4QQvw1ZsM0d7vF0AE8qIViqt6nPd+jxeW9xtlzWkgmh1lHvEiz1fL8JhsKVie0eq+HuH9RSlnU3rfFlFQvwHuF1R7t+hcBOK9XMAkh7tWusyClPOjxXKRBEWxDTcgsmnN+zCrmT0gjw9AQIYSkHM4ICCEk5XBGQAghKYdCQAghKScRVUPZRYtk51e+ErcZhJAGZuqLLzC/pSVuMwLl344c+UxKudjtdYkQgs6vfAU7fvGLuM0ghDQwZ44dw8rFrj4zUdywdu3HXl7H0BAhJPU0ogj4gUJACEk1Z44di9uE2KEQEEJST5pnA0BCcgSEEGLLzAyaSyWImRnA57qo8vQ0vnrttRgPybQoEACapESmXK55ZE8hIIQkmuZSCVcvWoQrslkIITy/b2pyEgAwf16y3aCUEsXPP8f50VHML5drOgdDQ4SQRCNmZlIrAgAghED2iisw4+P6zVAICCHJRkpfIqDTCCKgI4RAPc2CKASEkFQxNTnZUCIQBLwbhJBUoIeDwuKHTzyBQ4cO4YorrkA+n8fmO+/ET158EX/z5JOBnPvEiRPI5/P4wV/9VQDWVsMZASEkNcyfNy+U2cBDW7cit2wZ/umXv8TPX3kFD/zFXwR27g8OHQIA/PyVV3D+/HmcOHEisHPrcEZACGlozInh//fuu/jtSy/h4mefYeFVV+Hr992Hm2+9tebzF4tF7P3Nb/Dj55+vHMtms7hw4UJ9hmvsffddfPO22wAA+e5u7H33XTywbFkg59ahEBBCGhYrEdj9/POY1o5fPHcOuzUHXqsYHPzgA9z2jW/YPl8sFvFfH3oIn3/+OTZv2oQH7r8fe999Fz/56U+x6Mor8cADD+DChQtVj9esXl15//nz53HllVcCmBWYkYPB7yxKISDEgZFCAbsPHUJxfBzZ9nZsWL0a+ZzX7Y9JnFiViP72pZcqIqAzPTmJ3770Ul2zAiey2Sx+/sorAIBb/uRP8MD992NgYAD//ZFHKg7/oa1bqx5HDXMEhNgwUihg14EDKI7Prjstjo9j14EDGClY7lFPFMJuncDFzz6zfL3dcS90r1mDvb/5jeNrnn3uudmE78mTAIAfPPww/vaZZ7Dxjjtw4sSJOY+NLFq0qBJmKhaLWLRoUc222kEhIMSG3YcOYcq0UnOqXMZuLXlH1MRpsdjCq66yfI/dcS9ks1nc9o1v4Kcvvlg5ViwWKz8/+9xzWHb99fibJ5+shHiWLVuGn7/yCn7w8MP4yYsvznls5LZbb8Wv9+4FAOzduxe3hTBzoRAQYoM+E/B6nMTL1OSk64rhr993H+a1tlYdm9faiq/fd19dn/3j559H4cQJbLzjDmy84w787bPPVp677dZb8cyzz+KhrVsrx5597jlsvOMOPPt3f4f+u+6a89iIHi76T3/2Z7gimw0lfJSIzetXrloluTENiZptAwOWTj/b3o7HN2+OwSJixbzxcVz/1a8C8LZaOOiqIVU49tFHaJ+erjp2w9q1I1LKHrf3MllMlEG1xOyG1aux68CBqvBQS3MzNsSU0CPOeF0fcPOttzaE4w8SCgFRAj0xqztdPTELIDYx0D9XJXEicymbRsHEPxQCogROidk4HW8+l6PjV5gzx46hc8kS9g6qEyaLiRIwMUtqpaWJbqxeKKNECbLt7baJWRIPquVszOgbznOoUD8UAqIEqidmVXeKQaNSzkbfXP7am26ac4wEQ2xCIIRYr/14u5TysbjsIGqgcmJWJacYFV5yNlGL45ljx3DtTTdVREC1DefDbEMNzLahMDa2C5JYhEAI0Q1NAIQQjwkhuqWUwXdSIolC1cSsqonsMHHL2UQljkan/+G5c5XjqonAQ1u3Ys2aNRWnXywWA+s+WiwW8fgTT+DNwcHGEgLN6euOP0cRIH6wG4mGNUJNYyLbLWcThThajfz1vEA97P3wQ/zsvfdw7uJFLF64EN9ftw63rVxZ8/nCbkOdzWbx4+efx8EPPgjkfFbEmiMQQjwK4EGb57YA2AIA13R2RmkWURi7kejJ0VEMFwqhjFDTmMh2y9lEJY5Gpx/ELGDvhx/i799+G5Pa2oPRixfx92+/DQA1i0HYbaijIFYhkFI+LYR4QwgxLKUsmp7bDmA7MNtiIhYDiXLYjUQPHD8Oc7uUoEaoKiWyo4rLu+VskiqOP3vvvYoI6ExOT+Nn771X16zAiSS0oY4zR6CHiAqYHfk/HYctJFnYjTjtemYFMUJVJZEdddLaKWejkjj64dzFi76Oe6F7zRo89Jd/6fiaZ597bnabSUMb6h8+8QQ+//xz/Pgf/mHO42UB70DmRlwrMdYD0JtqZzErBoS44nfEGdQINZ/L4fHNm/HM976HxzdvjiVJrFJb7Hwuh/7e3sr9zba3o7+3V/nk+eKFC30d90LYbaijIK7Q0HYA9wgh+gFASrkrJjtIwrAaidrRJITyI1Q/qJa0DrPKK6x1At9ft64qRwAArfPm4fvr1tV13h8//zx++MQT2HjHHQCA1atX47/cfz+A2TbU/+2hh7BX21MAmBUH/fG2J5+c89jMQ1u34sTJk3ho61b84OGHA58xsA01SRzGOLkTzU1NuKevT/lRqlfS1BbbT3XQ+Lx5uOnGGz2fO+iqIVVgG2qiHG5JzXqSnsaRqJ1zBIDyzExD1fonNS6vGretXNkQjj9IKAQkcNySmkEmPd1CRcYFUHEne+tFlaQ1aTwoBCRw3BYbBbkYSX/9a/v3W1YOZdvbG6pFhKqrr4PE76IxgdmqMSFEeEYpjpQS9Vw9+7eSwHFLajo9v21gACMFf0Vk+VwO//GWW9DS3Fx1XA+b2AnPa/v3+/4sEi61JImbpETx889tS4gbHaldf1Md188ZAQkct8VGds8DtY/WncImr+7bZ/keKWXdM4NGCDmpht8VxJlyGedHR/HZuXNIoxQIzIphxkMlnR0UAhI4bklNt7h+PWEiq/c4CU89q48bKeSUZJoAzK/DCRIKAQkAq1Fxf2+vY2O4qXIZQojAVwRb2eI1oez3c17bt2/OCLTRu5KSxoRCQOrCblTc39s7p7bd/FqnmK7TimCjs1/Q2gopJSZKJbRlMihNT6M8MzPHlv7eXseEst9rfn1oyDYM0chdSUljwmQxqQs/bQ+sXmvH5NSUZSJXFxPd2V6anMREqQQAmCiVKiJgtsUtoeyH3YcOzfkcI6o3XiPEDGcEpC78tD1wGikvaG3FpcnJyuOJUsky3u5HTIyf+8jLLyPb3o6eXA5HTp/2lNy1SwS7jfiNwsJksjvGe/TlTAb3rlyJvqVL4zYrVVAISF3YJWKFEBgpFKqcnls1kVEIAOt4ez1hl+L4OIYLBU/N0axCXq/u24eTo6OOyee2TKZqK0cmk50x36M/lErYcfgwAFAMIoShIVIXG1avnhNuAS6XZhrDO1av1UMzXmcW9YZdvHbrtJt5DH30Ea760pfQ3DT3T6dJCNy5dq3jOeLqFqoqVveoVC5j8OjRmCxKJxQCUhd6O2KrVZ1mp+fUutjOwZuP2wmPTpMQWNDa6mizl1mF02uOnz2Lry1fXvU5bZkM7r3lFk+zFyaTL2N3L8YmJiK2JN0wNETqxmnRlvkP3a7W32tDNfPCMWPVkDkG79St0w2n8A8AHDl9Gv/jnntqOgeTyZexu0cdbW0xWJNeKAQkEOp1en4aqnntt1NPt84Nq1fbihvgbVTPbqHuWN2jTHMzNnV1xWhV+qAQkEAIwukF3VCtnm6d+VwO7x8/juNnz1o+70XgGq1baBgVUPlcDp9/+in+7+nTGJuYQEdbGzZ1dTFRHDEUAhIIqjo9r+JidnIrOjvx8WefWb7Wj8A1SrfQMCugVlx1Fe5asaJuG0ntUAhIYCTV6Vk5uaGPPrJ8rRAiEXvzBk2QrcOJelAISCyEuYOZX/wsUpNSptLxhVUBFdbexMQfFAISOVHuYOYFP84sDRU/ViIcZgWU37bTJHgoBCRyotzBzAtupaI6Saz4sXLqgH0ux06Ee3I5DBcKgVZAcTagDlxQRiKnnh3MwsBuxXPfjTdaLn5LCuYGfcXxcezcvx+vDw1VHTOuALcT4SOnT9suBvTLmWPHKiLA2YAacEZAIqfWHcyCCsv42T8hyVg59RkpAVMrbuNsy0mEgygGoACoCYWARE4tO5gFFZbxs39C0vEzg9JfG8VqaIqAesQmBEKILdqPy6WUj8VlRxJJemtjtzUHftck+LkfaSqD9Jr70F8LcDV0WolFCIQQ6wHskVIWhBBvCCHWSyn3xGFL0miU1sZmZ683pzOKgdeFYH7uRxIawb154AAOHD8OKSWEEOi94Qbc1dvr+zxWTr1JCAghqjbWMTr6MEWYqEtcM4Kc9m87gIL2M/FAo4xogxI0v/fDbpTs1rE0Kt48cKBqMZuUsvLYrxjYOXWrY8Z7FZYIs0pIXWIRAinldsPDbgA7za/RQkdbAOCazs6ILFOfJIxoAfeRYlCC5ud+jBQKKE1PW77+i1JpzkY6boQxGj5w/Ljl8aGPPsKR06d9f4adUw9i0ODnO2SSWG1iTRYLIboBvCOlPGh+ThOL7QCwctUq+13OU0YcrY39OjwvI8WgBM3r/TDbZGZGSl8iFFaITkr7X3XVwoBevkPjLIAioC5xryNYL6V8OmYbEoXTLl9hYFWLbt55zIyXnbm8bkTjhtf74aWNhB8RCmv3MasNfoL+jKBw+g71tQIrFy+u/CPqEpsQCCG26CKgJY+JB5x2+QqDWhyel5FiUILm9X54cfJ+RCisEF3vDTfU/NlR4/Yd0vknhzirhp4SQjwGYBGAu+OwI6lE2eWzFofnZUP7INtWe7kfbqWUfkUorBCdnhDWq4bsPlsFrL7DW665Bp3T0xSBhBFXsngPgCvj+Gzij1ocnlXZInB5Q3vgsvOOStDsbAJmBco4ywl79zM37urtxV29vZZ5DdVq+o3fIRPCySXuHAFRnFpCOH42tI8KqxBS3403oqW5uTLydsp/jBQK2DYwgEdefhnbBgYAIPQQXdRhwHq59qab4jaB1AhbTBBHag3h+NnQPirMM5BtAwOeyh/jbEuRpM1+uE4guVAIiCu1OiPVS1295j8aZRFfmDAslGwYGiKhoXqpq9cS1qQs4osLikDy4YyAhEbUG9r7Hbl7TfjGMbNJCmkUgcLICA7t3o3xYhHt2SxWb9iAXD4ft1l1QSEgoRJGjNsu/ON35O5VqNiR05q0isCBXbtQnpoCAIwXiziwaxcAJFoMKAQkUTi1dqhl5O5FqKKe2SSJNIkAABzavbsiAjrlqSkc2r2bQkBIVDiFf/yM3P32T0pS9U4UpLVCaLxY9HU8KVAISKJw20oRcB+5O80qvLyfzJK22QAAtGezlk6/PZuNwZrgoBCQROEW/vEycrebVfzi/fcxXS4ruemPKhvABJUXGDp1CoNHj2JsYgIdbW3Y1NWFvqVLK8+rmpBdvWFDVY4AAJpbWrB6w4YYraoflo+SRBFESardrGKiVAqlo2i91NIBNgyCFIEdhw9jbGICADA2MYF/PHgQ//u99wBcTsjqI289IVsYGanrc4Mgl8+jt7+/MgNoz2bR29+vhEjVA2cEJFEEkbj1s5cvEP96ARUWtAVZITR49ChKpuspNzXh7bNn8R+0mYDKCdlcPq+EHUFCISCJo97ErV1SuWXePFyanJzz+rjXC7iVxYYZNgpjYxl9JmDmi9bWSjjIiqQnZFWGQkBSh9NeviquF3DKi4S1UxoQ3jqBjrY2SzFonZzEeLEIIYRlC263TXtI7VAISM2oksCsBadZhfGaVnR2YvehQ3h1377YrtGpLDassJEuAvM/+QQDL7wQaNJ2U1cX/vHgQZSbLqcom8pl5AoF26ocwHkbT1IfFAJSE2GOROPEKBCqXKNTXiToDq/GUND8Tz4JZRVt39KlOHfiBN4+exZftLaidXISuUIBnRcuYHV/v214KO4STVUrmYKAQkBqQoUEZtiodI12M5ig+iBZ5QIGXnghtKTtt9etqySGK47VUH2jWolmo7aW0KEQkJpIQ0fOJFxjEH2Q7HIBYSdt7apv9GMqjb5Vr2SqFwoBqYk0dORMwjXWW07rlBCOcxVt3CWa5jBQo1cyUQhITaShI2dSrtFvOa3XktBGXUXrhlUYyI648xZBQSEgNZGGjpyNeI1+SkKDDNG4tZQIi1oSvFZhICsaSRQpBA1E1OWcaejIGdc1BvVdWnUJ9bMuIIgQjd5SQl9NPDYxgR2HDwMAlpw9i+G33sLkpUsAgExbG9beeWcgYaFaE7xuMwBV8hZBQiFoEFQpdUwSqq6DCOK7DGNFsF/00fieP/ojlObPr3quVC7j9X/9V/T89reYMYTeShMT2L9zJ4D6q3FqTfAacwJnr74ahVwOk62taJuawn/+2tcimclEDYWgQVCp1DEJqCycQX2XcbaJNo7GJ1tbLV9zsVyuEgEdOTPj6Ky9hntqTfDquZHTV16Jo11dmNGaHE5kMpWZTKOJQaxCIITollIejNOGRiGIUkdVR8hhoLJw1vtdqrBpjHE03jo5iUnTjEA/boeds7YK9+x79VXse/VVANWhJbeqJztB0UXl7z7+uCICOqVyGYNHj1IIgkIIsR7AUwAaI8gWM/WWOqo8Qg4DldcI1NJrx+z8g54N+E32Gh1wrlCoGlkDQKa5GSs+/dT2/XbVOG6JXGNoyanqyS1/kMvnMXHmjOVn2DXNSzKxCYGUco8Q4nxcn99o1FvqqPIIOQxUXiNg11PH7niQzeGsRslnlyyxTfbaiYFxNL5kdHT23FqsvWPBAmzq6sKSq6/G0O9/Pyc8JJqabKtxvNTt66GlzY8/DsC66mlg2zbL/MHwW29VXt92yy2YyGTmnL+jrc3VhqTBHEGD4NRRc9vAwJxwjzkMpPIIOQxUXCOgfyd2mEUq6ISw3Sj5/XXrUJqZqXqtW4jEPBpfMjqKzgsXqjdx0d7rp2rIaXGXEf01dlVPdueYvHSpYsv1x4/Pmck0lcu47sgRFLLZhqkYAhQWAiHEFgBbAOCazs6YrUkG5lJHu3DPydFRDBcKVcftUGGEHBYt8+ZV7kFbJoM7166NbfZj/q7M2IlUkCEguyqbi+UyYBGWcgqReF2D4Lc81SrcY4XbQi8vgqLPZE4sX44vMplKc7zs6CgO/Pu/V+xvBJQVAinldgDbAWDlqlWB9Z9lQrSMoY8+8vT+uEfIfvH63Vo53WkbBxwVVt+VTlS/p3aO0S7Z6xYi0Z28Hm4a+PWvUThxolKK+a3Fi/Htdet82WgWGCucQks6XgVlyehoRRCMNFKfIUBhIQgDJkTd0cNEUYpkEOLs57tVMR/i9F09vnlz1eOwqoLsRskrPv0UHy5fXrW9ZKa5GZu6ulzPqYebrEoxf3n+PPDeezWJge6ACyMjNS1Is5qxTE1OouQjEdwofYaAeKuG+gH0CCH6pZS7ovhMFR1AmPjdmzfb3j7H6YRNUOLs57tVMR/iJXldS1LYT4sFuyqbjX196FmypKYWEXq4qZDLzSnFnGluxv85dw7f9nw1c6ln5bP5veYcCTB7/c3z5lkKhDH8lPS9CuKsGtoFIBIB0FHRAYSJVULUjrjCQEGJs5/vVsWKIa/Ja78i4KfFglNcPwf/i6gKIyOVUbPdorKJlhZf5/TymbU6ZLvrB5z3R2iEvQpSFRpS0QGEie5IX9u/37YuXUoZa64kKHH2892qWDEURoO7WlosBNX+WXeOOnZ5hvmlEga2bat7JF0YGcH7v/hF1ci9FofsdP12AtMIexWkSghUdABhozsSq+vu7+2NPSQWlDj7+W5V7SoadIO7KHvomxecXXfkCLIG52i1qKypXMayQqFiT60jaauQjk5QDtlJIBphr4JUCYGqDiBsVL7uoMTZ7zUmrXNqLQniqDaWseoueuG669B16VKl4sa8qKxtagrLP/kEV509W3WuWhy322pj/R4EEce3OkecG/gERaqEAEieAwgKVa87n8vh5OgoDhw/DiklhBDoqdHWpLeMdsPvmoGoNpYZPHq0qqIImE0EF3K5qtLLJaOjyJVKlRW/Lz/yiOX5/I6k3V7fns0GEse3O0eupweF4eFEb+DTFLcBJN2MFAoYLhQqOQwpJYYLBYwUCjFb5g296kkPbxXHx/Hqvn340euvx34NuXwevf39lZFpezZbvbI3IOwWlpkTxGbnaDdi9juSdnq9/plOcXyv2J3j9JEjkdznMPE8IxBCLANwF4BdUsqTQojNUsqB8EwjaSDpJb12C8EuTU5i5/79eGt4GJcmJwPbXMZveCOKvX872tosxWBhc7PjRi6dK1bgo6GhOe/rXLHC1+fbLQ5rXbAAPd/5DnL5fKU7qRmnLqfm++yUC4h7j+V68RMa6gewB8DdQoh3ANwOgEJA6kLlkl4vIR8nO2ekxCWt1XK9ixdXLl6sbJnipq6uqhwBMLvg7NYvfQnTDu87feSIr+N2eGln4SeOb3efM21trusJkoofIdgjpfwAwAdCiG8CUH+4Ruom7Ph33CW9dtfndaGbn0V79c50VCpTNI+YN3z963j3D3/AxXIZrZOTuOnUKVw8fRpSa1ZnJVpOI+wDb76J00eO+Jr5AJfFQA/56Mf95Evs7vO8lhY0t7RUPdfU3IypyUm8/MgjiVxIpuNHCIp6OEhK+Wun3uikMYiiJUecJb1O1+c1ZOVn0Z7+GVZ2eBFbVcoUrUbMTb/6FfJSVhw/AJhXrphFy6nxmzFk5GXm42V/AcC9CZ7+XismL13CH3/3u5VztC5YgNIXX1RmCarM0GrBU7JYCLFQSnnCmBOQUv46PLOICjg5w6DI53Lo7+2tzACy7e2RrW9wuj6vISvd/jaLvvVWmGc6VsnmXQcOYO/+/Thz7FhVfiCo5Gq9WI2YZ8rlKhGww+hkV2/YgGaPK4vdErteksG5fL6q3PPQ7t0ojIzMOZfTfc7l89j8+OP43jPPYF4mM+ea/SagVcHrjOCvhRA7pZSHhBBrAEgpZXDegChJVPF7P2WfQYaqnK7PT8hKt99oW1smg9L0NMoGR2E107ETo/d+/3vcZUqaRlUO6kY9M5CMoWOpPmq2S+T6+VwvsyWvORav99npM82hItV7EXkVgmEAOSFEQUr5gRDitjCNImoQd/zeTNChKqfrqyVkZbUfRK3J5j+USnOO+QlvhInXzWGsMIeUc/n8nNYQTp/r1ybje7zmWNzus+7U3dCFZvTkyap1BiqGkLwKQQ5AEcDTWhnpOwD2hmYVCYR6R8+qteQIutTU6fqCWI3tZaZjJ0Z2vf7rLVMMYmRqNWJuam6GNOUIrNDbRRspTzvVFl1mvFjEwLZtljZ7GcX7ybHY3WendhZWlKemcPzAgTm9vlTrReRVCApSyjcB/C8AEEJE26uY+CaI0bNqrSmCDlW5XV8UK5WtxMhrr3+/BFV+6tSlUz+mNzQ0YzWq9+pUnWz2MlsKovzTrZ2FFXZ7TavUi8iTEEgp3xRCXK8tJFsDYHnIdpE6CWr0rFJrijBCVXFfn/7Zv3r/ffyhVPLV698vQZSfmmcUf/zd71o6ZLve/n7zGVaCYmez1f4CemfTTFsbprQ1HVXnN+xm5mW25OS87cJTfkQxLjyXj0opT2r/fwDgg7AMIsGg8kKtWlEtVBUUndPT2LJmjedeQrWGd+otP/Uzo/CTz2hdsMAyZATUPpo222qXg8jMn19J5nq5Nidnb3W8uaUlEb2IUtd0Li1EleiNcg9o1UJVQeJHBGoN79TbJdPvjMJrPqPnO9+xrRyqZTRdGBnB/tdesxURI7oAeb02u3YWdjbq4nf19dfHnuR3gkLQoEQxeo5jD+i4Qzn1cGpoCEcHBzExNoa2jg50bdqE5o4OX+fw44yNM4fWBQswbRHb9jMyDWtBWy6fx+jJk3P6DtUymtaF0osIAJcFxeu1mWc6TkKld1nV36eS4zdDIWhQohjBPWI2AAAPsklEQVQ9J71hnBeCmvGcGhrC4R07UNbKQifGxnB4xw5c961vYd03vuH5PF4dlnnmYBV6MTZl80LQfffNIa4b+/os20r4GU37SeYaBcXPtRmdelCttOOGQtDAhD16bsQ8hJEgZzxHBwcrIqBTLpVwdmgIH958s+fQkFeH5cUhzstkfI1Sg+oWCliHuArDw1Xtm43JXqvEtBVODlg0NSEzfz4mL12aIyi1LtZrhE1pAAoBqQPVFpy54Xd0H+SMZ2JszPW4ebtHq+oho8M6e/XVlR2/FjY349pTpyqv9zIi9TtqDapbKOAe4qo1F+KUzL3l3nsd92rW7fITx1dltXe9UAhIzXjJQ0SZTHailtF9kDOeto4OSzFo03IEVts97jh8GACqxEB3TP80NISj111X2QP44sxM1eudKnF0/I5aa8kR2FU4uZ2r1lJXO8fsZaOYWuL4qqz2rhcKAakZtzxEHMlkO2oZ3Qc54+natKkqRwAAzZkMlvT1AbDe7rFULmPw6NE5s4JcPo/fF4uYMZVE6q9fcvYsSl984WhPc0sLOlesqAq9uDkwv2EQp1G927lqTUzr9g+/9VZFCJvnhevmVE8Ee4FCQOrCKQ+hUjK5ltF9UJVXZ44dQ3NHB6771rdwdmgIE2NjyCxciM4//VN0aPkBu+0eazl+aGjIsdVDezaLzhUr5vS/2b9zZ8WBWgmDXemkXesHp1G9W0il3ti7sUKqNDGhXG8f1aAQkNBQKZlcy+g+iMorvY30ysWL8eHNN1ccvxm77R7teg45vd5p1Py9Z54BAAxs2za3Fn5mpjKKtorJm8MgRvxuPOMWUrETnanJSRRGRhwdukob+CSF2IRACNGP2UZ23VLKp+Oyg4SHSsnkWkf3djMeP7kP3fE7VQbZbfdo13PI6fVnhoZcR9NeEsV+naf59XZ5itYFCwA4h1SsQjyAt9G9Khv4JAlPG9MEjRCiGwCklHswu/NZdxx2kHDZsHo1WrRkpk7YLSFGCgVsGxjAIy+/jG0DAxgpFAAEuwGO3WYy+meZ+fDcOddz9i1dij9ftaoyA+hoa8Ofr1pl23PI6fVWG76YK1m8hlis+vl73RfAblGX18VeuXwe8yw2/HHb/MVt1TGZS1wzgnsx28oaAAoA1gM4GJMtJCSibgnhlpwOal2Fn9zHtTfdVLXLmBN9S5f6ajZn93ovlSx2oRczbv38nV5v19/Hy94DOrWM7ldv2GDbssJYnpr0Sp8giUsIsgDOGx7PWWcvhNgCYAsAXNPZGZFZJGiibAkRVXLaKffh1emHjVsli/6c06YwXvv5270+iMVWtZwjl8/bCsF4sRhYO+5GIpbQkBeklNullD1Syp4rFy2K2xySAKJKTtvlOL6cyWDl4sWW/1Qkl8+jpbXV8jkhxJzae7cdwsyv9xKicsPpHPrK45cfeQQD27ZVhX2c9h32sr9x2ohrRlAEoHv3LADrZZeE+CCq5LTdZjL3rlwZ6OdEgd0oX0rpeRcwu8VaQSy2ctoEx2lU71Se6jRbiArVQlNxCcFOAD3azzkAe2KygzQQUe1XYM59fDmTwb0rV4aymUzY+G22Bvhz7EEstrI6x+s/+pFjiaje0VTfJlIIgVxPD3L5/JxKJJ2o+gOpGJqKRQiklAeFED1CiPUAilJKJopJ3USZnM7ncujU9tpVNfTjBb+9clRYRVsYGbFtn6GLWmFkBIXh4UqFkpQSheFhALBcdd3U3BxZfyAV1znEto5ASrk9rs8mjUvYyel/GxzE6X/5F5QuXkRm4UKs3bgRSLAQBN0rJ4qQh1MsXwhRscHK2VptJA/478TqhNs9UHGdA1cWE+KRU0ND+Pif/xlSmwmULl6MfUofBEGN8qMKeTg5TCmlY1ms3RoGPyWtTni5Byq2rla2aogQ1fjw9dcrIqCT9moTI1FV47g5zPLUFIQQls/ZHQ/KCXu5B0FUUwUNZwSEeKR08aLlcbYumMXP7mn1hI+8LIaTUqK5pWVO7iPsjeS93AMVW1dTCAjxwJljx5BZuNBSDJK2G1VYeAl5BBE+cmp+Z/zM1Rs2WDrbMDeS9xr2USHpboRCQIhH1m7cWPNuVKrVjYeBlwqkoCpmdEdqFhbjZ9o52zCdcFJ3LKMQEOKC3jai1im9inXjYeDl/gRdMaNamEU1e7xCISDEA/pagVpGkyrWjYeF2/0Jo2JGtTCLavZ4gUJAiANBNJFzGwUnOWzk1/akhk4aHQoBIS7Uu3LYaRSc5LBRLbbXEjpJslAmBQoBITYE1VLaaRSc5LBRrbb7CZ0kWSiTBBeUEeJAEH2Ecvk8evv7K3FwY8tmFdsNeCUK29kyOho4IyAkAuxGwSq2G/BKFLYnWSi9okLoizMCQiw4c+xYJF1FVWw34BUr2wHgi/Fx7HziCcsNY/zitMFMI2DeB1oPfUW9tzKFgJAYcQobqY5ue+uCBVXHy1NTlSZu9Tq2JAulF1QJfTE0REjMJKXu3C6EcWj3btv9AYD6kt9JXaDlFVVCXxQCQogrTtU7XpxWPY4tKUJZC6rkiBgaIsREUGWjjYRTCMOL02qUmH7QqBL6ohAQYkGSt58MA6cQhl3SWKeRYvpBo0qOiKEhQgxwNmCNUwjDHMdvXbAAUkqUJiYaLqYfBiqEvigEhJjgbGAubj2CVHBmpHYoBIRocDZgT6NX76QdCgEhuCwCQcwGVFgpGgYc9TcuFAKSKE4NDeHo4CAmxsbQ1tGBrk2bsLSvr65zBi0CbJJGkgarhkhiODU0hMM7dmBibAwAMDE2hsM7duDU0FDd5w4qL6DKSlFC/BDrjEAI0S2lPBinDSQ5HB0cRLlUqjpWLpVwdHDQcVYQxizCDlVWigZBo4a4yFxiEwIhxHoATwHgbxbxhD4T8HocuDyL0AVEn0UACEUMol4pGpazZogrXcQWGpJS7gFwPq7PJ8mjraPD13HAeRYBBF8pFOVK0TA7VzLElS6YLCaJoWvTpqrRPQA0ZzLo2rTJ9j1eZhFBrhsIsszSbbQf5u5mjRTiIu4oKwRCiC0AtgDANZ2dMVtDVEAP5fiJ97d1dFiKgdMsol6CKLP0EpoJ01mr0gyNRENoQqA5cjMFLSTkipRyO4DtALBy1SoZpG0kuSzt6/MV23eaRai8gMzLaD9MZ+22kpg0FqEJgebICYkVp1lEVLuQ1YKX0X6YzporidNFnFVD/QB6hBD9UspdcdlBGh+rWYTKIgB4G+2H7ay5kjg9xCYEmvOnAJDIUTkkpON1tE9nTYJA2WQxIWEQZDuJMGFohkQJhYCkDtVFQIejfRIV7DVEUkMSQkKExAFnBCQVOIWE2FOHpB0KAUkNdiLAnjok7TA0RBoep5AQe+oQQiEgDY5blRB76hBCISANjJdSUbt2DOypQ9IEhYA0JF7XC0TZNpoQVWGymDQcfhaNceEWIRQC0mDUsnKYC7dI2mFoiDQcSVk5TIgqUAhIw8CVw4TUBoWANBScDRDiHwoBaQg4GyCkdigEJPEkpbU0IapCISANAUWAkNqhEBBCSMqhEBBCSMrhgjKSaFTfhJ4EC/eOCAcKAUksrBRKF9w7IjwYGiKJhJVC6YN7R4QHhYAkFopAuuDeEeFBISCJgyGhdMK9I8KDQkASBUNC6YV7R4QHk8UkcVAE0gn3jgiP2IRACLFF+3G5lPKxuOwgyYEhIcK9I8IhltCQEGI9gD1Syu0ActpjQlzhbICQ4IkrR5ADoDv/gva4CiHEFiHEsBBi+ML585EaR9SDswFCwiMWIZBSbtdmAwDQDWDY5jU9UsqeKxctitZAohRMEBMSLrEmi4UQ3QDekVIejNMOoi5sIUFI+IQmBIZksJGClHKP4fF6KeXTYdlA1ObU0BCODg5iYmwMbR0d6Nq0CUv7+irPMxxESDSEJgSG0I8lQogtuggIIdabBII0OKeGhnB4xw6USyUAwMTYGA7v2AEAWNrXx5kAIRESZ9XQU0KI3wkhLsRhA4mXo4ODFRHQKZdK+PD11ykChERMLDkCbfR/ZRyfTdRgYmzM8njp4kWKACERwxYTJBbaOjosj7NvDCHRQyEgsdC1aROaM5mqY+wbQ0g8sNcQiQW9OkivGsosXIi1GzeyfQAhMUAhILGxtK8PzVqIiHkBQuKDoSESG1wxTIgaUAhIrFAECIkfCgGJBa4VIEQdKAQkctg6ghC1oBCQSGFegBD1oBCQyKEIEKIWFAISGcwLEKImFAISCcwLEKIuFAISOswLEKI2FAISCRQBQtSFQkBChXkBQtSHQkAIISlHSCnjtsEVIcQ5AB+H/DFXAfgs5M8IiqTYSjuDJym20s7gqcXWr0opXafkiRCCKBBCDEspe+K2wwtJsZV2Bk9SbKWdwROmrQwNEUJIyqEQEEJIyqEQXGZ73Ab4ICm20s7gSYqttDN4QrOVOQJCCEk5nBEQQkjKoRCQyBBCdMdtQ5Lh/Us3QohHwzo3N6+3QAixXvvxdinlY7Ea44AQYov243KV7QQq9/QpAPm4bTEihOgHUATQLaV8Om577FD1/plJ4O8koPjfOVCxdW1Y5+eMwIQ26rpdSrkHQLeqozDtF2OPlHI7gJzhl1pJtPt5Pm47jOjfrWZbUdXvGlDz/plJ0u9kUv7Oo4JCYEJKedAwOshJKQ/GapA9OQD6H1pBe0z8cS9mZwPA7D1U1nElhMT8Tibo7xxCiG5NsEKDoSEbtHjcg3HbYYc26tLpBrAzLlsSTBbVo+yOuAxpBJL4O6n637nGorA/gEJgg5TyaSHEG9qy7qL7O+JBm9K+E/eIxhAbNlIIeyRD1EOV30kvqP53HsVsAEipEDg5LUPc+CBmp7dbAMSSRPToXNerkOQ0jQaTQhGXR1tZAGMx2tJIKPE76YRKf+cu5IQQOcPP3WEIbCqFwMVprQeg3+gsgPfDt8gaN+cqhNii/8EJIdarPPrWqnN6hBD9UspdcdujsROA3sQrB4D3r04S9DupzN+5E/p3rQ0Ks2F9DlcWmxBCZAHcg9nY8e1SSiXjh1pFxhuYtXMRgLsV/qNTFu0PrIDZhGESZzXKkKTfyaT8nUcFhYAQQlIOy0cJISTlUAgIISTlUAgIISTlUAgIISTlUAgIISTlUAgIISTlUAgIISTlpHJlMSG1oq3wzWF2EdpaAP9TxR41hPiBMwJCPCKEyGlL/nXHv1MXASFEt8r99wlxgkJAiEeklAXtxzxmN2AxNv+6FyH2giEkTCgEhHjEsItVTkpp3tFM+d77hNjBHAEh3lmvtQR+RwsDKb11JCFeYdM5QgJA62K6HEwekwRCISCEkJTDHAEhhKQcCgEhhKQcCgEhhKQcCgEhhKQcCgEhhKQcCgEhhKQcCgEhhKSc/w839kqwF1J9YQAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for k in [1, 15, 30]:\n", " kTest(sample, sample, labels, k)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 1.9" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we want to examine the *k*-nearest neighbour algorithm more closely. We are especially interested in the relation of _k_ to the accuracy of the model." ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Working on 10\n", "Working on 20\n", "Working on 30\n", "Working on 40\n", "Working on 50\n", "Working on 60\n", "Working on 70\n", "Working on 80\n", "Working on 90\n", "Working on 100\n", "Working on 110\n", "Working on 120\n", "Working on 130\n", "Working on 140\n", "Working on 150\n", "Working on 160\n", "Working on 170\n", "Working on 180\n", "Working on 190\n", "Working on 200\n" ] } ], "source": [ "accuracies = np.zeros(len(sample))\n", "for i in range(1, len(sample) + 1):\n", " preds = np.array([1 if x > 0.5 else 0 for x in nearNeigh(sample, sample, labels, i)])\n", " accuracies[i - 1] = accuracy(labels, preds)\n", " \n", "test_accuracies = np.zeros(len(sample))\n", "for i in range(1, len(sample) + 1):\n", " if i % 10 == 0:\n", " print(\"Working on\", i)\n", " preds = np.array([1 if x > 0.5 else 0 for x in nearNeigh(test_sample, sample, labels, i)])\n", " test_accuracies[i - 1] = accuracy(test_labels, preds)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we have calculated the accuracy for the value _k_ from 1 up to 200, let us plot the accuracy vs. the value of *k*." ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "small, = plot.plot([i for i in range(1, len(sample) + 1)], accuracies, color = 'blue')\n", "large, = plot.plot([i for i in range(1, len(sample) + 1)], test_accuracies, color = 'orange')\n", "plot.legend([small, large], [\"Small\", \"Large\"])\n", "plot.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see in the plot, the accuracy of the model is almost stable as long as *k* is smaller than about 170. The outlier of the blue graph in the beginning is due to the fact, that each vector has itself as its closest neighbour, hence in this case the training and test set are the same.\n", "\n", "After about 170, the accuracy decreases rapidly until it reaches 50%. This is caused by each vector being compared to all training samples. Since there are equally many in both classes, every vector gets a score of 0.5. Thus, all vectors with a label of 0 are scored correctly and all vectors with label 1 are scored incorrectly. As each of the sets is 50% labelled 0 and 50% labelled 1, we get an accuracy of 50%." ] } ], "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.6.3" } }, "nbformat": 4, "nbformat_minor": 2 }