Skip to content

Instantly share code, notes, and snippets.

@iglesias
Last active August 8, 2017 11:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iglesias/6576096 to your computer and use it in GitHub Desktop.
Save iglesias/6576096 to your computer and use it in GitHub Desktop.
GSoC 2013 notebook about metric learning applied to metagenomics.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Metric Learning with the Shogun Machine Learning Toolbox"
]
},
{
"cell_type": "heading",
"level": 5,
"metadata": {},
"source": [
"By Fernando J. Iglesias Garcia. Style inspired by \"Blind Source Separation with the Shogun Machine Learning Toolbox\", by Kevin Hughes."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this notebook we are going to see how metric learning can be used for classification and feature selection using the Shogun Machine Learning Toolbox. In particular, will we be dealing with an algorithm for metric learning called *Large Margin Nearest Neighbour*, or just LMNN, for short."
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Building up the intuition to understand LMNN"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First of all, let us introduce LMNN through a simple example. For this purpose, we will be using the following two-dimensional toy data set:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import numpy\n",
"\n",
"x = numpy.array([[0,0],[-1,0.1],[0.3,-0.05],[0.7,0.3],[-0.2,-0.6],[-0.15,-0.63],[-0.25,0.55],[-0.28,0.67]])\n",
"y = numpy.array([0,0,0,0,1,1,2,2])"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is, there are eight feature vectors where each of them belongs to one out of three different classes (identified by either 0, 1, or 2). Let us have a look at this data:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import matplotlib.pyplot as pyplot\n",
"\n",
"%matplotlib inline\n",
"\n",
"def plot_data(features,labels,axis,alpha=1.0):\n",
" # separate features according to their class\n",
" X0,X1,X2 = features[labels==0], features[labels==1], features[labels==2]\n",
" \n",
" # class 0 data\n",
" axis.plot(X0[:,0], X0[:,1], 'o', color='green', markersize=12, alpha=alpha)\n",
" # class 1 data\n",
" axis.plot(X1[:,0], X1[:,1], 'o', color='red', markersize=12, alpha=alpha)\n",
" # class 2 data\n",
" axis.plot(X2[:,0], X2[:,1], 'o', color='blue', markersize=12, alpha=alpha)\n",
" \n",
" # set axes limits\n",
" axis.set_xlim(-1.5,1.5)\n",
" axis.set_ylim(-1.5,1.5)\n",
" axis.set_aspect('equal')\n",
" \n",
" axis.set_xlabel('x')\n",
" axis.set_ylabel('y')\n",
"\n",
"figure,axis = pyplot.subplots(1,1)\n",
"plot_data(x,y,axis)\n",
"axis.set_title('Toy data set')\n",
"pyplot.show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\n",
"text": [
"<matplotlib.figure.Figure at 0x322bfd0>"
]
}
],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the figure above, we can see that two of the classes are represented by two points that are, for each of these classes, very close to each other. The third class, however, has four points that are close to each other with respect to the y-axis, but spread along the x-axis. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we were to apply kNN (*k-nearest neighbors*) in a data set like this, we would expect quite some errors using the standard Euclidean distance. This is due to the fact that the spread of the data is not similar amongst the feature dimensions. The following piece of code plots an ellipse on top of the data set. The ellipse in this case is in fact a circunference that helps to visualize how the Euclidean distance weights equally both feature dimensions. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def make_covariance_ellipse(covariance):\n",
" import matplotlib.patches as patches\n",
" import scipy.linalg as linalg\n",
" \n",
" # the ellipse is centered at (0,0)\n",
" mean = numpy.array([0,0])\n",
" \n",
" # eigenvalue decomposition of the covariance matrix (w are eigenvalues and v eigenvectors),\n",
" # keeping only the real part\n",
" w,v = linalg.eigh(covariance)\n",
" # normalize the eigenvector corresponding to the largest eigenvalue\n",
" u = v[0]/linalg.norm(v[0])\n",
" # angle in degrees\n",
" angle = 180.0/numpy.pi*numpy.arctan(u[1]/u[0])\n",
" # fill Gaussian ellipse at 2 standard deviation\n",
" ellipse = patches.Ellipse(mean, 2*w[0]**0.5, 2*w[1]**0.5, 180+angle, color='orange', alpha=0.3)\n",
" \n",
" return ellipse\n",
"\n",
"# represent the Euclidean distance\n",
"figure,axis = pyplot.subplots(1,1)\n",
"plot_data(x,y,axis)\n",
"ellipse = make_covariance_ellipse(numpy.eye(2))\n",
"axis.add_artist(ellipse)\n",
"axis.set_title('Euclidean distance')\n",
"pyplot.show()\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\nPfatAAAAAElFTkSuQmCC\n",
"text": [
"<matplotlib.figure.Figure at 0x322bf10>"
]
}
],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A possible workaround to improve the performance of kNN in a data set like this would be to input to the kNN routine a distance measure. For instance, in the example above a good distance measure would give more weight to the y-direction than to the x-direction to account for the large spread along the x-axis. Nonetheless, it would be nicer (and, in fact, much more useful in practice) if this distance could be learnt automatically from the data at hand. Actually, LMNN is based upon this principle: given a number of neighbours *k*, find the Mahalanobis distance measure which maximizes kNN accuracy (using the given value for *k*) in a training data set. As we usually do in machine learning, under the assumption that the training data is an accurate enough representation of the underlying process, the distance learnt will not only perform well in the training data, but also have good generalization properties. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, let us use the [LMNN class](http://www.shogun-toolbox.org/doc/en/latest/classshogun_1_1CLMNN.html) implemented in Shogun to find the distance and plot its associated ellipse. If everything goes well, we will see that the new ellipse only overlaps with the data points of the green class."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, we need to wrap the data into Shogun's feature and label objects:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from modshogun import RealFeatures, MulticlassLabels\n",
"\n",
"features = RealFeatures(x.T)\n",
"labels = MulticlassLabels(y.astype(numpy.float64))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Secondly, perform LMNN training:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from modshogun import LMNN\n",
"\n",
"# number of target neighbours per example\n",
"k = 1\n",
"\n",
"lmnn = LMNN(features,labels,k)\n",
"# set an initial transform as a start point of the optimization\n",
"init_transform = numpy.eye(2)\n",
"lmnn.set_maxiter(2000)\n",
"lmnn.train(init_transform)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"LMNN is an iterative algorithm. The argument given to [`train`](http://www.shogun-toolbox.org/doc/en/latest/classshogun_1_1CLMNN.html#ab1b8bbdb8390415ac3ae7dc655cb512d) represents the initial state of the solution. By default, if no argument is given, then LMNN uses [PCA](http://en.wikipedia.org/wiki/Principal_component_analysis) to obtain this initial value."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we retrieve the distance measure learnt by LMNN during training and visualize it together with the data:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# get the linear transform from LMNN\n",
"L = lmnn.get_linear_transform()\n",
"# square the linear transform to obtain the Mahalanobis distance matrix\n",
"M = numpy.matrix(numpy.dot(L.T,L))\n",
"\n",
"# represent the distance given by LMNN\n",
"figure,axis = pyplot.subplots(1,1)\n",
"plot_data(x,y,axis)\n",
"ellipse = make_covariance_ellipse(M.I)\n",
"axis.add_artist(ellipse)\n",
"axis.set_title('LMNN distance')\n",
"pyplot.show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\n",
"text": [
"<matplotlib.figure.Figure at 0x41f2e90>"
]
}
],
"prompt_number": 6
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Beyond the main idea"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"LMNN is one of the so-called linear metric learning methods. What this means is that we can understand LMNN's output in two different ways: on the one hand, as a distance measure, this was explained above; on the other hand, as a linear transformation of the input data. Like any other linear transformation, LMNN's output can be written as a matrix, that we will call $L$. In other words, if the input data is represented by the matrix $X$, then LMNN can be understood as the data transformation expressed by $X'=L X$. We use the convention that each column is a feature vector; thus, the number of rows of $X$ is equal to the input dimension of the data, and the number of columns is equal to the number of vectors.\n",
"\n",
"So far, so good. But, if the output of the same method can be interpreted in two different ways, then there must be a relation between them! And that is precisely the case! As mentioned above, the ellipses that were plotted in the previous section represent a distance measure. This distance measure can be thought of as a matrix $M$, being the distance between two vectors $\\vec{x_i}$ and $\\vec{x_j}$ equal to $d(\\vec{x_i},\\vec{x_j})=(\\vec{x_i}-\\vec{x_j})^T M (\\vec{x_i}-\\vec{x_j})$. In general, this type of matrices are known as *Mahalanobis* matrices. In LMNN, the matrix $M$ is precisely the 'square' of the linear transformation $L$, i.e. $M=L^T L$. Note that a direct consequence of this is that $M$ is guaranteed to be positive semi-definite (PSD), and therefore define a valid metric.\n",
"\n",
"This distance measure/linear transform duality in LMNN has its own advantages. An important one is that the optimization problem can go back and forth between the $L$ and the $M$ representations, giving raise to a very efficient solution."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us now visualize LMNN using the linear transform interpretation. In the following figure we have taken our original toy data, transform it using $L$ and plot both the before and after versions of the data together."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# project original data using L\n",
"lx = numpy.dot(L,x.T)\n",
"\n",
"# represent the data in the projected space\n",
"figure,axis = pyplot.subplots(1,1)\n",
"plot_data(lx.T,y,axis)\n",
"plot_data(x,y,axis,0.3)\n",
"ellipse = make_covariance_ellipse(numpy.eye(2))\n",
"axis.add_artist(ellipse)\n",
"axis.set_title('LMNN\\'s linear transform')\n",
"pyplot.show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAARwAAAETCAYAAADkork1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl01FWa8PFvbdlDEkiorBBZwk4AQUBlCM0uymAfDwOt\niMuxGUfUme5Rx3EDFY5L2/POaB+X1kGR7gg6ttCikUWDthJAQVpkCYpIEpJAVrJUklru+8ePhISk\nstevljyfcwKpqpuqpypVT+5+DUophRBC6MDo7QCEEH2HJBwhhG4k4QghdCMJRwihG0k4QgjdSMIR\nQuhGEo5wKyMjgzfeeAOAP/3pT8yfP9/LEfmGRx99lLi4OBITE70dit+RhONBqamp7N69u9X12dnZ\nGI1GfvnLX7a4/vDhwxiNRmbNmtV0ndFoZPz48TSfLvXoo49y++23A3D69GmMRiOLFi1qcV+33HIL\na9eubXq85vfZWQaDAYPBAMDNN9/MJ5980uX78ITbbruNxx57zCuPfebMGX7/+99z/Phxzp4965UY\n/JkkHA9q/oG9XFxcHDk5OZSVlTVd99Zbb5GWltbqZwoLC3nnnXda3O/l9u/fz969ezv12P7E6XR2\n+WccDocHItGcOXOGAQMGMGDAgC7/rCfj8heScLwkKCiIJUuWNCUSp9PJli1buPnmm7l88veDDz7I\nE0880e6H78EHH+SRRx5xe3tj8lFK8W//9m9YrVaioqIYP34833//fYfxvvnmm8yYMaPpstFo5NVX\nXyUtLY2YmBhWr17dovz//u//Mnr0aPr378+CBQs4c+ZM0233338/gwYNIioqismTJ/O3v/2t6bY1\na9Zw0003sWLFCqKionjrrbda3O9rr73Gn//8Z5577jkiIyP5x3/8R0CrTT733HOMHz+eyMhInE4n\nzzzzDMOGDaNfv36MGTOGDz74oMXzufbaa3nggQfo378/Q4YMISsrq8XtQ4cOpV+/fgwZMoQ///nP\n7N69m3nz5nH27FkiIyO54447ANi2bRtjxowhJiaGWbNmcfz48ab7uTyuH3/8EaPRyJtvvsmgQYMY\nMGAAr7zyCgcOHGD8+PHExMRw7733dvj78FtKeExqaqravXt3q+s/++wzlZycrL766is1depUpZRS\n27dvV/Pnz1evv/66ysjIaCprMBjUyZMn1ZVXXqlef/11pZRSjzzyiLrtttuUUkr99NNPymAwqKqq\nKpWUlKR27dqllFLqlltuUWvWrGn12FlZWerKK69UlZWVSimljh8/rgoLC9uMPyMjQ73xxhtKKaU2\nbNigrr322hZx3XDDDaqyslKdOXNGxcXFqaysLKWUUh988IEaNmyYOn78uHI6nerpp59WV199ddPP\nbtq0SZWVlSmn06leeOEFFR8fr+rr65VSSj3xxBPKYrGorVu3KqWUstlsreK67bbb1GOPPdbiusGD\nB6uJEyeq/Px8VVdXp5RS6t133216bps3b1bh4eGqqKio6flYLBb1+uuvK5fLpV5++WWVmJiolFKq\nurpa9evXT+Xm5iqllCoqKlLff/+9Ukqp7OxslZyc3PS4J06cUOHh4WrXrl3K4XCo5557Tg0bNkzZ\n7fY242r8fd19992qvr5e7dixQwUFBaklS5ao8+fPq4KCAjVw4EC1Z8+eNn8n/k5qOF40ffp0ysrK\nyM3NZePGjaxcubLNckajkaeeeoqnnnoKu93eZpmwsDAeeeQRHn300XYfMygoiKqqKo4dO4bL5WLE\niBHEx8d3K/7/+I//oF+/fqSkpDBr1iwOHz4MwCuvvMLDDz/MiBEjMBqNPPzww3z77bfk5eUBWn9Q\nTEwMRqOR3/zmN9TX13PixImm+7366qtZvHgxACEhIW0+trqsFmgwGLjvvvtISkoiODgYgJtuuqnp\nuS1dupThw4ezb9++pp8ZPHgwd955JwaDgVtvvZXCwkLOnTsHaK/5d999h81mw2q1Mnr06DYfd/Pm\nzVx//fXMnj0bk8nEv//7v2Oz2fjqq6/cxgXw2GOPERQUxNy5c4mMjORXv/oVsbGxJCYmMmPGDA4d\nOtSVX4XfkITjZStWrODFF18kOzubG2+8sdUbutHChQtJTk7m1Vdfdds3c+edd1JcXMyHH37o9vFm\nzZrF6tWrueeee7BaraxatYqqqqpuxd48UYWFhVFdXQ3Azz//zP33309MTAwxMTFN/R0FBQUA/O53\nv2P06NFER0cTExNDZWUlJSUlTfeVnJzcrXhSUlJaXN64cSMTJ05siuPIkSOUlpa6jR+gurqa8PBw\nNm/ezCuvvEJiYiLXX399i4TYXGFhIYMGDWq6bDAYSElJaXqubcUFYLVam74PDQ1tdbnxtQw0knC8\n7JZbbuHll19m0aJFbv+aN1q3bh3r16+ntra2zduDgoJ44okneOyxx9wmLoB7772Xr7/+mqNHj5Kb\n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\n",
"text": [
"<matplotlib.figure.Figure at 0x408e610>"
]
}
],
"prompt_number": 7
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the figure above, the transparent points represent the original data and are shown to ease the visualization of the LMNN transformation. Note also that the ellipse plotted is the one corresponding to the common Euclidean distance. This is actually an important consideration: if we think of LMNN as a linear transformation, the distance considered in the projected space is the Euclidean distance, and no any Mahalanobis distance given by M. To sum up, we can think of LMNN as a linear transform of the input space, or as method to obtain a distance measure to be used in the input space. It is an error to apply **both** the projection **and** the learnt Mahalanobis distance. "
]
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"Neighbourhood graphs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"An alternative way to visualize the effect of using the distance found by LMNN together with kNN consists of using neighbourhood graphs. Despite the fancy name, these are actually pretty simple. The idea is just to construct a graph in the Euclidean space, where the points in the data set are the nodes of the graph, and a directed edge from one point to another denotes that the destination node is the 1-nearest neighbour of the origin node. Of course, it is also possible to work with neighbourhood graphs where $k \\gt 1$. Here we have taken the simplification of $k = 1$ so that the forthcoming plots are not too cluttered."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us define a data set for which the Euclidean distance performs considerably bad. In this data set there are several levels or layers in the y-direction. Each layer is populated by points that belong to the same class spread along the x-direction. The layers are close to each other in pairs, whereas the spread along x is larger. Let us define a function to generate such a data set and have a look at it."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import numpy\n",
"import matplotlib.pyplot as pyplot\n",
"%matplotlib inline\n",
"\n",
"def sandwich_data():\n",
" from numpy.random import normal\n",
" \n",
" # number of distinct classes\n",
" num_classes = 6\n",
" # number of points per class\n",
" num_points = 9\n",
" # distance between layers, the points of each class are in a layer\n",
" dist = 0.7\n",
" \n",
" # memory pre-allocation\n",
" x = numpy.zeros((num_classes*num_points, 2))\n",
" y = numpy.zeros(num_classes*num_points)\n",
" \n",
" for i,j in zip(xrange(num_classes), xrange(-num_classes//2, num_classes//2 + 1)):\n",
" for k,l in zip(xrange(num_points), xrange(-num_points//2, num_points//2 + 1)):\n",
" x[i*num_points + k, :] = numpy.array([normal(l, 0.1), normal(dist*j, 0.1)])\n",
" \n",
" y[i*num_points:i*num_points + num_points] = i\n",
" \n",
" return x,y\n",
" \n",
"\n",
"def plot_sandwich_data(x, y, axis=pyplot, cols=['r', 'b', 'g', 'm', 'k', 'y']):\n",
" for idx,val in enumerate(numpy.unique(y)):\n",
" xi = x[y==val]\n",
" axis.scatter(xi[:,0], xi[:,1], s=50, facecolors='none', edgecolors=cols[idx])\n",
"\n",
"x, y = sandwich_data()\n",
"figure, axis = pyplot.subplots(1, 1, figsize=(5,5))\n",
"plot_sandwich_data(x, y, axis)\n",
"\n",
"axis.set_aspect('equal')\n",
"axis.set_title('\"Sandwich\" toy data set')\n",
"axis.set_xlabel('x')\n",
"axis.set_ylabel('y')\n",
"\n",
"pyplot.show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\n",
"text": [
"<matplotlib.figure.Figure at 0x3eba490>"
]
}
],
"prompt_number": 8
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let the fun begin now! In the following block of code, we create an instance of a kNN classifier, compute the nearest neighbours using the Euclidean distance and, afterwards, using the distance computed by LMNN. The data set in the space result of the linear transformation given by LMNN is also shown."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from modshogun import KNN, EuclideanDistance, LMNN, RealFeatures, MulticlassLabels\n",
"\n",
"def plot_neighborhood_graph(x, nn, axis=pyplot, cols=['r', 'b', 'g', 'm', 'k', 'y']):\n",
"\tfor i in xrange(x.shape[0]):\n",
"\t\txs = [x[i,0], x[nn[1,i], 0]]\n",
"\t\tys = [x[i,1], x[nn[1,i], 1]]\n",
"\t\taxis.plot(xs, ys, cols[int(y[i])])\n",
"\n",
"features = RealFeatures(x.T)\n",
"labels = MulticlassLabels(y)\n",
"\n",
"fig, axes = pyplot.subplots(1, 3, figsize=(15, 10))\n",
"\n",
"# use k = 2 instead of 1 because otherwise the method nearest_neighbors just returns the same\n",
"# points as their own 1-nearest neighbours\n",
"k = 2\n",
"\n",
"knn = KNN(k, EuclideanDistance(features, features), labels)\n",
"\n",
"plot_sandwich_data(x, y, axes[0])\n",
"plot_neighborhood_graph(x, knn.nearest_neighbors(), axes[0])\n",
"axes[0].set_title('Euclidean neighbourhood in the input space')\n",
"\n",
"lmnn = LMNN(features, labels, k)\n",
"# set a large number of iterations. The data set is small so it does not cost a lot, and this way\n",
"# we ensure a robust solution\n",
"lmnn.set_maxiter(3000)\n",
"lmnn.train()\n",
"knn.set_distance(lmnn.get_distance())\n",
"\n",
"plot_sandwich_data(x, y, axes[1])\n",
"plot_neighborhood_graph(x, knn.nearest_neighbors(), axes[1])\n",
"axes[1].set_title('LMNN neighbourhood in the input space')\n",
"\n",
"# plot features in the transformed space, with the neighbourhood graph computed using the Euclidean distance\n",
"L = lmnn.get_linear_transform()\n",
"xl = numpy.dot(x, L.T)\n",
"features = RealFeatures(xl.T)\n",
"knn.set_distance(EuclideanDistance(features, features))\n",
"\n",
"plot_sandwich_data(xl, y, axes[2])\n",
"plot_neighborhood_graph(xl, knn.nearest_neighbors(), axes[2])\n",
"axes[2].set_ylim(-3, 2.5)\n",
"axes[2].set_title('Euclidean neighbourhood in the transformed space')\n",
"\n",
"[axes[i].set_xlabel('x') for i in xrange(len(axes))]\n",
"[axes[i].set_ylabel('y') for i in xrange(len(axes))]\n",
"[axes[i].set_aspect('equal') for i in xrange(len(axes))]\n",
"\n",
"pyplot.show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\n",
"text": [
"<matplotlib.figure.Figure at 0x4ea1f90>"
]
}
],
"prompt_number": 10
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice how all the lines that go across the different layers in the left hand side figure have disappeared in the figure in the middle. Indeed, LMNN did a pretty good job here. The figure in the right hand side shows the disposition of the points in the transformed space; from which the neighbourhoods in the middle figure should be clear. In any case, this toy example is just an illustration to give an idea of the power of LMNN. In the next section we will see how after applying a couple methods for feature normalization (e.g. scaling, whitening) the Euclidean distance is not so sensitive against different feature scales."
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Real data sets"
]
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"Feature selection in metagenomics"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Metagenomics is a modern field in charge of the study of the DNA of microorganisms. The data set we have chosen for this section contains information about three different types of apes; in particular, gorillas, chimpanzees, and bonobos. Taking an approach based on metagenomics, the main idea is to study the DNA of the microorganisms (e.g. bacteria) which live inside the body of the apes. Owing to the many chemical reactions produced by these microorganisms, it is not only the DNA of the host itself important when studying, for instance, sickness or health, but also the DNA of the microorganisms inhabitants."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First of all, let us load the ape data set. This data set contains features taken from the bacteria inhabitant in the gut of the apes."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from modshogun import CSVFile, RealFeatures, MulticlassLabels\n",
"\n",
"ape_features = RealFeatures(CSVFile('../../../data/multiclass/fm_ape_gut.dat'))\n",
"ape_labels = MulticlassLabels(CSVFile('../../../data/multiclass/label_ape_gut.dat'))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 11
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is of course important to have a good insight of the data we are dealing with. For instance, how many examples and different features do we have?"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print('Number of examples = %d, number of features = %d.' % (ape_features.get_num_vectors(), ape_features.get_num_features()))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Number of examples = 85, number of features = 1472.\n"
]
}
],
"prompt_number": 12
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So, 1472 features! Those are quite many features indeed. In other words, the feature vectors at hand lie on a 1472-dimensional space. We cannot visualize in the input feature space how the feature vectors look like. However, in order to gain a little bit more of understanding of the data, we can apply dimension reduction, embed the feature vectors in a two-dimensional space, and plot the vectors in the embedded space. To this end, we are going to use one of the [many](http://www.shogun-toolbox.org/doc/en/latest/classshogun_1_1CEmbeddingConverter.html) methods for dimension reduction included in Shogun. In this case, we are using t-distributed stochastic neighbour embedding (or [t-dsne](http://jmlr.org/papers/v9/vandermaaten08a.html)). This method is particularly suited to produce low-dimensional embeddings (two or three dimensions) that are straightforward to visualize."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def visualize_tdsne(features, labels):\n",
" from modshogun import TDistributedStochasticNeighborEmbedding\n",
" \n",
" converter = TDistributedStochasticNeighborEmbedding()\n",
" converter.set_target_dim(2)\n",
" converter.set_perplexity(25)\n",
" \n",
" embedding = converter.embed(features)\n",
" \n",
" import matplotlib.pyplot as pyplot\n",
" % matplotlib inline\n",
" \n",
" x = embedding.get_feature_matrix()\n",
" y = labels.get_labels()\n",
" \n",
" pyplot.scatter(x[0, y==0], x[1, y==0], color='green')\n",
" pyplot.scatter(x[0, y==1], x[1, y==1], color='red')\n",
" pyplot.scatter(x[0, y==2], x[1, y==2], color='blue')\n",
" pyplot.show()\n",
" \n",
"visualize_tdsne(ape_features, ape_labels)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\n",
"text": [
"<matplotlib.figure.Figure at 0x3feb590>"
]
}
],
"prompt_number": 13
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the figure above, the green points represent chimpanzees, the red ones bonobos, and the blue points gorillas. Providing the results in the figure, we can rapidly draw the conclusion that the three classes of apes are somewhat easy to discriminate in the data set since the classes are more or less well separated in two dimensions. Note that t-dsne use randomness in the embedding process. Thus, the figure result of the experiment in the previous block of code will be different after different executions. Feel free to play around and observe the results after different runs! After this, it should be clear that the bonobos form most of the times a very compact cluster, whereas the chimpanzee and gorillas clusters are more spread. Also, there tends to be a chimpanzee (a green point) closer to the gorillas' cluster. This is probably a outlier in the data set."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Even before applying LMNN to the ape gut data set, let us apply kNN classification and study how it performs using the typical Euclidean distance. Furthermore, since this data set is rather small in terms of number of examples, the kNN error above may vary considerably (I have observed variation of almost 20% a few times) across different runs. To get a robust estimate of how kNN performs in the data set, we will perform cross-validation using [Shogun's framework](http://www.shogun-toolbox.org/doc/en/latest/classshogun_1_1CCrossValidation.html) for evaluation. This will give us a reliable result regarding how well kNN performs in this data set."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from modshogun import KNN, EuclideanDistance\n",
"from modshogun import StratifiedCrossValidationSplitting, CrossValidation\n",
"from modshogun import CrossValidationResult, MulticlassAccuracy\n",
"\n",
"# set up the classifier\n",
"knn = KNN()\n",
"knn.set_k(3)\n",
"knn.set_distance(EuclideanDistance())\n",
"\n",
"# set up 5-fold cross-validation\n",
"splitting = StratifiedCrossValidationSplitting(ape_labels, 5)\n",
"# evaluation method\n",
"evaluator = MulticlassAccuracy()\n",
"cross_validation = CrossValidation(knn, ape_features, ape_labels, splitting, evaluator)\n",
"# locking is not supported for kNN, deactivate it to avoid an inoffensive warning\n",
"cross_validation.set_autolock(False)\n",
"# number of experiments, the more we do, the less variance in the result\n",
"num_runs = 200\n",
"cross_validation.set_num_runs(num_runs)\n",
"\n",
"# perform cross-validation and print the result!\n",
"result = cross_validation.evaluate()\n",
"result = CrossValidationResult.obtain_from_generic(result)\n",
"print('kNN mean accuracy in a total of %d runs is %.4f.' % (num_runs, result.mean))\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"kNN mean accuracy in a total of 200 runs is 0.9855.\n"
]
}
],
"prompt_number": 14
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we can say that KNN performs actually pretty well in this data set. The average test classification error is less than between 2%. This error rate is already low and we should not really expect a significant improvement applying LMNN. This ought not be a surprise. Recall that the points in this data set have more than one thousand features and, as we saw before in the dimension reduction experiment, only two dimensions in an embedded space were enough to discern arguably well the chimpanzees, gorillas and bonobos."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that we have used stratified splitting for cross-validation. Stratified splitting divides the folds used during cross-validation so that the proportion of the classes in the initial data set is approximately maintained for each of the folds. This is particular useful in *skewed* data sets, where the number of examples among classes varies significantly."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nonetheless, LMNN may still turn out to be very useful in a data set like this one. Making a small modification of the vanilla LMNN algorithm, we can enforce that the linear transform found by LMNN is diagonal. This means that LMNN can be used to weight each of the features and, once the training is performed, read from these weights which features are relevant to apply kNN and which ones are not. This is indeed a form of *feature selection*. Using Shogun, it is extremely easy to switch to this so-called *diagonal* mode for LMNN: just call the method [`set_diagonal(use_diagonal)`](http://www.shogun-toolbox.org/doc/en/latest/classshogun_1_1CLMNN.html#ad2f03dbad3ad08ab76aecbb656a486e6) with `use_diagonal` set to `True`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following experiment takes about five minutes until it is completed (using Shogun Release, i.e. compiled with optimizations enabled). This is mostly due to the high dimension of the data (1492 features) and the fact that, during training, LMNN has to compute many outer products of feature vectors, which is a computation whose time complexity is proportional to the square of the number of features. For the illustration purposes of this notebook, in the following cell we are just going to use a small subset of all the features so that the training is finished in a few seconds."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from modshogun import LMNN\n",
"import numpy\n",
"\n",
"# to make training faster, use a portion of the features\n",
"fm = ape_features.get_feature_matrix()\n",
"ape_features_subset = RealFeatures(fm[:300, :])\n",
"\n",
"# number of targer neighbours in LMNN, here we just use the same value that was used for KNN before\n",
"k = 3\n",
"lmnn = LMNN(ape_features_subset, ape_labels, k)\n",
"lmnn.set_diagonal(True)\n",
"lmnn.set_maxiter(1200)\n",
"init_transform = numpy.eye(ape_features_subset.get_num_features())\n",
"lmnn.train(init_transform)\n",
"\n",
"diagonal = numpy.diag(lmnn.get_linear_transform())\n",
"print('%d out of %d elements are non-zero.' % (numpy.sum(diagonal != 0), diagonal.size))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"65 out of 300 elements are non-zero.\n"
]
},
{
"output_type": "stream",
"stream": "stderr",
"text": [
"-c:14: RuntimeWarning: \u001b[1;34m[WARN]\u001b[0m In file /home/iglesias/workspace/shogun/src/shogun/metric/LMNNImpl.cpp line 287: Maximum number of iterations reached before convergence.\n"
]
}
],
"prompt_number": 15
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So only 65 out of the 300 first features are important according to the result transform! The rest of them have been given a weight exactly equal to zero, even if all of the features were weighted equally with a value of one at the beginnning of the training. In fact, if all the 1472 features were used, only about 158 would have received a non-zero weight. Please, feel free to experiment using all the features!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is a fair question to ask how did we know that the maximum number of iterations in this experiment should be around 1200 iterations. Well, the truth is that we know this only because we have run this experiment with this same data beforehand, and we know that after this number of iterations the algorithm has converged. This is not something nice, and the ideal case would be if one could completely forget about this parameter, so that LMNN uses as many iterations as it needs until it converges. Nevertheless, this is not practical at least because of two reasons:\n",
"\n",
"- If you are dealing with many examples or with very high dimensional feature vectors, you might not want to wait until the algorithm converges and have a look at what LMNN has found before it has completely converged.\n",
"- As with any other algorithm based on gradient descent, the termination criteria can be tricky. Let us illustrate this further:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import matplotlib.pyplot as pyplot\n",
"%matplotlib inline\n",
"\n",
"statistics = lmnn.get_statistics()\n",
"pyplot.plot(statistics.obj.get())\n",
"pyplot.grid(True)\n",
"pyplot.xlabel('Number of iterations')\n",
"pyplot.ylabel('LMNN objective')\n",
"pyplot.show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\ndOvWjYceekjbXrlyJX/+858d8tqJiYn84x//cMhr/ZRNmzYRGhqq3dakUWVlJTfffDMAn3/+Oe+9\n957D3rO2tpa//vWvF30vIZxJCpHwOD169OCf//wnx44dAxx7hf7lvFZDQ0O7n5uamsrf//53duzY\n0ax9wIABbNq0CYC9e/eydetWh8Vw/Phx1qxZc9H3EsKZpBAJj2MwGLjnnnt46aWXWuz7cY/myiuv\nBCAvL48bb7yRmTNnEhgYyKOPPkp6ejpRUVFERETwzTffaMds376dcePGMWzYMN59910Azp07x8MP\nP0xUVBQjR47k9ddf1173hhtuYMaMGYwYMaJFPG+//TYRERGEh4fz6KOPAvDUU0/x0Ucfceedd/LI\nI480e35paSnh4eGcPXuWP/3pT2zYsIFRo0axadMmfvjhB+68807Gjx/P6NGjyc7OBuxXxickJBAb\nG0t8fDw//PADcXFxjBkzhoiICO15jz76KAcPHmTUqFEsW7aMQ4cOERYWBsDp06e54447iIiIYPTo\n0drdj9etW8esWbOYMmUKwcHBLFu2TPt5JCYmEh4eTkREBC+//HIHf4uiS3HwNVFC6O7KK69UJ06c\nUAEBAaq2tlatXLlSPfnkk0oppRITE1VmZmaz5yql1M6dO5Wvr686fPiwOnPmjBowYIB64oknlFJK\nrVq1Sj3wwANKKaUWLVqkpkyZopRSymKxKJPJpE6fPq3+9re/qWeeeUYpZb9Z49ixY5XValU7d+5U\nvXr1UqWlpS3itNlsatCgQeq7775TDQ0NasKECWrLli1KKaViYmJUYWFhi2Oaro68bt26ZhcMPvbY\nY2r9+vVKKft9joKDg9UPP/yg3njjDWUymbSLLRsaGtSJEyeUUkodPXpUBQUFKaWUKi0tbbbyctP3\nWrlypUpKSlJKKfXVV1+pQYMGqdOnT6s33nhDDR06VJ04cUKdPn1aDR48WJWXl6uCggIVHx+vvVbT\n+9gI8WPSIxIeqXfv3ixcuJDVq1e3+5hx48bh7+9Pjx49CAoK0m4tHxYWRmlpKWAfmps7dy4AQUFB\nDB06lK+++orc3FzefPNNRo0aRXR0NNXV1Xz99dcAREVFMXjw4Bbv9+mnn3LTTTfh5+dH9+7due22\n29i1a5e2X7Vxrbmy38ZF287NzWXFihWMGjWKm266iTNnzlBWVoaXlxfx8fH4+voCcP78eR577DFG\njhxJfHw8lZWVfPvttz/5fh999BG33347AMOGDWPw4MGUlJTg5eVFbGwsvXv35oorriA0NJSysjIC\nAwP55ptvuP/++3n//ffx8fFp68cvujBvvQMQwlkeeOABRo8ezR133KG1eXt7c/78ecD+gVxfX6/t\nu+KKK7Tvu3Xrpm1369btJ+dWGueN/vKXvxAfH99sX15eHr169Wr1uKYf/kqpZnNQlzIftXnzZsxm\nc7O2/Pz8ZjG89dZbfPfddxQVFdG9e3eGDBnC6dOn23zt1gpV059b9+7daWhowNfXl88//5z333+f\n1157jY0bN5KamtrhfETXID0i4bGuuuoq5s6dS2pqqvahHhAQQGFhIQDZ2dmcPXu2Q6+plGLTpk0o\npTh48CDffPMNISEhTJo0iTVr1mgFq6SkhJMnT/7ka40bN44PP/yQY8eOce7cOTIyMrjxxhvbHYuP\njw91dXXa9qRJk5r1APfu3avF3NSJEyfo168f3bt3Z+fOnRw6dAiw9yKbvl5TN9xwg7b6cklJCWVl\nZYSEhFy0OCmltJxmzZrF008/TVFRUbvzEl2PFCLhcZr2JH73u9/x3Xffadt33303H374IZGRkeze\nvVs7WeHHx/349Rr3eXl5MWjQIKKiopg6dSp/+9vf6NGjB3fddRehoaGMHj2a8PBwkpOTaWho+Ml7\n1FxzzTWsWLGCm266icjISMaOHcv06dPbnd9NN91EcXGxdrLC448/ztmzZ4mIiCAsLIwnnniiRfwA\nt912GwUFBURERJCens7w4cMB8PPz4/rrryc8PJxly5Y1O27x4sWcP3+eiIgIbrnlFtLS0jAYDBfN\nz8vLC5vNxk033cSoUaNYsGBBi/ssCdGULHoqhBBCV9IjEkIIoSspREIIIXQlhUgIIYSupBAJIYTQ\nlRQiIYQQupJCJIQQQlf/H0gmjBpGbki6AAAAAElFTkSuQmCC\n",
"text": [
"<matplotlib.figure.Figure at 0x560e210>"
]
}
],
"prompt_number": 16
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Along approximately the first three hundred iterations, there is not much variation in the objective. In other words, the objective curve is pretty much flat. If we are not careful and use termination criteria that are not demanding enough, training could be stopped at this point. This would be wrong, and might have terrible results as the training had not clearly converged yet at that moment."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In order to avoid disastrous situations, in Shogun we have implemented LMNN with really demanding criteria for automatic termination of the training process. Albeit, it is possible to tune the termination criteria using the methods [`set_stepsize_threshold`](http://www.shogun-toolbox.org/doc/en/latest/classshogun_1_1CLMNN.html#a76b6914cf9d1a53b0c9ecd828c7edbcb) and [`set_obj_threshold`](http://www.shogun-toolbox.org/doc/en/latest/classshogun_1_1CLMNN.html#af78c7dd9ed2307c0d53e7383cdc01a24). These methods can be used to modify the lower bound required in the step size and the increment in the objective (relative to its absolute value), respectively, to stop training. Also, it is possible to set a hard upper bound on the number of iterations using [`set_maxiter`](http://www.shogun-toolbox.org/doc/en/latest/classshogun_1_1CLMNN.html#afcf319806eb710a0d9535fbeddf93795) as we have done above. In case the internal termination criteria did not fire before the maximum number of iterations was reached, you will receive a warning message, similar to the one shown above. This is not a synonym that the training went wrong; but it is strongly recommended at this event to have a look at the objective plot as we have done in the previous block of code."
]
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"Multiclass classification"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In addition to feature selection, LMNN can be of course used for multiclass classification. I like to think about LMNN in multiclass classification as a way to empower kNN. This is, the idea is basically to apply kNN using the distance found by LMNN $-$ in contrast with using one of the other most common distances, such as the Euclidean one. To this end we will use the wine data set from the [UCI Machine Learning repository](http://archive.ics.uci.edu/ml/datasets/Wine \"Wine data set\")."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from modshogun import CSVFile, RealFeatures, MulticlassLabels\n",
"\n",
"wine_features = RealFeatures(CSVFile('../../../data/multiclass/fm_wine.dat'))\n",
"wine_labels = MulticlassLabels(CSVFile('../../../data/multiclass/label_wine.dat'))\n",
"\n",
"assert(wine_features.get_num_vectors() == wine_labels.get_num_labels())\n",
"print('%d feature vectors with %d features from %d different classes.' % (wine_features.get_num_vectors(), \\\n",
" wine_features.get_num_features(), wine_labels.get_num_classes()))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"178 feature vectors with 13 features from 3 different classes.\n"
]
}
],
"prompt_number": 17
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, let us evaluate the performance of kNN in this data set using the same cross-validation setting used in the previous section:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from modshogun import KNN, EuclideanDistance\n",
"from modshogun import StratifiedCrossValidationSplitting, CrossValidation\n",
"from modshogun import CrossValidationResult, MulticlassAccuracy\n",
"import numpy\n",
"\n",
"# kNN classifier\n",
"k = 5\n",
"knn = KNN()\n",
"knn.set_k(k)\n",
"knn.set_distance(EuclideanDistance())\n",
"\n",
"splitting = StratifiedCrossValidationSplitting(wine_labels, 5)\n",
"evaluator = MulticlassAccuracy()\n",
"cross_validation = CrossValidation(knn, wine_features, wine_labels, splitting, evaluator)\n",
"cross_validation.set_autolock(False)\n",
"num_runs = 200\n",
"cross_validation.set_num_runs(num_runs)\n",
"\n",
"result = CrossValidationResult.obtain_from_generic(cross_validation.evaluate())\n",
"euclidean_means = numpy.zeros(3)\n",
"euclidean_means[0] = result.mean\n",
"\n",
"print('kNN accuracy with the Euclidean distance %.4f.' % result.mean)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"kNN accuracy with the Euclidean distance 0.6971.\n"
]
}
],
"prompt_number": 18
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Seconly, we will use LMNN to find a distance measure and use it with kNN:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from modshogun import LMNN\n",
"\n",
"# train LMNN\n",
"lmnn = LMNN(wine_features, wine_labels, k)\n",
"lmnn.set_maxiter(5000)\n",
"lmnn.train()\n",
"\n",
"# evaluate kNN using the distance learnt by LMNN\n",
"knn.set_distance(lmnn.get_distance())\n",
"\n",
"result = CrossValidationResult.obtain_from_generic(cross_validation.evaluate())\n",
"lmnn_means = numpy.zeros(3)\n",
"lmnn_means[0] = result.mean\n",
"\n",
"print('kNN accuracy with the distance obtained by LMNN %.4f.' % result.mean)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"kNN accuracy with the distance obtained by LMNN 0.9710.\n"
]
},
{
"output_type": "stream",
"stream": "stderr",
"text": [
"-c:6: RuntimeWarning: \u001b[1;34m[WARN]\u001b[0m In file /home/iglesias/workspace/shogun/src/shogun/metric/LMNNImpl.cpp line 287: Maximum number of iterations reached before convergence.\n"
]
}
],
"prompt_number": 19
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The warning is fine in this case, we have made sure that the objective variation was really small after 5000 iterations. In any case, do not hesitate to check it yourself studying the objective plot as it was shown in the previous section."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As the results point out, LMNN really helps here to achieve better classification performance. However, this comparison is not entirely fair since the Euclidean distance is very sensitive to the scaling that different feature dimensions may have, whereas LMNN can adjust to this during training. Let us have a closer look to this fact. Next, we are going to retrieve the feature matrix and see what are the maxima and minima for every dimension."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print('minima = ' + str(numpy.min(wine_features, axis=1)))\n",
"print('maxima = ' + str(numpy.max(wine_features, axis=1)))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"minima = [ 1.10300000e+01 7.40000000e-01 1.36000000e+00 1.06000000e+01\n",
" 7.00000000e+01 9.80000000e-01 3.40000000e-01 1.30000000e-01\n",
" 4.10000000e-01 1.28000000e+00 4.80000000e-01 1.27000000e+00\n",
" 2.78000000e+02]\n",
"maxima = [ 1.48300000e+01 5.80000000e+00 3.23000000e+00 3.00000000e+01\n",
" 1.62000000e+02 3.88000000e+00 5.08000000e+00 6.60000000e-01\n",
" 3.58000000e+00 1.30000000e+01 1.71000000e+00 4.00000000e+00\n",
" 1.68000000e+03]\n"
]
}
],
"prompt_number": 20
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Examine the second and the last dimensions, for instance. The second dimension has values ranging from 0.74 to 5.8, while the values of the last dimension range from 278 to 1680. This will cause that the Euclidean distance works specially wrong in this data set. You can realize of this considering that the total distance between two points will almost certainly just take into account the contributions of the dimensions with largest range."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In order to produce a more fair comparison, we will rescale the data so that all the feature dimensions are within the interval [0,1]. Luckily, there is a [preprocessor](http://www.shogun-toolbox.org/doc/en/latest/classshogun_1_1CPreprocessor.html) class in Shogun that makes this straightforward."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from modshogun import RescaleFeatures\n",
"\n",
"# preprocess features so that all of them vary within [0,1]\n",
"preprocessor = RescaleFeatures()\n",
"preprocessor.init(wine_features)\n",
"wine_features.add_preprocessor(preprocessor)\n",
"wine_features.apply_preprocessor()\n",
"\n",
"# sanity check\n",
"feature_matrix = wine_features.get_feature_matrix()\n",
"assert(numpy.min(wine_features) >= 0.0 and numpy.max(wine_features) <= 1.0)\n",
"\n",
"# perform kNN classification after the feature rescaling\n",
"knn.set_distance(EuclideanDistance())\n",
"result = CrossValidationResult.obtain_from_generic(cross_validation.evaluate())\n",
"euclidean_means[1] = result.mean\n",
"\n",
"print('kNN accuracy with the Euclidean distance after feature rescaling %.4f.' % result.mean)\n",
"\n",
"# train kNN in the new features and classify with kNN\n",
"lmnn.train()\n",
"knn.set_distance(lmnn.get_distance())\n",
"result = CrossValidationResult.obtain_from_generic(cross_validation.evaluate())\n",
"lmnn_means[1] = result.mean\n",
"\n",
"print('kNN accuracy with the distance obtained by LMNN after feature rescaling %.4f.' % result.mean)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"kNN accuracy with the Euclidean distance after feature rescaling 0.9570.\n",
"kNN accuracy with the distance obtained by LMNN after feature rescaling 0.9969."
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 21
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Another different preprocessing that can be applied to the data is called *whitening*. Whitening, which is explained in an [article in wikipedia](http://en.wikipedia.org/wiki/Whitening_transformation \"Whitening transform\"), transforms the covariance matrix of the data into the identity matrix."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import scipy.linalg as linalg\n",
"\n",
"# shorthand for the feature matrix -- this makes a copy of the feature matrix\n",
"data = wine_features.get_feature_matrix()\n",
"# remove mean\n",
"data = data.T\n",
"data-= numpy.mean(data, axis=0)\n",
"# compute the square of the covariance matrix and its inverse\n",
"M = linalg.sqrtm(numpy.cov(data.T))\n",
"# keep only the real part, although the imaginary that pops up in the sqrtm operation should be equal to zero\n",
"N = linalg.inv(M).real\n",
"# apply whitening transform\n",
"white_data = numpy.dot(N, data.T)\n",
"wine_white_features = RealFeatures(white_data)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 22
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The covariance matrices before and after the transformation can be compared to see that the covariance really becomes the identity matrix."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import matplotlib.pyplot as pyplot\n",
"%matplotlib inline\n",
"\n",
"fig, axarr = pyplot.subplots(1,2)\n",
"axarr[0].matshow(numpy.cov(wine_features))\n",
"axarr[1].matshow(numpy.cov(wine_white_features))\n",
"pyplot.show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAWwAAACyCAYAAABm3PVSAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFZJJREFUeJzt3X9UVOeZB/DvVSCmEKkaGFKB4BpZGCCAP0pDw3FiHK3p\nag0SK6iwYuyeuMnGxJpk29PtcLZBPLRpMNmT3bpRsbpqNzmr1iVswpqxpoYmOaNuW62mlkmGqERj\noSGoCL77B0il4uS+l/sO88r3c86cM4zPfO8b8+RhMjP3vYYQQoCIiMLeiKFeABERmcOBTUSkCQ5s\nIiJNcGATEWmCA5uISBMc2EREmgjZwK6vr0daWhomTZqEdevW2ZodCARw3333ISMjA5mZmVi/fr2t\n+QDQ3d2N3NxczJ0719bc1tZWFBUVIT09HU6nE42Njbbmr127FhkZGcjKykJJSQkuXbpkOau8vBwO\nhwNZWVl9j50/fx5utxupqamYNWsWWltbbc1fs2YN0tPTkZ2djcLCQrS1tVnOV0VVb+vc14Da3raz\nrwG1vW1rX4sQ6OrqEhMnThRNTU2is7NTZGdni6NHj9qWf/r0aXHo0CEhhBCffvqpSE1NtTVfCCF+\n9KMfiZKSEjF37lxbc0tLS8XLL78shBDi8uXLorW11bbspqYmMWHCBHHx4kUhhBALFy4Umzdvtpz3\ni1/8Qvh8PpGZmdn32Jo1a8S6deuEEEJUVVWJp59+2tb8119/XXR3dwshhHj66acHla+Cyt7Wua+F\nUNfbdve1EGp7286+Dskr7HfeeQd33XUXUlJSEBkZiUWLFmH37t225SckJCAnJwcAEBMTg/T0dJw6\ndcq2/ObmZtTV1eHhhx+GsPE8o7a2Nhw4cADl5eUAgIiICMTGxtqWP3r0aERGRqKjowNdXV3o6OjA\n+PHjLecVFBRgzJgx/R7bs2cPysrKAABlZWXYtWuXrflutxsjRvS0aV5eHpqbmy3nq6Cyt3Xta0Bt\nb9vd14Da3razr0MysD/66CMkJSX1/ZyYmIiPPvpIybH8fj8OHTqEvLw82zKfeOIJVFdX9/0F26Wp\nqQlxcXFYtmwZJk+ejBUrVqCjo8O2/LFjx2L16tVITk7Gl770JXzxi1/EzJkzbcsHgJaWFjgcDgCA\nw+FAS0uLrfnX2rhxIx544AFl+VaEqrd16mtAbW+Hoq+B0PW2TF+HZGAbhhGKw6C9vR1FRUWoqalB\nTEyMLZl79+5FfHw8cnNzbX8V0tXVBZ/Ph5UrV8Ln8yE6OhpVVVW25Z88eRLPP/88/H4/Tp06hfb2\ndmzbts22/L9kGIayf9fPPvssoqKiUFJSoiTfqlD0tm59Dajt7VD3NaCut2X7OiQDe/z48QgEAn0/\nBwIBJCYm2nqMy5cvY8GCBViyZAnmz59vW+7BgwexZ88eTJgwAcXFxdi3bx9KS0ttyU5MTERiYiKm\nTZsGACgqKoLP57MlGwDee+895OfnY9y4cYiIiEBhYSEOHjxoWz7Q88rjzJkzAIDTp08jPj7e1nwA\n2Lx5M+rq6pT/R2mF6t7Wsa8Btb0dir4G1Pe2lb4OycCeOnUq3n//ffj9fnR2dmLnzp2YN2+ebflC\nCCxfvhxOpxOrVq2yLRcAKisrEQgE0NTUhB07dmDGjBnYsmWLLdkJCQlISkrCiRMnAAANDQ3IyMiw\nJRsA0tLS0NjYiAsXLkAIgYaGBjidTtvyAWDevHmora0FANTW1to6VICeb2BUV1dj9+7dGDVqlK3Z\ndlDZ27r2NaC2t0PR14Da3rbc15Y+9rSgrq5OpKamiokTJ4rKykpbsw8cOCAMwxDZ2dkiJydH5OTk\niNdee83WYwghhNfrtf3T9MOHD4upU6eKu+++Wzz44IO2fktECCHWrVsnnE6nyMzMFKWlpaKzs9Ny\n1qJFi8Qdd9whIiMjRWJioti4caP45JNPxP333y8mTZok3G63+OMf/2hb/ssvvyzuuusukZyc3Pfv\n9ZFHHrGcr4qq3ta5r4VQ29t29rUQanvbzr42hOD2qkREOuCZjkREmuDAJiLSRISK0FB9jY+Gr6F6\nJ4+9TaoF620lAxsAxD9d/5hnP+CZPnB91D+Y3yNi3Lhz1z3W7qlBjOfxAevPzPkr09kAkPnau9c9\n9rFnA+I9Kwasn4jfS+V/DEe/nwOeWiR5ygasffuxGVLZMVVnr3uss7IaUd9ZM2D9S9GPSOUvrX2l\n/wO7PMB8z4C1I772mVT2h47kfj8/57mAJz23XleXaJyXyrXb9wd4zAvAdYP6igGfISNY+mCpzFad\nrzJbdf6NsiuCPotviRARacLywFa5+x7RUGFfUzizNLC7u7vx6KOPor6+HkePHsX27dtx7Nixz32e\n604rRzMnymXfHgsDiXZNVpY92pWtLBsARhbkqwtPcymLvsel7B27AVntawBIUboylekqs1Xnq8xW\nnW8t29J/EdfuUAagb4ey9PT0vhrP/j/Xu+4EXCk9N1WiXF9RFw4g2jVFWXasK0dZNgCMLPiqunCl\nAzsSAPC29zLe9nYpO85VZvoa6Hn38aqUa27qqExXma06X2W26vyr2f7emzmWBvZAO5T96le/6ldz\now8XiWTd44rsG94A8FzFBSXHMdPXgNqPuWi4SUH/Xwz7By7rZektEX61iW5G7GsKd5YGdih23yMK\nNfY1hTtLA1v17ntEQ4F9TeHO0nvYERERePHFFzF79mx0d3dj+fLl130wQ6Qb9jWFO8vfm5ozZw7m\nzJlj51qIhhz7msKZku1VDcNA5Dnzp5oDQOe3zV+g87YXP5bKzok+LFX/1qtuqXo8KleOM+ZLy8RL\nUtG1K+RONb93wxtS9W8ZKRLVY6WysWScubqtxhDvJSJ3qvn3P+d042sN/jR20ltF0N7mqelERJrg\nwCYi0gQHNhGRJjiwiYg0wYFNRKQJDmwiIk1wYBMRaYIDm4hIExzYRESa4MAmItIEBzYRkSaU7SWS\nIE5KPaf9s9tM166N/kep7FdQJFV/FE6p+k9aTO6B0etK10jTtXHj5fZNObs/War+zum/k6r/YGea\n+eIEqWjTa/nASNdqLxEZMvuOANx75ObDvUSIiG4KlgZ2IBDAfffdh4yMDGRmZmL9+vV2r4toSLC3\nKZxZ2g87MjISP/7xj5GTk4P29nZMmTIFbrebm72T9tjbFM4svcJOSEhATk4OACAmJgbp6ek4deqU\nrQsjGgrsbQpnlq84c5Xf78ehQ4eQl5fX7/F2T03f/ShXHqJcXxnsoWiYuuh9Bxe974T8uDfqbcB7\nzf2U3huRFf7emzmDGtjt7e0oKipCTU0NYmJi+v1ZjOfxwUQT9Rnl+jJGub7c93Nbxb8oP2aw3gZc\nyo9Pw0UK+v/C3x+02vK3RC5fvowFCxZgyZIlmD9/vtUYorDD3qZwZWlgCyGwfPlyOJ1OrFq1yu41\nEQ0Z9jaFM0sD+5e//CW2bt2KN998E7m5ucjNzUV9fb3dayMKOfY2hTNL72Hfe++9uHLlit1rIRpy\n7G0KZ8pOTcfX5GLvfe0N07Uj0S2VvQErpOpTdwak6vGvcuW4aL50ydsbpKK3Vsj9s2KmXDk2S9TK\nnfUOHDZZ127ctKemy+Kp7DcbnppORHRT4MAmItIEBzYRkSY4sImINMGBTUSkCQ5sIiJNcGATEWmC\nA5uISBMc2EREmuDAJiLSBAc2EZEmlO0lkinkrhDym1enma6NW/ChVPbZnclS9T/75lyp+ifxnFT9\nJdxiuvbsUrm1J/z0D1L1nd3m1wIA538z3nzxKKloLPjrrabqXjWWci8Ri7j3SLjjXiJERDcFywO7\nu7sbubm5mDtX7tUoUbhjb1O4sjywa2pq4HQ6e/8Xkejmwd6mcGVpYDc3N6Ourg4PP/zwkL2XSKQC\ne5vCmaUrzjzxxBOorq7Gn/70pxvWfOz588b70a7JiHZNsXIoIpz1HsNZ77GQHMtMbwPea+6noP9V\nr4lk+Htv5kgP7L179yI+Ph65ubnwer03rIv3SF75hOgG4lzpiHOl9/18rOK/lBzHbG8DLiXHp+Eo\nBf1/4e8PWi39lsjBgwexZ88eTJgwAcXFxdi3bx9KS0tlY4jCDnubwp30wK6srEQgEEBTUxN27NiB\nGTNmYMuWLSrWRhRS7G0Kd4P+HjY/SaebFXubwo2lDx2vmj59OqZPn27XWojCBnubwhHPdCQi0oSy\nvUS+If5D6jm77yg2XTvi8GdS2VcWRUvVJ775vlR94NupUvWYZb7UmH1CKvpn4kmp+oXbfi5Vv3rx\nD0zX/vD170ll/+esvzFVt9DYy71EQoR7j4Qa9xIhIropcGATEWmCA5uISBMc2EREmuDAJiLSBAc2\nEZEmOLCJiDTBgU1EpAkObCIiTXBgExFpggObiEgTg9qtL5iP4ZB7whnzpVe6RsplX5Qrv4Rb5J4g\nsTcIAOCwTPH/SUVHoVOqXm4tQMpiv/liuS1ZcGmW5N87KSe7N4jM3iPcd0QeX2ETEWnC8sBubW1F\nUVER0tPT4XQ60djYaOe6iIYE+5rCmeW3RB5//HE88MADeOWVV9DV1YXPPpPb8pQoHLGvKZxZGtht\nbW04cOAAamtre0IiIhAbG2vrwohCjX1N4c7SwG5qakJcXByWLVuGI0eOYMqUKaipqcEXvvCFvpqA\np7bv/mhXNmJdOYNfLQ1Lx7xnccx7VvlxzPR1D+8191N6b0RW+Htv5lh6D7urqws+nw8rV66Ez+dD\ndHQ0qqqq+tUkecr6bhzWNBjprjgUepx9N1XM9HUP1zW3FGXroeEgBf37KThLAzsxMRGJiYmYNm0a\nAKCoqAg+n89KFFHYYF9TuLM0sBMSEpCUlIQTJ3quN9jQ0ICMjAxbF0YUauxrCneWvyXywgsvYPHi\nxejs7MTEiROxadMmO9dFNCTY1xTOLA/s7OxsvPvuu3auhWjIsa8pnBki2DXVrYYaBvCoXGzZCy+Z\nrq3D16WyZ+N/pOq3Ll0hVY+tkudgS5xuLiYUSSUbl+X+3uMCH0rVn52TbL643iOVjdtN1p8zoKBt\nTTEMA+Ap1baQOY0dGC6nslcE7W2emk5EpAkObCIiTXBgExFpggObiEgTHNhERJrgwCYi0gQHNhGR\nJjiwiYg0wYFNRKQJDmwiIk1wYBMRaULZXiIx7R9LPad9VZz54iWSC/LKlSd8/w9S9evxuFR9FDpN\n185PktsHpc0fJVUfW29+LQAw+etvma79Liqlsrdgqam63UYJ9xIZhobH3iPcS4SI6KZgeWCvXbsW\nGRkZyMrKQklJCS5dumTnuoiGBPuawpmlge33+7Fhwwb4fD78+te/Rnd3N3bs2GH32ohCin1N4c7S\nBQxGjx6NyMhIdHR0YOTIkejo6MD48ePtXhtRSLGvKdxZGthjx47F6tWrkZycjFtvvRWzZ8/GzJkz\n+9V0Vlb33R9ZkI+RBV8d3Epp2DrnPYpz3mPKj2Omr3t4r7mfAl45nazz997MsTSwT548ieeffx5+\nvx+xsbF46KGHsG3bNixevLivJuo7a6xEE13ndpcTt7ucfT8fr3hVyXHM9HUPl5Lj03CUgv6/8PcH\nrbb0HvZ7772H/Px8jBs3DhERESgsLMTBgwetRBGFDfY1hTtLAzstLQ2NjY24cOEChBBoaGiA0+n8\n/CcShTH2NYU7SwM7OzsbpaWlmDp1Ku6++24AwLe+9S1bF0YUauxrCneW3sMGgKeeegpPPfWUnWsh\nGnLsawpnPNORiEgTll9hf56Xoh+Rqv+3DX9nujaAJKnsDyLSpOo7u2+Rql+44+dS9ThsvjQu8KFU\ndOx/y+0NIm41pOoNw/weHgvwE6nsheJ/peppeJHdG+Rm3HuEr7CJiDTBgU1EpAkObCIiTXBgExFp\nggObiEgTHNhERJrgwCYi0gQHNhGRJjiwiYg0wYFNRKQJDmwiIk0YQgjzm0OYDTUMYLNk7N++b752\nxyS57Aa5cjwqV746+wdS9SkSlwR6bM6/S2VPfu0tqXqfca9UvWgxv/dIY3y2VPbf40VTdT6jAAra\n1hTDMAAN9pwgeTJ7j6jbd6QiaG/zFTYRkSaCDuzy8nI4HA5kZWX1PXb+/Hm43W6kpqZi1qxZaG1t\nVb5IIjuxr0lXQQf2smXLUF9f3++xqqoquN1unDhxAvfffz+qqqqULpDIbuxr0lXQgV1QUIAxY8b0\ne2zPnj0oKysDAJSVlWHXrl3qVkekAPuadCV9AYOWlhY4HA4AgMPhQEtLy8CFuzx/vp/m6rkRWfCp\n9xDavYeUHsN0XwMAvNfcT+m9EVnh772ZM6grzhiG0fup+QDmewYTTdTnNlcubnPl9v18umKT0uMF\n7WsAgEvp8Wk4SUH/X/j7g1ZLf0vE4XDgzJkzAIDTp08jPj5eNoIo7LCvSQfSA3vevHmora0FANTW\n1mL+/Pm2L4oo1NjXpIOgA7u4uBj5+fk4fvw4kpKSsGnTJjzzzDN44403kJqain379uGZZ54J1VqJ\nbMG+Jl0FfQ97+/btAz7e0CB76iBR+GBfk64G9aFjMCO+9plU/RWMNV+cILmY30nWj5Ir/+Hr35N7\ngsRZ+I/VJ0pFfxfvSNUvwE+k6mVON683jkhlzxavm6rzSaUSmSNzurnMaeyy2cHw1HQiIk1wYBMR\naYIDm4hIExzYRESa4MAmItIEBzYRkSY4sImINMGBTUSkCQ5sIiJNcGATEWmCA5uISBOGCHZNdauh\nhoFmIbE3CIDEpZ+Yrr3zp3Kbg3xwW5pU/YJPt0rVfxM7peov4RbTtUvjXpHK/sbZgTc2upFb0ClV\n/3tMNF07G+b2Brmqct4/m6ozfg4oaFtzxzYMwKZ9IWj4MLv3SAWC9zZfYRMRaSLowC4vL4fD4UBW\nVlbfY2vWrEF6ejqys7NRWFiItrY25Ysksht7m3QUdGAvW7YM9fX1/R6bNWsWfvvb3+LIkSNITU3F\n2rVrlS6QSAX2Nuko6MAuKCjAmDFj+j3mdrsxYkTP0/Ly8tDc3KxudUSKsLdJR4O6gMHGjRtRXFw8\n4J8957nQd/8eVwTucUUO5lA0jHnPAV7zn0nbIlhvA95r7qeg/1Wviczz997Msjywn332WURFRaGk\npGTAP3/Sc6vVaKJ+XLf33K6qOKH2eJ/X24BL7QJo2EhB/1/3+z+n3tK3RDZv3oy6ujps27ZN6nlv\ney9bOZwpF71yl8aSddZ7TFn2Me9ZZdkAcM57VFn2p95DyrK955RF35DV3pZ7nSRL12zV+Sqz1eZb\nTZYe2PX19aiursbu3bsxapTcxQ/f9nbJHs40DuwbO6dw7e0qB3aI3wYZTG/rO5hUZqvOV5mtNt9q\nctCBXVxcjPz8fBw/fhxJSUnYuHEjHnvsMbS3t8PtdiM3NxcrV660eGiiocPeJh0FfQ97+/brz5or\nLy9XthiiUGFvk46UnZpOpNLQnppOpE6w3lYysImIyH7cS4SISBMc2EREmuDAJiLSBAc2EZEmOLCJ\niDTBgU1EpIn/B6iv8unHcDDRAAAAAElFTkSuQmCC\n",
"text": [
"<matplotlib.figure.Figure at 0x5015910>"
]
}
],
"prompt_number": 23
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we evaluate again the performance obtained with kNN using the Euclidean distance and the distance found by LMNN using the whitened features."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"wine_features = wine_white_features\n",
"\n",
"# perform kNN classification after whitening\n",
"knn.set_distance(EuclideanDistance())\n",
"result = CrossValidationResult.obtain_from_generic(cross_validation.evaluate())\n",
"euclidean_means[2] = result.mean\n",
"\n",
"print('kNN accuracy with the Euclidean distance after whitening %.4f.' % result.mean)\n",
"\n",
"# train kNN in the new features and classify with kNN\n",
"lmnn.train()\n",
"knn.set_distance(lmnn.get_distance())\n",
"result = CrossValidationResult.obtain_from_generic(cross_validation.evaluate())\n",
"lmnn_means[2] = result.mean\n",
"\n",
"print('kNN accuracy with the distance obtained by LMNN after whitening %.4f.' % result.mean)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"kNN accuracy with the Euclidean distance after whitening 0.9565.\n",
"kNN accuracy with the distance obtained by LMNN after whitening 0.9967."
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 24
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As it can be seen, it did not really help to whiten the features in this data set with respect to only applying feature rescaling; the accuracy was already rather large after rescaling. In any case, it is good to know that this transformation exists, as it can become useful with other data sets, or before applying other machine learning algorithms."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us summarize the results obtained in this section with a bar chart grouping the accuracy results by distance (Euclidean or the one found by LMNN), and feature preprocessing:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"assert(euclidean_means.shape[0] == lmnn_means.shape[0])\n",
"N = euclidean_means.shape[0]\n",
"# the x locations for the groups\n",
"ind = 0.5*numpy.arange(N)\n",
"# bar width\n",
"width = 0.15\n",
"figure, axes = pyplot.subplots()\n",
"\n",
"euclidean_rects = axes.bar(ind, euclidean_means, width, color='y')\n",
"lmnn_rects = axes.bar(ind+width, lmnn_means, width, color='r')\n",
"\n",
"# attach information to chart\n",
"axes.set_ylabel('Accuracies')\n",
"axes.set_ylim(top=1.4)\n",
"axes.set_title('kNN accuracy by distance and feature preprocessing')\n",
"axes.set_xticks(ind+width)\n",
"axes.set_xticklabels(('Raw', 'Rescaling', 'Whitening'))\n",
"axes.legend(( euclidean_rects[0], lmnn_rects[0]), ('Euclidean', 'LMNN'), loc='upper right')\n",
"\n",
"def autolabel(rects):\n",
" # attach text labels to bars\n",
" for rect in rects:\n",
" height = rect.get_height()\n",
" axes.text(rect.get_x()+rect.get_width()/2., 1.05*height, '%.3f' % height,\n",
" ha='center', va='bottom')\n",
" \n",
"autolabel(euclidean_rects)\n",
"autolabel(lmnn_rects)\n",
"\n",
"pyplot.show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\n",
"text": [
"<matplotlib.figure.Figure at 0x477fe10>"
]
}
],
"prompt_number": 25
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"References"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Weinberger, K. Q., Saul, L. K. Distance Metric Learning for Large Margin Nearest Neighbor Classification. [(Link to paper in JMLR)](http://jmlr.org/papers/v10/weinberger09a.html)."
]
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment