1.4. Support Vector Machines

Support vector machines (SVMs) are a set of supervised learningmethods used for classification,regression and outliers detection.

The advantages of support vector machines are:

  • Effective in high dimensional spaces.

  • Still effective in cases where number of dimensions is greaterthan the number of samples.

  • Uses a subset of training points in the decision function (calledsupport vectors), so it is also memory efficient.

  • Versatile: different Kernel functions can bespecified for the decision function. Common kernels areprovided, but it is also possible to specify custom kernels.

The disadvantages of support vector machines include:

  • If the number of features is much greater than the number ofsamples, avoid over-fitting in choosing Kernel functions and regularizationterm is crucial.

  • SVMs do not directly provide probability estimates, these arecalculated using an expensive five-fold cross-validation(see Scores and probabilities, below).

The support vector machines in scikit-learn support both dense(numpy.ndarray and convertible to that by numpy.asarray) andsparse (any scipy.sparse) sample vectors as input. However, to usean SVM to make predictions for sparse data, it must have been fit on suchdata. For optimal performance, use C-ordered numpy.ndarray (dense) orscipy.sparse.csr_matrix (sparse) with dtype=float64.

1.4.1. Classification

SVC, NuSVC and LinearSVC are classescapable of performing multi-class classification on a dataset.

../_images/sphx_glr_plot_iris_svc_0011.png

SVC and NuSVC are similar methods, but acceptslightly different sets of parameters and have different mathematicalformulations (see section Mathematical formulation). On theother hand, LinearSVC is another implementation of SupportVector Classification for the case of a linear kernel. Note thatLinearSVC does not accept keyword kernel, as this isassumed to be linear. It also lacks some of the members ofSVC and NuSVC, like support_.

As other classifiers, SVC, NuSVC andLinearSVC take as input two arrays: an array X of size [n_samples,n_features] holding the training samples, and an array y of class labels(strings or integers), size [n_samples]:

>>>

  1. >>> from sklearn import svm
  2. >>> X = [[0, 0], [1, 1]]
  3. >>> y = [0, 1]
  4. >>> clf = svm.SVC()
  5. >>> clf.fit(X, y)
  6. SVC()

After being fitted, the model can then be used to predict new values:

>>>

  1. >>> clf.predict([[2., 2.]])
  2. array([1])

SVMs decision function depends on some subset of the training data,called the support vectors. Some properties of these support vectorscan be found in members supportvectors, support_ andn_support:

>>>

  1. >>> # get support vectors
  2. >>> clf.support_vectors_
  3. array([[0., 0.],
  4. [1., 1.]])
  5. >>> # get indices of support vectors
  6. >>> clf.support_
  7. array([0, 1]...)
  8. >>> # get number of support vectors for each class
  9. >>> clf.n_support_
  10. array([1, 1]...)

1.4.1.1. Multi-class classification

SVC and NuSVC implement the “one-against-one”approach (Knerr et al., 1990) for multi- class classification. Ifn_class is the number of classes, then n_class * (n_class - 1) / 2classifiers are constructed and each one trains data from two classes.To provide a consistent interface with other classifiers, thedecision_function_shape option allows to monotically transform the results of the“one-against-one” classifiers to a decision function of shape (n_samples,n_classes).

>>>

  1. >>> X = [[0], [1], [2], [3]]
  2. >>> Y = [0, 1, 2, 3]
  3. >>> clf = svm.SVC(decision_function_shape='ovo')
  4. >>> clf.fit(X, Y)
  5. SVC(decision_function_shape='ovo')
  6. >>> dec = clf.decision_function([[1]])
  7. >>> dec.shape[1] # 4 classes: 4*3/2 = 6
  8. 6
  9. >>> clf.decision_function_shape = "ovr"
  10. >>> dec = clf.decision_function([[1]])
  11. >>> dec.shape[1] # 4 classes
  12. 4

On the other hand, LinearSVC implements “one-vs-the-rest”multi-class strategy, thus training n_class models. If there are onlytwo classes, only one model is trained:

>>>

  1. >>> lin_clf = svm.LinearSVC()
  2. >>> lin_clf.fit(X, Y)
  3. LinearSVC()
  4. >>> dec = lin_clf.decision_function([[1]])
  5. >>> dec.shape[1]
  6. 4

See Mathematical formulation for a complete description ofthe decision function.

Note that the LinearSVC also implements an alternative multi-classstrategy, the so-called multi-class SVM formulated by Crammer and Singer, byusing the option multi_class='crammer_singer'. This method is consistent,which is not true for one-vs-rest classification.In practice, one-vs-rest classification is usually preferred, since the resultsare mostly similar, but the runtime is significantly less.

For “one-vs-rest” LinearSVC the attributes coef and intercepthave the shape [n_class, n_features] and [n_class] respectively.Each row of the coefficients corresponds to one of the n_class many“one-vs-rest” classifiers and similar for the intercepts, in theorder of the “one” class.

In the case of “one-vs-one” SVC, the layout of the attributesis a little more involved. In the case of having a linear kernel, theattributes coef and intercept have the shape[n_class (n_class - 1) / 2, n_features] and[n_class (n_class - 1) / 2] respectively. This is similar to thelayout for LinearSVC described above, with each row now correspondingto a binary classifier. The order for classes0 to n is “0 vs 1”, “0 vs 2” , … “0 vs n”, “1 vs 2”, “1 vs 3”, “1 vs n”, . .. “n-1 vs n”.

The shape of dualcoef is [n_class-1, n_SV] witha somewhat hard to grasp layout.The columns correspond to the support vectors involved in anyof the n_class * (n_class - 1) / 2 “one-vs-one” classifiers.Each of the support vectors is used in n_class - 1 classifiers.The n_class - 1 entries in each row correspond to the dual coefficientsfor these classifiers.

This might be made more clear by an example:

Consider a three class problem with class 0 having three support vectors

1.4. Support Vector Machines - 图2 and class 1 and 2 having two support vectors1.4. Support Vector Machines - 图3 and1.4. Support Vector Machines - 图4 respectively. For eachsupport vector1.4. Support Vector Machines - 图5, there are two dual coefficients. Let’s callthe coefficient of support vector1.4. Support Vector Machines - 图6 in the classifier betweenclasses1.4. Support Vector Machines - 图7 and1.4. Support Vector Machines - 图8

1.4. Support Vector Machines - 图9.Then dualcoef looks like this:

1.4. Support Vector Machines - 图101.4. Support Vector Machines - 图11Coefficientsfor SVs of class 0
1.4. Support Vector Machines - 图121.4. Support Vector Machines - 图13
1.4. Support Vector Machines - 图141.4. Support Vector Machines - 图15
1.4. Support Vector Machines - 图161.4. Support Vector Machines - 图17Coefficientsfor SVs of class 1
1.4. Support Vector Machines - 图181.4. Support Vector Machines - 图19
1.4. Support Vector Machines - 图201.4. Support Vector Machines - 图21Coefficientsfor SVs of class 2
1.4. Support Vector Machines - 图221.4. Support Vector Machines - 图23

1.4.1.2. Scores and probabilities

The decision_function method of SVC and NuSVC givesper-class scores for each sample (or a single score per sample in the binarycase). When the constructor option probability is set to True,class membership probability estimates (from the methods predict_proba andpredict_log_proba) are enabled. In the binary case, the probabilities arecalibrated using Platt scaling: logistic regression on the SVM’s scores,fit by an additional cross-validation on the training data.In the multiclass case, this is extended as per Wu et al. (2004).

Needless to say, the cross-validation involved in Platt scalingis an expensive operation for large datasets.In addition, the probability estimates may be inconsistent with the scores,in the sense that the “argmax” of the scoresmay not be the argmax of the probabilities.(E.g., in binary classification,a sample may be labeled by predict as belonging to a classthat has probability <½ according to predict_proba.)Platt’s method is also known to have theoretical issues.If confidence scores are required, but these do not have to be probabilities,then it is advisable to set probability=Falseand use decision_function instead of predict_proba.

Please note that when decision_function_shape='ovr' and n_classes > 2,unlike decision_function, the predict method does not try to break tiesby default. You can set break_ties=True for the output of predict to bethe same as np.argmax(clf.decision_function(…), axis=1), otherwise thefirst class among the tied classes will always be returned; but have in mindthat it comes with a computational cost.

../_images/sphx_glr_plot_svm_tie_breaking_0011.png

References:

1.4.1.3. Unbalanced problems

In problems where it is desired to give more importance to certainclasses or certain individual samples keywords class_weight andsample_weight can be used.

SVC (but not NuSVC) implement a keywordclass_weight in the fit method. It’s a dictionary of the form{class_label : value}, where value is a floating point number > 0that sets the parameter C of class class_label to C * value.

../_images/sphx_glr_plot_separating_hyperplane_unbalanced_0011.png

SVC, NuSVC, SVR, NuSVR, LinearSVC,LinearSVR and OneClassSVM implement also weights forindividual samples in method fit through keyword sample_weight. Similarto class_weight, these set the parameter C for the i-th example toC * sample_weight[i].

../_images/sphx_glr_plot_weighted_samples_0011.png

Examples:

1.4.2. Regression

The method of Support Vector Classification can be extended to solveregression problems. This method is called Support Vector Regression.

The model produced by support vector classification (as describedabove) depends only on a subset of the training data, because the costfunction for building the model does not care about training pointsthat lie beyond the margin. Analogously, the model produced by SupportVector Regression depends only on a subset of the training data,because the cost function for building the model ignores any trainingdata close to the model prediction.

There are three different implementations of Support Vector Regression:SVR, NuSVR and LinearSVR. LinearSVRprovides a faster implementation than SVR but only considerslinear kernels, while NuSVR implements a slightly differentformulation than SVR and LinearSVR. SeeImplementation details for further details.

As with classification classes, the fit method will take asargument vectors X, y, only that in this case y is expected to havefloating point values instead of integer values:

>>>

  1. >>> from sklearn import svm
  2. >>> X = [[0, 0], [2, 2]]
  3. >>> y = [0.5, 2.5]
  4. >>> clf = svm.SVR()
  5. >>> clf.fit(X, y)
  6. SVR()
  7. >>> clf.predict([[1, 1]])
  8. array([1.5])

Examples:

1.4.3. Density estimation, novelty detection

The class OneClassSVM implements a One-Class SVM which is used inoutlier detection.

See Novelty and Outlier Detection for the description and usage of OneClassSVM.

1.4.4. Complexity

Support Vector Machines are powerful tools, but their compute andstorage requirements increase rapidly with the number of trainingvectors. The core of an SVM is a quadratic programming problem (QP),separating support vectors from the rest of the training data. The QPsolver used by this libsvm-based implementation scales between

1.4. Support Vector Machines - 图27 and1.4. Support Vector Machines - 图28 depending on how efficientlythe libsvm cache is used in practice (dataset dependent). If the datais very sparse1.4. Support Vector Machines - 图29 should be replaced by the average numberof non-zero features in a sample vector.

Also note that for the linear case, the algorithm used inLinearSVC by the liblinear implementation is much moreefficient than its libsvm-based SVC counterpart and canscale almost linearly to millions of samples and/or features.

1.4.5. Tips on Practical Use

  • Avoiding data copy: For SVC, SVR, NuSVC andNuSVR, if the data passed to certain methods is not C-orderedcontiguous, and double precision, it will be copied before calling theunderlying C implementation. You can check whether a given numpy array isC-contiguous by inspecting its flags attribute.

    For LinearSVC (and LogisticRegression) any input passed as a numpyarray will be copied and converted to the liblinear internal sparse datarepresentation (double precision floats and int32 indices of non-zerocomponents). If you want to fit a large-scale linear classifier withoutcopying a dense numpy C-contiguous double precision array as input wesuggest to use the SGDClassifier class instead. The objectivefunction can be configured to be almost the same as the LinearSVCmodel.

  • Kernel cache size: For SVC, SVR, NuSVC andNuSVR, the size of the kernel cache has a strong impact on runtimes for larger problems. If you have enough RAM available, it isrecommended to set cache_size to a higher value than the default of200(MB), such as 500(MB) or 1000(MB).

  • Setting C: C is 1 by default and it’s a reasonable defaultchoice. If you have a lot of noisy observations you should decrease it.It corresponds to regularize more the estimation.

    LinearSVC and LinearSVR are less sensitive to C whenit becomes large, and prediction results stop improving after a certainthreshold. Meanwhile, larger C values will take more time to train,sometimes up to 10 times longer, as shown by Fan et al. (2008)

  • Support Vector Machine algorithms are not scale invariant, so itis highly recommended to scale your data. For example, scale eachattribute on the input vector X to [0,1] or [-1,+1], or standardize itto have mean 0 and variance 1. Note that the same scaling must beapplied to the test vector to obtain meaningful results. See sectionPreprocessing data for more details on scaling and normalization.

  • Parameter nu in NuSVC/OneClassSVM/NuSVRapproximates the fraction of training errors and support vectors.

  • In SVC, if data for classification are unbalanced (e.g. manypositive and few negative), set class_weight='balanced' and/or trydifferent penalty parameters C.

  • Randomness of the underlying implementations: The underlyingimplementations of SVC and NuSVC use a random numbergenerator only to shuffle the data for probability estimation (whenprobability is set to True). This randomness can be controlledwith the random_state parameter. If probability is set to Falsethese estimators are not random and random_state has no effect on theresults. The underlying OneClassSVM implementation is similar tothe ones of SVC and NuSVC. As no probability estimationis provided for OneClassSVM, it is not random.

    The underlying LinearSVC implementation uses a random numbergenerator to select features when fitting the model with a dual coordinatedescent (i.e when dual is set to True). It is thus not uncommon,to have slightly different results for the same input data. If thathappens, try with a smaller tol parameter. This randomness can also becontrolled with the random_state parameter. When dual isset to False the underlying implementation of LinearSVC isnot random and random_state has no effect on the results.

  • Using L1 penalization as provided by LinearSVC(loss='l2', penalty='l1',dual=False) yields a sparse solution, i.e. only a subset of featureweights is different from zero and contribute to the decision function.Increasing C yields a more complex model (more feature are selected).The C value that yields a “null” model (all weights equal to zero) canbe calculated using l1_min_c.

References:

1.4.6. Kernel functions

The kernel function can be any of the following:

  • linear:

    1.4. Support Vector Machines - 图30
    .

  • polynomial:

    1.4. Support Vector Machines - 图31
    .
    1.4. Support Vector Machines - 图32
    is specified by keyword degree,
    1.4. Support Vector Machines - 图33
    by coef0.

  • rbf:

    1.4. Support Vector Machines - 图34
    .
    1.4. Support Vector Machines - 图35
    isspecified by keyword gamma, must be greater than 0.

  • sigmoid (

    1.4. Support Vector Machines - 图36
    ),where
    1.4. Support Vector Machines - 图37
    is specified by coef0.

Different kernels are specified by keyword kernel at initialization:

>>>

  1. >>> linear_svc = svm.SVC(kernel='linear')
  2. >>> linear_svc.kernel
  3. 'linear'
  4. >>> rbf_svc = svm.SVC(kernel='rbf')
  5. >>> rbf_svc.kernel
  6. 'rbf'

1.4.6.1. Custom Kernels

You can define your own kernels by either giving the kernel as apython function or by precomputing the Gram matrix.

Classifiers with custom kernels behave the same way as any otherclassifiers, except that:

  • Field supportvectors is now empty, only indices of supportvectors are stored in support_

  • A reference (and not a copy) of the first argument in the fit()method is stored for future reference. If that array changes between theuse of fit() and predict() you will have unexpected results.

1.4.6.1.1. Using Python functions as kernels

You can also use your own defined kernels by passing a function to thekeyword kernel in the constructor.

Your kernel must take as arguments two matrices of shape(n_samples_1, n_features), (n_samples_2, n_features)and return a kernel matrix of shape (n_samples_1, n_samples_2).

The following code defines a linear kernel and creates a classifierinstance that will use that kernel:

>>>

  1. >>> import numpy as np
  2. >>> from sklearn import svm
  3. >>> def my_kernel(X, Y):
  4. ... return np.dot(X, Y.T)
  5. ...
  6. >>> clf = svm.SVC(kernel=my_kernel)

Examples:

1.4.6.1.2. Using the Gram matrix

Set kernel='precomputed' and pass the Gram matrix instead of X in the fitmethod. At the moment, the kernel values between all training vectors and thetest vectors must be provided.

>>>

  1. >>> import numpy as np
  2. >>> from sklearn import svm
  3. >>> X = np.array([[0, 0], [1, 1]])
  4. >>> y = [0, 1]
  5. >>> clf = svm.SVC(kernel='precomputed')
  6. >>> # linear kernel computation
  7. >>> gram = np.dot(X, X.T)
  8. >>> clf.fit(gram, y)
  9. SVC(kernel='precomputed')
  10. >>> # predict on training examples
  11. >>> clf.predict(gram)
  12. array([0, 1])

1.4.6.1.3. Parameters of the RBF Kernel

When training an SVM with the Radial Basis Function (RBF) kernel, twoparameters must be considered: C and gamma. The parameter C,common to all SVM kernels, trades off misclassification of training examplesagainst simplicity of the decision surface. A low C makes the decisionsurface smooth, while a high C aims at classifying all training examplescorrectly. gamma defines how much influence a single training example has.The larger gamma is, the closer other examples must be to be affected.

Proper choice of C and gamma is critical to the SVM’s performance. Oneis advised to use sklearn.model_selection.GridSearchCV withC and gamma spaced exponentially far apart to choose good values.

Examples:

1.4.7. Mathematical formulation

A support vector machine constructs a hyper-plane or set of hyper-planesin a high or infinite dimensional space, which can be used forclassification, regression or other tasks. Intuitively, a goodseparation is achieved by the hyper-plane that has the largest distanceto the nearest training data points of any class (so-called functionalmargin), since in general the larger the margin the lower thegeneralization error of the classifier.

../_images/sphx_glr_plot_separating_hyperplane_0011.png

1.4.7.1. SVC

Given training vectors

1.4. Support Vector Machines - 图39, i=1,…, n, in two classes, and avector1.4. Support Vector Machines - 图40, SVC solves the following primal problem:

1.4. Support Vector Machines - 图41

Its dual is

1.4. Support Vector Machines - 图42

where

1.4. Support Vector Machines - 图43 is the vector of all ones,1.4. Support Vector Machines - 图44 is the upper bound,1.4. Support Vector Machines - 图45 is an1.4. Support Vector Machines - 图46 by1.4. Support Vector Machines - 图47 positive semidefinite matrix,1.4. Support Vector Machines - 图48, where1.4. Support Vector Machines - 图49is the kernel. Here training vectors are implicitly mapped into a higher(maybe infinite) dimensional space by the function1.4. Support Vector Machines - 图50.

The decision function is:

1.4. Support Vector Machines - 图51

Note

While SVM models derived from libsvm and liblinear use C asregularization parameter, most other estimators use alpha. The exactequivalence between the amount of regularization of two models depends onthe exact objective function optimized by the model. For example, when theestimator used is sklearn.linear_model.Ridge regression,the relation between them is given as

1.4. Support Vector Machines - 图52.

This parameters can be accessed through the members dualcoefwhich holds the product

1.4. Support Vector Machines - 图53, supportvectors whichholds the support vectors, and intercept_ which holds the independentterm1.4. Support Vector Machines - 图54 :

References:

1.4.7.2. NuSVC

We introduce a new parameter

1.4. Support Vector Machines - 图55 which controls the number ofsupport vectors and training errors. The parameter1.4. Support Vector Machines - 图56 is an upper bound on the fraction of training errors and a lowerbound of the fraction of support vectors.

It can be shown that the

1.4. Support Vector Machines - 图57-SVC formulation is a reparameterizationof the1.4. Support Vector Machines - 图58-SVC and therefore mathematically equivalent.

1.4.7.3. SVR

Given training vectors

1.4. Support Vector Machines - 图59, i=1,…, n, and avector1.4. Support Vector Machines - 图60

1.4. Support Vector Machines - 图61-SVR solves the following primal problem:

1.4. Support Vector Machines - 图62

Its dual is

1.4. Support Vector Machines - 图63

where

1.4. Support Vector Machines - 图64 is the vector of all ones,1.4. Support Vector Machines - 图65 is the upper bound,1.4. Support Vector Machines - 图66 is an1.4. Support Vector Machines - 图67 by1.4. Support Vector Machines - 图68 positive semidefinite matrix,1.4. Support Vector Machines - 图69is the kernel. Here training vectors are implicitly mapped into a higher(maybe infinite) dimensional space by the function1.4. Support Vector Machines - 图70.

The decision function is:

1.4. Support Vector Machines - 图71

These parameters can be accessed through the members dualcoefwhich holds the difference

1.4. Support Vector Machines - 图72, supportvectors whichholds the support vectors, and intercept_ which holds the independentterm1.4. Support Vector Machines - 图73

References:

1.4.8. Implementation details

Internally, we use libsvm and liblinear to handle allcomputations. These libraries are wrapped using C and Cython.

References:

For a description of the implementation and details of the algorithmsused, please refer to