Skip to content

Instantly share code, notes, and snippets.

@michaelmalak
Created February 9, 2014 00:45
Show Gist options
  • Save michaelmalak/8892561 to your computer and use it in GitHub Desktop.
Save michaelmalak/8892561 to your computer and use it in GitHub Desktop.
CardinalityAlgorithms
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h1>Visualization of cardinality algorithm (naive version)</h1>"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import uuid\n",
"import math\n",
"%matplotlib inline"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 112
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Create a list of 10 random UUIDs"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"list10 = [str(uuid.uuid4()) for i in xrange(10)]\n",
"list10"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 113,
"text": [
"['0084d80c-283c-4392-947f-a3975ae4c88a',\n",
" '9ee0603d-f5bb-40ee-8e26-88668300cdbe',\n",
" '993c2ba5-1821-4fc8-acf6-f2349045aa5f',\n",
" '9f15bd5e-f872-4fbd-a0cb-a6b6c1e354d4',\n",
" '35467743-f5bb-49f9-8c3f-baad88aed594',\n",
" '48285124-11c6-4060-8b93-3aec01ef6fa8',\n",
" '11e632f1-665a-4074-a0fe-8a4e3ff1b83b',\n",
" '4d1b272f-b269-4716-9418-4d7fcce650fd',\n",
" 'a46cbf0d-ca3e-4dbf-8ab2-1240f5d96118',\n",
" 'd3e892b8-0548-4e25-98ef-65cf80959dd7']"
]
}
],
"prompt_number": 113
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now lists of 100 and 1000 UUIDs"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"list100 = [str(uuid.uuid4()) for i in xrange(100)]\n",
"list1000 = [str(uuid.uuid4()) for i in xrange(1000)]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 127
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Hash the list of 10 UUIDs with a hash function that maps to floating point numbers in the range [0,1)"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"h10 = [hash(x) / pow(2.0,32.0) + 0.5 for x in list10]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 116
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Find the smallest, and the exponentiate that to get the approximation of the size (cardinality) of the set"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"m10 = min(h10)\n",
"m10"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 117,
"text": [
"0.07389730727300048"
]
}
],
"prompt_number": 117
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"pow(10,-math.log10(m10))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 118,
"text": [
"13.532292811504993"
]
}
],
"prompt_number": 118
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Do the same for the sets of 100 and 1000"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"h100 = [hash(x) / pow(2.0,32.0) + 0.5 for x in list100]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 119
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"m100 = min(h100)\n",
"m100"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 120,
"text": [
"0.0026511941105127335"
]
}
],
"prompt_number": 120
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"pow(10,-math.log10(m100))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 121,
"text": [
"377.1885264963127"
]
}
],
"prompt_number": 121
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"h1000 = [hash(x) / pow(2.0,32.0) + 0.5 for x in list1000]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 122
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"m1000 = min(h1000)\n",
"m1000"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 123,
"text": [
"0.00014685397036373615"
]
}
],
"prompt_number": 123
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"pow(10,-math.log10(m1000))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 124,
"text": [
"6809.485623869372"
]
}
],
"prompt_number": 124
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Plot the hashed values. Top set of dots is for the set of 10 hashed UUIDs, middle set is for the set of 100 hashed UUIDs, and the bottom set is for the set of 1000 hashed UUIDs"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"scatter(h10 + h100 + h1000, [3]*10 + [2]*100 + [1]*1000)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 125,
"text": [
"<matplotlib.collections.PathCollection at 0xb385860>"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAXYAAAEACAYAAACnJV25AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl8VOXd9/HPTGayTPY9IQkEQlgDSYA2LiggBQVxq7TV\nWymiVVTQ4m2ta5/ic1u09fXc3qit9elTd4UqVsWyqKgBkU0wUpWyBIIkBBACSUjIMpn5PX+ca0JC\nQhJ2OP29X695Meec61znd65zznfOnCTqEBFBKaWUbTjPdAFKKaVOLg12pZSyGQ12pZSyGQ12pZSy\nGQ12pZSyGQ12pZSymQ6Dvb6+noKCAvLy8hgwYAAPPvhgmzaFhYVER0eTn59Pfn4+jz322CkrViml\nVOdcHS0MDQ3l008/xePx0NTUxPDhw1m+fDnDhw9v1W7EiBHMnz//lBaqlFKqazp9FOPxeABobGzE\n5/MRFxfXpo3+jZNSSp09Og12v99PXl4eycnJjBo1igEDBrRa7nA4WLFiBbm5uYwfP54NGzacsmKV\nUkp1rtNgdzqdfPXVV5SVlbFs2TIKCwtbLR8yZAilpaWsX7+eu+66i6uvvvpU1aqUUqoLHMfy34r5\nr//6L8LCwvjVr3511DY9e/Zk3bp1bR7Z9O7dm61btx5/pUop9W8oKyuL4uLiY1qnwzv2ffv2UVlZ\nCUBdXR0fffQR+fn5rdrs2bOn+Rn7mjVrEJF2n8Nv3boVETlnX7/97W/PeA3/jrVr/Wf+pfWf2dfx\n3BB3+Fsxu3btYvLkyfj9fvx+P5MmTWL06NE8//zzAEydOpV58+bx3HPP4XK58Hg8zJ0795iLUEop\ndfJ0GOyDBg3iyy+/bDN/6tSpze+nTZvGtGnTTn5lSimljov+5WkXjRw58kyXcNzO5dpB6z/TtP5z\nzzH98PSENuRwcJo2pZRStnE82al37EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa\n7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7Eop\nZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa\n7EopZTMdBnt9fT0FBQXk5eUxYMAAHnzwwXbb3X333WRnZ5Obm0tRUdEpKVQppVTXuDpaGBoayqef\nforH46GpqYnhw4ezfPlyhg8f3txm4cKFFBcXs2XLFlavXs0dd9zBqlWrTnnhSiml2tfpoxiPxwNA\nY2MjPp+PuLi4Vsvnz5/P5MmTASgoKKCyspI9e/acglLPXe+99x7duw8gJqYbN9zwCw4dOnRC/S1c\nuJAePXKIienGz342hZqampNUaed2797NqFFXEBWVQkxMdyIjE0lP789bb807bTV01Zw5c0lL60dc\nXDq33DKdhoaG5mWffvopCQndcTqjCQ6O5dZbp+P1etv08c4775CRMYDY2DQmTbqNurq646qlqKiI\ngQPPIzo6hREjLqe8vPy49+tc5Pf7efDB35KQ0IPk5Cz+53+eOdMl2Zt0wufzSW5urkRERMh9993X\nZvmECRPk888/b54ePXq0rF27tk27LmzKlr744gsJC0sS+Fhgu4SGXivXXXfzcff31VdficeTKPCh\nwHcSEnKdXHPNDSex4qPz+/0ycOAPxeV6QKBM4DWBRIF3xeNJkRUrVpyWOrpi6dKl4vF0E/hMYJuE\nhY2TqVN/KSIimzdvlpCQKIFuAqsEisXpvFDuvfehVn2sXr1aPJ5kgU/MsbtGbrjh1mOu5fvvv5fo\n6BSBVwTKxOV6SPr1Gyo+n++k7Ou5YNasJ8Xj+aHARoEi8Xiy5fXX55zpss4Jx5Odnd6xO51Ovvrq\nK8rKyli2bBmFhYXtfTi0mnY4HCfpY+fc98EHH9DYeBNwCdCD+vrZ/OMf7x93fx999BFe738AY4Du\nNDQ8w+LF/zg5xXZi7969FBcX09Q0C0gDbgCGAVBXdysLFiw6LXV0xfvvL+TQoTuA4UBP6ur+m3ff\ntcbpk08+oampB3AvUABk4ffP5q23Wh+XRYsWU18/BRhF4Ni9//6xH7s1a9YgMhiYBKTR1PQY27fv\nYPfu3Seyi+eUN9/8B4cO/Q7oC+Rx6NBDvPnm6Tlv/x11+Iy9pejoaC6//HLWrl3LyJEjm+enpaVR\nWlraPF1WVkZaWlq7fcycObP5/ciRI1v1Y1dRUVEEB6/n8Df4EiIiok+oP7e7hMNPDUoIDz/+/o5F\neHg4fn898D2QDDQBO4BogoNLiI3NOy11dEVMTBRu99ZW4xQZaY1TVFQUTmctPt+2FmuUEBMTfUQf\n0QQHb6C+vm0fxyIqKgq/vxTwAm5gLz7fISIjI4+5r3NVTEwUUNI87XSWEB9/es7bc01hYWG7N9DH\npKPb+b1798qBAwdEROTQoUNy0UUXyZIlS1q1WbBggYwbN05ERFauXCkFBQUn7euEHVRVVUlm5gAJ\nDf2ZOBwPiceTIn/725vH3d/Bgweld+9cCQ29VhyOhyUsLFVeeeW1k1hxxx5++FEJD+8r8IhAgUB/\nCQ6+XtLT+8j+/ftPWx2d2bt3r6SmZklIyCRxOh8QjydJFixYICIidXV10rdvvkC0wCSBe8XtjpFP\nPvmkVR+VlZXSvXs/CQm5TpzOhyQsLFnefvvtY67F5/PJ6NFXisczQuA3Eh7eTx544H+dlP08V6xZ\ns0bCwxMkKOgecbtvl5iYVNm2bduZLuuccDzZ6TArtuvrr79m8uTJ+P1+/H4/kyZN4r777uP5558H\nYOrUqQBMnz6dxYsXEx4ezosvvsiQIUPa9OVwONo8svl3UVVVxUsvvcSBA5VceulYzj///BPqr6am\nhhdeeIGKiv2MGfOjVr+ldDq8//77fPHFWvx+H05nELGxMUyZMoWYmJjTWkdnKioqePnllzl4sIYJ\nEy5n6NChzcvq6uqYPXs2H3/8Menp6dxzzz0MHjy4TR9VVVW8+OKLVFZWMW7cZRQUFBxXLU1NTbzy\nyits3/4dw4YN5corrzzu/TpXbdq0ibfemofb7eKGG24gPT39TJd0Tjie7Oww2E+mf+dgV0qp43U8\n2al/eaqUUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjaj\nwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6U\nUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjajwa6UUjaj\nwa6UUjbTYbCXlpYyatQoBg4cSE5ODk8//XSbNoWFhURHR5Ofn09+fj6PPfbYKStWKaVU51wdLXS7\n3Tz11FPk5eVRU1PD0KFDGTNmDP3792/VbsSIEcyfP/+UFqqUUqprOrxjT0lJIS8vD4CIiAj69+9P\neXl5m3YicmqqU0opdcy6/Ix9+/btFBUVUVBQ0Gq+w+FgxYoV5ObmMn78eDZs2HDSi1RKKdV1HT6K\nCaipqWHixInMnj2biIiIVsuGDBlCaWkpHo+HRYsWcfXVV7N58+Z2+5k5c2bz+5EjRzJy5MjjLlwp\npeyosLCQwsLCE+rDIZ08R/F6vUyYMIFx48YxY8aMTjvs2bMn69atIy4urvWGHA59ZKOUUsfoeLKz\nw0cxIsItt9zCgAEDjhrqe/bsad7omjVrEJE2oa6UUur06fBRzOeff85rr73G4MGDyc/PB2DWrFns\n2LEDgKlTpzJv3jyee+45XC4XHo+HuXPnnvqqlVJKHVWnj2JO2ob0UYxSSh2zk/4oRiml1LlHg10p\npWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxG\ng10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10p\npWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWxGg10ppWymw2AvLS1l1KhRDBw4\nkJycHJ5++ul22919991kZ2eTm5tLUVHRKSlUKaVU17g6Wuh2u3nqqafIy8ujpqaGoUOHMmbMGPr3\n79/cZuHChRQXF7NlyxZWr17NHXfcwapVq0554afL/v37efbZZ1myZAklJdtpbGwgNjaWK6+8kilT\nprBz506WLfuM1NQUpkyZQmho6FH7WrRoETNm3IPX6+W6635GaGgYYWGhTJo0ieLiYj76aAlxcbFM\nnDiRP/3pT6xYsZJ+/fry0EMPkZGRQXl5Oa+99hobN24iJCSEAQP6c/PNNxMeHo7f7+f1119n8+Yt\nDB48iIkTJ+JwOBAR/vCHP7Bw4SLS0rrx1FNP8fLLL7No0WK6dUvld7/7HXV1dcyb9zbBwW5uvPFG\n0tLSqKio4KWXXqKmppYrrphAZmYmd955J6WlZTgc4PeDy+XkwguHM3bsGL755hs++eRTIiIiuOyy\nS6mtraW0tIzzzz+P8ePHtxqHpUuX8sYbcygtLWXw4EEEBwfjcrnJy8vlnXfeZceOHYwefQkzZszA\n4/G0Wre2tpY//vGPLFnyMVVVVdTX11NVVUlQkJvU1BR+9KPReL1NzJv3FuXlu0lIiGPhwoX06dOH\n2bNn849/LCAxMYGMjAyKir4iNTWVBx64n5ycnOZtVFZWMm3aNEpLy7j00rFMmzaNl156iaKirygv\nLycoKIgrrpjAbbfdhtvtBmDjxo289dY8XK4gQkND2b//AHl5uVRWVvL2228TFuZh6tTbGDt2LA0N\n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\nZ8+e5nGoqqqSq666XoKDY8XpjBKPJ16iorpJXFyG5OaeJy5XnDgcERIfn9nm5zki1iODxMRe5mcF\nkc3Hw3oUEClRUekSGhpnwtgjECVXXXWVrF+/XlJT+4jDES5BQbESGhorDkeUuFwxcttt08Xr9TZv\n449//KO43fEC4ZKQ0EueeeYZSUvrKy5XjDgc0eJwREhGxgBZs2aNiIj4fD759a8fkfj47hIX111S\nUnpJVFSyDBkyXDIzB4jDES1BQZEycuTlUlFRIcuXL5fw8EDohwmES1JSloSHJ0pYWLI4HIHaw00b\nj4SGJsv8+fOba/R6vfLLX/5a4uIyJDw8RUJCosXpjJWQkFi54orr5MCBAyIi8u2330pkZHLzOLnd\n0fLRRx+1e46uWrVK+vYdJh5PgoSEJEtkZJL89Kc3yb59+2To0IvE4YgQhyNKgoLCzAfT4fGPjk6U\n888fI1FRKdKrV6707Zvb6hgFBUVLYmIvefHFl5u3t3btWunf/4cSFZUso0ZdIbt27WpVj8/nk/vv\n/43Ex3eXpKRe8tRTT7dbt9/vlyeffEqio9NMXdZxv/POae22P9ccT3Y6zIrtWr58ORdffDGDBw9u\nfrwya9YsduzYAcDUqVMBmD59OosXLyY8PJwXX3yRIUOGtOkr8BsaSimluu54srPDYD+ZNNiVUurY\nHU926l+eKqWUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WU\nzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiw\nK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WUzWiwK6WU\nzXQa7DfffDPJyckMGjSo3eWFhYVER0eTn59Pfn4+jz322EkvUimlVNe5OmswZcoU7rrrLn7+858f\ntc2IESOYP3/+SS1MKaXU8en0jv2iiy4iNja2wzYictIKUkopdWJO+Bm7w+FgxYoV5ObmMn78eDZs\n2HAy6lJKKXWcOn0U05khQ4ZQWlqKx+Nh0aJFXH311WzevLndtjNnzmx+P3LkSEaOHHmim1dKKVsp\nLCyksLDwhPpwSBeeo2zfvp0rrriCr7/+utMOe/bsybp164iLi2u9IYdDH9kopdQxOp7sPOFHMXv2\n7Gne6Jo1axCRNqGulFLq9On0Ucz111/P0qVL2bdvHxkZGTz66KN4vV4Apk6dyrx583juuedwuVx4\nPB7mzp17yotWSil1dF16FHNSNqSPYpRS6pidkUcxSimlzi4a7EopZTMa7EopZTMa7EopZTMa7Eop\nZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa\n7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTMa7Eop\nZTMa7EopZTMa7EopZTMa7EopZTMa7EopZTOdBvvNN99McnIygwYNOmqbu+++m+zsbHJzcykqKjqp\nBSqllDo2rs4aTJkyhbvuuouf//zn7S5fuHAhxcXFbNmyhdWrV3PHHXewatWqk17omdLU1MSuXbuo\nqKhgyZIl9OjRg4iICKqrq0lMTOSVV16hoaGBHj16sHr1aiIiIkhMTCQ7O5uwsDAqKyvJzMzE5/Nx\n8OBB9u/fT11dHR6PB4/Hw8aNG6mpqSE3N5eYmBhEhLVr1+JyuQgODiYsLIzs7Gz8fj/h4eE0NTWR\nlJTEe++9R0lJCUOGDMHj8VBdXU1sbCz79u2jsrKSiooKdu/eTY8ePcjMzGTgwIG89957NDY24nQ6\nCQsL4/rrr6exsZHy8nK2bt1KYmIiGRkZNDQ00KtXL6qqqkhNTWXBggVUVlYyduxYevfuTXFxMQCZ\nmZmsXr2atWvX0q9fP5KSktixYwehoaHs3r2b4OBg8vLy8Hg81NfXExUVxfr169m7dy9paWnU19dT\nWVlJZGQkkydP5r333qOoqIjExEQGDBhAZGQkK1aswO1209TUhN/vp7y8nOXLl5ORkcHo0aNJSUlh\ny5YtVFVVERERwcGDB4mPj6eyspLBgwdTX19PWFgY5eXlhISE4HA4CAsLIzw8nPLycurq6qiursbh\ncDBq1CgiIiJYs2YNlZWVZGRkkJycTFlZGcHBwWRkZLBp0yYSEhJobGykuLiYiooKevTowXnnnUev\nXr2oqamhtrYWh8PBO++8w65du6ipqWHUqFH07t2bnTt3kpKSQnp6Om+88QYxMTE4HA6io6OJiIhg\n/vz5uN1uwsLCuOCCC/j4448ZPHgwqamphIeHs3HjRrp168b27duJjIzE4XAQGhpKYmIi69at4+DB\n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\nHhYW1vybGX6/dYcc+M2THTt20NTURGhoKGFhYdTX1zcf09raWtxuN16vl9ra2ubfNunTpw/9+/en\noaGB2tpaduzYQUlJSXPtoaGhJCUlcejQIeLi4nC5XBQXFyMizcfQ6/W2elzgcrloamrC5XIRExMD\nQG1tbfOxDfwbHByM2+2msrISEcHhcOB0Opt/m0hEmrcTFBRESkoKsbGxbNq0CafTSVxcHNXV1fj9\nfkJCQkhMTOTgwYMcOHCAhoYGRKT5t5KCgoKIjIzE6/XS0NDQ5nh4vV5EhKCgIFJTU7nmmmvYunUr\na9eubc6N+vr65mMpIiQnJ3PbbbdRXl7OihUrKC4uxu/3ExkZSVhYGHv37sXn8xEfH09UVBS7du1q\nvj68Xi9hYWG43W6CgoJoamqirq6uebwvuOACpk2bRm5u7vFc/meFUxLsJ8u5GuxKKXUmnZHfilFK\nKXV20WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb\n0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBX\nSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb0WBXSimb6TTYFy9e\nTL9+/cjOzub3v/99m+WFhYVER0eTn59Pfn4+jz322CkpVCmlVNd0GOw+n4/p06ezePFiNmzYwJw5\nc/jXv/7Vpt2IESMoKiqiqKiIRx555JQVeyYVFhae6RKO27lcO2j9Z5rWf+7pMNjXrFlD7969yczM\nxO12c9111/Hee++1aScip6zAs8W5fHKcy7WD1n+maf3nng6DfefOnWRkZDRPp6ens3PnzlZtHA4H\nK1asIDc3l/Hjx7Nhw4ZTU6lSSqkucXW00OFwdNrBkCFDKC0txePxsGjRIq6++mo2b9580gpUSil1\njKQDK1eulEsvvbR5etasWfLEE090tIpkZmZKRUVFm/lZWVkC6Etf+tKXvo7hlZWV1WHmtqfDO/Zh\nw4axZcsWtm/fTrdu3fjb3/7GnDlzWrXZs2cPSUlJOBwO1qxZg4gQFxfXpq/i4uKONqWUUuok6TDY\nXS4Xzz77LJdeeik+n49bbrmF/v378/zzzwMwdepU5s2bx3PPPYfL5cLj8TB37tzTUrhSSqn2OeTf\n4VdalFLq38gp+8vT/fv3M2bMGPr06cPYsWOprKxs06a0tJRRo0YxcOBAcnJyePrpp09VOV3S2R9j\nAdx9991kZ2eTm5tLUVHRaa6wY53V//rrr5Obm8vgwYO58MIL+ec//3kGqjy6row/wBdffIHL5eLv\nf//7aayuc12pv7CwkPz8fHJychg5cuTpLbATndW/b98+LrvsMvLy8sjJyeGll146/UUexc0330xy\ncjKDBg06apuz+drtrP5jvnaP+al8F913333y+9//XkREnnjiCbn//vvbtNm1a5cUFRWJiMjBgwel\nT58+smHDhlNVUoeampokKytLSkpKpLGxUXJzc9vUsmDBAhk3bpyIiKxatUoKCgrORKnt6kr9K1as\nkMrKShERWbRo0TlXf6DdqFGj5PLLL5d58+adgUrb15X6Dxw4IAMGDJDS0lIREdm7d++ZKLVdXan/\nt7/9rTzwwAMiYtUeFxcnXq/3TJTbxrJly+TLL7+UnJycdpefzdeuSOf1H+u1e8ru2OfPn8/kyZMB\nmDx5Mu+++26bNikpKeTl5QEQERFB//79KS8vP1Uldagrf4zVcp8KCgqorKxkz549Z6LcNrpS//nn\nn090dDRg1V9WVnYmSm1XV/8Y7plnnmHixIkkJiaegSqPriv1v/HGG1x77bWkp6cDkJCQcCZKbVdX\n6k9NTaW6uhqA6upq4uPjcbk6/DHdaXPRRRcRGxt71OVn87ULndd/rNfuKQv2PXv2kJycDEBycnKn\ng7h9+3aKioooKCg4VSV1qCt/jNVem7MlHLtSf0t//etfGT9+/OkorUu6Ov7vvfced9xxB9C1v7M4\nXbpS/5YtW9i/fz+jRo1i2LBhvPrqq6e7zKPqSv233nor3377Ld26dSM3N5fZs2ef7jKP29l87R6r\nrly7J/RxO2bMGHbv3t1m/u9+97tW0w6Ho8OLsKamhokTJzJ79mwiIiJOpKTj1tWQkCN+1ny2hMux\n1PHpp5/ywgsv8Pnnn5/Cio5NV+qfMWMGTzzxBA6HAxE5q/5TFl2p3+v18uWXX/Lxxx9z6NAhzj//\nfM477zyys7NPQ4Ud60r9s2bNIi8vj8LCQrZu3cqYMWNYv349kZGRp6HCE3e2XrvHoqvX7gkF+0cf\nfXTUZcnJyezevZuUlBR27dpFUlJSu+28Xi/XXnstN954I1dfffWJlHNC0tLSKC0tbZ4uLS1t/sp8\ntDZlZWWkpaWdtho70pX6Af75z39y6623snjx4g6/+p1uXal/3bp1XHfddYD1g7xFixbhdru58sor\nT2ut7elK/RkZGSQkJBAWFkZYWBgXX3wx69evPyuCvSv1r1ixgocffhiArKwsevbsyaZNmxg2bNhp\nrfV4nM3Xblcd07V7Un8C0MJ9993X/Feqjz/+eLs/PPX7/TJp0iSZMWPGqSqjy7xer/Tq1UtKSkqk\noaGh0x+erly58qz6AUxX6v/uu+8kKytLVq5ceYaqPLqu1N/STTfdJG+//fZprLBjXan/X//6l4we\nPVqampqktrZWcnJy5Ntvvz1DFbfWlfrvuecemTlzpoiI7N69W9LS0tr9K/MzpaSkpEs/PD3brt2A\njuo/1mv3lAV7RUWFjB49WrKzs2XMmDFy4MABERHZuXOnjB8/XkREPvvsM3E4HJKbmyt5eXmSl5cn\nixYtOlUldWrhwoXSp08fycrKklmzZomIyJ///Gf585//3Nxm2rRpkpWVJYMHD5Z169adqVLb1Vn9\nt9xyi8TFxTWP9Q9+8IMzWW4bXRn/gLMt2EW6Vv+TTz4pAwYMkJycHJk9e/aZKrVdndW/d+9emTBh\nggwePFhycnLk9ddfP5PltnLddddJamqquN1uSU9Pl7/+9a/n1LXbWf3Heu3qHygppZTN6P8aTyml\nbEaDXSmlbEaDXSmlbEaDXSmlbEaDXSmlbEaDXSmlbEaDXSmlbEaDXSmlbOb/A99rYAoz+bayAAAA\nAElFTkSuQmCC\n",
"text": [
"<matplotlib.figure.Figure at 0xb46ea58>"
]
}
],
"prompt_number": 125
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Zoom in to the left portion of the above plot."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"fig, ax = plt.subplots()\n",
"fig.set_size_inches(12,4)\n",
"ax.set_xlim([0, 0.1])\n",
"ax.set_ylim([0, 4])\n",
"ax.scatter(h10 + h100 + h1000, [3]*10 + [2]*100 + [1]*1000)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 126,
"text": [
"<matplotlib.collections.PathCollection at 0xb71e908>"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\n0kvq33+EWrfupl69fq6HHlpSo5ry8/N1772/U2xskq666lodOXKkxudVXS+99LJ69YpWixZd9LOf\nDdXrr7+uefNuUUhIN4WEdNGMGSmaPHmGYmOTdM8992vr1q0aPny8hg4dpy1btpSZ69tvv9WNN96s\nmJhEzZnzK3377bcerTU/P1/33HO/YmOTNG7cVRo//mrFxCRqwYJF+uabb0rWWkrKTcrOzj6vubdt\n26aEhIkaPPgKrVu3rsrxX3zxha65ZpZiYhL1m98sVG5uriTp6NGjmjr1esXGJunuu+9TXl5epfPk\n5eXprrvuVUxMopKTU3T8+HF99NFHuuKKqzVgwKgy73kvv7xOgwdfoYSEidq2bdt5nZ/Tu+++q2HD\nxiosLELh4T/TkCFJio1N0MiRk/W3v/1NeXl5Wrjwt4qNTdLUqdfr2LFj5eZ48cW1xfVcqe3bt1d5\nzG+++UazZ/9SMTGJuummW5WTk6P8/HwtWvSAfvaz4erYsbcuvXSQbrvtLp05c6Zkv507d5a6jiaW\nua+69uzZo5EjJ2vgwNF66qmnZWYqLCzUgw8+rNjYJF155XT9+9//Lrff+vXrNXjwFYqPn6ilS5eq\nZ89+at68ky677PKS61xpH374ocaMuUpxcaP0pz89Ue28UpGtW7eWvD+dK9d9+umnmjx5pmJjk3Tf\nfQ8qLy9P1157g5o376TWrS/W/Pnzy2SqG26YrebNOyokpKueeuopSdIHH3ygUaOmaODA0Xryyacq\nrfnYsWO69NIBCgzsoPDwvjU+tzKsGg4dOmQ9evSo8L6UlBRbs2ZNyXbXrl3t888/LzdOkklPmZ9f\niL322mvVOWydeuutt8zPr5VJT5r0jPn5tbENGzacc/yGDRvMz6+NSc+Y9IT5+rawxo0DTAoy6SGT\n1lrjxl3td79bXOWxc3Jy7IIL2pjUyqRnTXrcGjUKtG3btpUbe+zYMQsKutC8vBaZtM7c7mibP/+2\nWp37+UhIGG9+fiNN2mA+PjdZcHCY+fl1NukvJi01f/8W9o9//KNac/3613ea232JSS+bl9f9FhjY\n2o4cOVLh2O+++87at48wH5+bio8db15eF5i0xqTl5na3sPfff9+Tp1qlvXv3mtvdwqRHTXrB3O6O\n9vjjT5YZ85e/vGhud6hJz5n0J3O7W9r27dstPT3d/PxamLTCpOdNamsu10jz8QkyqZdJ60xaYJK/\n7dmzxzZu3Gh+fhcWr7cnTWpq0myTXjSpk0kzzeVqZ15eo0zaYI0bX2/dul1iZ86cKVd3bm6uRUT0\nLV5vRY+nyzXIpACT7jPpZZO6W4cOFb/Gq+PNN980l6uZSTNM2mDSaOvW7RIrLCys1v4zZ/7C3O7L\nTVpvXl6/sUaNgqxx4+nFtY41l6tj8WM0zKRQk9abdEnxn/XWqNFd1qJFmJ04caLc3IsXP2Jud3jx\nY/eI+fu3sP3791u/fkPN13eSSRusSZOZ1qpVe3O7e5r0kkkPmtTEpOYmPVH8PIRY48YdLTKyn7nd\nMcW1LrALLgi1L7/80szMjh8/bs2btynzep0379c1ekxfffVV8/MLMekpk/5sPj4tzOW60KS1xdec\nZia5LSZmkLndQ03aYN7et5qXV1Nr1GhO8bqIMi+vFsXXmSdMCrYmTcLtl788/2tIcnKKud0Dix/v\nO6xVq/b21Vdf1ejcqmP16jXWuHELky4seT15eQWaNKh4jd1kUrBJ3U1ab02a9LZGjZqbtMqkp83P\nr7Vt3rzZzMzy8/PtkksutyZNphY/38nWp0+s5efne6zeqVOvL358ni9+rc03aYP5+g61Fi06mK/v\nxOLn5DoLD+9b4Wu1Ijt27Ci+dqw06Xlzu8NszZoXzjk+JyfH2rXrZt7eRcf380uwUaMmWXZ2trVu\n3dG8vW8zab253UNs8uQZlR57woRk8/MbVry2brFWrdqZv39Lc7n+YNJac7u72+9+t9jWrHnB3O6w\n4nNfaX5+LWzHjh3n9fid9d5775mv7wUm9TRpYvFzfZVJ4SYtMbe7hY0YMcb8/IaYtN68vW+z1q07\nWnZ2dskczz77vLnd7UxabdIKc7tb2M6dO895zLy8POvV6+fWpMn04udsikVHD7JrrrnB3O644uvN\n7Sa1Nl/fETZixFgzM8vIyDCXK8CkW4vH9LPOnSPP63z/8Y9/mL9/C5OWmvSiud0X29Klf7S5c28x\nt/tnJq0zL697rHnzNmWy1Qsv/MX8/M6+19xWfD1fWbx9oTVu3NQ+/vjjkvEHDhywgICW5nI9XPzc\nRdgDDzx0XrWetWXLFvPza23Sn+1cue7LL7+0Fi3CrFGjBcXrLdbat+9mUkTxe85vTfIz6UaTHjcv\nL3+TLih5rUsB9oc//KH4sVlS/Nh0tUce+b8Kazp58qQFBISYNK94zQyyakbcStU6JCclJdn27dtL\ntgcPHmy7d+8ufyDJJDNplQ0bNq6G5XrOqFFTTHqsuCYz6QXr3z/hnOP794836YVS45eb1L74Qnj2\ntr0WEtKpymO/8sor5uUVWvxmfHbf/7PRo6eUG/vHP/7R/Pymlhp3xPz8Amt17tX15ZdfWuPGzUw6\nXXzsQnO5epv0h5J6XK477OabqxcCAgJamPTvkn2bNJlpjzzySIVjt27dak2b9jOpsHj891YUFL8s\n3r7frrtujidPt0qzZt1k0r2lnos37OKLLy0zpm/fwVYU5s6OWWpXXjndpk693qTFpW7fZNLlJv3c\nikLw2duvsAkTJlhsbGLxBf7s7StMmlz8899M6mhSiEm5Jc9N06a9yrwWz9q5c6f5+oYVH+/sfKdM\n8jXp6+LtDJP8LCsrq0aPzcCB8SZdXOr5yjMvrwssIyOjyn3z8/PN27uJSV+VOr+LTCoo3s43Kcyk\nj4vXYpBJR60oxP6n5Jz8/cfaU089VW7+Nm26Fs9ZNM7L6xabNesX5na3NSmv5PErCp0flXqMeha/\nzv97jZDiTPIutQ7N/P0n2JNPFv1l6dFHHzU/v6tL7XPUfH2b1egxHTZsnBUFvrNz/dmkIaW25xc/\nLm6TckrdHmNFQdpMGmpFfzk4e98fTRp/3teQ3Nxca9SosUnflMwVEJBkzz//fI3OrToiIwdY0V+C\nzr6evi4+1+9LnU+sFb3RnjDpCiv6i8DZ+561uLhRZmb24Ycfmr9/x1JrqsD8/TvZvn37PFJr2cfn\nZcfz9JFJgWXWWkBAj2qHyMmTZ5r0cKn5NlifPgPPOX7z5s3WtGlsmde6j4+/rVq1ypo2HVHq9m+t\nUaPG9v3331c4T05Ojnl7+5r0Xck+jRt3NC+vm0rN8YGFhHSyPn0GWlEwOXv7wzZ58swaPZZTplxr\nRaEvrPi1b8XPW1eTdpu00IquXd+WWovD7cUXXyyZo1evWJM2l6rnQUtOTjnnMXfv3m0BAV3LXHP8\n/EKLn9PsUvOMMmmVNWkSZFlZWXbDDTeYNLDU/SdNanTOx7QiN9/8a5PuKDXHDgsL625NmjQ16VjJ\n7X5+U+yxxx4r2e+SSwZZUTA3K/pw4pEya0S62O64486S8XfeucC8vH5Vaswea92683k+O0UGD77C\npKdLzVU+161atcr8/ceVGnOi+Hk7VOq25OLX+Nnr7fpS9y2xFi3amct1W6nb0i00NKLCmtavX2/S\n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\n",
"text": [
"<matplotlib.figure.Figure at 0xb70c4e0>"
]
}
],
"prompt_number": 126
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h1>Improving the accuracy</h1>\n",
"<p>We can improve the accuracy by splitting the original set into m subsets, applying the above naive algorithm over each of the m subsets, and averaging the results together.</p>\n",
"<p>Below we do so for the set of 1000 hashed UUIDs, where we split it up into 10 subsets of 100 each, average the resulting min hash values, exponentiate that average, and then multiply that back by 10 to get the cardinality of the whole set.</p>"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"betterm1000=mean([min(h1000[x:x+100]) for x in xrange(10)])"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 132
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"10*pow(10,-math.log10(betterm1000))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 136,
"text": [
"358.90695792638485"
]
}
],
"prompt_number": 136
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<p>As you can see, this resulted in a result that is off by a factor of 3, instead of off by a factor of 7 as before.</p><p>There are even more clever and accurate ways to average the mins, such as using a geometric average, or the ultimate, the HyperLogLog algorithm for averaging as described in <a href=\"http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf\">HyperLogLog: the analysis of a near-optimal cardinality estimation algorithm</a>."
]
},
{
"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