{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# k-Nearest Neighbors algorithm\n", "\n", "For further reading this tutorial is recomended\n", "\n", "http://machinelearningmastery.com/tutorial-to-implement-k-nearest-neighbors-in-python-from-scratch/'\n", "\n", "First we will generate random numbers with very simple differences, and use them to understand KNN. The data will overlap, but we hope to find a clear tendency.\n", "\n", "\n", "\n", "We will model Huey, Dewey and Louie - who share a room for at any point in time does have an afinity to stay close to their own bed.\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import numpy\n", "import matplotlib.pyplot as plt\n", "\n", "data = numpy.zeros((500,3))\n", "data[:,0] = numpy.random.choice([-0.5, 0.0, 0.5],size=500)\n", "data[:, 1:] = numpy.random.normal(0.5, 0.15, (500,2))\n", "\n", "#Structure data in label and positions\n", "labels = data[:, 0]\n", "position = data[:, 1:]\n", "\n", "#Introduce bias to data\n", "position[:, 0] += labels\n", "\n", "#Views for nicer viewing\n", "huey = position[labels == -0.5]\n", "dewey = position[labels == 0.0]\n", "louie = position[labels == 0.5]\n", "\n", "plt.plot(huey[:, 0], huey[:, 1] , 'bo')\n", "plt.plot(dewey[:,0], dewey[:, 1] , 'ro')\n", "plt.plot(louie[:,0], louie[:, 1] , 'go')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can easily make a function that finds the euclidean distance between a new point and all points in the room." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def all_dist(observation, data):\n", " return numpy.sqrt((data[:, 0] - observation[0])**2 + (data[:, 1] - observation[1])**2)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[-0.5, -0.5, -0.5, -0.5, -0.5]\n" ] } ], "source": [ "distances = all_dist((0,0), position)\n", "votes = []\n", "for _ in range(5):\n", " winner = numpy.argmin(distances)\n", " votes.append(labels[winner])\n", " distances[winner] = 1000 #Just set so high that it cannot win again\n", "print(votes)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I guess Huey\n" ] } ], "source": [ "import collections\n", "winner = collections.Counter(votes).most_common(1)[0][0] #Counter returns a list of tuples\n", "if winner == -0.5:\n", " print('I guess Huey')\n", "elif winner == 0.0:\n", " print('I guess Dewey')\n", "elif winner == 0.5:\n", " print('I guess Louie')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lets produce a set of random Dewey positions and see how well we fare." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('Got it wrong in', 8, 'cases of 100')\n" ] } ], "source": [ "wrong = 0\n", "for _ in range(100):\n", " distances = all_dist(numpy.random.normal(0.5, 0.15, 2), position)\n", " votes = []\n", " for _ in range(5):\n", " winner = numpy.argmin(distances)\n", " votes.append(labels[winner])\n", " distances[winner] = 1000 #Just set so high that it cannot win again\n", " winner = collections.Counter(votes).most_common(1)[0][0] #Counter returns a list of tuples\n", " if winner != 0.0:\n", " wrong += 1\n", "print('Got it wrong in',wrong,'cases of 100')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So obviously, while we should get most correct classifications, the afinity of our ducklings is not sufficient to get it right every time." ] } ], "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.15" } }, "nbformat": 4, "nbformat_minor": 2 }