{ "metadata": { "name": "08A_unsupervised_dimreduction" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Unsupervised Learning: Dimensionality Reduction and Visualization" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Unsupervised learning is interested in situations in which X is available, but not y: data without labels.\n", "\n", "A typical use case is to find hiden structure in the data.\n", "\n", "Previously we worked on visualizing the iris data by plotting\n", "pairs of dimensions by trial and error, until we arrived at\n", "the best pair of dimensions for our dataset. Here we will\n", "use an unsupervised *dimensionality reduction* algorithm\n", "to accomplish this more automatically." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By the end of this section you will\n", "\n", "- Know how to instantiate and train an unsupervised dimensionality reduction algorithm:\n", " Principal Component Analysis (PCA)\n", "- Know how to use PCA to visualize high-dimensional data" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Dimensionality Reduction: PCA" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dimensionality reduction is the task of deriving a set of new\n", "artificial features that is smaller than the original feature\n", "set while retaining most of the variance of the original data.\n", "Here we'll use a common but powerful dimensionality reduction\n", "technique called Principal Component Analysis (PCA).\n", "We'll perform PCA on the iris dataset that we saw before:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from sklearn.datasets import load_iris\n", "iris = load_iris()\n", "X = iris.data\n", "y = iris.target" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 0 }, { "cell_type": "markdown", "metadata": {}, "source": [ "PCA is performed using linear combinations of the original features\n", "using a truncated Singular Value Decomposition of the matrix X so\n", "as to project the data onto a base of the top singular vectors.\n", "If the number of retained components is 2 or 3, PCA can be used\n", "to visualize the dataset." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from sklearn.decomposition import PCA\n", "pca = PCA(n_components=2, whiten=True)\n", "pca.fit(X)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stderr", "text": [ "/usr/local/lib/python2.7/site-packages/scikits/__init__.py:1: UserWarning: Module argparse was already imported from /usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.pyc, but /usr/local/lib/python2.7/site-packages is being added to sys.path\n", " __import__('pkg_resources').declare_namespace(__name__)\n" ] }, { "output_type": "pyout", "prompt_number": 3, "text": [ "PCA(copy=True, n_components=2, whiten=True)" ] } ], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once fitted, the pca model exposes the singular vectors in the components_ attribute:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "pca.components_" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 4, "text": [ "array([[ 0.17650757, -0.04015901, 0.41812992, 0.17516725],\n", " [-1.33840478, -1.48757227, 0.35831476, 0.15229463]])" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Other attributes are available as well:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "pca.explained_variance_ratio_" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 5, "text": [ "array([ 0.92461621, 0.05301557])" ] } ], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "pca.explained_variance_ratio_.sum()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 6, "text": [ "0.97763177502480336" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us project the iris dataset along those first two dimensions:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "X_pca = pca.transform(X)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "PCA `normalizes` and `whitens` the data, which means that the data\n", "is now centered on both components with unit variance:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import numpy as np\n", "np.round(X_pca.mean(axis=0), decimals=5)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 8, "text": [ "array([-0., 0.])" ] } ], "prompt_number": 6 }, { "cell_type": "code", "collapsed": false, "input": [ "np.round(X_pca.std(axis=0), decimals=5)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 9, "text": [ "array([ 1., 1.])" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Furthermore, the samples components do no longer carry any linear correlation:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "np.corrcoef(X_pca.T)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 10, "text": [ "array([[ 1.00000000e+00, -3.90798505e-16],\n", " [ -4.02640884e-16, 1.00000000e+00]])" ] } ], "prompt_number": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can visualize the projection using pylab, but first\n", "let's make sure our ipython notebook is in pylab inline mode" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%pylab inline" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "\n", "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].\n", "For more information, type 'help(pylab)'.\n" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can visualize the results using the following utility function:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import pylab as pl\n", "from itertools import cycle\n", "\n", "def plot_PCA_2D(data, target, target_names):\n", " colors = cycle('rgbcmykw')\n", " target_ids = range(len(target_names))\n", " pl.figure()\n", " for i, c, label in zip(target_ids, colors, target_names):\n", " pl.scatter(data[target == i, 0], data[target == i, 1],\n", " c=c, label=label)\n", " pl.legend()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now calling this function for our data, we see the plot:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "plot_PCA_2D(X_pca, iris.target, iris.target_names)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "display_data", "png": "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\n" } ], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that this projection was determined *without* any information about the\n", "labels (represented by the colors): this is the sense in which the learning\n", "is **unsupervised**. Nevertheless, we see that the projection gives us insight\n", "into the distribution of the different flowers in parameter space: notably,\n", "*iris setosa* is much more distinct than the other two species." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note also that the default implementation of PCA computes the\n", "singular value decomposition (SVD) of the full\n", "data matrix, which is not scalable when both ``n_samples`` and\n", "``n_features`` are big (more that a few thousands).\n", "If you are interested in a number of components that is much\n", "smaller than both ``n_samples`` and ``n_features``, consider using\n", "`sklearn.decomposition.RandomizedPCA` instead." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Other dimensionality reduction techniques which are useful to know about:\n", "\n", "- [sklearn.decomposition.PCA](http://scikit-learn.org/0.13/modules/generated/sklearn.decomposition.PCA.html): \n", " Principal Component Analysis\n", "- [sklearn.decomposition.RandomizedPCA](http://scikit-learn.org/0.13/modules/generated/sklearn.decomposition.RandomizedPCA.html):\n", " fast non-exact PCA implementation based on a randomized algorithm\n", "- [sklearn.decomposition.SparsePCA](http://scikit-learn.org/0.13/modules/generated/sklearn.decomposition.SparsePCA.html):\n", " PCA variant including L1 penalty for sparsity\n", "- [sklearn.decomposition.FastICA](http://scikit-learn.org/0.13/modules/generated/sklearn.decomposition.FastICA.html):\n", " Independent Component Analysis\n", "- [sklearn.decomposition.NMF](http://scikit-learn.org/0.13/modules/generated/sklearn.decomposition.NMF.html):\n", " non-negative matrix factorization\n", "- [sklearn.manifold.LocallyLinearEmbedding](http://scikit-learn.org/0.13/modules/generated/sklearn.manifold.LocallyLinearEmbedding.html):\n", " nonlinear manifold learning technique based on local neighborhood geometry\n", "- [sklearn.manifold.IsoMap](http://scikit-learn.org/0.13/modules/generated/sklearn.manifold.Isomap.html):\n", " nonlinear manifold learning technique based on a sparse graph algorithm" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Exercise: Randomized PCA" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Repeat the above dimensionality reduction with\n", "``sklearn.decomposition.RandomizedPCA``.\n", "\n", "You can re-use the ``plot_PCA_2D`` function from above.\n", "Are the results similar to those from standard PCA?" ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 12 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Exercise: Dimension reduction of digits" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Take the digits data, applied to it PCA (or RandomizedPCA?).\n", "\n", "Try also dictionnary learning, as well as Isomap.\n" ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 13 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that such data reduction can be used as a first step before a supervised problem. We will see more about this soon." ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 14 } ], "metadata": {} } ] }