1.4. Support Vector Machines
The advantages of support vector machines are:
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 , below).
The support vector machines in scikit-learn support both dense( 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
.
SVC
, and LinearSVC
are classescapable of performing multi-class classification on a dataset.
SVC
and are similar methods, but acceptslightly different sets of parameters and have different mathematicalformulations (see section Mathematical formulation). On theother hand, 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 of and NuSVC
, like support_
.
As other classifiers, , NuSVC
and 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]
:
>>>
After being fitted, the model can then be used to predict new values:
>>>
- >>> clf.predict([[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
:
>>>
- >>> # get support vectors
- >>> clf.support_vectors_
- array([[0., 0.],
- [1., 1.]])
- >>> # get indices of support vectors
- >>> clf.support_
- >>> # get number of support vectors for each class
- >>> clf.n_support_
- array([1, 1]...)
SVC
and 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) / 2
classifiers 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)
.
>>>
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:
>>>
- >>> lin_clf = svm.LinearSVC()
- >>> lin_clf.fit(X, Y)
- LinearSVC()
- >>> dec = lin_clf.decision_function([[1]])
- >>> dec.shape[1]
- 4
See 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” the attributes coef
and intercept
have 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 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
and class 1 and 2 having two support vectors and
respectively. For eachsupport vector, there are two dual coefficients. Let’s callthe coefficient of support vector
in the classifier betweenclasses and
.Then dualcoef
looks like this:
1.4.1.2. Scores and probabilities
The decision_function
method of 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=False
and use 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.
References:
Wu, Lin and Weng,“Probability estimates for multi-class classification by pairwise coupling”,JMLR 5:975-1005, 2004.
Platt.
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 ) 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
.
, NuSVC
, , NuSVR
, ,LinearSVR
and 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]
.
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:, NuSVR
and . LinearSVR
provides a faster implementation than but only considerslinear kernels, while NuSVR
implements a slightly differentformulation than and LinearSVR
. See 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:
>>>
- >>> from sklearn import svm
- >>> X = [[0, 0], [2, 2]]
- >>> y = [0.5, 2.5]
- >>> clf = svm.SVR()
- >>> clf.fit(X, y)
- SVR()
- >>> clf.predict([[1, 1]])
- array([1.5])
Examples:
The class 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
and depending on how efficientlythe cache is used in practice (dataset dependent). If the datais very sparse 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 implementation is much moreefficient than its libsvm-based counterpart and canscale almost linearly to millions of samples and/or features.
References:
- Fan, Rong-En, et al.,“LIBLINEAR: A library for large linear classification.”,Journal of machine learning research 9.Aug (2008): 1871-1874.
1.4.6. Kernel functions
The kernel function can be any of the following:
linear:
.polynomial:
.is specified by keyworddegree
, bycoef0
.rbf:
. isspecified by keywordgamma
, must be greater than 0.sigmoid (
),where is specified bycoef0
.
Different kernels are specified by keyword kernel at initialization:
>>>
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:
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:
- >>> import numpy as np
- >>> from sklearn import svm
- >>> def my_kernel(X, Y):
- ... return np.dot(X, Y.T)
- ...
- >>> 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.
>>>
- >>> import numpy as np
- >>> from sklearn import svm
- >>> X = np.array([[0, 0], [1, 1]])
- >>> y = [0, 1]
- >>> clf = svm.SVC(kernel='precomputed')
- >>> # linear kernel computation
- >>> gram = np.dot(X, X.T)
- >>> clf.fit(gram, y)
- SVC(kernel='precomputed')
- >>> # predict on training examples
- >>> clf.predict(gram)
- 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 withC
and gamma
spaced exponentially far apart to choose good values.
Examples:
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.
Given training vectors
, i=1,…, n, in two classes, and avector, SVC solves the following primal problem:
Its dual is
where
is the vector of all ones, is the upper bound, is an
by positive semidefinite matrix,
, whereis the kernel. Here training vectors are implicitly mapped into a higher(maybe infinite) dimensional space by the function
.
The decision function is:
Note
While SVM models derived from libsvm and 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
.
This parameters can be accessed through the members dualcoef
which holds the product
, supportvectors
whichholds the support vectors, and intercept_
which holds the independentterm :
References:
“Automatic Capacity Tuning of Very Large VC-dimension Classifiers”,I. Guyon, B. Boser, V. Vapnik - Advances in neural informationprocessing 1993.
,C. Cortes, V. Vapnik - Machine Learning, 20, 273-297 (1995).
1.4.7.2. NuSVC
We introduce a new parameter
which controls the number ofsupport vectors and training errors. The parameter 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
-SVC formulation is a reparameterizationof the-SVC and therefore mathematically equivalent.
Given training vectors
, i=1,…, n, and avector
-SVR solves the following primal problem:
Its dual is
where
is the vector of all ones, is the upper bound,
is an by
positive semidefinite matrix,is the kernel. Here training vectors are implicitly mapped into a higher(maybe infinite) dimensional space by the function
.
The decision function is:
These parameters can be accessed through the members dualcoef
which holds the difference
, whichholds the support vectors, and
intercept_
which holds the independentterm
References:
- ,Alex J. Smola, Bernhard Schölkopf - Statistics and Computing archiveVolume 14 Issue 3, August 2004, p. 199-222.
1.4.8. Implementation details
Internally, we use 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