Skip to content

Instantly share code, notes, and snippets.

@amueller
Created December 24, 2013 14:33
Show Gist options
  • Save amueller/8114153 to your computer and use it in GitHub Desktop.
Save amueller/8114153 to your computer and use it in GitHub Desktop.
Benchmarking differente minibatch reassignment stategies.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "Untitled0"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"import numpy as np\n",
"import scipy.stats\n",
"\n",
"\n",
"class ChineseRestaurantProcess(object):\n",
" def __init__(self, alpha):\n",
" self.alpha = alpha\n",
" self.customers = []\n",
" def sample(self, n_samples=1):\n",
" samples = []\n",
" for i in xrange(n_samples):\n",
" probs = np.hstack([self.customers, self.alpha])\n",
" probs /= probs.sum()\n",
" table = np.where(np.random.multinomial(1, probs))[0][0]\n",
" if table < len(self.customers):\n",
" self.customers[table] += 1\n",
" else:\n",
" self.customers.append(1)\n",
" samples.append(table)\n",
" if len(samples) == 1:\n",
" return samples[0]\n",
" return samples\n",
"\n",
"class WishartSampler(object):\n",
" # Odell and Feiveson, 1966: A numerical procedure to generate a sample covariance matrix\n",
" def __init__(self, degrees_freedom, n_features):\n",
" if degrees_freedom < n_features - 1:\n",
" raise ValueError(\"Degrees of freedom must be bigger than n_features - 1\")\n",
" self.degrees_freedom = degrees_freedom\n",
" self.n_features = n_features\n",
" def sample(self, n_samples=1):\n",
" samples = []\n",
" inds = np.arange(self.n_features)\n",
" for i in xrange(n_samples):\n",
" V = [np.random.chisquare(self.degrees_freedom - k + 1)\n",
" for k in xrange(self.n_features)]\n",
" V = np.array(V)\n",
" N = np.random.normal(size=(self.n_features, self.n_features))\n",
" N = np.triu(N, 1)\n",
" diag = V + np.sum(N ** 2, axis=0)\n",
" B = N * np.sqrt(V) + np.dot(N.T, N)\n",
" B = np.triu(B, 1)\n",
" B += B.T\n",
" B[inds, inds] = diag\n",
" samples.append(B)\n",
" if len(samples) == 1:\n",
" return samples[0]\n",
" return samples\n",
"\n",
"class MultiVariateGaussian(object):\n",
" def __init__(self, mean, covariance):\n",
" self.mean = mean\n",
" self.covariance = covariance\n",
" def sample(self, n_samples=1):\n",
" samples = np.random.multivariate_normal(mean=self.mean,\n",
" cov=self.covariance, size=n_samples)\n",
" return samples\n",
"\n",
"\n",
"class DPGMMSampler(object):\n",
" def __init__(self, alpha, degrees_freedoms, sigma, n_features):\n",
" self.alpha = alpha\n",
" self.n_features = n_features\n",
" self.deg_freedoms = degrees_freedoms\n",
" self.sigma = sigma\n",
" self.crp = ChineseRestaurantProcess(alpha)\n",
" self.wishart = WishartSampler(degrees_freedoms, n_features)\n",
" self.gaussian_prior = scipy.stats.norm(scale=self.sigma)\n",
" self.gaussians = []\n",
" def sample(self, n_samples):\n",
" samples = []\n",
" for i in xrange(n_samples):\n",
" cluster = self.crp.sample()\n",
" if cluster >= len(self.gaussians):\n",
" mean = self.gaussian_prior.rvs(size=self.n_features)\n",
" covariance = np.linalg.inv(self.wishart.sample())\n",
" self.gaussians.append(MultiVariateGaussian(mean, covariance))\n",
" samples.append(self.gaussians[cluster].sample())\n",
" return np.vstack(samples)\n",
"\n",
"\n",
"def test_crp():\n",
" crp = ChineseRestaurantProcess(.5)\n",
" print(crp.sample(10))\n",
"\n",
"def test_wishart():\n",
" wishart = WishartSampler(6, 4)\n",
" print(wishart.sample())\n",
"\n",
"\n",
"def test_dpgmm():\n",
" import matplotlib.pyplot as plt\n",
" dpgmm = DPGMMSampler(10.1, 10, 3, 2)\n",
" X = dpgmm.sample(100)\n",
" plt.scatter(X[:, 0], X[:, 1], c='b')\n",
" for g in dpgmm.gaussians:\n",
" plt.plot(g.mean[0], g.mean[1], 'r.')\n",
" plt.show()\n",
"\n",
"if __name__ == \"__main__\":\n",
" #test_crp()\n",
" #test_wishart()\n",
" test_dpgmm()\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"png": "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\nAABJRU5ErkJggg==\n",
"text": [
"<matplotlib.figure.Figure at 0x3666d90>"
]
}
],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"dpgmm = DPGMMSampler(5.1, 1, 10, 2)\n",
"X = dpgmm.sample(1000)\n",
"plt.scatter(X[:, 0], X[:, 1], c='b')\n",
"for g in dpgmm.gaussians:\n",
" plt.plot(g.mean[0], g.mean[1], 'r.')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"png": "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\n0qlTp4iIqLi4mLy8vCg7O1vwXEREpaWlRESk0+koKCiIUlJSmp3L5J/o161bh2XLlkEqlQIAOnbs\nCED4gVbUQA+W0Jna24A0Gxsbw+2SkhI4OjoKngnQXwYsFuv/KQcFBeH69euC5/L29oaXl9dD24XM\nlJaWBg8PD7i6ukIqlWLq1KlISEgwSdt1BQcHw97evt62PXv2YNasWQCAWbNmYffu3SbN1LlzZ/j7\n+wMArK2t0atXL+Tl5QmeCwAUCgUAQKvVorq6Gvb29s3OZfJCf/HiRRw9ehQDBw6ERqNBeno6AOEH\nWq1duxZqtRovvPCC4WuQkJna64C0t99+Gy4uLti8ebPha6TQmerauHEjRo8e3e5y/ULITHl5eejW\nrZsgbf+WW7duwcnJCQDg5OSEW7duCZblypUrOHXqFIKCgtpFrpqaGvj7+8PJycnQvdTcXEa56ubX\nHjXQqqqqCvfv38fx48fx448/YvLkybh8+XKDxzHm1TqPyvTyyy9jxYoVAPT90IsWLcKGDRsEzSTU\ngLTGMsXExGDs2LGIjo5GdHQ0Vq1ahYULF2LTpk1tnqkpuQD9+2ZpaYnIyMhGj2PK96qpTHVV2uNy\n9ZtIJBIsa0lJCSZOnIg1a9bU+wYrZC6xWIzTp0+jsLAQYWFhOHLkSLNztUmhP3ToUKOPrVu3DhER\nEQCA/v37QywW486dO3B2dq53cu/69etwdnY2Saa65s6da/hPKlSmc+fOITc3F2q12tBuYGAgTpw4\n0W7ep8jISMMn57bO1JRcmzdvxv79+/Htt98atrWX96ouU7xXTW372rVr9b5dCMnJyQn5+fno3Lkz\nbt68iU6dOpk8g06nw8SJEzFz5kyMHz++3eT6RYcOHTBmzBhkZGQ0P1cbn0d4yPr162nFihVERJST\nk0PdunUjov+dpKqsrKTLly+Tm5sb1dTUmCTTjRs3DLc/+ugjmjZtmuCZ6mroZKwQmS5cuGC4HRcX\nRzNmzBA8ExFRYmIi+fj4UEFBQb3tQuciItJoNJSent4uMul0OnJzc6Pc3FyqrKwU7GQsEVFubu5D\nJ2NXrVpFRESxsbEmP+lZU1NDM2fOpIULF9bbLnSugoICun//PhERlZWVUXBwMH3zzTfNzmXyQq/V\namnGjBnk6+tLffv2pSNHjhgei46OJnd3d+rZsyclJSWZLNPMmTOpT58+5OfnR8888wzl5+cLnqmu\nHj16GAq9kJkmTpxIvr6+pFarKSIigm7duiV4JiIiDw8PcnFxIX9/f/L396eXX35Z8Fy7du0i7BBw\ntAAAAK9JREFUlUpFVlZW5OTkROHh4YJnIiLav38/eXl5kbu7O8XExJi07V9MnTqVunTpQlKplFQq\nFW3cuJHu3r1LI0aMIE9PTwoNDTUUN1NJSUkhkUhEarXa8O8oMTFR8FxnzpyhgIAAUqvV1KdPH/rg\ngw+IiJqdiwdMMcaYmeOlBBljzMxxoWeMMTPHhZ4xxswcF3rGGDNzXOgZY8zMcaFnjDEzx4WeMcbM\nHBd6xhgzc/8PhgPWwZy2vr4AAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x356a890>"
]
}
],
"prompt_number": 3
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from sklearn import cluster\n",
"reload(cluster)\n",
"from sklearn.cluster import KMeans, MiniBatchKMeans"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"km = KMeans(n_clusters=10)\n",
"mbkm = MiniBatchKMeans(n_clusters=10)\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from sklearn.preprocessing import MinMaxScaler\n",
"dpgmm = DPGMMSampler(5.1, 10, 10, 10)\n",
"inertias = []\n",
"\n",
"for i in xrange(50):\n",
" init = np.random.uniform(-2, 2, size=(10, 10))\n",
" #init = \"k-means++\"\n",
" mbkm_rnd = MiniBatchKMeans(n_clusters=100, verbose=0, reassignment_ratio=.01)\n",
"\n",
" mbkm_prop = MiniBatchKMeans(n_clusters=100, verbose=0, reassignment_ratio=.01, reassign_strat=\"proportional\")\n",
"\n",
" mbkm_aprop = MiniBatchKMeans(n_clusters=100, verbose=0, reassignment_ratio=.01, reassign_strat=\"anti-proportional\")\n",
"\n",
" mbkm_rnd_no_reassign = MiniBatchKMeans(n_clusters=100, reassignment_ratio=0, verbose=0)\n",
" X = dpgmm.sample(1000)\n",
" X = MinMaxScaler().fit_transform(X)\n",
" #km.fit(X)\n",
" mbkm_rnd_no_reassign.fit(X)\n",
" #mbkm.fit(X)\n",
" mbkm_rnd.fit(X)\n",
" mbkm_prop.fit(X)\n",
" mbkm_aprop.fit(X)\n",
" \n",
" #print(\"mbkm: %f rand init: %f no reassign: %f \" % (mbkm.inertia_, mbkm_rnd.inertia_, mbkm_rnd_no_reassign.inertia_))\n",
" print(\"rand: %f proportional: %f, anti-prop: %f no reassign: %f \" % (mbkm_rnd.inertia_, mbkm_prop.inertia_, mbkm_aprop.inertia_, mbkm_rnd_no_reassign.inertia_))\n",
" inertias.append([mbkm_rnd.inertia_, mbkm_prop.inertia_, mbkm_aprop.inertia_, mbkm_rnd_no_reassign.inertia_])\n",
"inertias = np.array(inertias)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"rand: 1.772005 proportional: 1.847923, anti-prop: 3.261370 no reassign: 2.367366 \n",
"rand: 2.752568 proportional: 4.112111, anti-prop: 3.035706 no reassign: 2.450619 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.049575 proportional: 1.635045, anti-prop: 1.219321 no reassign: 2.181509 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.795491 proportional: 1.193666, anti-prop: 3.747234 no reassign: 2.265726 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 4.384088 proportional: 3.427167, anti-prop: 2.547961 no reassign: 4.243244 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 3.295296 proportional: 2.009086, anti-prop: 2.831159 no reassign: 2.261997 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 5.237820 proportional: 1.639279, anti-prop: 1.876905 no reassign: 1.892878 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 3.742800 proportional: 1.821921, anti-prop: 2.222175 no reassign: 3.804934 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.270057 proportional: 2.416636, anti-prop: 1.875983 no reassign: 5.192144 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.289749 proportional: 3.510500, anti-prop: 2.583173 no reassign: 0.923047 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.529926 proportional: 3.889857, anti-prop: 3.464754 no reassign: 4.411481 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 3.993346 proportional: 2.267331, anti-prop: 2.507039 no reassign: 2.334013 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.916099 proportional: 1.944319, anti-prop: 3.613417 no reassign: 4.148719 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.792369 proportional: 1.703580, anti-prop: 2.967400 no reassign: 2.134545 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.286218 proportional: 1.445793, anti-prop: 2.564894 no reassign: 2.758914 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.629151 proportional: 4.373362, anti-prop: 3.340981 no reassign: 4.288961 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 3.668481 proportional: 2.036587, anti-prop: 2.656289 no reassign: 2.623744 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 3.188192 proportional: 3.583042, anti-prop: 2.997535 no reassign: 2.778245 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.939142 proportional: 1.680269, anti-prop: 1.753178 no reassign: 1.675715 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.147162 proportional: 2.442726, anti-prop: 2.387180 no reassign: 1.180850 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.354418 proportional: 3.160347, anti-prop: 3.273171 no reassign: 3.538052 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.340961 proportional: 3.076064, anti-prop: 5.238821 no reassign: 2.514561 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 3.455085 proportional: 0.946843, anti-prop: 2.233253 no reassign: 2.045285 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.508964 proportional: 1.147197, anti-prop: 1.979640 no reassign: 1.263920 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.164010 proportional: 1.558028, anti-prop: 1.747443 no reassign: 2.155830 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.564652 proportional: 3.556103, anti-prop: 1.772440 no reassign: 1.954820 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.477820 proportional: 2.049219, anti-prop: 1.878552 no reassign: 2.241281 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.637525 proportional: 3.407667, anti-prop: 1.110831 no reassign: 1.497486 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.948334 proportional: 1.778383, anti-prop: 2.262329 no reassign: 2.059060 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 5.000199 proportional: 4.596560, anti-prop: 4.911463 no reassign: 1.543705 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.446776 proportional: 2.309572, anti-prop: 1.788310 no reassign: 4.241694 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.634129 proportional: 2.975772, anti-prop: 3.142181 no reassign: 1.993234 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.006656 proportional: 2.779137, anti-prop: 1.771872 no reassign: 2.232456 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.548140 proportional: 1.994322, anti-prop: 0.941439 no reassign: 1.389210 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.512067 proportional: 1.881107, anti-prop: 1.330542 no reassign: 2.063717 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 3.472564 proportional: 1.240599, anti-prop: 1.676250 no reassign: 3.405024 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.722840 proportional: 2.163586, anti-prop: 2.862660 no reassign: 2.645002 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.893246 proportional: 5.047901, anti-prop: 4.981979 no reassign: 1.138517 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 0.975638 proportional: 3.446890, anti-prop: 1.811046 no reassign: 4.437824 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.418361 proportional: 2.248068, anti-prop: 2.091185 no reassign: 1.678213 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.645944 proportional: 2.575237, anti-prop: 2.425103 no reassign: 1.507275 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 4.644548 proportional: 2.543474, anti-prop: 1.996039 no reassign: 1.589186 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.879324 proportional: 1.252655, anti-prop: 2.787054 no reassign: 3.488014 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 3.204402 proportional: 2.386024, anti-prop: 2.675200 no reassign: 1.734311 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.816867 proportional: 1.621323, anti-prop: 2.444619 no reassign: 2.817188 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 2.548767 proportional: 2.181170, anti-prop: 1.531666 no reassign: 1.574779 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 3.093741 proportional: 1.637682, anti-prop: 3.494572 no reassign: 3.982243 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 1.642235 proportional: 3.109875, anti-prop: 4.849171 no reassign: 1.757611 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 3.439032 proportional: 1.936238, anti-prop: 2.251420 no reassign: 1.438098 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"rand: 3.262671 proportional: 4.381104, anti-prop: 3.347316 no reassign: 3.823352 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 19
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"inertias.mean(axis=0)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 8,
"text": [
"array([ 16.29422086, 14.20688592, 22.67847799, 51.50836142])"
]
}
],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"inertias.std(axis=0)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 9,
"text": [
"array([ 5.15283738, 4.93171943, 6.42158876, 13.23895656])"
]
}
],
"prompt_number": 9
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ten clusters, hundered points."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"means = inertias.mean(axis=0)\n",
"stds = inertias.std(axis=0)\n",
"print(\"rand: %f (%f) proportional: %f (%f), anti-proportional: %f (%f) no reassign: %f (%f)\" % (means[0], stds[0], means[1], stds[1], means[2], stds[2], means[3], stds[3]))\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"rand: 16.294221 (5.152837) proportional: 14.206886 (4.931719), anti-proportional: 22.678478 (6.421589) no reassign: 51.508361 (13.238957)\n"
]
}
],
"prompt_number": 10
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ten clusters, thousand points"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"means = inertias.mean(axis=0)\n",
"stds = inertias.std(axis=0)\n",
"print(\"rand: %f (%f) proportional: %f (%f), anti-proportional: %f (%f) no reassign: %f (%f)\" % (means[0], stds[0], means[1], stds[1], means[2], stds[2], means[3], stds[3]))\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"rand: 76.511687 (18.523295) proportional: 64.689732 (22.908376), anti-proportional: 86.902682 (30.102101) no reassign: 265.570305 (100.189549)\n"
]
}
],
"prompt_number": 14
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"hundred clusters, thousand points"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"means = inertias.mean(axis=0)\n",
"stds = inertias.std(axis=0)\n",
"print(\"rand: %f (%f) proportional: %f (%f), anti-proportional: %f (%f) no reassign: %f (%f)\" % (means[0], stds[0], means[1], stds[1], means[2], stds[2], means[3], stds[3]))\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"rand: 54.261285 (21.362259) proportional: 30.213327 (13.376316), anti-proportional: 80.781385 (52.572353) no reassign: 328.203081 (189.251195)\n"
]
}
],
"prompt_number": 16
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"using random init"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"means = inertias.mean(axis=0)\n",
"stds = inertias.std(axis=0)\n",
"print(\"rand: %f (%f) proportional: %f (%f), anti-proportional: %f (%f) no reassign: %f (%f)\" % (means[0], stds[0], means[1], stds[1], means[2], stds[2], means[3], stds[3]))\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"rand: 3.884792 (2.060288) proportional: 3.415392 (1.355468), anti-proportional: 4.009269 (1.570707) no reassign: 3.971875 (1.800300)\n"
]
}
],
"prompt_number": 18
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"using k-means++ init"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"means = inertias.mean(axis=0)\n",
"stds = inertias.std(axis=0)\n",
"print(\"rand: %f (%f) proportional: %f (%f), anti-proportional: %f (%f) no reassign: %f (%f)\" % (means[0], stds[0], means[1], stds[1], means[2], stds[2], means[3], stds[3]))\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"rand: 2.578789 (0.984230) proportional: 2.479367 (0.989023), anti-proportional: 2.601224 (0.976214) no reassign: 2.513392 (1.045584)\n"
]
}
],
"prompt_number": 21
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment