{ "cells": [ { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from matplotlib import style\n", "style.use('ggplot')" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD8CAYAAABn919SAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4wLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvFvnyVgAAE7hJREFUeJzt3X1sVXfhx/HPub23PC19vCOmLYRWShScjOKk0D0YuNNkbtH4R+PITMg0y6iEzJmNikQWh/OKXiFISf1r+2sx/kWyZcblglkT6BRpDQ1sdCP9IVhNLYXy1PY+nO/vj26dpTz0PvWcfvt+/Uf7Pf1+6CGf++Xcc+7XMcYYAQBmvYDXAQAA+UGhA4AlKHQAsASFDgCWoNABwBIUOgBYgkIHAEtQ6ABgCQodACxBoQOAJYIzPWF/f3/Wx4bDYQ0ODuYxTX74MZcfM0nkyhS5MmNrrqqqqmmNY4UOAJag0AHAEhQ6AFiCQgcAS8z4m6IAMBcYNy1zslOm84iGjFHaceRsiMhpWC8nUJi1NIUOAHlmrl6Re3CPdLFPSiaV/PTrH56SebdWgW275JSU5X1eLrkAQB4Z1x0v875eKZmc/M1kUurrlXtwj4zr5n1uCh0A8sh0dY6vzO/mYp9M9/t5n5tCB4A8MsfjU1fmt0omZY7F8z43hQ4A+ZRITHPcWN6nptABIJ+Ki6c5bl7ep6bQASCPnA0RKRS6+6BQSE5TJO9zU+gAkEdOw3qppvbug2pq5axpzPvcFDoA5JETCCiwbZdUu2LqSj0UkmpXjN+HXoCHi3iwCADyzCkpU6B1r0x3p8yxIwoZV0knIKcpImdNI0+KAsBs4gQCctY2SWubVDFDn9POJRcAsASFDgCWoNABwBIUOgBYgkIHAEtQ6ABgCQodACxBoQOAJe75YNGhQ4fU1dWl0tJSxWIxSdL169e1b98+/fe//9X999+vH/3oR7rvvvsKHhYAcGf3XKF/7Wtf086dOyd97fDhw3rggQd04MABPfDAAzp8+HDBAgIApueehb5y5copq+8TJ07osccekyQ99thjOnHiRGHSAQCmLatr6MPDwyovL5cklZWVaXh4OK+hAACZy/nDuRzHkeM4d/x+PB5XPD6+d140GlU4HM56rmAwmNPxheLHXH7MJJErU+TKzFzPlVWhl5aW6vLlyyovL9fly5dVUlJyx7GRSESRyGc7c+TyiWPhGfrEskz5MZcfM0nkyhS5MmNrrqqqqmmNy+qSy1e+8hW99957kqT33ntPDz30UDY/BgCQR/dcoe/fv19nzpzRtWvX9Pzzz6u5uVnf/va3tW/fPh09enTitkUAgLfuWegvvPDCbb/+s5/9LO9hAADZ40lRALAEhQ4AlqDQAcASFDoAWIJCBwBLUOgAYAkKHQAsQaEDgCUodACwBIUOAJag0AHAEhQ6AFiCQgcAS1DoAGAJCh0ALEGhA4AlKHQAsASFDgCWoNABwBIUOgBYgkIHAEtQ6ABgCQodACxBoQOAJSh0ALAEhQ4AlqDQAcASFDoAWIJCBwBLBL0OAHjFuGmZk50ynUc0ZIzSjiNnQ0ROw3o5AdY6swXn8TM5Ffrbb7+to0ePynEcLVmyRC0tLSouLs5XNqBgzNUrcg/ukS72Scmkkp9+/cNTMu/WKrBtl5ySMk8z4t44j5Nl/fI1NDSkP/3pT4pGo4rFYnJdV8ePH89nNqAgjOuOl0Bfr5RMTv5mMin19co9uEfGdb0JiGnhPE6V0/9HXNdVIpFQOp1WIpFQeXl5vnIBBWO6OsdXdHdzsU+m+/2ZCYSscB6nyrrQKyoq9NRTT2nr1q167rnntHDhQq1evTqf2YCCMMfjU1d0t0omZY7FZyYQssJ5nCrra+jXr1/XiRMn1NbWpoULF+q3v/2tOjo69Oijj04aF4/HFY+P/0Kj0ajC4XD2YYPBnI4vFD/m8mMmyR+5hozRPWpAkhQyrio8zuqH39ft+CEX5/E282R7YE9PjxYvXqySkhJJ0rp169Tb2zul0CORiCKRyMSfBwcHs51S4XA4p+MLxY+5/JhJ8keutONMa1zSCXie1Q+/r9vxQ665dB6rqqqmNS7rSy7hcFgfffSRxsbGZIxRT0+Pqqurs/1xwIxxNkSkUOjug0IhOU2Ru4+BpziPU2W9Qq+vr1djY6N27NihoqIiLVu2bNJKHPArp2G9zLu143dH3ElNrZw1jTMXChnjPE6V033ozc3Nam5uzlcWYEY4gYAC23ZNun95Qigk1Xxy//IceyhltuE8TsWTopiTnJIyBVr3ynR3yhw7opBxlXQCcpoictY0zqkSmM04j5NR6JiznEBAztomaW2TKnzwJh+yw3n8zNx6+QIAi1HoAGAJCh0ALEGhA4AlKHQAsASFDgCWoNABwBIUOgBYgkIHAEtQ6ABgCQodACxBoQOAJSh0ALAEhQ4AlqDQAcASFDoAWIJCBwBLUOgAYAkKHQAsQaEDgCUodACwBIUOAJag0AHAEhQ6AFiCQgcAS1DoAGAJCh0ALBHM5eAbN26ovb1dFy5ckOM42rp1q1asWJGvbACADORU6K+//roefPBB/fjHP1YqldLY2Fi+cgEAMpT1JZebN2/qgw8+0MaNGyVJwWBQixYtylswAEBmsl6hDwwMqKSkRIcOHdL58+dVV1enLVu2aP78+fnMBwCYJscYY7I58Ny5c/rpT3+qV199VfX19Xr99de1YMECffe73500Lh6PKx6PS5Ki0agSiUTWYYPBoFKpVNbHF4ofc/kxk0SuTJErM7bmKi4unt482U5QWVmpyspK1dfXS5IaGxt1+PDhKeMikYgikcjEnwcHB7OdUuFwOKfjC8WPufyYSSJXpsiVGVtzVVVVTWtc1tfQy8rKVFlZqf7+fklST0+Pampqsv1xAIAc5XSXy7PPPqsDBw4olUpp8eLFamlpyVcuAECGcir0ZcuWKRqN5isLACAHPCkKAJag0AHAEhQ6AFiCQgcAS1DoAGAJCh0ALEGhA4AlKHQAsASFDgCWoNABwBIUOgBYgkIHAEtQ6ABgCQodACxBoQOAJSh0ALAEhQ4AlqDQAcASFDoAWIJCBwBLUOgAYAkKHQAsQaEDgCUodACwBIUOAJag0AHAEhQ6AFiCQgcAS1DoAGAJCh0ALJFzobuuq5dfflnRaDQfeQAAWcq50N955x1VV1fnIwsAIAc5FfqlS5fU1dWlTZs25SsPACBLORX6G2+8oWeeeUaO4+QrDwAgS8FsDzx58qRKS0tVV1en06dP33FcPB5XPB6XJEWjUYXD4WynVDAYzOn4QvFjLj9mksiVKXJlZq7ncowxJpsD33zzTXV0dKioqEiJREIjIyP66le/qu3bt9/1uP7+/qyCSlI4HNbg4GDWxxeKH3P5MZNErkyRKzO25qqqqprWuKxX6Js3b9bmzZslSadPn9Zbb711zzIHABQO96EDgCWyXqH/r1WrVmnVqlX5+FEAgCyxQgcAS1DoAGAJCh0ALEGhA4AlKHQAsASFDgCWoNABwBIUOgBYgkIHAEvk5UnRQjJuWuZkp0znEQ0Zo7TjyNkQkdOwXk6A1yMA+JSvC91cvSL34B7pYp+UTCr56dc/PCXzbq0C23bJKSnzNCMA+IVvl7jGdcfLvK9XSiYnfzOZlPp65R7cI+O63gQEAJ/xb6F3dY6vzO/mYp9M9/szEwgAfM6/hX48PnVlfqtkUuZYfGYCAYDP+bbQlUhMc9xYYXMAwCzh30IvLp7muHmFzQEAs4RvC93ZEJFCobsPCoXkNEVmJhAA+Jx/C71hvVRTe/dBNbVy1jTOTCAA8Dn/FnogoMC2XVLtiqkr9VBIql0xfh86DxcBgCSfP1jklJQp0LpXprtT5tgRhYyrpBOQ0xSRs6aRMgeA/+HrQpfGV+rO2iZpbZMqwmENDg56HQkAfIklLgBYgkIHAEtQ6ABgCQodACxBoQOAJSh0ALAEhQ4AlqDQAcASFDoAWCLrJ0UHBwfV1tamK1euyHEcRSIRPfHEE/nMBgDIQNaFXlRUpO9973uqq6vTyMiIWltb9eUvf1k1NTX5zAcAmKasC728vFzl5eWSpAULFqi6ulpDQ0NzptCNm5Y52SnTeURDxijtOHI2ROQ0rOdDwwB4wjHGmFx/yMDAgHbv3q1YLKaFCxdO+l48Hlc8Pr7vZzQaVWK6W8vdRjAYVCqVyilrPrhXhnT5tZeV+r+PpeT//H1CxQouW67ynXsVKKvwLqD887u6FbkyQ67M2JqreJo7uOVc6KOjo9q9e7e+853vaN26dfcc39/fn/VcYR982qJxXbnRl6W+3jsPql2hQOteT1fqfvhd3Q65MkOuzNiaq6qqalrjcmqcVCqlWCymRx55ZFplbgPT1Sld7Lv7oIt9Mt3vz0wgAPhE1oVujFF7e7uqq6v15JNP5jOTr5njcSmZvPugZFLmWHxmAgHAJ7J+U/Ts2bPq6OjQ0qVL9dJLL0mSnn76aTU0NOQtnC9N9z2AxFhhcwDALbIu9C984Qv64x//mM8ss8M035xQ8bzC5gCAW3B/XYacDZGpm1bfKhSS0xSZmUAA8AkKPUNOw3qppvbug2pq5axpnJlAAPAJCj1DTiCgwLZdUu2KqSv1UGj8lsVtu3i4CMCMy/oa+lzmlJQp0LpXprtT5tgRhYyrpBOQ0xSRs6aRMgfgCQo9S04gIGdtk7S2SRU+fZgBwNzCUhIALEGhA4AlKHQAsASFDgCWoNABwBIUOgBYgkIHAEv4/j50tnoDgOnxdaGbq1fkHtwzvqFEMqlPP4XcfHhK5t3a8UfsS8o8zQgAfuHbJa5x3fEy7+uduqFEMin19co9uEfGdb0JCAA+499CZ6s3AMiIfwudrd4AICO+LXS2egOAzPi30NnqDQAy4ttCZ6s3AMiMfwudrd4AICP+LXS2egOAjPj6wSK2egOA6fN1oUts9QYA08USFwAsQaEDgCUodACwBIUOAJZwjDHG6xAAgNzNqhV6a2ur1xFuy4+5/JhJIlemyJWZuZ5rVhU6AODOKHQAsETRK6+88orXITJRV1fndYTb8mMuP2aSyJUpcmVmLufiTVEAsASXXADAEr7/LBdJOnTokLq6ulRaWqpYLOZ1HEnS4OCg2tradOXKFTmOo0gkoieeeMLrWEokEtq9e7dSqZTS6bQaGxvV3NzsdawJruuqtbVVFRUVvrkj4Yc//KHmz5+vQCCgoqIiRaNRryNJkm7cuKH29nZduHBBjuNo69atWrFihaeZ+vv7tW/fvok/DwwMqLm5Wd/85jc9TCW9/fbbOnr0qBzH0ZIlS9TS0qLi6W6SU0DvvPOOjhw5ImOMNm3aVPjfk5kFTp8+bc6dO2defPFFr6NMGBoaMufOnTPGGHPz5k2zfft2c+HCBY9TGeO6rhkZGTHGGJNMJs1PfvITc/bsWY9Tfeatt94y+/fvN7/85S+9jjKhpaXFDA8Pex1jit/97ncmHo8bY8bP5fXr1z1ONFk6nTY/+MEPzMDAgKc5Ll26ZFpaWszY2JgxxphYLGb+8pe/eJrJGGPOnz9vXnzxRTM6OmpSqZT5+c9/bv79738XdM5Zccll5cqVuu+++7yOMUl5efnEmxwLFixQdXW1hoaGPE4lOY6j+fPnS5LS6bTS6bQcx/E41bhLly6pq6tLmzZt8jqK7928eVMffPCBNm7cKEkKBoNatGiRx6km6+np0ec+9zndf//9XkeR67pKJBJKp9NKJBIqLy/3OpL+9a9/afny5Zo3b56Kior0xS9+UX/9618LOuesuOTidwMDA+rr69Py5cu9jiJp/B/3jh079J///Eff+MY3VF9f73UkSdIbb7yhZ555RiMjI15HmeIXv/iFJOnxxx9XJOL9toYDAwMqKSnRoUOHdP78edXV1WnLli0TL9Z+cOzYMTU1NXkdQxUVFXrqqae0detWFRcXa/Xq1Vq9erXXsbRkyRL94Q9/0LVr11RcXKzu7m59/vOfL+ics2KF7mejo6OKxWLasmWLFi5c6HUcSVIgENCvf/1rtbe369y5c/rnP//pdSSdPHlSpaWlvryl7NVXX9WvfvUr7dy5U3/+85915swZryMpnU6rr69PX//617V3717NmzdPhw8f9jrWhFQqpZMnT6qx0fstIK9fv64TJ06ora1Nv//97zU6OqqOjg6vY6mmpkbf+ta3tGfPHr322mtatmyZAgXelIcVeg5SqZRisZgeeeQRrVu3zus4UyxatEirVq3SP/7xDy1dutTTLGfPntXf//53dXd3K5FIaGRkRAcOHND27ds9zSWNr/AkqbS0VA899JA+/vhjrVy50tNMlZWVqqysnPjfVWNjo68Kvbu7W7W1tSorK/M6inp6erR48WKVlJRIktatW6fe3l49+uijHieTNm7cOHHZ7M0331RlZWVB52OFniVjjNrb21VdXa0nn3zS6zgTrl69qhs3bkgav+Pl1KlTqq6u9jiVtHnzZrW3t6utrU0vvPCCvvSlL/mizEdHRycuAY2OjurUqVOev/hJUllZmSorK9Xf3y9pvLRqamo8TvUZv1xukaRwOKyPPvpIY2NjMsaop6fHF//mJWl4eFjS+F1xf/vb3/Twww8XdL5ZsULfv3+/zpw5o2vXrun5559Xc3PzxKueV86ePauOjg4tXbpUL730kiTp6aefVkNDg6e5Ll++rLa2NrmuK2OM1q9fr7Vr13qayc+Gh4f1m9/8RtL4ZY6HH35YDz74oMepxj377LM6cOCAUqmUFi9erJaWFq8jSfrshe+5557zOookqb6+Xo2NjdqxY4eKioq0bNkyX7wPIkmxWEzXrl1TMBjU97///YK/sc2TogBgCS65AIAlKHQAsASFDgCWoNABwBIUOgBYgkIHAEtQ6ABgCQodACzx/4eWwY6qjvlMAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# input features\n", "X = np.array([\n", " [1, 3],\n", " [2, 1.8],\n", " [5, 8],\n", " [8, 8],\n", " [1., 0.8],\n", " [9, 11]\n", " ])\n", "plt.scatter(X[:,0], X[:,1], s=100)\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [], "source": [ "# colors for our groups \n", "colors = 5*['r', 'b', 'g', 'm', 'y', 'c']" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "class K_Means:\n", " def __init__(self, k=2, tol=0.01, max_iter=300):\n", " self.k = k # num groups to cluster\n", " self.tol = tol # tolerance: how much centroid can move before converging\n", " self.max_iter = max_iter # if tolerance is not reached (did not converge)\n", " def fit(self, data):\n", " self.centroids = {}\n", " # first k centroids are chosen arbitraraly\n", " # in this case the first k features are the initial centroids\n", " for i in range(self.k):\n", " self.centroids[i] = data[i]\n", "\n", " for i in range(self.max_iter):\n", " # contains (centroid, fetures) pairs\n", " self.classifications = {}\n", "\n", " for i in range(self.k):\n", " self.classifications[i] = []\n", "\n", " for featureset in data:\n", " # list of distances from each centroid from the feature\n", " distances = [np.linalg.norm(featureset - self.centroids[centroid]) for centroid in self.centroids]\n", " classification = distances.index(min(distances))\n", " self.classifications[classification].append(featureset)\n", " prev_centroids = dict(self.centroids)\n", "\n", " for classification in self.classifications:\n", " # centroid changes to mean of features\n", " self.centroids[classification] = np.average(self.classifications[classification], axis=0)\n", " # see if converged\n", " converged = True\n", " for c in self.centroids:\n", " origanal_centroid = prev_centroids[c]\n", " current_centroid = self.centroids[c]\n", " if np.sum((current_centroid-origanal_centroid) / origanal_centroid*100.0) > self.tol:\n", " print('centroid moved: ', np.sum((current_centroid-origanal_centroid) / origanal_centroid*100.0))\n", " converged = False\n", " def predict(self, data):\n", " distances = [np.linalg.norm(data - self.centroids[centroid]) for centroid in self.centroids]\n", " classification = distances.index(min(distances))\n", " return classification" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "centroid moved: 625.0\n", "centroid moved: 47.53623188405797\n", "centroid moved: 32.478632478632456\n" ] } ], "source": [ "clf = K_Means(k=2)\n", "clf.fit(X)" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for centroid in clf.centroids:\n", " plt.scatter(clf.centroids[centroid][0], clf.centroids[centroid][1],\n", " marker = 'o', c='k',s=60)\n", "for classification in clf.classifications:\n", " color = colors[classification]\n", " for featureset in clf.classifications[classification]:\n", " plt.scatter(featureset[0], featureset[1], marker='x', c=color, s=70,linewidth=3)\n", "# plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 2 }