Skip to content
Snippets Groups Projects
Representation Learning.ipynb 336 KiB
Newer Older
       "    ws.close = function () {\n",
       "        comm.close();\n",
       "    };\n",
       "    ws.send = function (m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function (msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data']);\n",
       "    });\n",
       "    return ws;\n",
       "};\n",
       "\n",
       "mpl.mpl_figure_comm = function (comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = document.getElementById(id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm);\n",
       "\n",
       "    function ondownload(figure, _format) {\n",
       "        window.open(figure.canvas.toDataURL());\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element;\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error('Failed to find cell for figure', id, fig);\n",
       "        return;\n",
       "    }\n",
       "    fig.cell_info[0].output_area.element.on(\n",
       "        'cleared',\n",
       "        { fig: fig },\n",
       "        fig._remove_fig_handler\n",
       "    );\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
       "    var width = fig.canvas.width / fig.ratio;\n",
       "    fig.cell_info[0].output_area.element.off(\n",
       "        'cleared',\n",
       "        fig._remove_fig_handler\n",
       "    );\n",
       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable();\n",
       "    fig.parent_element.innerHTML =\n",
       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "    fig.close_ws(fig, msg);\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width / this.ratio;\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] =\n",
       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function () {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message('ack', {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () {\n",
       "        fig.push_to_output();\n",
       "    }, 1000);\n",
       "};\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function () {\n",
       "    var fig = this;\n",
       "\n",
       "    var toolbar = document.createElement('div');\n",
       "    toolbar.classList = 'btn-toolbar';\n",
       "    this.root.appendChild(toolbar);\n",
       "\n",
       "    function on_click_closure(name) {\n",
       "        return function (_event) {\n",
       "            return fig.toolbar_button_onclick(name);\n",
       "        };\n",
       "    }\n",
       "\n",
       "    function on_mouseover_closure(tooltip) {\n",
       "        return function (event) {\n",
       "            if (!event.currentTarget.disabled) {\n",
       "                return fig.toolbar_button_onmouseover(tooltip);\n",
       "            }\n",
       "        };\n",
       "    }\n",
       "\n",
       "    fig.buttons = {};\n",
       "    var buttonGroup = document.createElement('div');\n",
       "    buttonGroup.classList = 'btn-group';\n",
       "    var button;\n",
       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            /* Instead of a spacer, we start a new button group. */\n",
       "            if (buttonGroup.hasChildNodes()) {\n",
       "                toolbar.appendChild(buttonGroup);\n",
       "            }\n",
       "            buttonGroup = document.createElement('div');\n",
       "            buttonGroup.classList = 'btn-group';\n",
       "            continue;\n",
       "        }\n",
       "\n",
       "        button = fig.buttons[name] = document.createElement('button');\n",
       "        button.classList = 'btn btn-default';\n",
       "        button.href = '#';\n",
       "        button.title = name;\n",
       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
       "        button.addEventListener('click', on_click_closure(method_name));\n",
       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
       "        buttonGroup.appendChild(button);\n",
       "    }\n",
       "\n",
       "    if (buttonGroup.hasChildNodes()) {\n",
       "        toolbar.appendChild(buttonGroup);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = document.createElement('span');\n",
       "    status_bar.classList = 'mpl-message pull-right';\n",
       "    toolbar.appendChild(status_bar);\n",
       "    this.message = status_bar;\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = document.createElement('div');\n",
       "    buttongrp.classList = 'btn-group inline pull-right';\n",
       "    button = document.createElement('button');\n",
       "    button.classList = 'btn btn-mini btn-primary';\n",
       "    button.href = '#';\n",
       "    button.title = 'Stop Interaction';\n",
       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
       "    button.addEventListener('click', function (_evt) {\n",
       "        fig.handle_close(fig, {});\n",
       "    });\n",
       "    button.addEventListener(\n",
       "        'mouseover',\n",
       "        on_mouseover_closure('Stop Interaction')\n",
       "    );\n",
       "    buttongrp.appendChild(button);\n",
       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
       "};\n",
       "\n",
       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
       "    var fig = event.data.fig;\n",
       "    if (event.target !== this) {\n",
       "        // Ignore bubbled events from children.\n",
       "        return;\n",
       "    }\n",
       "    fig.close_ws(fig, {});\n",
       "};\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function (el) {\n",
       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
       "};\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
       "    // this is important to make the div 'focusable\n",
       "    el.setAttribute('tabindex', 0);\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    } else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager) {\n",
       "        manager = IPython.keyboard_manager;\n",
       "    }\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which === 13) {\n",
       "        this.canvas_div.blur();\n",
       "        // select the cell after this one\n",
       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
       "        IPython.notebook.select(index + 1);\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "};\n",
       "\n",
       "mpl.find_output_cell = function (html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i = 0; i < ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code') {\n",
       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] === html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "};\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel !== null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target(\n",
       "        'matplotlib',\n",
       "        mpl.mpl_figure_comm\n",
       "    );\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+gAAAPoCAYAAABNo9TkAAAgAElEQVR4nOzda5DeZX3/8Xs3JEsIIQkRCgkBEqQCVSFQLS0pIQlCsKhEheJhTBQHkWiVcnBEC9oCGhUV2wIVR7RYEImIloNEDqIoBBwdPAAaNVZsgaiQcJYEPv8H/LOyLofgIb8vXK/XzOdB7r137ys7XA/e2QO9AAAAAJ3rdX0AAAAAQKADAABACQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBABwAAgAIEOgAAABQg0AEAAKAAgQ4AAAAFCHQAAAAoQKADAABAAQIdAAAAChDoADytnXnmmen1eo+7K6+88k/+2suXL1+v7/vH0Ov1cvzxx3fy2o9l+fLl6fV6OfPMM7s+CgB0RqAD8LS2NnTPPPPMXHPNNcO2atWqP/lr/z6RvWLFilxzzTV54IEH/vgHWwfVAv2BBx7INddckxUrVnR9FADojEAH4GltbSRff/31nb12V18F/0NUCfQ1a9Z09o8UAFCNQAfgaW1dA/2cc85Jr9fLv/7rvw55/Ljjjkt/f3+WLFmS5Lffar1o0aKccMIJmTJlSgYGBrLbbrvlsssue8zXfnSgL1myJC996UszefLkDAwMZLvttsuhhx6aX/7yl0/6vjNnzsxf/MVf5LrrrsuMGTMyevToTJ06Ne973/vy0EMPDXn/VatW5cgjj8y2226bkSNHZtKkSXnb296We+65Z9jz3vjGN2bTTTfNmDFjsu++++aHP/zhkwb6ihUrMnLkyLz73e8e9rabbropvV4vp5xyyuBz3/zmN2fHHXfMmDFjstlmm2XWrFn52te+NuT9Hv25/Zd/+Zdsu+22GTFiRC655JLH/Bb3ZcuWZcGCBXn2s5+d0aNHZ9KkSdl///3z3e9+d8jHvfLKK9Pr9XL22Wfn2GOPzZZbbpmxY8dmzpw5ufnmm4ed/5JLLsns2bOzySabZPTo0dlhhx1y0kknDXnO9ddfn5e85CWZMGFCBgYGsssuu+Tcc8993M8XAPwxCHQAntbWhu61116b1atXD9maNWuGPPewww7LqFGjBmP+8ssvT39//5AIXRuKU6ZMyYwZM/L5z38+5513Xl7wghdk5MiR+eY3vznstR8d2aeddlre97735Utf+lKuuuqqfPrTn87OO++c5zznOXnwwQef8H1nzpyZiRMnZvvtt8/pp5+er3zlKzn88MPT6/Xy6U9/evB59957b3bZZZc861nPyoc//OFcdtllOeWUUzJu3LjMnj07Dz/8cJLk4YcfzqxZszIwMJATTzwxS5YsyfHHH59p06at01fQ582blylTpgz7x4Fjjjkmo0aNyq9+9askyc0335w3v/nN+exnP5uvfvWrufDCC3PIIYekv79/yO8AWPu5nTx5cmbNmpXFixdnyZIlWb58+WMG+lVXXZUjjzwyixcvzlVXXZUvfOELOeCAAzJ69Ogh4b020Lfddtu85jWvyUUXXZRzzjknW2+9dbbffvsh/x184hOfSF9fX/baa6+cffbZueyyy3Lqqafm8MMPH3zOFVdckVGjRuVv//Zvc+655+bLX/5yFixY4GfkAfiTE+gAPK090S+JGzFixJDnPvDAA5k+fXqmTp2aG2+8MX/2Z3+WmTNnDgm4taE4adKk3H///YOP33XXXdl0002z9957D3vtx/sW94cffjirV6/O//zP/6TX6+WLX/ziE77vzJkz0+v1snTp0iEfZ6eddsq+++47+Of3ve996e/vH/ZdA4sXL06v18vFF1+c5JGvFD/6K91rnXjiiesU6F/60pfS6/UGv7sgeeRb0idNmpRXvOIVj/t+a9asyerVqzNnzpzMmzdv8PG1n9vttttuyD9WPPptTxTAa9asyYMPPpjtt98+RxxxxODjawP9xS9+8ZDnf+5zn0uv18s111yTJLn77ruzySabZMaMGYP/iPFYdthhh0yfPj2rV68e8vj++++fLbfcctg/WADAH4tAB+BpbW3o/ud//meuv/76IfvWt7417PnLli3LJptskg033DCbb755/u///m/I29eG4lve8pZh7zt//vyMGjVqMOgfK7Jvv/32vOlNb8pWW22V/v7+If9g8P73v3/YuX830LfYYothr3vwwQdnhx12GPzzHnvskec///nDvmPg7rvvTl9fX4455pgkj3ylu9frDX6l+3f/jk8W6KtXr84WW2yRV73qVYOPXXTRRen1ernooouGPPe0007L9OnTMzAwMOTv/Ohzr33dR8f1777t0YG+evXqnHjiidlxxx0zcuTIIR937ty5g89bG+inn376kI958803p9fr5bOf/WyS5NJLLx38VvjHs2zZsvR6vXzoQx8a9vk99dRT0+v1cuONNz7h5w0Afl8CHYCntd/nl8T93d/93ZOG4gknnDDsbe94xzvS6/WycuXKIa+9NrIfeuih7Lzzztlss83ysY99LFdeeWWuu+66XHvttcOC+Il+Bv13zZ8/P9tss83gn5/97Gc/4f9a7g1veEOS5JBDDskGG2ww7OPdf//96/xL4o4++uhsuOGGufPOO5MkBx54YLbccssh33Vw8sknp9fr5bDDDsuFF16Ya6+9Ntdff33mzp075NxrP7cf+MAHhr3OYwX6W9/61vT39+ed73xnvvzlL2fp0qW5/vrrs/POO2fmzJmDz1sb6Oedd94TfszPfOYz6fV6w342/tGuvvrqJ/zcPtn7A8AfQqAD8LT2VAP9jDPOSK/Xywtf+MKMHDky11577ZC3/yFfQb/hhhvS6/XyqU99asj7rf2q7B8r0Hffffc873nPG/YdA2u39mP+oV9BT5Ibb7wxvV4vp512Wu64444MDAzkHe94x5DnTJ8+PXvttdew991jjz0eM9A/+MEPDnvuYwX6hAkTsmDBgmHPnTx58u8V6OvyFfS1X3V/5zvf+bif37vuuutx3x8A/hACHYCntacS6N/97nczevTovO51r8tvfvOb7Lbbbtlmm21yxx13DD7nyX4Gfc6cOcNee20Qf/e7302v18s555wz5HWPOuqoP2qgn3DCCdloo43y05/+9An/vn/oz6Cv9Vd/9Vd54QtfmH/7t39Lr9cb9pvRd9111yE/I5888o8V/f39f1Cgb7rppnnTm9405HkXXnhher3e7xXod999d8aNG5c999zzCX8Gffvttx/28+wAsD4IdACe1taG7plnnplrrrlm2FasWJEkueeee7LDDjtkp512Gvxfkf3kJz/JuHHj8rKXvWzw4/3ub3E///zzs3jx4rzgBS/IBhtskKuvvnrYa6+N7AcffDDbbbddttlmm5x99tn58pe/nIULF+bP//zP/6iBfs8992T69OnZaqutcvLJJ+crX/lKLr300pxxxhk58MADB78r4KGHHsqee+6ZgYGBnHTSSU/5t7iv9R//8R/p9XrZaqut8jd/8zfD3n7cccelr68vxx13XC6//PKceuqp2WKLLQY/F7/7uV3XQH/d616XgYGBfOQjH8nll1+eD3zgA9lss82y1VZb/V6BnjzyW9x7vV5mz56dc845J1dccUU+/vGPZ+HChYPPueKKKzIwMJB99tknZ5999uBvkD/ppJPyyle+cp0+ZwDw+xDoADytPdFvce/1ejnjjDOSJK997Wuz0UYb5Qc/+MGQ9z/vvPPS6/XykY98JMnQ/1f3e9/73my11VYZNWpUpk+fnksvvfQxX/vRkX3jjTfmRS96UcaOHZsJEybkwAMPzM9//vM/aqAnj0T6u9/97jznOc/JqFGjMm7cuDzvec/LEUcckdtuu23weStXrswb3vCGjB8/PhtttFFe9KIXDX4b97oG+qpVqzJ69Oghn89H+81vfpOjjjoqkydPzoYbbphdd901F1xwwbBzP9VAv/POO3PIIYdk8803z0YbbZQZM2bk61//embOnPl7B3qSXHzxxZk5c2bGjBmTjTbaKDvttFMWLVo05Dk33HBDDjrooGy++eYZOXJktthii8yePXvYL6IDgD8mgQ4Aj/JEEQkA8Kck0AHgUQQ6ANAVgQ4AjyLQAYCuCHQAAAAoQKADAABAAQIdAAAAChDoAAAAUIBAb8xDDz2UW265JStXrsyqVavMzMzMzKzRrVy5MrfcckseeuihrjOF/0+gN+aWW25Jr9czMzMzMzNLr9fLLbfc0nWm8P8J9MasXLly8BJ2/S92ZmZmZmbW3dZ+8W7lypVdZwr/n0BvzKpVq9Lr9bJq1aqujwIAAHRIG9Qj0BvjEgIAAIk2qEigN8YlBAAAEm1QkUBvjEsIAAAk2qAigd4YlxAAAEi0QUUCvTEuIQAAkGiDigR6Y1xCAAAg0QYVCfTGuIQAAECiDSoS6I1xCQEAgEQbVCTQG+MSAgAAiTaoSKA3xiUEAAASbVCRQG+MSwgAACTaoCKB3hiXEAAASLRBRQK9MS4hAACQaIOKBHpjXEIAACDRBhUJ9Ma4hAAAQKINKhLojXEJAQCARBtUJNAb4xICAACJNqhIoDfGJQQAABJtUJFAb4xLCAAAJNqgIoHeGJcQAABItEFFAr0xLiEAAJBog4oEemNcQgAAINEGFQn0xriEAABAog0qEuiNcQkBAIBEG1Qk0BvjEgIAAIk2qEigN8YlBAAAEm1QkUBvjEsIAAAk2qAigd4YlxAAAEi0QUUCvTEuIQAAkGiDigR6Y1xCAAAg0QYVCfTGuIQAAECiDSoS6I1xCQEAgEQbVCTQG7P2Ek55++eyzTsufMYNAABYNwK9HoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4YgQ4AACQCvSKB3hiBDgAAJAK9IoHeGIEOAAAkAr0igd4Y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RKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABADXNRf8AACAASURBVIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBXJNAbI9ABAIBEoFck0Bsj0AEAgESgVyTQGyPQAQCARKBX1ESgX3XVVVm9evWwx1evXp2rrrqqgxN1xyUEAAASbVBRE4He39+f22+/fdjjv/rVr9Lf39/BibrjEgIAAIk2qKiJQO/r68uKFSuGPf7DH/4wY8eO7eBE3XEJAQCARBtU9IwO9Hnz5mXevHnp7+/Pi1/84sE/z5s3Ly996Uuz7bbbZt999+36mOuVSwgAACTaoKJndKAvWLAgCxYsSF9fX/7+7/9+8M8LFizIoYcempNOOim//OUvuz7meuUSAgAAiTao6Bkd6Gu95z3vyT333NP1MUpwCQEAgEQbVNREoPNbLiEAAJBog4qaCPTbbrstr33ta7PllltmxIgR6e/vH7KWuIQAAECiDSpqItDnzp2bnXbaKaeeemq+8IUv5IILLhiylriEAABAog0qaiLQN95443znO9/p+hgluIQAAECiDSpqItB33HHHfPvb3+76GCW4hAAAQKINKmoi0C+99NLss88+Wb58eddH6ZxLCAAAJNqgoiYCffz48Rk1alT6+/uz8cYbZ8KECUPWEpcQAABItEFFTQT6pz71qSdcS1xCAAAg0QYVNRHo/JZLCAAAJNqgomYC/cc//nHe9a535eCDD87tt9+eJLnkkkvy/e9/v+OTrV8uIQAAkGiDipoI9K9+9asZPXp09t5774waNSo/+clPkiSLFi3KK17xio5Pt365hAAAQKINKmoi0HffffecfPLJSR75f6KvDfTrrrsukyZN6vJo651LCAAAJNqgoiYCfcyYMfnpT3+aZGigL1++PAMDA10ebb1zCQEAgEQbVNREoE+ePDnf+MY3kgwN9PPPPz/Tpk3r8mjrnUsIAAAk2qCiJgL96KOPzowZM3Lrrbdm7NixWbZsWa6++upMmzYt73nPe7o+3nrlEgIAAIk2qKiJQH/wwQfz6le/Ov39/enr68vIkSPT39+f1772tVmzZk3Xx1uvXEIAACDRBhU1Eehr/fjHP855552Xc889Nz/60Y+6Pk4nXEIAACDRBhU1Fei4hAAAwCO0QT1NBPqaNWvyiU98Iq961asyZ86czJo1a8ha4hICAACJNqioiUBfuHBhxowZk4MOOihve9vb8va3v33IWuISAgAAiTaoqIlAnzhxYi666KKuj1GCSwgAACTaoKImAn3LLbfMD3/4w66PUYJLCAAAJNqgoiYC/UMf+lAOP/zwPPzww10fpXMuIQAAkGiDipoI9AMOOCDjxo3L1KlTs//++2fevHlD1hKXEAAASLRBRU0E+oIFC55wLXEJAQCARBtU1ESg81suIQAAkGiDipoK9BUrVuTrX/96rr766qxYsaLr43TCJQQAABJtUFETgX7PPffk9a9/fUaMGJG+vr709fVlgw02yBve8Ibce++9XR9vvXIJAQCARBtU1ESgH3rooZk2bVouvvjirFq1KqtWrcpFF12U7bbbLocddljXx1uvXEIAACDRBhU1EegTJ07MlVdeOezxK664Is961rPW/4E65BICAACJNqioiUAfPXp0brzxxmGPf//7389GG23UwYm64xICAACJNqioiUCfPXt2DjzwwNx///2Dj91333058MADM2fOnA5Ptv65hAAAQKINKmoi0L/3ve9l8uTJmThxYmbPnp05c+Zk4sSJmTx5cr7//e93fbz1yiUEAAASbVBRE4GePPIV849//OP5x3/8xxxxxBE544wzct9993V9rPXOJQQAABJtUFEzgc4jXEIAACDRBhU1E+g333xzFi5cOPgt7gsXLsxNN93U9bHWO5cQAABItEFFTQT6eeedlw022CC77757jjjiiBxxxBH567/+62ywwQb53Oc+1/Xx1iuXEAAASLRBRU0E+tSpU/NP//RPwx4/7rjjMnXq1A5O1B2XEAAASLRBRU0E+ujRo7Ns2bJhj//oRz/K6NGjOzhRd1xCAAAg0QYVNRHo++23Xz75yU8Oe/yTn/xk9tlnnw5O1B2XEAAASLRBRU0E+mmnnZbNNtssCxcuzFlnnZWzzjorCxcuzOabb57TTjstX/ziFwf3TOcSAgAA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joVOBAZ6NQ4++OA4/fTT+z22zz77+CZxTcZAbx7vvvtunHnmmbHjjjvG888/X/o4vM8+/elPx4QJE0ofg03w2muvxbx58/p10EEHxUknneR7RzShVatWxU477RSXXnpp6aOwCU444YR1vnxs0qRJ63xWHf6TDPRK/PPHrN12220xf/78mDRpUnR0dMSSJUtKH41N9Prrr0dPT0/09PREo9GIa665Jnp6evwIvQ+4008/PbbZZpt45JFH+v1YnzfffLP00dhEF154YcycOTMWL14cc+fOjSlTpsQWW2wRDz74YOmjsZl5iXvzOPfcc+ORRx6JRYsWxeOPPx7HHHNMDB482P9HfcA98cQTMXDgwLj88sujt7c37rnnnthqq63i7rvvLn00KmagV+T666+Pzs7O2HLLLePAAw/045qaxO9+97toNBrr5LNxH2zru6aNRiNuv/320kdjE51yyil9/xYPHz48jjjiCOO8SRnozWP8+PExcuTIaG1tjR133DHGjRvn+0Y0iV/96lex7777RltbW+y9996+izvFGegAAACQgIEOAAAACRjoAAAAkICBDgAAAAkY6AAAAJCAgQ4AAAAJGOgAAACQgIEOAAAACRjoANDEGo1GTJ8+vfQxAIANYKADQGHHHHNMHHHEEet92+zZs6PRaMQf//jH/9dzL1u2LFatWrUpxwMA/kMMdAAobPr06TFgwIBYsmTJOm+bOHFiHHDAARv9nKtXr94cRwMA/oMMdAAo7J133okRI0bEJZdc0u/xv//97zF48OC45JJL4vjjj4+ddtop2tvbY999942f/OQn/d63q6srzjzzzPj2t78dw4YNizFjxkTEui9xP//882OPPfaI9vb22G233eLiiy+Ot99+u+/t3d3dMXr06Pjxj38cnZ2dsfXWW8f48ePjtdde63uftWvXxve+97348Ic/HFtuuWXssssuMXXq1L63v/TSS3HcccfFtttuG0OHDo0vfvGLsXjx4s35VwYATclAB4AEJk+eHKNGjYp3332377E77rgj2tra4qWXXoof/OAH0dPTEwsXLowf/ehH0dLSEo8//njf+3Z1dcWgQYNi8uTJ8eyzz8YzzzwTEesO9O9+97sxa9asWLx4cdx///0xYsSIuPLKK/ve3t3dHYMGDYpx48bFvHnzYubMmbHDDjvElClT+t7n/PPPjyFDhsQdd9wRCxYsiN///vdxyy23RMQ/Pqiwxx57xCmnnBJz586N+fPnx9e+9rXYa6+9fFYfAN6DgQ4ACTzzzDPRaDTit7/9bd9jY8aMiRNOOGG97//5z38+zj333L5fd3V1rfel8O/1TeK+//3vx8c+9rG+X3d3d8dWW23V7zPmkydPjo9//OMREfHaa69FW1tb3yD/d7fddlvstdde/T7QsHr16mhvb4/f/OY3/+s5AAADHQDS+OQnPxknnXRSREQsWLAgBgwYEA899FCsWbMmpk6dGvvtt18MHTo0Ojo6YuDAgfHVr3617/d2dXXFxIkT13nOfx/o9957bxx66KExYsSI6OjoiLa2thg+fHjf27u7u+MjH/lIv+e45pprYrfddouIiDlz5kSj0YhFixat989wxhlnREtLS3R0dPRrwIABccMNN/z//3IAoAIGOgAkcdttt0V7e3usXLkyLrroor6XvF955ZUxbNiwuOuuu+Kpp56K3t7eOProo2Ps2LF9v7erqyvOOeecdZ7zXwf6Y489Fi0tLTF16tR48skn4/nnn4/LLrssttlmm773/+fXoP+ra6+9Njo7OyMiYu7cuf/nQD/ttNPi4IMPjt7e3nVasWLFpv4VAUBTM9ABIInXX389Bg0aFDfeeGPsvPPOcemll0bEP34M2ymnnNL3fmvXro0999xzowf6VVddFbvvvnu/t5966qkbNdDfeuutaG9v/19f4n7zzTfHkCFDYuXKlRvxJwcAIgx0AEjl1FNPjSFDhsQWW2wRL7zwQkRETJo0KXbZZZeYNWtWzJ8/PyZOnBhbb731Rg/0X/7ylzFw4MCYNm1aLFiwIH74wx/G0KFDN2qgR0RccsklMWTIkLjzzjtjwYIF8dhjj8Wtt94aEf/zTeIOP/zwmDlzZixatCgeeeSROPvss2Pp0qWb7e8JAJqRgQ4AicyePTsajUZ85jOf6Xvs5ZdfjrFjx8agQYNi++23j4svvjhOPvnkjR7oEf/4hm/Dhg2LQYMGxfjx4+Paa6/d6IG+du3amDp1anR2dkZra2vsuuuuccUVV/S9fdmyZXHyySfHdtttF21tbbH77rvHN77xDZ9VB4D3YKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACRgoAMAAEACBjoAAAAkYKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACRgoAMAAEACBjoAAAAkYKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACRgoAMAAEACBjoAAAAkYKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACRgoAMAAEACBjoAAAAkYKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACRgoAMAAEACBjoAAAAkYKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACRgoAMAAEACBjoAAAAkYKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACRgoAMAAEACBjoAAAAkYKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACRgoAMAAEACBjoAAAAkYKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACRgoAMAAEACBjoAAAAkYKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACRgoAMAAEACBjoAAAAkYKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACRgoAMAAEACBjoAAAAkYKADAABAAgY6AAAAJGCgAwAAQAIGOgAAACTwX4bHXNYRYvPHAAAAAElFTkSuQmCC\" width=\"1000\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.barh([\"PCA 1\", \"PCA 2\"], pca.explained_variance_)\n",
    "plt.gca().set(xlabel=\"Variance\", ylabel=\"Component\", title=\"Explained variance\")\n",
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Clearly the zeroth PCA component holds most of the variance and we could therefore use this component to closely determine where a data sample point should be if we dropped the other component. This is equivalent to fitting a line and using the projection of the point in the line to characterize the data, instead of using the two coordinates.\n",
    "\n",
    "While this may seem superfluous in this simple case, if one has hundreds of variables, PCA provides a simple and almost automatic way to reduce the amount of features being examined, by concentrating most of the variance in a few variables. Which variables to choose, can be decided from the `explained_variance_` attribute."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7bcb1e2c",
   "metadata": {},
   "source": [
    "## Other representation learning methods\n",
    "\n",
    "While PCA is a great method for both data visualization and choosing a latent space to condense the information contained in the data, there are many other available, which differ on the assumptions made. Here are some of them and easy-to-read and practical references on how to use them and which assumptions they entail.\n",
    "\n",
    "  * Kernel PCA: While PCA does a great job at finding the directions where most of the variance is, it focuses on making only *linear* combinations of the features to find the new representation directions. A straightforward method to generalise this idea to non-linear transformations is to apply a non-linear transformation to the data features and after that apply PCA. This is similar to what Kernel PCA does, generalizing the PCA idea. Of course, a non-linearity transformation needs to be chosen for this and this adds extra assumptions in the model. Some more on this can be read here: https://scikit-learn.org/stable/modules/decomposition.html#kernel-pca\n",
    "  \n",
    "  * Independent Component Analysis: PCA  looks for the direction containing most of the variance, but this is not always the optimal representation of the data for all goals. In some cases, independence is much more important than decorrelation and this is where the Independent Component Analysis comes in. The ICA also assumes that the new representation can be built from a linear combination of the existing data, but it assumes additionally each observed feature comes from a linear combination of independent latent representations we want to discover. Since independence is a very strong requirement, it is imposed through various different proxy methods. One set of methods focuses on reducing the mutual information (as defined in statistics) between the new features, while an alternative imposes non-Gaussianity requirements on the underlying latent features to be discovered. Since Gaussians do not have statistical moments above the second-order moment (covariance), one can require for example, the fourth order statistical moment (kurtosis) to be maximized in the new representation. More on the scikit-learn implementation can be found here: https://scikit-learn.org/stable/modules/decomposition.html#ica .\n",
    "  \n",
    "  * t-SNE embedding: If the objective is only to visualize the data, there are many alternative solutions which focus on reducing the dimensionality of the data into a 2D representation. The t-SNE method assumes that a Gaussian probability can be used to model similarity between data points in N dimensions and that one should maintain that similarity measure when projecting the data in two dimensions, assuming however that the 2D data points' similarity can be represented with a t-Student distribution. Full details on the method can be seen here: https://jmlr.org/papers/volume9/vandermaaten08a/vandermaaten08a.pdf It can be easily tried in scikit-learn following the procedure here: https://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18c90048",
   "metadata": {},
   "source": [
    "### Contact us at the EuXFEL Data Analysis group at any time if you need help analysing your data!\n",
    "\n",
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "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",