├── LICENSE ├── README ├── make_plotly2d.ipynb ├── make_plotly3d.ipynb ├── svm.ipynb └── svm.py /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | SVM example mapping 2-d non-linearly separable points to 3-d using a custom kernel. 2 | 3 | svm.py and svm.ipynb: 4 | generate points, fit model (using sklearn package) 5 | 6 | make_plotly*d.ipynb: 7 | generate plotly plots (2d makes use of plotly's matplotlib converter, but 3d--not supported by the converter--is written from scratch) 8 | -------------------------------------------------------------------------------- /make_plotly2d.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "", 4 | "signature": "sha256:7f1e471e736dca032e43aaee8b3e94455c16633e52d039dcd1a5ea5e5d36cd55" 5 | }, 6 | "nbformat": 3, 7 | "nbformat_minor": 0, 8 | "worksheets": [ 9 | { 10 | "cells": [ 11 | { 12 | "cell_type": "code", 13 | "collapsed": false, 14 | "input": [ 15 | "import numpy as np\n", 16 | "import matplotlib.pyplot as plt\n", 17 | "from mpl_toolkits.mplot3d import Axes3D\n", 18 | "import plotly.plotly as py" 19 | ], 20 | "language": "python", 21 | "metadata": {}, 22 | "outputs": [], 23 | "prompt_number": 13 24 | }, 25 | { 26 | "cell_type": "code", 27 | "collapsed": false, 28 | "input": [ 29 | "np.random.seed(0)\n", 30 | "# create 400 points randomly distributed between -3 and 3 (along x and y)\n", 31 | "X = np.random.uniform(-3,3,(400,2))\n", 32 | "\n", 33 | "# points within a circle centered at (1.5, 0) of radius 1 are labeled class +1,\n", 34 | "# and -1 otherwise\n", 35 | "shift = 1.5\n", 36 | "radius = 1\n", 37 | "X_shift = X[:,0]-shift\n", 38 | "R_shift = np.sqrt(X_shift**2 + X[:,1]**2)\n", 39 | "\n", 40 | "# class labels\n", 41 | "Y = np.asarray(map(lambda x: 1 if x else -1, R_shift < radius))" 42 | ], 43 | "language": "python", 44 | "metadata": {}, 45 | "outputs": [], 46 | "prompt_number": 14 47 | }, 48 | { 49 | "cell_type": "code", 50 | "collapsed": false, 51 | "input": [ 52 | "mpl_fig_obj= plt.figure()\n", 53 | "\n", 54 | "# plot 2-d data\n", 55 | "plt.scatter(X[:,0], X[:,1], c=Y, cmap=plt.cm.Paired)\n", 56 | "fig = plt.gcf()\n", 57 | "circle = plt.Circle((shift,0), radius, color='black', fill=False)\n", 58 | "fig.gca().add_artist(circle)\n", 59 | "fig.gca().set_aspect('equal')\n", 60 | "plt.xlabel('x')\n", 61 | "plt.ylabel('y')" 62 | ], 63 | "language": "python", 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "metadata": {}, 68 | "output_type": "pyout", 69 | "prompt_number": 15, 70 | "text": [ 71 | "" 72 | ] 73 | }, 74 | { 75 | "metadata": {}, 76 | "output_type": "display_data", 77 | "png": "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\n", 78 | "text": [ 79 | "" 80 | ] 81 | } 82 | ], 83 | "prompt_number": 15 84 | }, 85 | { 86 | "cell_type": "code", 87 | "collapsed": false, 88 | "input": [ 89 | "#plotly_fig = tls.mpl_to_plotly(mpl_fig_obj)\n", 90 | "#plot_url = py.plot(plotly_fig, filename='2d-binaryclass')\n", 91 | "\n", 92 | "py.plot_mpl(mpl_fig_obj, filename = '2d-classification')" 93 | ], 94 | "language": "python", 95 | "metadata": {}, 96 | "outputs": [ 97 | { 98 | "metadata": {}, 99 | "output_type": "pyout", 100 | "prompt_number": 16, 101 | "text": [ 102 | "u'https://plot.ly/~frangipane/67'" 103 | ] 104 | } 105 | ], 106 | "prompt_number": 16 107 | } 108 | ], 109 | "metadata": {} 110 | } 111 | ] 112 | } -------------------------------------------------------------------------------- /make_plotly3d.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "", 4 | "signature": "sha256:d0a682199aeed2325beecd67cb8fa3aabc10fcebc786c8a8de77aa3aff308931" 5 | }, 6 | "nbformat": 3, 7 | "nbformat_minor": 0, 8 | "worksheets": [ 9 | { 10 | "cells": [ 11 | { 12 | "cell_type": "code", 13 | "collapsed": false, 14 | "input": [ 15 | "import numpy as np\n", 16 | "import matplotlib.pyplot as plt\n", 17 | "from mpl_toolkits.mplot3d import Axes3D\n", 18 | "from sklearn import svm\n", 19 | "from sklearn import metrics\n", 20 | "import sklearn\n", 21 | "import re\n", 22 | "\n", 23 | "import plotly.plotly as py\n", 24 | "import plotly.graph_objs as go" 25 | ], 26 | "language": "python", 27 | "metadata": {}, 28 | "outputs": [], 29 | "prompt_number": 1 30 | }, 31 | { 32 | "cell_type": "code", 33 | "collapsed": false, 34 | "input": [ 35 | "np.random.seed(0)\n", 36 | "# create 400 points randomly distributed between -3 and 3 (along x and y)\n", 37 | "X = np.random.uniform(-3,3,(400,2))\n", 38 | "\n", 39 | "# points within a circle centered at (1.5, 0) of radius 1 are labeled class +1,\n", 40 | "# and -1 otherwise\n", 41 | "shift = 1.5\n", 42 | "radius = 1\n", 43 | "X_shift = X[:,0]-shift\n", 44 | "R_shift = np.sqrt(X_shift**2 + X[:,1]**2)\n", 45 | "\n", 46 | "# class labels\n", 47 | "Y = np.asarray(map(lambda x: 1 if x else -1, R_shift < radius))" 48 | ], 49 | "language": "python", 50 | "metadata": {}, 51 | "outputs": [], 52 | "prompt_number": 2 53 | }, 54 | { 55 | "cell_type": "code", 56 | "collapsed": false, 57 | "input": [ 58 | "def map_func(x):\n", 59 | " \"\"\"\n", 60 | " Map d-dimensional data to d+1-dimensions. Return a numpy array of data points. \n", 61 | " \n", 62 | " x : matrix, a collection of data points, shape = [n_samples, n_features]\n", 63 | " \"\"\"\n", 64 | " if len(x.shape) == 1:\n", 65 | " # x contains only a single data point\n", 66 | " return np.r_[x, calc_z(x)]\n", 67 | " else:\n", 68 | " z = [np.r_[j, calc_z(j)] for j in x]\n", 69 | " return np.array(z)\n", 70 | "\n", 71 | "def calc_z(x):\n", 72 | " \"\"\"\n", 73 | " Take the dot product of an array with itself.\n", 74 | " \n", 75 | " x : array, shape = [1, n_features]\n", 76 | " \"\"\"\n", 77 | " return np.dot(x, x.T)\n", 78 | "\n", 79 | "def my_kernel(x1, x2):\n", 80 | " \"\"\"\n", 81 | " Custom kernel to pass to sklearn svm.SVC via its kernel parameter\n", 82 | " \n", 83 | " x1 : matrix, a collection of data points, shape = [n_samples, n_features]\n", 84 | " x2 : matrix, a collection of data points, shape = [n_samples, n_features]\n", 85 | " \"\"\"\n", 86 | " return np.dot(map_func(x1), map_func(x2).T)\n", 87 | "\n", 88 | "def calc_plane_norm(sv, coef):\n", 89 | " \"\"\"\n", 90 | " Calculate the normal to the hyperplane (in mapped space)\n", 91 | " \n", 92 | " sv : matrix, contains mapped points, shape = [n_supportvectors, n_mappedfeatures]\n", 93 | " coef : array of floats, shape = [n_supportvectors, 1]\n", 94 | " \"\"\" \n", 95 | " components = coef[:, np.newaxis]*sv\n", 96 | " return np.sum(components, axis = 0)\n", 97 | "\n", 98 | "def calc_z_plane(x):\n", 99 | " \"\"\"\n", 100 | " Calculate z-coordinates of the decision plane\n", 101 | " \n", 102 | " x: matrix, shape = [n_samples, n_features]\n", 103 | " \"\"\"\n", 104 | " return (-w[0]*x[0] - w[1]*x[1] - b)/w[2]" 105 | ], 106 | "language": "python", 107 | "metadata": {}, 108 | "outputs": [], 109 | "prompt_number": 3 110 | }, 111 | { 112 | "cell_type": "code", 113 | "collapsed": false, 114 | "input": [ 115 | "model = svm.SVC(kernel=my_kernel, C=1000, tol=1e-3)\n", 116 | "model.fit(X,Y)\n", 117 | "\n", 118 | "# coef : dual coefficients alpha_i*y_i per support vector in decision function\n", 119 | "coef = model.dual_coef_[0]\n", 120 | "# intercept in decision function\n", 121 | "b = model.intercept_\n", 122 | "\n", 123 | "# bug in sklearn versions before 0.16: https://github.com/scikit-learn/scikit-learn/issues/4262\n", 124 | "# The first class to appear in the dataset, i.e. Y[0], is mapped to the class +1, even if it is labeled -1\n", 125 | "version_check = re.match(r\"0\\.(\\d+).\", sklearn.__version__).group(1)\n", 126 | "if np.sign(Y[0]) == -1 and int(version_check) < 16:\n", 127 | " coef = -coef" 128 | ], 129 | "language": "python", 130 | "metadata": {}, 131 | "outputs": [], 132 | "prompt_number": 4 133 | }, 134 | { 135 | "cell_type": "code", 136 | "collapsed": false, 137 | "input": [ 138 | "# create mapped data points (from 2d to 3d)\n", 139 | "Xm = map_func(X)\n", 140 | "\n", 141 | "# Xm_sv is an array of the support vectors (in 3d)\n", 142 | "# model.support_ contains the indices of the support vectors\n", 143 | "Xm_sv = np.array([Xm[i] for i in model.support_])\n", 144 | "w = calc_plane_norm(Xm_sv, coef)" 145 | ], 146 | "language": "python", 147 | "metadata": {}, 148 | "outputs": [], 149 | "prompt_number": 5 150 | }, 151 | { 152 | "cell_type": "code", 153 | "collapsed": false, 154 | "input": [ 155 | "# zgrid corresponds to z coordinates of paraboloid in the mapped space\n", 156 | "xgrid, ygrid = np.meshgrid(np.arange(-3,3,0.1), np.arange(-3,3,0.1))\n", 157 | "zgrid = np.array(map(calc_z, np.c_[xgrid.ravel(), ygrid.ravel()]))\n", 158 | "zgrid = zgrid.reshape(xgrid.shape)\n", 159 | "\n", 160 | "# zplane is the z coordinates of the hyperplane\n", 161 | "zplane = np.array(map(calc_z_plane, np.c_[xgrid.ravel(), ygrid.ravel()]))\n", 162 | "zplane = zplane.reshape(xgrid.shape)" 163 | ], 164 | "language": "python", 165 | "metadata": {}, 166 | "outputs": [], 167 | "prompt_number": 6 168 | }, 169 | { 170 | "cell_type": "code", 171 | "collapsed": false, 172 | "input": [ 173 | "Y_ind = (Y == 1)" 174 | ], 175 | "language": "python", 176 | "metadata": {}, 177 | "outputs": [], 178 | "prompt_number": 7 179 | }, 180 | { 181 | "cell_type": "code", 182 | "collapsed": false, 183 | "input": [ 184 | "# subscripts: 1->points inside circle, 2-> points outside circle\n", 185 | "#x1 = x_all[Y_ind]\n", 186 | "#x2 = x_all[~Y_ind]\n", 187 | "#y1 = y_all[Y_ind]\n", 188 | "#y2 = y_all[~Y_ind]\n", 189 | "x1 = [k[1] for k in enumerate(Xm[:,0]) if Y_ind[k[0]]]\n", 190 | "x2 = [k[1] for k in enumerate(Xm[:,0]) if ~Y_ind[k[0]]]\n", 191 | "y1 = [k[1] for k in enumerate(Xm[:,1]) if Y_ind[k[0]]]\n", 192 | "y2 = [k[1] for k in enumerate(Xm[:,1]) if ~Y_ind[k[0]]]\n", 193 | "z1 = [k[1] for k in enumerate(Xm[:,2]) if Y_ind[k[0]]]\n", 194 | "z2 = [k[1] for k in enumerate(Xm[:,2]) if ~Y_ind[k[0]]]" 195 | ], 196 | "language": "python", 197 | "metadata": {}, 198 | "outputs": [], 199 | "prompt_number": 8 200 | }, 201 | { 202 | "cell_type": "code", 203 | "collapsed": false, 204 | "input": [ 205 | "# 2-d points inside circle - scatter plot\n", 206 | "\n", 207 | "scatter2d_in = go.Scatter3d(\n", 208 | " x = x1,\n", 209 | " y = y1,\n", 210 | " z = np.array([0]*len(x1)),\n", 211 | " mode = 'markers',\n", 212 | " marker = dict(\n", 213 | " size=3,\n", 214 | " symbol='dot',\n", 215 | " color='rgb(177,40,40)',\n", 216 | " opacity = 0.5\n", 217 | " ),\n", 218 | " showlegend = False\n", 219 | ")\n", 220 | "\n", 221 | "# 2-d points outside circle - scatter plot\n", 222 | "\n", 223 | "scatter2d_out = go.Scatter3d(\n", 224 | " x = x2,\n", 225 | " y = y2,\n", 226 | " z = np.array([0]*len(x2)),\n", 227 | " mode = 'markers',\n", 228 | " marker = dict(\n", 229 | " size=3,\n", 230 | " symbol='dot',\n", 231 | " color='rgb(83,101,227)',\n", 232 | " opacity = 0.5\n", 233 | " ),\n", 234 | " showlegend = False\n", 235 | ")\n", 236 | "\n", 237 | "# 3-d points inside circle - scatter plot\n", 238 | "scatter3d_in = go.Scatter3d(\n", 239 | " x = x1,\n", 240 | " y = y1,\n", 241 | " z = z1,\n", 242 | " mode = 'markers',\n", 243 | " marker = dict(\n", 244 | " size=3,\n", 245 | " symbol='dot',\n", 246 | " color='rgb(177,40,40)',\n", 247 | " opacity = 1\n", 248 | " ),\n", 249 | " showlegend = False\n", 250 | ")\n", 251 | "\n", 252 | "# 3-d points outside circle - scatter plot\n", 253 | "scatter3d_out = go.Scatter3d(\n", 254 | " x = x2,\n", 255 | " y = y2,\n", 256 | " z = z2,\n", 257 | " mode = 'markers',\n", 258 | " marker = dict(\n", 259 | " size=3,\n", 260 | " symbol='dot',\n", 261 | " color='rgb(83,101,227)',\n", 262 | " opacity = 1\n", 263 | " ),\n", 264 | " showlegend = False\n", 265 | ")\n", 266 | "\n", 267 | "# hyperplane - surface plot\n", 268 | "surface_plane = go.Surface(\n", 269 | " z = zplane,\n", 270 | " x = xgrid,\n", 271 | " y = ygrid,\n", 272 | " name = 'hyperplane',\n", 273 | " opacity = 1,\n", 274 | " showlegend = False,\n", 275 | " zauto = False,\n", 276 | " showscale = False,\n", 277 | " zmin = 0,\n", 278 | " zmax = 1,\n", 279 | " colorscale = [[0, 'rgb(70,70,70)'],[1, 'rgb(70,70,70)']]\n", 280 | ")\n", 281 | "\n", 282 | "# paraboloid - surface plot\n", 283 | "surface_paraboloid = go.Surface(\n", 284 | " z = zgrid,\n", 285 | " x = xgrid,\n", 286 | " y = ygrid,\n", 287 | " name = 'paraboloid',\n", 288 | " opacity = 0.99,\n", 289 | " showlegend = False,\n", 290 | " zauto = False,\n", 291 | " showscale = False,\n", 292 | " zmin = 0,\n", 293 | " zmax = 1,\n", 294 | " colorscale = [[0, 'rgb(255,255,0)'],[1, 'rgb(255,255,0)']]\n", 295 | ")" 296 | ], 297 | "language": "python", 298 | "metadata": {}, 299 | "outputs": [], 300 | "prompt_number": 26 301 | }, 302 | { 303 | "cell_type": "code", 304 | "collapsed": false, 305 | "input": [ 306 | "data = go.Data([scatter2d_in, scatter2d_out, scatter3d_in, scatter3d_out, surface_plane, surface_paraboloid])" 307 | ], 308 | "language": "python", 309 | "metadata": {}, 310 | "outputs": [], 311 | "prompt_number": 27 312 | }, 313 | { 314 | "cell_type": "code", 315 | "collapsed": false, 316 | "input": [ 317 | "layout = go.Layout(\n", 318 | " title='SVM classifier',\n", 319 | " autosize=False,\n", 320 | " width=800,\n", 321 | " height=800,\n", 322 | " margin=dict(\n", 323 | " l=0,\n", 324 | " r=0,\n", 325 | " b=0,\n", 326 | " t=0\n", 327 | " ),\n", 328 | " scene = go.Scene(\n", 329 | " zaxis = dict(\n", 330 | " autorange = False,\n", 331 | " range = [-2,18])\n", 332 | " )\n", 333 | ")" 334 | ], 335 | "language": "python", 336 | "metadata": {}, 337 | "outputs": [], 338 | "prompt_number": 28 339 | }, 340 | { 341 | "cell_type": "code", 342 | "collapsed": false, 343 | "input": [ 344 | "fig = go.Figure(data=data, layout=layout)\n", 345 | "plot_url = py.plot(fig, filename='SVM-classifier')" 346 | ], 347 | "language": "python", 348 | "metadata": {}, 349 | "outputs": [], 350 | "prompt_number": 29 351 | }, 352 | { 353 | "cell_type": "code", 354 | "collapsed": false, 355 | "input": [ 356 | "plot_url" 357 | ], 358 | "language": "python", 359 | "metadata": {}, 360 | "outputs": [ 361 | { 362 | "metadata": {}, 363 | "output_type": "pyout", 364 | "prompt_number": 13, 365 | "text": [ 366 | "u'https://plot.ly/~frangipane/35'" 367 | ] 368 | } 369 | ], 370 | "prompt_number": 13 371 | } 372 | ], 373 | "metadata": {} 374 | } 375 | ] 376 | } -------------------------------------------------------------------------------- /svm.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | from mpl_toolkits.mplot3d import Axes3D 4 | from sklearn import svm 5 | from sklearn import metrics 6 | import sklearn 7 | import re 8 | 9 | 10 | # generate non-linearly separable data and plot 11 | 12 | np.random.seed(0) 13 | # create 400 points randomly distributed between -3 and 3 (along x and y) 14 | X = np.random.uniform(-3,3,(400,2)) 15 | 16 | # points within a circle centered at (1.5, 0) of radius 1 are labeled class +1, 17 | # and -1 otherwise 18 | shift = 1.5 19 | radius = 1 20 | X_shift = X[:,0]-shift 21 | R_shift = np.sqrt(X_shift**2 + X[:,1]**2) 22 | 23 | # class labels 24 | Y = np.asarray(map(lambda x: 1 if x else -1, R_shift < radius)) 25 | 26 | # plot 2-d data 27 | plt.scatter(X[:,0], X[:,1], c=Y, cmap=plt.cm.Paired) 28 | fig = plt.gcf() 29 | circle = plt.Circle((shift,0), radius, color='black', fill=False) 30 | fig.gca().add_artist(circle) 31 | fig.gca().set_aspect('equal') 32 | plt.xlabel('x') 33 | plt.ylabel('y') 34 | plt.show() 35 | 36 | #============================================================================== 37 | 38 | def map_func(x): 39 | """ 40 | Map d-dimensional data to d+1-dimensions. Return a numpy array of data points. 41 | 42 | x : matrix, a collection of data points, shape = [n_samples, n_features] 43 | """ 44 | if len(x.shape) == 1: 45 | # x contains only a single data point 46 | return np.r_[x, calc_z(x)] 47 | else: 48 | z = [np.r_[j, calc_z(j)] for j in x] 49 | return np.array(z) 50 | 51 | def calc_z(x): 52 | """ 53 | Take the dot product of an array with itself. 54 | 55 | x : array, shape = [1, n_features] 56 | """ 57 | return np.dot(x, x.T) 58 | 59 | def my_kernel(x1, x2): 60 | """ 61 | Custom kernel to pass to sklearn svm.SVC via its kernel parameter 62 | 63 | x1 : matrix, a collection of data points, shape = [n_samples, n_features] 64 | x2 : matrix, a collection of data points, shape = [n_samples, n_features] 65 | """ 66 | return np.dot(map_func(x1), map_func(x2).T) 67 | 68 | 69 | # fit SVM with custom non-linear kernel 70 | model = svm.SVC(kernel=my_kernel, C=1000, tol=1e-3) 71 | model.fit(X,Y) 72 | 73 | # coef : dual coefficients alpha_i*y_i per support vector in decision function 74 | coef = model.dual_coef_[0] 75 | # intercept in decision function 76 | b = model.intercept_ 77 | 78 | # bug in sklearn versions before 0.16: https://github.com/scikit-learn/scikit-learn/issues/4262 79 | # The first class to appear in the dataset, i.e. Y[0], is mapped to the class +1, even if it is labeled -1 80 | version_check = re.match(r"0\.(\d+).", sklearn.__version__).group(1) 81 | if np.sign(Y[0]) == -1 and int(version_check) < 16: 82 | coef = -coef 83 | 84 | def calc_plane_norm(sv, coef): 85 | """ 86 | Calculate the normal to the hyperplane (in mapped space) 87 | 88 | sv : matrix, contains mapped points, shape = [n_supportvectors, n_mappedfeatures] 89 | coef : array of floats, shape = [n_supportvectors, 1] 90 | """ 91 | components = coef[:, np.newaxis]*sv 92 | return np.sum(components, axis = 0) 93 | 94 | def calc_z_plane(x): 95 | """ 96 | Calculate z-coordinates of the decision plane 97 | 98 | x: matrix, shape = [n_samples, n_features] 99 | """ 100 | return (-w[0]*x[0] - w[1]*x[1] - b)/w[2] 101 | 102 | # create mapped data points (from 2d to 3d) 103 | Xm = map_func(X) 104 | 105 | # Xm_sv is an array of the support vectors (in 3d) 106 | # model.support_ contains the indices of the support vectors 107 | Xm_sv = np.array([Xm[i] for i in model.support_]) 108 | w = calc_plane_norm(Xm_sv, coef) 109 | 110 | # zgrid corresponds to z coordinates of paraboloid in the mapped space 111 | xgrid, ygrid = np.meshgrid(np.arange(-3,3,0.1), np.arange(-3,3,0.1)) 112 | zgrid = np.array(map(calc_z, np.c_[xgrid.ravel(), ygrid.ravel()])) 113 | zgrid = zgrid.reshape(xgrid.shape) 114 | 115 | fig2 = plt.figure() 116 | ax = fig2.gca(projection='3d') 117 | 118 | # zplane is the z coordinates of the hyperplane 119 | zplane = np.array(map(calc_z_plane, np.c_[xgrid.ravel(), ygrid.ravel()])) 120 | zplane = zplane.reshape(xgrid.shape) 121 | 122 | # plot original points and highlight support vectors 123 | ax.scatter(X[:,0], X[:,1], [0]*len(X[:,0]), c = Y, cmap='coolwarm', linewidth=0, alpha=0.3) 124 | ax.scatter(X[model.support_, 0], X[model.support_, 1],[0]*len(model.support_), s=80, facecolors='none') 125 | 126 | # plot decision boundary 127 | ax.plot_surface(xgrid, ygrid, zplane, alpha=0.5, linewidth=0, color='grey') 128 | 129 | # plot mapped points 130 | ax.plot_surface(xgrid, ygrid, zgrid, alpha=0.2, linewidth=0, color='yellow') 131 | ax.scatter(X[:,0], X[:,1], map(calc_z, X), c = Y, cmap='coolwarm', linewidth=0.5) 132 | 133 | ax.set_zlim([0,15]) 134 | ax.set_xlabel('x') 135 | ax.set_ylabel('y') 136 | ax.set_zlabel('x^2 + y^2') 137 | plt.axis('tight') 138 | plt.show() 139 | 140 | # predicted Y (on training set) 141 | Ypred = model.predict(X) 142 | 143 | print("Classification report %s:\n%s\n" 144 | % (model, metrics.classification_report(Y, Ypred))) 145 | print("Confusion matrix:\n%s" % metrics.confusion_matrix(Y, Ypred)) --------------------------------------------------------------------------------