Skip to content

Instantly share code, notes, and snippets.

@mdouze
Created November 2, 2022 09:16
Show Gist options
  • Save mdouze/9126b72eb9a4b8bd6f624e20649edf73 to your computer and use it in GitHub Desktop.
Save mdouze/9126b72eb9a4b8bd6f624e20649edf73 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"dataExplorerConfig": {},
"bento_stylesheets": {
"bento/extensions/flow/main.css": true,
"bento/extensions/kernel_selector/main.css": true,
"bento/extensions/kernel_ui/main.css": true,
"bento/extensions/new_kernel/main.css": true,
"bento/extensions/system_usage/main.css": true,
"bento/extensions/theme/main.css": true
},
"kernelspec": {
"display_name": "faiss",
"language": "python",
"name": "bento_kernel_faiss",
"metadata": {
"kernel_name": "bento_kernel_faiss",
"nightly_builds": true,
"fbpkg_supported": true,
"cinder_runtime": true,
"is_prebuilt": true
},
"cinder_runtime": true
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3"
},
"last_server_session_id": "fee0da06-51a0-452e-ada2-cd475ebdc33c",
"last_kernel_id": "b22c9636-0aae-4eee-a616-5703983565d3",
"last_base_url": "https://devvm4950.lla0.facebook.com:8090/",
"last_msg_id": "6c942bee-03277f91cf9e78ed201987bd_1581",
"outputWidgetContext": {}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "markdown",
"metadata": {
"originalKey": "29a41e66-c7c3-4662-a20a-3d69d287a7be",
"showInput": false,
"customInput": null
},
"source": [
"This script demonstrates how to do a k-means variant where in addition the clusters are constrained to contain \n",
"no more than a maximum number of points."
],
"attachments": {}
},
{
"cell_type": "code",
"metadata": {
"collapsed": false,
"originalKey": "1d337248-037f-49bd-8d28-4e57aa6081fa",
"requestMsgId": "1d337248-037f-49bd-8d28-4e57aa6081fa",
"customOutput": null,
"executionStartTime": 1665435409373,
"executionStopTime": 1665435409414
},
"source": [
"import numpy as np\n",
"import faiss\n",
"from faiss.contrib.datasets import SyntheticDataset\n",
"from faiss.contrib.clustering import reassign_centroids \n",
"\n",
"from matplotlib import pyplot\n",
"\n",
"import matplotlib\n",
"matplotlib.style.use('default')"
],
"execution_count": 38,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"originalKey": "1af0501a-cd56-4aa3-9d8d-6ccc9136bd36",
"showInput": false,
"customInput": null
},
"source": [
"Make a small dataset in 2D to make visualization easier. "
],
"attachments": {}
},
{
"cell_type": "code",
"metadata": {
"originalKey": "548cfa85-eaac-4c2a-adca-8e1ce7b36b39",
"showInput": true,
"customInput": null,
"collapsed": false,
"requestMsgId": "548cfa85-eaac-4c2a-adca-8e1ce7b36b39",
"customOutput": null,
"executionStartTime": 1665425284002,
"executionStopTime": 1665425284100
},
"source": [
"# 2 for visualization\n",
"ds = SyntheticDataset(2, 100, 0, 0)\n",
"k = 30 # number of clusters"
],
"execution_count": 23,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"originalKey": "4ab48d50-7759-4bf3-adf8-75d32e6c71d9",
"showInput": false,
"customInput": null
},
"source": [
"Visualize the training set"
],
"attachments": {}
},
{
"cell_type": "code",
"metadata": {
"originalKey": "8c8e9eca-5a71-4c1f-a4b8-ad15d7eec614",
"showInput": true,
"customInput": null,
"collapsed": false,
"requestMsgId": "8c8e9eca-5a71-4c1f-a4b8-ad15d7eec614",
"customOutput": null,
"executionStartTime": 1665425322719,
"executionStopTime": 1665425322779
},
"source": [
"xtrain = ds.get_train()"
],
"execution_count": 26,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"originalKey": "dff4b249-cce3-42f7-8626-79ddf35f9bdc",
"showInput": true,
"customInput": null,
"collapsed": false,
"requestMsgId": "dff4b249-cce3-42f7-8626-79ddf35f9bdc",
"customOutput": null,
"executionStartTime": 1665425324165,
"executionStopTime": 1665425324387
},
"source": [
"pyplot.plot(xtrain[:, 0], xtrain[:, 1], '.')"
],
"execution_count": 27,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "[<matplotlib.lines.Line2D at 0x7fcb3874d460>]"
},
"metadata": {
"bento_obj_id": "140510802253952"
},
"execution_count": 27
},
{
"output_type": "display_data",
"data": {
"text/plain": "<Figure size 640x480 with 1 Axes>",
"image/png": "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fP7555o2bZrcbrdSUlI0a9YsHTlypNX0+/fvl8vlavHxwgsv+NK19PqqVausLEqH0U4NuyDQRqhNGdVTm4su0XOzL9TmokvoYAxbsXQU1bRp01RZWan169fr+PHjmjlzpubMmaNnn322xfTZ2dmqrKz02/b4449r8eLFuvzyy/22P/nkkyooKPA9T0lJsagUp6etdmp+6SBcWLYBVmGUHuzKsgBn165dWrdunbZu3aqRI0dKkh5++GFdccUVWrJkibKyspq9Jz4+XhkZGX7b1q5dqylTpujMM8/0256SktIsrR01tVOfHOTQTo1wI9AGEGssa6IqLS1VSkqKL7iRpLy8PMXFxamsrCygfWzbtk07duzQrFmzmr124403KjU1VaNHj9aKFStkjGlxH5HS1NdBEu3UiDg6hEYX+koBp8+yGpyqqir16NHD/8POOEPdu3dXVVVVQPtYvny5LrjgAo0ZM8Zv+913361LL71USUlJev311/Xzn/9cR44c0c0339zifurr61VfX+977vV6O1SmQLU0+dXmoktsORESYoPdZxzFN5g8DwiNoAOcoqIi3X///W2m2bVrV6uvGWPkcrlafb1JXV2dnn32Wc2fP7/ZaydvGz58uGpra/XAAw+0GuCUlJRo4cKF7X5mKLTW12Fz0SXK7Xt2WPIAtMTOM47iK/SVAkIn6ADn1ltv1YwZM9pM06dPH2VkZKi6utpv+4kTJ/TFF18oPT293c958cUXdfToUU2fPr3dtDk5Obrnnnv05ZdfKjExsdnrxcXFKiws9D33er3Kzs5ud78dQV8H2BkdQu2N6wcQOkEHOGlpaUpLS2s3XW5urg4dOqRt27ZpxIgRkqSNGzeqsbFROTk57b5/+fLl+sEPfhDQZ+3YsUPdunVrMbiRpISEBCUkJLS7n1CgUzGAjuL6AYSOZZ2ML7jgAhUUFGj27NnasmWL/vGPf2ju3LmaOnWqbwTVJ598ogEDBmjLli1+7927d6/+9re/6brrrmu23z/96U9avny53nvvPe3du1ePPvqo7rvvPt10001WFSVosy7q7evQSV8HAIFi8jwgdCydB+eZZ57R3LlzNWHCBMXFxemqq67S0qVLfa8fP35ce/bs0dGj/muXrFixQt/61rd02WWXNdtnp06d9Mgjj+iWW26RMUb9+vXTgw8+qNmzZ1tZlICc3DnQ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vueLFi0yKSkp5o9//KN55513zJVXXtniMPHhw4ebsrIys3nzZnPeeedFbJh4W/n4+OOPzfnnn2/Kysr83vfBBx8Yl8tlXnvttWb7fPnll81///d/m507d5oPPvjA/O53vzNJSUlmwYIFYSnTyYIt3969e83dd99t/vnPf5ry8nLzxz/+0fTp08eMGzfO956mYeKXXXaZ2bFjh1m3bp1JS0uL6DDxYMro9XpNTk6OGTx4sNm7d6/fsNQTJ04YE8Fj2DSUdOXKleb99983c+bMMSkpKb4Raz/5yU9MUVGRL/0//vEPEx8fb5YsWWJ27dpl7rrrrhaHibd3PoZTsGW8//77TefOnc2LL77od6yarkGHDx82v/rVr0xpaakpLy83f/3rX813vvMdc95554U94O5I+RYuXGj+8pe/mH379plt27aZqVOnmsTERPPee+/50kT7MWxytI5oewAAAiRJREFU0UUXmSlTpjTbbrdjePjwYd+9TpJ58MEHzfbt282HH35ojDGmqKjI/OQnP/Gl//e//226dOlibrvtNrNr1y6zbNmyVoeJt/Y/CwUCnCBde+21RlKzxxtvvOFL0zRfSJPGxkYzf/58k56ebhISEsyECRPMnj17/Pb72WefmauvvtqceeaZxu12m5kzZ/oFTeHSXj7Ky8ubldcYY4qLi80555xjGhoamu3ztddeM8OGDTNnnnmm6dq1qxk6dKh57LHHWkxrtWDLV1FRYcaNG2e6d+9uEhISTL9+/cxtt93mNw+OMcbs37/fXH755aZLly4mNTXV3HrrrX5DrMMp2DK+8cYbLX6nJZny8nJjInwMH374YdOzZ0/TuXNnM3r0aPPWW2/5Xhs/fry59tpr/dI///zzpn///qZz587m29/+tnnllVf8Xg/kfAy3YMp47rnntnis7rrrLmOMMUePHjWXXXaZSUtLM506dTLnnnuumT17dkhvHMEKpny33HKLL216erq54oorzNtvv+23v2g/hsYYs2fPHiPJvP766832Zbdj2No1oqlM1157rRk/frzfezZu3GiGDRtmOnfubPr06eN3T2zS1v8sFFwm3GN1AQAALGafLucAAAAhQoADAAAchwAHAAA4DgEOAABwHAIcAADgOAQ4AADAcQhwAACA4xDgAAAAxyHAAQAAjkOAAwAAHIcABwAAOA4BDgAAcJz/D28Q525fkmN/AAAAAElFTkSuQmCC\n"
},
"metadata": {
"bento_obj_id": "140510802623552"
}
}
]
},
{
"cell_type": "markdown",
"metadata": {
"originalKey": "4492ec28-9306-4c0b-aef5-7412c8805ca6",
"showInput": false,
"customInput": null
},
"source": [
"## Default k-means"
],
"attachments": {}
},
{
"cell_type": "code",
"metadata": {
"originalKey": "fd8c4d3d-b1b6-4c3a-9120-f68eba391e68",
"showInput": true,
"customInput": null,
"collapsed": false,
"requestMsgId": "fd8c4d3d-b1b6-4c3a-9120-f68eba391e68",
"customOutput": null,
"executionStartTime": 1665435964854,
"executionStopTime": 1665435964869
},
"source": [
"km = faiss.Kmeans(ds.d, k)\n",
"km.train(xtrain)\n",
"_, labels = km.assign(xtrain)"
],
"execution_count": 71,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"originalKey": "4f1b97de-c510-43e0-b369-ba0dfb3dd9e8",
"showInput": true,
"customInput": null,
"collapsed": false,
"requestMsgId": "4f1b97de-c510-43e0-b369-ba0dfb3dd9e8",
"customOutput": null,
"executionStartTime": 1665435965565,
"executionStopTime": 1665435965603
},
"source": [
"np.bincount(labels).max(), km.obj[-1]"
],
"execution_count": 72,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "(10, 1.8227806091308594)"
},
"metadata": {
"bento_obj_id": "140510801513024"
},
"execution_count": 72
}
]
},
{
"cell_type": "markdown",
"metadata": {
"originalKey": "22306615-9259-46b4-b95e-f0fbdaf6ae7d",
"showInput": false,
"customInput": null
},
"source": [
"max number of points per cluster and final k-means objective. \n",
"Below: visualize one color per cluster."
],
"attachments": {}
},
{
"cell_type": "code",
"metadata": {
"originalKey": "b9461112-f08f-4cb7-b37f-34381e640a9b",
"showInput": true,
"customInput": null,
"collapsed": false,
"requestMsgId": "b9461112-f08f-4cb7-b37f-34381e640a9b",
"customOutput": null,
"executionStartTime": 1665435973914,
"executionStopTime": 1665435974153
},
"source": [
"for i in range(k):\n",
" ss = labels == i \n",
" pyplot.plot(xtrain[ss, 0], xtrain[ss, 1], '.')"
],
"execution_count": 73,
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": "<Figure size 640x480 with 1 Axes>",
"image/png": "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\n"
},
"metadata": {
"bento_obj_id": "140510847671840"
}
}
]
},
{
"cell_type": "markdown",
"metadata": {
"originalKey": "143af58a-2748-4941-93f7-a095833cf670",
"showInput": false,
"customInput": null
},
"source": [
"## k-means with max nb points per cluster\n",
"\n",
"The k-means implementation below is a practical way to limit the number of points per cluster. It is purely heuristic, just tweaks the allocation stage to stop accepting points in clusters."
],
"attachments": {}
},
{
"cell_type": "code",
"metadata": {
"originalKey": "963e2f20-9d42-47cc-8eb4-df1dde01e2b9",
"showInput": true,
"customInput": null,
"collapsed": false,
"requestMsgId": "963e2f20-9d42-47cc-8eb4-df1dde01e2b9",
"customOutput": null,
"executionStartTime": 1665435943651,
"executionStopTime": 1665435943675
},
"source": [
"def kmeans_max_pts(data, k, max_pts, seed=123, niter=25): \n",
" n, d = xtrain.shape\n",
" assert max_pts * k >= n\n",
" rs = np.random.RandomState(seed)\n",
" perm = rs.choice(n, size=k, replace=False)\n",
" centroids = data[perm]\n",
" objectives = []\n",
" for i in range(niter):\n",
" # compute all distances, WARN: matrix of size n * k \n",
" D = faiss.pairwise_distances(data, centroids)\n",
" order = D.min(axis=1).argsort()\n",
" assign = -np.ones(n, dtype=int) # assignment of each point\n",
" hassign = np.zeros(k, dtype=int) # nb of assignments per centroid\n",
" sums = np.zeros((k, d), dtype=float) # sum of points per centroid\n",
" obj = 0\n",
" for i in order: \n",
" # strictly speaking, the order will become invalid after columns are removed\n",
" ai = D[i].argmin()\n",
" obj += D[i, ai]\n",
" assert np.isfinite(obj)\n",
" assign[i] = ai\n",
" hassign[ai] += 1\n",
" sums[ai] += data[i]\n",
" if hassign[ai] == max_pts: \n",
" D[:, ai] = np.inf # ai will not be used again\n",
"\n",
" fac = hassign.reshape(-1, 1).astype('float32')\n",
" fac[fac == 0] = 1 # quiet warning\n",
"\n",
" centroids = sums / fac # computer center of mass per cluster\n",
"\n",
" nsplit = reassign_centroids(hassign, centroids, rs)\n",
" objectives.append(obj)\n",
"\n",
" return assign, centroids, objectives\n",
""
],
"execution_count": 68,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"originalKey": "6fa92a53-bace-42e2-8572-faedae61c3f6",
"showInput": true,
"customInput": null,
"collapsed": false,
"requestMsgId": "6fa92a53-bace-42e2-8572-faedae61c3f6",
"customOutput": null,
"executionStartTime": 1665435948725,
"executionStopTime": 1665435948769
},
"source": [
"labels2, _, obj = kmeans_max_pts(xtrain, k, 4)"
],
"execution_count": 69,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"originalKey": "6d6dca5f-f75e-489a-9c11-35d1e8ccebdd",
"showInput": true,
"customInput": null,
"collapsed": false,
"requestMsgId": "6d6dca5f-f75e-489a-9c11-35d1e8ccebdd",
"customOutput": null,
"executionStartTime": 1665435952142,
"executionStopTime": 1665435952207
},
"source": [
"np.bincount(labels2).max(), obj[-1]"
],
"execution_count": 70,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "(4, 1.838280936703086)"
},
"metadata": {
"bento_obj_id": "140510848594432"
},
"execution_count": 70
}
]
},
{
"cell_type": "markdown",
"metadata": {
"originalKey": "dac836eb-7407-4d5c-80e1-e618d89970e5",
"showInput": false,
"customInput": null
},
"source": [
"The constraint is respected. The consequence is that the k-means objective is a bit worse. "
],
"attachments": {}
},
{
"cell_type": "code",
"metadata": {
"originalKey": "146ace66-6c5c-4615-8b06-7b52c251cfd7",
"showInput": true,
"customInput": null,
"collapsed": false,
"requestMsgId": "146ace66-6c5c-4615-8b06-7b52c251cfd7",
"customOutput": null,
"executionStartTime": 1665435922105,
"executionStopTime": 1665435922357
},
"source": [
"for i in range(k):\n",
" ss = labels2 == i \n",
" pyplot.plot(xtrain[ss, 0], xtrain[ss, 1], '.')"
],
"execution_count": 67,
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": "<Figure size 640x480 with 1 Axes>",
"image/png": "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\n"
},
"metadata": {
"bento_obj_id": "140510801146928"
}
}
]
},
{
"cell_type": "code",
"metadata": {
"originalKey": "9a9c58a8-7331-4b07-b1f1-d6988a563d68",
"showInput": true,
"customInput": null
},
"source": [
""
],
"execution_count": null,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment