{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# 2A.algo - Plus proches voisins en grande dimension - correction\n", "\n", "La m\u00e9thodes des [plus proches voisins](https://fr.wikipedia.org/wiki/Recherche_des_plus_proches_voisins) est un algorithme assez simple qui devient tr\u00e8s lent en grande dimension. Ce notebook propose un moyen d'aller plus vite (ACP) mais en perdant un peu en performance. "]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"data": {"text/html": ["
run previous cell, wait for 2 seconds
\n", ""], "text/plain": [""]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["from jyquickhelper import add_notebook_menu\n", "add_notebook_menu()"]}, {"cell_type": "code", "execution_count": 2, "metadata": {"collapsed": true}, "outputs": [], "source": ["%matplotlib inline"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Q1 : k-nn : mesurer la performance"]}, {"cell_type": "code", "execution_count": 3, "metadata": {"collapsed": true}, "outputs": [], "source": ["import time\n", "from sklearn.datasets import make_classification\n", "from sklearn.neighbors import KNeighborsClassifier\n", "\n", "def what_to_measure(n, n_features, n_classes=3, n_clusters_per_class=2, n_informative=8,\n", " neighbors=5, algorithm=\"brute\"):\n", " datax, datay = make_classification(n, n_features=n_features, n_classes=n_classes, \n", " n_clusters_per_class=n_clusters_per_class, \n", " n_informative=n_informative)\n", " model = KNeighborsClassifier(neighbors, algorithm=algorithm)\n", " model.fit(datax, datay)\n", " t1 = time.perf_counter()\n", " y = model.predict(datax)\n", " t2 = time.perf_counter()\n", " return t2 - t1, y"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"data": {"text/plain": ["0.10705330522077405"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["dt, y = what_to_measure(2000, 10)\n", "dt"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### dimension"]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["nf=10 dt=0.6019994840499943 dt2=0.4292384048532486\n", "nf=20 dt=0.5500524838884142 dt2=0.7831398125750371\n", "nf=50 dt=0.6259959000542419 dt2=1.5448688850936674\n", "nf=100 dt=0.6438388418700143 dt2=4.1738660655414535\n", "nf=200 dt=0.6644507680583498 dt2=None\n", "nf=500 dt=0.7658491664009883 dt2=None\n", "nf=1000 dt=0.8855807775832769 dt2=None\n", "nf=2000 dt=1.2180050749569489 dt2=None\n", "nf=5000 dt=2.158468552926159 dt2=None\n", "nf=10000 dt=3.9253579156251845 dt2=None\n"]}], "source": ["x = []\n", "y = []\n", "ys = []\n", "for nf in [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]:\n", " x.append(nf)\n", " dt, _ = what_to_measure(5000, n_features=nf)\n", " y.append(dt)\n", " if nf <= 100:\n", " dt2, _ = what_to_measure(5000, n_features=nf, algorithm=\"ball_tree\")\n", " else:\n", " dt2 = None\n", " ys.append(dt2)\n", " print(\"nf={0} dt={1} dt2={2}\".format(nf, dt, dt2))"]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 7, "metadata": {}, "output_type": "execute_result"}, {"data": {"image/png": "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\n", "text/plain": [""]}, "metadata": {}, "output_type": "display_data"}], "source": ["import matplotlib.pyplot as plt\n", "fig, ax = plt.subplots(1, 1)\n", "ax.plot(x, y, \"o-\", label=\"brute\")\n", "ax.plot(x, ys, \"o-\", label=\"ball_tree\")\n", "ax.set_xlabel(\"number of features\")\n", "ax.set_ylabel(\"prediction time in seconds\")\n", "ax.legend()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### observations"]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["nobs=1000 dt=0.04316123279656381 dt2=0.29295767748226\n", "nobs=2000 dt=0.09993351118991356 dt2=1.391681116032256\n", "nobs=5000 dt=0.6326372748990323 dt2=9.683458350469117\n", "nobs=10000 dt=2.956841532632261 dt2=None\n", "nobs=12000 dt=4.304105121060601 dt2=None\n", "nobs=15000 dt=6.1131095943392495 dt2=None\n", "nobs=17000 dt=7.52556105612517 dt2=None\n", "nobs=20000 dt=15.684603238001102 dt2=None\n"]}], "source": ["x = []\n", "y = []\n", "ys = []\n", "for nobs in [1000, 2000, 5000, 10000, 12000, 15000, 17000, 20000]:\n", " x.append(nobs)\n", " dt, _ = what_to_measure(nobs, n_features=200)\n", " y.append(dt)\n", " if nobs <= 5000:\n", " dt2, _ = what_to_measure(nobs, n_features=200, algorithm=\"ball_tree\")\n", " else:\n", " dt2 = None\n", " ys.append(dt2)\n", " print(\"nobs={0} dt={1} dt2={2}\".format(nobs, dt, dt2))"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 9, "metadata": {}, "output_type": "execute_result"}, {"data": {"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEKCAYAAAAfGVI8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl8FPX9+PHXmySQg0CAoEA4wiGgHHJEQUEFFUXFimi9\nW6+K1dajfrVqrdr6s9aqtVWrIChq61FQEaX1QiuggEggyCn3lQASAiRA7uT9+2MmuMRkszk2s5t9\nPx+PfezuZ2Zn3pkk896Z+cz7I6qKMcaYyNXM6wCMMcZ4yxKBMcZEOEsExhgT4SwRGGNMhLNEYIwx\nEc4SgTHGRDhLBMYYE+EsERhjTISzRGCMMREu2usAApGcnKypqaleh2GMMWFl6dKle1W1fU3zhUUi\nSE1NJT093eswjDEmrIjItkDms1NDxhgT4YKWCERkmojsEZFVldpvE5HvRGS1iDwRrPUbY4wJTDCP\nCF4Fxvo2iMho4CLgRFXtBzwVxPUbY4wJQNCuEajqfBFJrdR8C/C4qha58+yp6/JLSkrIzMyksLCw\n7kFGoNjYWDp37kxMTIzXoRhjQkRjXyzuDZwmIn8CCoG7VXVJVTOKyERgIkDXrl1/ND0zM5PExERS\nU1MRkSCG3HSoKjk5OWRmZtK9e3evwzHGhIjGTgTRQFtgOHASMENEemgVo+Oo6hRgCkBaWtqPphcW\nFloSqCURoV27dmRnZ3sdijGmBrMysnjyk3XsPFBAp6Q47jm3D+MHpwRlXY2dCDKBme6O/xsRKQeS\ngTrtmSwJ1J5tM2NC36yMLO6fuZKCkjIAsg4UcP/MlQBBSQaN3X10FjAaQER6A82BvY0cgzHGhLQn\nP1l3JAlUKCgp48lP1gVlfcHsPvoWsAjoIyKZInIjMA3o4XYp/TdwbVWnhcLF1q1b6d+/f50/v3z5\ncj788MMGjMgY0xTsPFBQq/b6CmavoSurmXRNsNbpT2Oeb/NVVlZGVFRUldOWL19Oeno6559/ftDj\nMMaEj45Jsew88OMekZ2S4oKyvoi4s7jifFvWgQKUH863zcrIqveyS0tLufbaaxk4cCCXXnop+fn5\npKam8sgjjzBy5EjefvttRo0adaRExt69e0lNTaW4uJiHHnqI6dOnM2jQIKZPn87hw4e54YYbOPnk\nkxk8eDDvv/9+veMzxoSfs/oe86O2uJgo7jm3T1DWFxa1hmryx9mrWbMzr9rpGdsPUFxWflRbQUkZ\nv31nBW99s73Kz5zQqRUPX9ivxnWvW7eOl19+mREjRnDDDTfwwgsvAE5//a+++gqAyZMn/+hzzZs3\n55FHHiE9PZ1//OMfAPzud7/jzDPPZNq0aRw4cICTTz6Zs88+m4SEhBrjMMY0DarKkq37OTaxBVFR\nwq4DhU2u15AnKieBmtpro0uXLowYMQKAa665hmeffRaAyy+/vNbL+vTTT/nggw946innhuvCwkK2\nb9/O8ccfX+84jTHhYe76bL7bfZCnfnoilw7t3CjrbBKJoKZv7iMe/x9ZVVxkSUmKY/rNp9Rr3ZW7\nY1a89/0WHx0dTXm5k3T83Qmtqrz77rv06ROcwz9jTOibPHcTHVvH8pMTOzXaOiPiGsE95/YhLubo\nC7YNdb5t+/btLFq0CIA333yTkSNH/mie1NRUli5dCsA777xzpD0xMZGDBw8eeX/uuefy3HPPUdGR\nKiMjo97xGWPCx7Lt+1m8ZR83juxO8+jG2z1HRCIYPziFP08YQEpSHIJzJPDnCQMa5Hxb3759ee21\n1xg4cCD79+/nlltu+dE8d999N5MmTeLUU08lJyfnSPvo0aNZs2bNkYvFDz74ICUlJQwcOJB+/frx\n4IMP1js+Y0z4mDx3E63jYrjy5B+X1QkmCYdu/GlpaVp5YJq1a9faufM6sm1nTOjZuOcQY/42j9tG\n9+Kucxrm9LCILFXVtJrmi4gjAmOMCXVT5m+iRXQzrj01tdHXbYnAGGM8tiu3gPcysrgsrQvtWrZo\n9PVbIjDGGI9N+2oL5Qo3ndbDk/VbIjDGGA/l5pfw5uLtjBvYkS5t4z2JwRKBMcZ46PXF2zhcXMbN\np/f0LAZLBMYY45HCkjKmfbWFUX3ac0KnVp7FYYnAGGM88vbSTHIOF/PLM7w7GoBISgQrZsDf+sMf\nkpznFTPqvcjajkdw3XXXHbmz2LciaVUee+yxesdnjAldpWXlTJ2/mUFdkhjWva2nsURGIlgxA2bf\nDrk7AHWeZ9/eIMkgWKpLBKp6pG6RMSZ8fbhqN9v35XPLqJ6eDyEbtKJzIjINGAfsUdX+lab9H/AU\n0F5V6z9U5Uf3we6V1U/PXAJlRUe3lRTA+7+Gpa9V/ZkOA+C8x2tcdcV4BBkZGfTu3Zt//vOfPPXU\nU8yePZuCggJOPfVUXnzxxVr9ou+77z4KCgoYNGgQ/fr1409/+hPnnXceo0ePZtGiRcyaNYt169bx\n8MMPU1RURM+ePXnllVdo2bIlS5cu5a677uLQoUMkJyfz6quv0rFjx4DXbYwJPlVl8txN9GyfwJjj\nj/U6nKAeEbwKjK3cKCJdgHOAqgcCCIbKSaCm9lpYt24dEydOZMWKFbRq1YoXXniBX//61yxZsoRV\nq1ZRUFDAf/7zn1ot8/HHHycuLo7ly5fzxhtvHFnPz3/+czIyMkhISODRRx/ls88+Y9myZaSlpfH0\n009TUlLCbbfdxjvvvMPSpUu54YYbeOCBB+r9MxpjGtaXG/ayZlceN5/ek2bNvD0agOAOVTlfRFKr\nmPQ34LdAww2/VdM397/1d08LVdK6C1z/33qtuqrxCLp3784TTzxBfn4++/bto1+/flx44YX1Wk+3\nbt0YPnw4AF9//TVr1qw5st7i4mJOOeUU1q1bx6pVqxgzZgzgDJNpRwPGhJ5JczfRoVUsFw1uvFLT\n/jTqeAQichGQparfNuo5sbMecq4JlPiMSRAT57TXU1XjEdx6662kp6fTpUsX/vCHP/gdgyBQvuMb\nqCpjxozhrbfeOmqelStX0q9fvyNlsY0xoefbHQdYtDmHB84/nhbRVY9n3tga7WKxiMQDvwMC2vuK\nyEQRSReR9Ozs7PqtfOBlcOGzzhEA4jxf+KzTXk/VjUeQnJzMoUOHjhp/oDZiYmIoKSmpctrw4cNZ\nsGABGzduBODw4cOsX7+ePn36kJ2dfSSekpISVq9eXaf1G2OCY/K8TbSKjebKYY1batqfxjwi6Al0\nByqOBjoDy0TkZFXdXXlmVZ0CTAGnDHW91z7wsgbZ8VdWMR7BzTffzHHHHcctt9zC/v37GTBgAKmp\nqZx00kl1Wu7EiRMZOHAgQ4YM4U9/+tNR09q3b8+rr77KlVdeSVGRc53j0UcfpXfv3rzzzjvcfvvt\n5ObmUlpayp133km/fjWPvWyMCb7N2Yf4ePVubh3Vk5YtQmeAyKCOR+BeI/hP5V5D7rStQFogvYZs\nPIKGZdvOGG/c9+4K3svI4qt7z6R9YvCrjHo+HoGIvAUsAvqISKaI3BisdRljTKjbk1fIzGVZ/DSt\nc6MkgdoIZq+hK2uYnhqsdYeTYcOGHTm9U+Ff//oXAwYM8CgiY0wwvLxgC6Xl5Uw8zdtyElUJnZNU\ndaCqnt+RV1+LFy9u1PWFw9CkxjQ1uQUlvPH1di4Y2Imu7bwpNe1P2JaYiI2NJScnx3ZstaCq5OTk\nEBsb63UoxkSUNxZv41BRKTef7s3AMzUJ2yOCzp07k5mZSb27lkaY2NhYOnfu7HUYxkQMp9T0Vk47\nLpn+Ka29DqdKYZsIYmJi6N69u9dhGGOMX+8uy2TvoSJuGTXI61CqFbanhowxJtSVlStT52/mxM6t\nOaVHO6/DqZYlAmOMCZKPV+1ma04+vzzD+1LT/lgiMMaYIFBVJs3bSI/kBM7p18HrcPyyRGCMMUGw\nYGMOq7LymHh6D6JCoNS0PzUmAhG5Q0RaieNlEVkmIuc0RnDGGBOuJs/bxDGJLbh4SIrXodQokCOC\nG1Q1D2cwmfbA9UDNQ3cZY0yEWpmZy1cb93LjyO4hU2ran0ASQcUxzfnAK6r6rU+bMcaYSibP20Ri\nbDRXhVCpaX8CSQRLReRTnETwiYgkAjZ6ujHGVGHr3sN8tGoX1wzvRmJsjNfhBCSQG8puBAYBm1U1\nX0Ta4ZweMsYYU8mULzcTHdWM60ekeh1KwKpNBCIypFJTj1DuB2uMMV7bc7CQd5ZmcunQzhyTGD41\nvfwdEfzVfY4FhgIrcK4NDAQWAyODG5oxxoSXVxZspbSsnImnhWZxuepUe41AVUer6mhgGzBUVdNU\ndSgwGNjYWAEaY0w4yCss4fVF2zivf0dSkxO8DqdWArlY3FdVV1a8UdVVONcM/BKRaSKyR0RW+bQ9\nKSLficgKEXlPRJLqFrYxxoSWNxdv52BRKb88I/QGnqlJIIlgrYi8JCKj3MdUYG0An3sVGFupbQ7Q\nX1UHAuuB+2sVrTHGhKCi0jKmfbWFkb2SGdA5NEtN+xNIIrgeWA3c4T7WEECvIVWdD+yr1Papqpa6\nb78GrDC+MSbsvbcsiz0Hi8LyaAAC6D6qqoXA39xHQ7oBmN7AyzTGmEZVVq68OH8zA1JaM6JX6Jaa\n9ieQWkMjRGSOiKwXkc0Vj/qsVEQeAEqBN/zMM1FE0kUk3UYhM8aEqk9X72bL3sMhX2ran0BuKHsZ\n+A2wFCir7wpF5DpgHHCW+hlwWFWnAFMA0tLSbGBiY0zIUVUmz9tEart4xvYP7VLT/gSSCHJV9aOG\nWJmIjAV+C5yhqvkNsUxjjPHKos05fJuZy2MXDwj5UtP+BJIIvhCRJ4GZQFFFo6ou8/chEXkLGAUk\ni0gm8DBOL6EWwBz3EOprVf1l3UI3xhhvTZq7ieSWLZgQBqWm/QkkEQxzn9N82hQ409+HVPXKKppf\nDjAuY4wJaauycvlyw15+O7YPsTGhX2ran0B6DY1ujECMMSacvDh/M4ktorlmeDevQ6m3QHoNtRaR\npyt68IjIX0Uk/O6YMMaYBrIt5zD/XbGTq4Z3pVWYlJr2J5AbyqYBB4HL3Ece8EowgzLGmFA29cvN\nRDdrxo0junsdSoMI5BpBT1W9xOf9H0VkebACMsaYUJZ9sIi30zO5ZGgKx7QKn1LT/gRyRFAgIkdK\nTovICKAgeCEZY0zoenXhForLyrkpzEpN+xPIEcEtwGs+1wX2A9cFLSJjjAlRh4pK+deibYzt14Ee\n7Vt6HU6DCaTX0HLgRBFp5b7PC3pUxhgTgt5avJ28wvAsNe1PIL2GHhORJFXNU9U8EWkjIo82RnDG\nGBMqikrLeOmrzZzasx0ndmlaQ6kEco3gPFU9UPFGVfcD5wcvJGOMCT3vZ+zk+7zwLTXtTyCJIEpE\nWlS8EZE4nDIRxhgTEcrLlcnzN9GvUytOOy7Z63AaXCAXi98APheRinsHrgdeC15IxhgTWuas/Z7N\n2Yd57srBYVtq2p9ALhb/RUS+Bc52m/6fqn4S3LCMMSY0qCqT5m6ia9t4zgvjUtP+BHJEAM4YxaWq\n+pmIxItIoqoeDGZgxhgTChZv2cfyHQf4f+P7Ex0VyNn08BNIr6GbgHeAF92mFGBWMIMyxphQMXne\nJpJbNuenQ5vuEOuBpLdfASNwagyhqhuAY4IZlDHGhII1O/OYuy6b60d0D/tS0/4EkgiKVLW44o2I\nROOMR2CMMU3ai/M3kdA8imuGhX+paX8CSQTzROR3QJyIjAHeBmbX9CERmSYie0RklU9bWxGZIyIb\n3Oc2dQ/dGGOCZ8e+fP6zYhdXD+9G6/jwLzXtTyCJ4D4gG1gJ3Ax8CPw+gM+9CoytYlmfq+pxwOfu\ne2OMCTlTv9xMM4EbmkipaX8C6T5aDkwFpopIW6CzqtZ4akhV54tIaqXmi3DGMQbnXoS5wL2Bh2uM\nMcGXc6iIGek7uHhwCh1aN41S0/4E0mtoroi0cpPAcuAVEXm6jus7VlV3ua93A8fWcTnGGBM0ry3c\nSlFpORNPb3rlJKoSyKmh1m7F0QnAK6o6lB9uLqsz96ii2iMLEZlYMTxmdnZ2fVdnjDEBOVxUymuL\ntnHOCcfS65imU2ran0ASQbSIdMQZpvI/9Vzf9+6ycJ/3VDejqk5R1TRVTWvfvn09VxuBVsyAv/WH\nPyQ5zytmeB2RMWHhrW+2k1tQ0iSLy1UnkETwCPAJsFFVl4hID2BDHdf3AXCt+/pa4P06Lsf4s2IG\nzL4dcncA6jzPvt2SgTE1KC4t5+WvtjC8R1sGd42cTo01JgJVfVtVB6rqre77zZXGMK6SiLwFLAL6\niEimiNwIPA6MEZENOKeXHq9f+KZKnz8CJZVGEy0pcNqNMdX64Nud7MotjKijAQi81lCtqeqV1Uw6\nK1jrNK7czNq1G2OcUtPzNnF8x1ac0TuyTkc3zQpKka51NTVRqms3xvD5d3vYuOcQvzyjR5MsNe2P\nJYKm6KyHQCr9amPinHZjzI84paY30rlNHBcM6Oh1OI2uxlND7uhklwCpvvOrqp1wDlUdTwQthxat\noOigcyRw1kMw8DKvIzMmJC3Zup9l2w/wyEX9mmypaX8CuUbwPpALLAWKghuOaRALn4PoWLg9AxKa\n3rB6xjS0yfM20TahOT8d2sXrUDwRSCLorKqVawaZUHVwN6yYDoN/ZknAmAB8tzuP/323h/8b05u4\n5k231LQ/gRwDLRSRAUGPxDSMxZOhvBRO+ZXXkRgTFl6ct5n45lH87JSmXWran0COCEYC14nIFpxT\nQ4JTIWJgUCMztVd0EJZMg+MvhHaR1Q/amLrI3J/PB9/u5LpTU0mKb+51OJ4JJBGcF/QoTMNY+hoU\n5cKIO7yOxJiw8NKXW2gm8IvTmn6paX+qTQQi0sotNmeD1IeDshL4ehJ0GwkpQ72OxpiQt+9wMdOX\n7OCiQSl0bB3ndTie8ndE8CYwDqe3kOKcEqqgQI8gxmVqa9VMyMuEcXWtEG5MZHlt4VYKSsr45Rm2\nK6s2EajqOPc5so+ZwoEqLHgG2h8PvcZ4HY0xIS+/uJTXFm1lzAnH0uuYRK/D8Vzk3TnRFG36HPas\nhlNvg2b2KzWmJtOX7OBAfmSVmvbH9hpNwYJnILEjDPip15EYE/JKysp56cstnJzalqHdIqfUtD+W\nCMLdzuWwZT4MvwWiI7f7mzGBmv3tTrIOFHDLKDsaqBBQIhCRkSJyvfu6vYjYdYNQsfBZaJ4IQ6/z\nOhJjQl5Fqem+HRIZ1SeySk37E8jg9Q8D9wL3u00xwOvBDMoEaP9WWP0epF0Psa29jsaYkPfFuj2s\n//4QN0dgqWl/AjkiuBj4CXAYQFV3AnaZPRQsegEkyjktZIyp0eR5m0hJimPcwE5ehxJSAkkExaqq\nOPcOICIJ9V2piPxGRFaLyCoReUtEYuu7zIiTvw8y/uWUlm5lf9TG1GTptn0s2bqfm07rTkwElpr2\nJ5CtMUNEXgSSROQm4DNgal1XKCIpwO1Amqr2B6KAK+q6vIi15CUoyXe6jBpjajRp7mbaxMdw2UmR\nWWranxprDanqUyIyBsgD+gAPqeqcBlhvnIiUAPHAznouL7KUFMDiF+G4c+CY472OxpiQt/77g3y2\n9nvuPPs44psHbaj2sBXQFlHVOSKyuGJ+EWmrqvvqskJVzRKRp4DtQAHwqap+Wnk+EZkITATo2rVr\nXVbVdC1/E/L3WnE5YwL04rzNxMVEce0pqV6HEpIC6TV0s4jsBlYA6Ti1h9LrukIRaQNcBHQHOgEJ\nInJN5flUdYqqpqlqWvv21s3riPIyWPQP6DQEuo3wOhpjQt7OAwW8vzyLK07uQpsEu9emKoEcEdwN\n9FfVvQ20zrOBLaqaDSAiM4FTsS6pgfnuP7BvM/z0NbDub8bU6KUvtwDwi9OsuFx1AkkEm4D8Blzn\ndmC4iMTjnBo6i3ocYUQUVVjwLLTp7gw+Y4yp0qyMLJ78ZB07DxQAMLRbEilJkV1q2p9AEsH9OMNV\nLsZn8HpVvb0uK1TVxSLyDrAMKAUygCl1WVbE2b4IstLhgr9Cs8gcW9WYmszKyOL+mSspKCk70rYy\nK49ZGVmMH5ziYWShK5BE8CLwP2AlUN4QK1XVh4GHG2JZEWXBMxDfDgZd7XUkxoSsJz9Zd1QSACgq\nLefJT9ZZIqhGIImgVFXvCnokxr8938H6j2HU/RBjh7jGVKfidFCg7SawG8q+EJGJItJRRNpWPIIe\nmTnawucgOg5OusnrSIwJSarK/777nqhmVXei6GTXCKoVyBHBVe7z/T5tNlRlY8rbBSumOxVGE9p5\nHY0xIWf1zlwe+3AtCzbmkNyyOXkFJRSX6ZHpcTFR3HNuHw8jDG2B3FlsJae9tngyaBmc8iuvIzEm\npOzOLeSpT9fx7rJMkuJi+MOFJ3DVsG58uHLXkV5DnZLiuOfcPnZ9wI9qE4GInKmq/xORCVVNV9WZ\nwQvLHFGYB+nT4ISLoK3lZGMADheV8uL8zUydv5mycuWm03rwq9G9aB0XA8D4wSm2468Ff0cEZ+D0\nFqqqw7oClggaw7LXoCgPTq1Tb11jmpSycuXt9B38dc56sg8WMW5gR+4d25cubeO9Di2sVZsI3C6e\nAI+o6hbfaTZCWSMpLXbGHEg9DVKGeB2NMZ6atz6bx/67lnXfH2Rotza8+LOhDOlqYw43hEAuFr8L\nVN4LvQMMbfhwzFFWvQsHd8JPnvU6EmM8893uPB778Dvmr8+ma9t4Xrh6COf172AjjDUgf9cI+gL9\ngNaVrhO0AmwgmWBTdcYjPuYE6HW219EY0+j25BXy9Jz1zEjfQWJsDL+/4Hh+dko3WkTbXfUNzd8R\nQR9gHJDE0dcJDgLWmT3YNn4Ge9bA+MlWXM5ElPziUqbO38KL8zdRUlbO9SO6c9uZvUiKt8qhweLv\nGsH7wPsicoqqLmrEmAw45SQSO0H/S7yOxJhGUVauzFyWyVOfruP7vCLO69+Be8f2JTW53qPjmhoE\nch+BJYHGlrUMtn4J5zwK0fYtyDR9Czbu5dH/rmXtrjwGdUni+auGkJZqBQwai43ZFooWPgstWsGQ\na72OxJig2vD9Qf780Xf877s9dG4Tx3NXDmbcwI52IbiRWSIINfu2wJr3nfsGYlt5HY0xQZF9sIi/\nf7aefy/ZQXzzKH53fl9+fkoqsTF2IdgLNSYCEWkBXAKk+s6vqo8EL6wItuh5kCgY9kuvIzGmwRWW\nlPHyV1uYNHcThSVl/Gx4N24/6zja2hCSngrkiOB9IBdnrOKiGuY19XE4BzJeh4GXQ6uOXkdjTJ35\njhDWKSmOu8f0RsUZK2BXbiHnnHAs953Xlx7tW3odqiGwRNBZVcc25EpFJAl4CeiPU67iBrsoDSyZ\nCqUFcOptXkdiTJ1VHiEs60ABd73zLaowsHNr/nb5IIb3sCq6oSSQRLBQRAao6soGXO8zwMeqeqmI\nNAesUEhxPnwzBXqPhWP6eh2NMXVW1QhhqtAmPoZZt46gWTXjBRjvBJIIRgLXicgWnFNDAqiqDqzL\nCkWkNXA6cB3OgoqB4rosq0n59k3Iz4ERd3gdiTH1Ut1IYAfySywJhKhAEsF5DbzO7kA28IqInIhz\n7eEOVT3cwOsJH+VlsPAfkJIGXU/xOhpjak1Vmb9hL89/sRGtZh4bISx01ThUpapu44cyExcCSW5b\nXUXjFLGbpKqDgcPAfZVncofHTBeR9Ozs7HqsLgysnQ37t8CI262chAkrZeXKhyt3Me65r7h22jfs\n2JfPhMGdiI05etdiI4SFtkC6j96BU1uoYvyB10Vkiqo+V8d1ZgKZqrrYff8OVSQCVZ0CTAFIS0ur\n7ktG+FN1ykm07QF9x3kdjTEBKSkrZ1ZGFpPmbWJz9mF6JCfwxCUDGT84hebRzTi9d5aNEBZGAjk1\ndCMwrOLUjYj8BVgE1CkRqOpuEdkhIn1UdR1wFrCmLstqErYtgJ3L4IKnoZndTGNCW0FxGdOXbGfq\nl1vIOlDACR1b8fxVQxjbv8NRg8bbCGHhJZBEIIBvF4Ayt60+bgPecHsMbQaur+fywteCZyE+GQZd\n5XUkxlQrr7CEfy3axrSvtpBzuJiTUtvw6MX9GdW7vZWDaAICSQSvAItF5D33/Xjg5fqsVFWXA2n1\nWUaTsGctbPgERj8AMXYhzYSevYeKeGXBFv65cBsHi0oZ1ac9t47qxcndrSBcUxJI9dGnRWQuTjdS\ngOtVNSOoUUWKhc9BTDyc9AuvIzHmKFkHCpg6fzP/XrKdotJyzh/QkVvO6En/lNZeh2aCwN8IZa1U\nNU9E2gJb3UfFtLaqui/44TVheTthxQxIuwHi7duVCQ2bsg8xee4m3svIAmDCkBRuPqMnPa0URJPm\n74jgTZwRypbCUV2DxX3fI4hxNX1fTwItg1Nu9ToSY1iVlcsLczfy0ardtIhuxjXDu3HT6T1Isb7/\nEcHfCGXj3OfujRdOhCjMhaWvQr+LoU2q19GYCPbNln08/8VG5q3PJjE2ml+N6sX1I1Jp17KF16GZ\nRhTIfQSfq+pZNbWZWlj6KhTlOWMOGNPIVJW567J5/ouNpG/bT7uE5vx2bB+uGd6NVrExXodnPODv\nGkEsTjG4ZBFpww9dRlsB1kG4rkqLndNC3U+HToO8jsZEkLJy5aNVu3j+i02s3ZVHSlIcf/xJPy5L\n60Jcc7uHJZL5OyK4GbgT6IRznaAiEeQB/whyXE3Xyrfh4C64yDahaRzFpeW8l5HJ5Hmb2bL3MD3a\nJ/DUT0/kokGdiImqscqMiQD+rhE8AzwjIrfVo5yE8aXqdBk9tj/0tDNrJrjyi0v59zc7mPrlZnbl\nFtI/pRWTrh7COf2OvgvYmEBuKCsXkSRVPQDgnia6UlVfCG5oTdCGOZC9Fi6eYsXlTNDkFpTwr0Vb\nmbZgK/sOFzOse1v+cslATjsu2e4CNlUKJBHcpKrPV7xR1f0ichNgiaC2FjwDrTpD/wleR2KaoOyD\nRbz81RZe/3obh4pKObPvMdw6qidpqXafivEvkEQQJSKiqgogIlGAjTRdW5lLYdtXcM6fIMp6ZpiG\ns2NfPlPmb2ZG+g5Kysq5YGAnbjmjJyd0auV1aCZMBJIIPgami8iL7vub3TZTGwufgRatYei1Xkdi\nmoiNew7YPxSVAAAZgklEQVTywtxNvL98J80ELhnSmZvP6En35ASvQzNhJpBEcC/Ozv8W9/0cnIHn\nTaD2bXYGnxlxB7RI9DoaE+ZWZB7ghS828cma3cRGR3Hdqan84rTudGxtdwGbugmk6Fw5MMl9mLpY\n9Dw0i4Zhv/Q6EhMmZmUcPbDL3ef0pkPrOF6Yu5EvN+ylVWw0t43uxXUjutM2wc7Umvrxd0PZDFW9\nTERWwo+HIa3r4PUR5/BeyHgdBl4OiR28jsaEgVkZWdw/cyUFJc4wIFkHCrjr7W9RheSWLbjvvL5c\nPawriXYXsGkg/o4I7nCfbfzE+vhmKpQWWjkJE7AnP1l3JAlUUIXWcTF8de9oYmPsLmDTsPzdULbL\nfa7PQPXVcnsfpQNZFQXumpzifPhmCvQ5H9r39joaEyayDhRU2Z5XUGJJwASFv1NDB6nilFAFVa1v\n37Q7gLU4tYuapuVvQME+OxowAVmZmcsTn3xX7fROVhLaBIm/I4JEABF5BNgN/Aun3tDVQL26vohI\nZ+AC4E/AXfVZVsgqK4VF/4DOJ0PX4V5HY0LY5uxD/HXOev67Yhdt4mMYP6gTH6/eTWFJ+ZF54mKi\nuOfcPh5GaZqyQLqPnquqw3zeTxKRxcAT9Vjv34HfUs+EEtLWfgD7t8I5j1o5CVOl3bmFPPP5Bmak\n76BFdDNuP7MXvzi9B61iY37Ua+iec/swfrAV/TXBEUgiKBORq4F/45wquhIo8/+R6onIOGCPqi4V\nkVF+5psITATo2rVrXVfnDVWnnES7Xs71AWN85OaXMGneJl5ZsIVyVX42vBu/Gt2L9ok/DAYzfnCK\n7fhNowkkEVwFPOM+FFjgttXVCOAnInI+EAu0EpHXVfUa35lUdQowBSAtLa3aaxUhaeuXsGs5jPs7\nNLOLe8aRX1zKKwu2MnneJg4VlXLxoBR+M6Y3XdrGex2aiXCB3FC2FbiooVaoqvcD9wO4RwR3V04C\nYW/Bs5DQHk680utITAgoKSvn30t28OznG8g+WMTZxx/D3ef2oW+HpttPwoSXQIaq7I1zV/Gxqtpf\nRAYCP1HVR4MeXTj6fjVsnANn/h5iYr2OxniovFyZvWInT89Zz7acfE5KbcOkq4dYNVATcgI5NTQV\nuAd4EUBVV4jIm0C9E4GqzgXm1nc5IWXhcxCTAGk3eh2J8YiqMm99Nk98vI41u/Lo2yGRV647iVF9\n2tt4ACYkBZII4lX1m0p/wKVBiie85WY5Q1GedBPE27e+SLR0236e+Pg7Fm/ZR9e28TxzxSAuHNiJ\nZjYimAlhgSSCvSLSE/fmMhG5FNgV1KjC1dcvOD2GTrnV60hMI1v//UGe/GQdc9Z8T3LLFjxyUT+u\nOKkrzaNtTGAT+gJJBL/C6b3TV0SygC04N5UZX4W5sPQ16HcxJIVZd1dTZzv25fP3zzYwMyOTls2j\nufuc3lw/ojsJLQL51zImNPj9axWRZkCaqp4tIglAM1U92DihhZn0V6D4IIywchKRYO+hIp7/YiNv\nfL0dBG46rQe3nNGTNlYS2oQhv4lAVctF5NfADFU93EgxhZ/SIvh6EvQYBR1P9DoaE0QHC0t46cst\nvPTlZgpKyrgsrQt3nH2cDQpjwlogx69zRORuYDpwJBmo6r6gRRVuVr4Nh3bDxTZ2T1NRucTDnWcf\nR15hKc9/sZF9h4s5f0AH7hrTh17HtPQ6VGPqTdwx6aufQWRLFc2qqj2CE9KPpaWlaXp6emOtrnbK\ny+GF4RDdHG7+0uoKNQGVB4YBp9qiAiN7JXPPuX04sUuSZ/EZEygRWaqqaTXNF8idxd0bJqQmasOn\nsHcdTJhqSaCJqHJgGKBdQnNe/8Wwqj9kTBgL5M7iWOBWYCTO/8OXwGRVLQxybOFh4bPQuovTW8iE\ntZKycuaty652YJh9h4sbOSJjGkcg1wj+CRwEnnPfX4UzNsFPgxVU2MhMh20L4Nw/Q5SNHxuOVJVV\nWXm8uyyT2d/uJOdwMc0Eyqs4Y2oDw5imKpBE0EdVfbvCfCEi3wYroLCy4BmITYIhP/c6ElNLu3IL\nmJWxk5nLMtmw5xDNo5ox5oRjmTAkhQP5xfx+1uqjTg/ZwDCmKQskEWSIyHBV/RpARIbhlKKObDmb\nYO1sOO0uaGE9R8LB4aJSPl61m5kZmSzclIMqpHVrw2MXD+CCAR1pHf/DUV1Us2Y2MIyJGIEkgmHA\nz0Vku/u+K/CdiKzE6T00MGjRhbJF/3BOB518s9eRGD/KypVFm3KYuSyTj1btpqCkjK5t47n9zOOY\nMCSFbu0SqvycDQxjIkkgiWBs0KMIN4eyYfmbzngDicd6HY2pwvrvDzJzWRazMrLYnVdIYmw04wen\ncMmQFIZ2a2NVQI3xEUj30W2NEUhY+WaKczfxqbd5HYnxsfdQER8s38l7GVmszMolqpkwqnd7Hhx3\nAmcdfwyxMTZanDFVscpYtVV8GJZMhb4XQPJxXkcT8QpLyvh87R5mLstk7vpsysqV/imteGjcCfxk\nUCeSW7aoeSHGRDhLBLWV8QYU7IdTrbicV1SV9G37mbksi/+s2MnBwlI6tIrlptN6MGFICr2PTfQ6\nRGPCSqMnAhHpgnNvwrE4N6hNUdVnGjuOOikrhUXPQZdh0NXuMG1s23IOM3NZFu9lZLF9Xz5xMVGc\n178DE4Z05pSe7YiywV+MqRMvjghKgf9T1WUikggsFZE5qrrGg1hqZ+37cGA7jH3c60giRm5+Cf9d\nuYuZyzJJ37YfETi1ZzvuOOs4xvbvYHX/jWkAjf5fpKq7cEc4U9WDIrIWSAFCOxGoOjeQtTsOep/n\ndTRNWklZOfPXZzNzWRZz1n5PcWk5vY5pyb1j+zJ+cCcr+WxMA/P065SIpAKDgcVVTJsITATo2jUE\nRvzaMh92fQsXPgvNbPjBhlZVqYe2Cc256uSuXDKkM/1TWlmXT2OCxLNEICItgXeBO1U1r/J0VZ2C\nM0QmaWlp/mtlN4aFz0LCMTDwcq8jaVKqKvVw9gnHMGFwZ87o056YKEu6xgSbJ4lARGJwksAbqjrT\nixhqZfcq2PgZnPkgxMR6HU3YO1xUyierdzNzWRYLNu1FFYZ2a8OfLu7PuAGdjir1YIwJPi96DQnw\nMrBWVZ9u7PXXycLnICYBTrrR60jClm+ph49X7ya/uIwubeO4/czjuHhwCqnJVZd6MMYEnxdHBCOA\nnwErRWS52/Y7Vf3Qg1hqlpsJq96BkydCXBuvowk7G74/yLuVSj1cNKgTE4Z0Js1KPRgTErzoNfQV\nzsh/oW3FDPj8Ecjd4bxPCoEL1mFi76EiZn+7k5nLfij1cEbv9vx+3PGcffyxVurBmBBjnbCrsmIG\nzL4dSnxGqvr8jxDfDgZe5l1cIayi1MN7GZnMXZdNqU+phwtP7ET7RCv1YEyoskRQlc8fOToJgPP+\n80csEfhQVZZu28+7PqUejm3VghtP686EwZ3p08FKPRgTDiwRVCU3s3btEWZ7Tj4zMzJ5LyOLbTlO\nqYex/TswYUgKp/ZMtlIPxoQZSwSV5e9zBpwpq2Kg8tadGz+eEJFbUMKHbqmHJVt/KPVw25lOqYeW\nVurBmLBl/72+cjbBGz+F8jKIan50MoiJg7Me8i42D1RV6qFn+wR+O7YP4wel2GDuxjQRlggqbF8M\nb13hvL7+Q6e43OePOKeDWnd2kkAEXB9QVVbvdEo9fLD86FIPE4akMCCltXX5NKaJsUQAsPo9mHkz\ntE6Bq9+Bdj2h6/CI2PFXqKrUw1nHH8OEIZ05o3d7mkdbqQdjmqrITgQVFUU/exi6DIcr3oSEdl5H\n1Wis1IMxBiI5EZSVwkf3QPo06DcBxk9qUnWEZmVk8eQn69h5oIBOSXHcc24fxg9Ooaxc+XpzDu8u\ny+TjVT+UerjNLfXQ3Uo9GBNxIjMRFB2Et6+HjXNg5G/gzIeaVGnpWRlZ3D9zJQUlZQBkHSjg3ndX\nMPvbnazZlceu3EISW1ipB2OMI/ISQd5OeOMy2LMGxv0d0q73OqIG9+Qn644kgQpFpeV8/t0ezux7\nDA9cYKUejDE/iKxEsHuV0z20KA+umgHHne11RPVyIL+YbTn5bM05fNRz1oGCKucXYNp1JzVukMaY\nkBc5iWDjZzDjOmiRCDd8DB0GeB1RjVSVnMPFbMs5zNa9+c5zzg/PuQUlR83fsXUs3drFE988ivzi\nsh8tz/r9G2Oq0nQTwZHqoZkQlwQFB+DY/nDVdKebaIgoL1f2HCxyv8377Oj35rN9Xz6HikqPzNtM\nIKVNHKntEhg3sCOp7RLo1i6e1OQEuraNP3Kqp/I1AoC4mCjuObdPo/98xpjQ1zQTQeXqoQX7QZrB\nsImeJIGycmXngQKf0zfODn97Tj7b9h2msKT8yLzRzYSubePp1i6ek7u3dXb07g6/c5v4gPrzjx/s\n/IxV9RoyxpjKRNX74YBrkpaWpunp6YF/4G/9fxhHwFfrLvCbVQEtorrul9UpKSsnc3+Bs6Pf6+7o\n9zk7/h378ikp+2E7t4huRrd28XRrl0C3tvF0S04g1d3hd2wdS7SN02uMaQAislRV02qaz6sxi8cC\nzwBRwEuq+niDrqCe1UOr6n55/8yVlJSVM6hLks95eufibMUF2rLyH3b2Cc2j6NYugb4dEjnnhA6k\nujv+1OR4jk2MpZlV6DTGhAgvxiyOAp4HxgCZwBIR+UBV1zTUOvLjOhBfsKvK9mYlZeQXl5FfXEpB\ncRmH3df5RWXkl5SRX1TKnz9a+6PulwUlZdzzzoqj2lrFRtM9OYFBXZK4aFAnZ0fv7vCTWza3vvnG\nmLDgxRHBycBGVd0MICL/Bi4CGiwRPFFyOb/VF4iXH6qH5mtz7su9mA8e/Lhey37mikFHdvhJ8c3r\nG6oxxnjOi0SQAviewM8EhlWeSUQmAhMBunat3XjBrx06mX3Nivlt9Aw6SQ47tR1PlF7GB+Ujuefc\nPsQ3jyKheTRxzaNIaBFFXEw0CS2iiG8eRXzzaC6ZtJBduYU/DjwpjosG2QVXY0zTErK9hlR1CjAF\nnIvFtflsp6Q4Pjgwkg+KRx7VnpIUx69G96rx8/eO7WvdL40xEcOL7ilZQBef953dtgZzz7l9iKtU\nPqE2O/Lxg1P484QBpCTFITgJ5M8TBlj3S2NMk+TFEcES4DgR6Y6TAK4ArmrIFTREP/rxg1Nsx2+M\niQiNnghUtVREfg18gtN9dJqqrm7o9diO3BhjAuPJNQJV/RD40It1G2OMOZrdwmqMMRHOEoExxkQ4\nSwTGGBPhLBEYY0yEC4vqoyKSDWzzOo5qJAN7vQ7CD4uvfiy++rH46q8+MXZT1fY1zRQWiSCUiUh6\nIGVevWLx1Y/FVz8WX/01Rox2asgYYyKcJQJjjIlwlgjqb4rXAdTA4qsfi69+LL76C3qMdo3AGGMi\nnB0RGGNMhLNEUImIdBGRL0RkjYisFpE73PY/iEiWiCx3H+f7fOZ+EdkoIutE5Fyf9rFu20YRua8B\nY9wqIivdONLdtrYiMkdENrjPbdx2EZFn3RhWiMgQn+Vc686/QUSubaDY+vhso+Uikicid3q9/URk\nmojsEZFVPm0Nts1EZKj7O9nofrZW45RWE9+TIvKdG8N7IpLktqeKSIHPtpxcUxzV/az1jK/Bfqci\n0l1EFrvt00WkVsP/VRPfdJ/YtorIcg+3X3X7ldD4G1RVe/g8gI7AEPd1IrAeOAH4A3B3FfOfAHwL\ntAC6A5twqqpGua97AM3deU5ooBi3AsmV2p4A7nNf3wf8xX19PvARIMBwYLHb3hbY7D63cV+3aeBt\nGQXsBrp5vf2A04EhwKpgbDPgG3decT97XgPEdw4Q7b7+i098qb7zVVpOlXFU97PWM74G+50CM4Ar\n3NeTgVvqG1+l6X8FHvJw+1W3XwmJv0E7IqhEVXep6jL39UFgLc7wmtW5CPi3qhap6hZgI864zEfG\nZlbVYqBibOZguQh4zX39GjDep/2f6vgaSBKRjsC5wBxV3aeq+4E5wNgGjuksYJOq+rsZsFG2n6rO\nB/ZVse56bzN3WitV/Vqd/8h/+iyrzvGp6qeqWuq+/RpnEKdq1RBHdT9rnePzo1a/U/eb65nAO8GI\nz13+ZcBb/pYR5O1X3X4lJP4GLRH4ISKpwGBgsdv0a/cwbZrPoWFVYzCn+GlvCAp8KiJLxRnbGeBY\nVd3lvt4NHOthfBWu4Oh/vlDZfhUaapuluK+DGesNON/yKnQXkQwRmScip/nEXV0c1f2s9dUQv9N2\nwAGfpNfQ2+804HtV3eDT5tn2q7RfCYm/QUsE1RCRlsC7wJ2qmgdMAnoCg4BdOIeaXhmpqkOA84Bf\nicjpvhPdbwSedgdzz/H+BHjbbQql7fcjobDNqiMiDwClwBtu0y6gq6oOBu4C3hSRVoEurwF/1pD+\nnfq4kqO/kHi2/arYrzTIcuvLEkEVRCQG55f1hqrOBFDV71W1TFXLgak4h7lQ/RjMQRubWVWz3Oc9\nwHtuLN+7h4cVh7h7vIrPdR6wTFW/d2MNme3no6G2WRZHn7ZpsFhF5DpgHHC1u6PAPeWS475einPe\nvXcNcVT3s9ZZA/5Oc3BOfURXaq83d5kTgOk+cXuy/arar/hZbqP+DVoiqMQ9n/gysFZVn/Zp7+gz\n28VARe+ED4ArRKSFOOMwH4dz0ebI2Mzut+Mr3HnrG1+CiCRWvMa5oLjKXXZFD4Jrgfd94vu52wth\nOJDrHop+ApwjIm3cQ/pz3LaGctS3sFDZfpU0yDZzp+WJyHD37+fnPsuqMxEZC/wW+Imq5vu0txeR\nKPd1D5xttrmGOKr7WesTX4P8Tt0E9wVwaUPG5zob+E5Vj5w28WL7Vbdf8bPcxv0bDPSqcqQ8gJE4\nh2crgOXu43zgX8BKt/0DoKPPZx7A+VaxDp8r9e7n1rvTHmig+Hrg9Lb4FlhdsVyc86yfAxuAz4C2\nbrsAz7sxrATSfJZ1A86FvI3A9Q24DRNwvuW19mnzdPvhJKVdQAnO+dMbG3KbAWk4O8JNwD9wb9as\nZ3wbcc4HV/wdTnbnvcT93S8HlgEX1hRHdT9rPeNrsN+p+3f9jfszvw20qG98bvurwC8rzevF9qtu\nvxISf4N2Z7ExxkQ4OzVkjDERzhKBMcZEOEsExhgT4SwRGGNMhLNEYIwxEc4SgQkrIjJXRII+xqyI\n3C4ia0XkjZrndm78EpF/BDuuAOIYLyIn+Lx/RETO9jImE/qia57FmKZBRKL1h3o2NbkVp//7lmDG\n5E8t460wHvgPsAZAVR9q8MBMk2NHBKbBiVPvfa2ITBWn9vqnIhLnTjvyjV5EkkVkq/v6OhGZJSKz\nRWSLiPxaRO5yC4N9LSJtfVZxjYgsFJFVInKy+/kEcQqffeN+5iKf5b4tIrOBT6uI9S53OatE5E63\nbTLODU4fiMhvKs0fKyKviFP3PUNERvtM7iIiH4tTb/9hn7j+KyLfuuu43G0fKk7Bs6Ui8on8UGZg\nrog8JiLzgAdEZJuINPNZ1g4RiRGRm0Rkibvcd0UkXkROxanv9KQ4dfZ7isirInKp+/mz3JhXutuq\nhdu+VUT+KCLL3Gl93fYz5Iea/Rni3tFumqCGupvUHvaoeODUey8FBrnvZwDXuK/n4t4lCSQDW93X\n1+HcKZkItAdyce8IBf6GU6Sr4vNT3den49aVBx7zWUcSzt2rCe5yM6niTlBgKM5dmwlAS5y7TQe7\n07ZSacwHt/3/gGnu677AdiDWXc8unDtF43Du8EzDuYt1qs/nWwMxwEKgvdt2uc8y5wIv+Mz/PjDa\nZ76X3NftfOZ5FLjNff0qcKnPtFdxSjfE4tyl3Ntt/6fPNt3q8/lbfdYxGxjhvm6JOzaCPZrew44I\nTLBsUdXl7uulOMmhJl+o6kFVzcZJBLPd9pWVPv8WHKlB30qckbvOAe4TZxSquTg7vq7u/HNUtapa\n9SOB91T1sKoeAmbilCz2ZyTwurv+74BtOAXLKtaTo6oF7rJGurGPEZG/iMhpqpoL9AH6A3PceH/P\n0QXDpld6fbn7+gqfaf1F5EsRWQlcDfSrIe4+OL+T9e7713ASaYWKImi+v6sFwNMicjuQpLU/TWXC\nhF0jMMFS5PO6DOdbMjhHChVfQGL9fKbc5305R/+tVq6Loji1WS5R1XW+E0RkGHC4VpHX3Y/iUtX1\n4gwzeD7wZxH5FKdi7GpVPaWa5fjG+wHwmHtqbCjwP7f9VWC8qn4rToXSUfWMvWJbl+Fua1V9XET+\n68b+tYic7SY/08TYEYFpbFtxdmjwQ7XJ2qo4zz4SpypjLk5VxtvcyouIyOAAlvMlMN49v56AU0Hz\nywA+c7W7jt44Rx0VyWeMOGPQxuFctF0gIp2AfFV9HXgKZzjFdUB7ETnFXU6MiFT5jd49UlkCPAP8\nR1XL3EmJwC5xShtf7fORg+60ytYBqSLSy33/M2Cevx9URHqq6kpV/QuQjnMqzDRBdkRgGttTwAwR\n+RlO1cW62C8iC4FWOJUYAf4f8HdghXtxdQtOHf9qqeoyEXkVp+olOOfGM2pY9wvAJPeUTClwnaoW\nufnnK5yKnL2AN1U1XZyB258UkXKcypi3qGqxewH3WRFpjfN/+HecaxRVmY5TkXOUT9uDOCNcbcM5\n/VSx8/83MNU9nXMk0apqoYhcD7wtTo3+JThjA/tzp3sxvNyN7aMa5jdhyqqPGmNMhLNTQ8YYE+Es\nERhjTISzRGCMMRHOEoExxkQ4SwTGGBPhLBEYY0yEs0RgjDERzhKBMcZEuP8PSoE5H46rvTgAAAAA\nSUVORK5CYII=\n", "text/plain": [""]}, "metadata": {}, "output_type": "display_data"}], "source": ["fig, ax = plt.subplots(1, 1)\n", "ax.plot(x, y, \"o-\", label=\"brute\")\n", "ax.plot(x, ys, \"o-\", label=\"ball_tree\")\n", "ax.set_xlabel(\"number of observations\")\n", "ax.set_ylabel(\"prediction time in seconds\")\n", "ax.legend()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Q2 : k-nn avec sparse features\n", "\n", "On recommence cette mesure de temps mais en cr\u00e9ant des jeux de donn\u00e9es [sparses](https://fr.wikipedia.org/wiki/Matrice_creuse). On utilise le jeu pr\u00e9c\u00e9dent et on lui adjoint des coordonn\u00e9es al\u00e9atoires et sparse. La premi\u00e8re fonction ``random_sparse_matrix`` cr\u00e9e un vecteur sparse."]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"data": {"text/plain": ["('% non null coefficient', 0.2, 'shape', (20, 20))"]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["import numpy\n", "import numpy.random\n", "import random\n", "import scipy.sparse\n", "\n", "\n", "def random_sparse_matrix(shape, ratio_sparse=0.2):\n", " rnd = numpy.random.rand(shape[0] * shape[1])\n", " sparse = 0\n", " for i in range(0, len(rnd)):\n", " x = random.random()\n", " if x <= ratio_sparse - sparse:\n", " sparse += 1 - ratio_sparse\n", " else:\n", " rnd[i] = 0\n", " sparse -= ratio_sparse\n", " rnd.resize(shape[0], shape[1])\n", " return scipy.sparse.csr_matrix(rnd)\n", "\n", "\n", "mat = random_sparse_matrix((20, 20))\n", "\"% non null coefficient\", 1. * mat.nnz / (mat.shape[0] * mat.shape[1]), \"shape\", mat.shape"]}, {"cell_type": "code", "execution_count": 10, "metadata": {"collapsed": true}, "outputs": [], "source": ["import random\n", "from scipy.sparse import hstack\n", "\n", "def what_to_measure_sparse(n, n_features, n_classes=3, n_clusters_per_class=2, n_informative=8,\n", " neighbors=5, algorithm=\"brute\", nb_sparse=20, ratio_sparse=0.2):\n", " datax, datay = make_classification(n, n_features=n_features, n_classes=n_classes, \n", " n_clusters_per_class=n_clusters_per_class, \n", " n_informative=n_informative)\n", " \n", " sp = random_sparse_matrix((datax.shape[0], (nb_sparse - n_features)), ratio_sparse=ratio_sparse)\n", " datax = hstack([datax, sp])\n", " model = KNeighborsClassifier(neighbors, algorithm=algorithm)\n", " model.fit(datax, datay)\n", " t1 = time.perf_counter()\n", " y = model.predict(datax)\n", " t2 = time.perf_counter()\n", " return t2 - t1, y, datax.nnz / (datax.shape[0] * datax.shape[1])"]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"data": {"text/plain": ["(0.2765191784464065, 0.28)"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["dt, y, sparse_ratio = what_to_measure_sparse(2000, 10, nb_sparse=100, ratio_sparse=0.2)\n", "dt, sparse_ratio"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Seul l'algorithme *brute* accepte les features sparses."]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["nf=10 dt=1.5204501486022934 ratio=0.9977333333333334\n", "nf=20 dt=1.7614489740851411 ratio=0.9917340909090909\n", "nf=50 dt=1.7535465636979097 ratio=0.96\n", "nf=100 dt=1.8724837066859834 ratio=0.88889\n", "nf=200 dt=2.00825006429622 ratio=0.75\n", "nf=500 dt=2.029575471120438 ratio=0.4897964285714286\n", "nf=1000 dt=1.7852292915800945 ratio=0.30555583333333336\n", "nf=2000 dt=1.8195703866820168 ratio=0.17355363636363635\n", "nf=5000 dt=1.6611926978457063 ratio=0.07544375\n", "nf=10000 dt=1.7084732344021063 ratio=0.038831225490196075\n"]}], "source": ["x = []\n", "y = []\n", "nfd = 200\n", "for nf in [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]:\n", " x.append(nf)\n", " dt, _, ratio = what_to_measure_sparse(2000, n_features=nfd, nb_sparse=nfd+nf, \n", " ratio_sparse=1.*nfd/(nfd+nf))\n", " y.append(dt)\n", " print(\"nf={0} dt={1} ratio={2}\".format(nf, dt, ratio))"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}, {"data": {"image/png": "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\n", "text/plain": [""]}, "metadata": {}, "output_type": "display_data"}], "source": ["fig, ax = plt.subplots(1, 1)\n", "ax.plot(x, y, \"o-\", label=\"brute\")\n", "ax.set_xlabel(\"number of dimensions\")\n", "ax.set_ylabel(\"prediction time in seconds\")\n", "ax.legend()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["La dimension augmente mais le nombre de features non nulle est constant. Comme l'algorithme est fortement d\u00e9pendant de la distance entre deux \u00e9l\u00e9ments et le co\u00fbt de cette distance d\u00e9pend du nombre de coefficients non nuls."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Q3 : Imaginez une fa\u00e7on d'aller plus vite ?\n", "\n", "Le co\u00fbt d'un algorithme des plus proches voisins est lin\u00e9aire selon la dimension car la majeure partie du temps est pass\u00e9 dans la fonction de distance et que celle-ci est lin\u00e9aire. Mesurons la performance en fonction de la dimension. Ce n'est pas vraiment rigoureux de le faire dans la mesure o\u00f9 les donn\u00e9es changent et n'ont pas les m\u00eames propri\u00e9t\u00e9s mais cela donnera une id\u00e9e."]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"text/plain": ["(0.11310998940052741, 0.18479999999999999)"]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["from sklearn.model_selection import train_test_split\n", "\n", "def what_to_measure_perf(n, n_features, n_classes=3, n_clusters_per_class=2, n_informative=8,\n", " neighbors=5, algorithm=\"brute\"):\n", " datax, datay = make_classification(n, n_features=n_features, n_classes=n_classes, \n", " n_clusters_per_class=n_clusters_per_class, \n", " n_informative=n_informative)\n", " X_train, X_test, y_train, y_test = train_test_split(datax, datay)\n", " model = KNeighborsClassifier(neighbors, algorithm=algorithm)\n", " model.fit(X_train, y_train)\n", " t1 = time.perf_counter()\n", " y = model.predict(X_test)\n", " t2 = time.perf_counter()\n", " good = (y_test == y).sum() / len(datay)\n", " return t2 - t1, good\n", "\n", "what_to_measure_perf(5000, 100)"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["nf=10 perf=0.2144 dt=0.12195857150595657\n", "nf=20 perf=0.2084 dt=0.10057272030894637\n", "nf=50 perf=0.2094 dt=0.08913530176550921\n", "nf=100 perf=0.1766 dt=0.11379739599328786\n", "nf=200 perf=0.1672 dt=0.1173173918214161\n", "nf=500 perf=0.1396 dt=0.19581724940167078\n", "nf=1000 perf=0.1206 dt=0.2313699973888106\n", "nf=2000 perf=0.1104 dt=0.3402820658384371\n", "nf=5000 perf=0.0948 dt=0.7753081181533616\n", "nf=10000 perf=0.0934 dt=1.331557928030179\n"]}], "source": ["x = []\n", "y = []\n", "for nf in [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]:\n", " x.append(nf)\n", " dt, perf = what_to_measure_perf(5000, n_features=nf)\n", " y.append(perf)\n", " print(\"nf={0} perf={1} dt={2}\".format(nf, perf, dt))"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}, {"data": {"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYsAAAEKCAYAAADjDHn2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XucVXW9//HXZ++ZYYbrgEwqMyAoF0VBsREvIOIlIU8p\nmaWW5aXyVEer44kS+2W/qH5anDyZmpfMsk6pqURqKpp4CW8BQiDowIAIM3gZkAGEAeby+f2x1gyb\nue0FzJ49s/f7+Xjsx6z1XbfPmgXz2d/1/a7vMndHRESkPbF0ByAiIl2fkoWIiCSlZCEiIkkpWYiI\nSFJKFiIikpSShYiIJJXSZGFmU82szMzKzezaVpZfY2YrzGypmT1jZoeF5ceZ2ctmtjxcdmEq4xQR\nkfZZqp6zMLM4sBL4GFABLAAudvcVCeucDrzq7jvM7GvAZHe/0MxGAu7uq8xsELAIOMrdq1MSrIiI\ntCuVNYvxQLm7r3H33cD9wHmJK7j7s+6+I5x9BSgJy1e6+6pwegPwPlCUwlhFRKQdOSncdzGwPmG+\nAjixnfW/BDzRvNDMxgN5wOr2DjZw4EAfOnTovkcpIpLFFi1atNHdk34ZT2WyiMzMLgFKgdOalR8K\n/AG41N0bWtnuSuBKgCFDhrBw4cJOiFZEJHOY2dtR1kvlbahKYHDCfElYthczOwv4HnCuu+9KKO8L\n/A34nru/0toB3P0udy9199KiIt2lEhFJlVQmiwXACDMbZmZ5wEXAI4krmNk44E6CRPF+Qnke8Bfg\n9+7+UApjFBGRCFKWLNy9DrgKmAu8AfzZ3Zeb2UwzOzdcbRbQG3jQzJaYWWMy+SwwCbgsLF9iZsel\nKlYREWlfyrrOdrbS0lJXm4WIRFFbW0tFRQU7d+5MdyidJj8/n5KSEnJzc/cqN7NF7l6abPsu0cAt\nItKZKioq6NOnD0OHDsXM0h1Oyrk7mzZtoqKigmHDhu3XPrI+WcxZXMmsuWVsqK5hUGEB06eMYtq4\n4nSHJSIptHPnzqxJFABmxkEHHURVVdV+7yOrk8WcxZXMmL2Mmtp6ACqra5gxexmAEoZIhsuWRNHo\nQM83qwcSnDW3rClRNKqprWfW3LI0RSQi0jVldbLYUF2zT+UiIh1h7dq1HHPMMfu9/ZIlS3j88cc7\nMKLksjpZDCos2KdyEclOcxZXMuHGeQy79m9MuHEecxa3eL64w9XX17e5TMmik02fMor83L1/BQW5\ncaZPGZWmiESkq2ls26ysrsHZ07Z5oAmjrq6OSy+9lLFjx3LBBRewY8cOhg4dysyZM5k4cSIPPvgg\nkydPbhrGaOPGjQwdOpTdu3dz/fXX88ADD3DcccfxwAMPsH37dq644grGjx/PuHHj+Otf/9oBZ763\nrG7gbmzE/tYDSwAoVm8okazzw0eXs2LD1jaXL15Xze76vYemq6mt5zsPLeW+f65rdZvRg/ryg08e\n3e5xy8rK+M1vfsOECRO44oor+NWvfgUEz0PMnz8fgDvuuKPFdnl5ecycOZOFCxdy6623AnDddddx\nxhlncM8991BdXc348eM566yz6NWrV7sx7IusrllAkDB65sX58sRhvHjtGUoUIrKX5okiWXlUgwcP\nZsKECQBccsklTQniwgv3/V1vTz31FDfeeCPHHXcckydPZufOnaxb13oi219ZXbNo4s59/1zHb+a/\npWctRLJMshrAhBvnUdlKp5fiwgIe+PeT9/u4zbuyNs4n1gZycnJoaAiSUntPm7s7Dz/8MKNGpe4W\netbXLOYsrmRHbQPbd9d36P1IEckM06eMoiA3vldZR7Rtrlu3jpdffhmAP/3pT0ycOLHFOkOHDmXR\nokUAPPTQnjFV+/Tpw7Zt25rmp0yZwi233ELj8E2LFy8+oNhak/XJ4oePLm9RpmctRKTRtHHF3HD+\nGIoLCzCCGsUN54854LsPRx55JPfeey9jx45l8+bNfO1rX2uxzre//W1uv/12TjnlFDZt2tRUfvrp\np7NixYqmBu7vf//71NbWMnbsWI4++mi+//3vH1BsrcnqgQTnLK5satxuzoC3bvy3DohMRLqaN954\ng6OOOirdYXS61s476kCCWV2zaK/2oGctRET2yOpk0d6T2nrWQkRkj6xOFm3VHgoLctUbSiTDZcot\n+KgO9HyzOlm01cvh/57bflc6Eene8vPz2bRpU9YkjMb3WeTn5+/3PrL6OYvG2sOsuWVUVteQG7cO\n6eUgIl1bSUkJFRUVB/R+h+6m8U15+yurkwUECWPauGK+fO8CNlTvVKIQyQK5ubn7/ca4bJXVt6ES\n9ciJs6uu7VEeRUSymZJFKC8ndsBjvYiIZColi1BePMbuOiULEZHWKFmE8nKULERE2qJkEeqRE2OX\nkoWISKtSmizMbKqZlZlZuZld28rya8xshZktNbNnzOywhGWXmtmq8HNpKuME1SxERNqTsmRhZnHg\n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\n", "text/plain": [""]}, "metadata": {}, "output_type": "display_data"}], "source": ["fig, ax = plt.subplots(1, 1)\n", "ax.plot(x, y, \"o-\", label=\"brute\")\n", "ax.set_xlabel(\"number of dimensions\")\n", "ax.set_ylabel(\"% good classification\")\n", "ax.legend()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["M\u00eame si les performances ne sont pas tout-\u00e0-fait comparables, il est vrai qu'il est plus difficile de construire un classifieur bas\u00e9 sur une distance en grande dimension. La raison est simple : plus il y a de dimensions, plus la distance devient binaire : soit les coordonn\u00e9es concordent sur les m\u00eames dimensions, soit elles ne concordent pas et la distance est presque \u00e9quivalente \u00e0 la somme des carr\u00e9s des coordonn\u00e9es.\n", "\n", "Revenons au probl\u00e8me principal. Acc\u00e9l\u00e9rer le temps de calcul des plus proches voisins.\n", "L'id\u00e9e est d'utiliser une [ACP](https://fr.wikipedia.org/wiki/Analyse_en_composantes_principales) : l'ACP a la propri\u00e9t\u00e9 de trouver un hyperplan qui r\u00e9duit les dimensions mais qui conserve le plus possible l'inertie d'un nuage de points et on l'exprimer ainsi :\n", "\n", "$$I = \\frac{1}{n} \\sum_i^n \\left\\Vert X_i - G \\right\\Vert^2 = \\frac{1}{n^2} \\sum_i^n\\sum_j^n \\left\\Vert X_i - X_j \\right\\Vert^2$$\n", "\n", "Bref, l'ACP conserve en grande partie les distances. Cela veut dire qu'une ACP r\u00e9duit les dimensions, donc le temps de pr\u00e9diction, tout en conservant le plus possible la distance entre deux points."]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"data": {"text/plain": ["(0.11917180937643934,\n", " 0.19159999999999999,\n", " 0.09498141829362794,\n", " 0.017255880783523025,\n", " 0.22220000000000001)"]}, "execution_count": 18, "metadata": {}, "output_type": "execute_result"}], "source": ["from sklearn.decomposition import PCA\n", "\n", "def what_to_measure_perf_acp(n, n_features, acp_dim=10,\n", " n_classes=3, n_clusters_per_class=2, n_informative=8,\n", " neighbors=5, algorithm=\"brute\"):\n", " datax, datay = make_classification(n, n_features=n_features, n_classes=n_classes, \n", " n_clusters_per_class=n_clusters_per_class, \n", " n_informative=n_informative)\n", " X_train, X_test, y_train, y_test = train_test_split(datax, datay)\n", " \n", " # sans ACP\n", " model = KNeighborsClassifier(neighbors, algorithm=algorithm)\n", " model.fit(X_train, y_train)\n", " t1o = time.perf_counter()\n", " y = model.predict(X_test)\n", " t2o = time.perf_counter()\n", " goodo = (y_test == y).sum() / len(datay)\n", " \n", " # ACP\n", " model = KNeighborsClassifier(neighbors, algorithm=algorithm)\n", " pca = PCA(n_components=acp_dim)\n", " t0 = time.perf_counter()\n", " X_train_pca = pca.fit_transform(X_train)\n", " model.fit(X_train_pca, y_train)\n", " t1 = time.perf_counter()\n", " X_test_pca = pca.transform(X_test)\n", " y = model.predict(X_test_pca)\n", " t2 = time.perf_counter()\n", " good = (y_test == y).sum() / len(datay)\n", " \n", " return t2o - t1o, goodo, t2 - t1, t1 - t0, good\n", "\n", "what_to_measure_perf_acp(5000, 100)"]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["nf=10 perf=0.2234 dt_predict=0.10264007588375534 dt_train=0.0019678001367537945\n", "nf=20 perf=0.224 dt_predict=0.10264244625113861 dt_train=0.009018063386065478\n", "nf=50 perf=0.2224 dt_predict=0.10190328663293258 dt_train=0.012852527977429418\n", "nf=100 perf=0.2148 dt_predict=0.10305410008413673 dt_train=0.020230692072345846\n", "nf=200 perf=0.2202 dt_predict=0.10624896049512245 dt_train=0.048967053076012235\n", "nf=500 perf=0.2116 dt_predict=0.09763267441076096 dt_train=0.07658064997849579\n", "nf=1000 perf=0.199 dt_predict=0.09247554472040065 dt_train=0.13868111958754525\n", "nf=2000 perf=0.1912 dt_predict=0.11294327354880807 dt_train=0.26802101567864156\n", "nf=5000 perf=0.1536 dt_predict=0.14626945627333043 dt_train=0.8286757586065505\n", "nf=10000 perf=0.1488 dt_predict=0.1786099611535974 dt_train=1.3338382216238642\n"]}], "source": ["x = []\n", "y = []\n", "yp = []\n", "p = []\n", "p_noacp = []\n", "y_noacp = []\n", "for nf in [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]:\n", " x.append(nf)\n", " dt_noacp, perf_noacp, dt, dt_train, perf = what_to_measure_perf_acp(5000, n_features=nf)\n", " p.append(perf)\n", " y.append(perf)\n", " yp.append(dt_train)\n", " y_noacp.append(dt_noacp)\n", " p_noacp.append(perf_noacp)\n", " print(\"nf={0} perf={1} dt_predict={2} dt_train={3}\".format(nf, perf, dt, dt_train))"]}, {"cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 20, "metadata": {}, "output_type": "execute_result"}, {"data": {"image/png": "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\nM2vCP0zkLci4jyz3AAAAAElFTkSuQmCC\n", "text/plain": [""]}, "metadata": {}, "output_type": "display_data"}], "source": ["fig, ax = plt.subplots(1, 2, figsize=(12,5))\n", "ax[0].plot(x, y, \"o-\", label=\"prediction time with PCA\")\n", "ax[0].plot(x, yp, \"o-\", label=\"training time with PCA\")\n", "ax[0].plot(x, y_noacp, \"o-\", label=\"prediction time no PCA\")\n", "ax[0].set_xlabel(\"number of dimensions\")\n", "ax[0].set_ylabel(\"time\")\n", "ax[1].plot(x, p, \"o-\", label=\"with PCA\")\n", "ax[1].plot(x, p_noacp, \"o-\", label=\"no PCA\")\n", "ax[1].set_xlabel(\"number of dimensions\")\n", "ax[1].set_ylabel(\"% good classification\")\n", "ax[0].legend()\n", "ax[1].legend()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Etonnament, l'ACP am\u00e9liore les performances du mod\u00e8le en terme de pr\u00e9diction. Cela sugg\u00e8re que les donn\u00e9es sont bruit\u00e9es et que l'ACP en a r\u00e9duit l'importance. Le calcul de l'ACP est lin\u00e9aire par rapport au nombre de features. Une partie des co\u00fbts a \u00e9t\u00e9 transf\u00e9r\u00e9e sur l'apprentissage et le pr\u00e9diction est constant car on conseerve toujours le m\u00eame nombre de dimensions."]}, {"cell_type": "code", "execution_count": 20, "metadata": {"collapsed": true}, "outputs": [], "source": []}], "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.7.2"}}, "nbformat": 4, "nbformat_minor": 2}