1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
|
.. _svm:
=======================
Support Vector Machines
=======================
.. currentmodule:: sklearn.svm
**Support vector machines (SVMs)** are a set of supervised learning
methods used for :ref:`classification <svm_classification>`,
:ref:`regression <svm_regression>` and :ref:`outliers detection
<svm_outlier_detection>`.
The advantages of support vector machines are:
- Effective in high dimensional spaces.
- Still effective in cases where number of dimensions is greater
than the number of samples.
- Uses a subset of training points in the decision function (called
support vectors), so it is also memory efficient.
- Versatile: different :ref:`svm_kernels` can be
specified for the decision function. Common kernels are
provided, 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 of
samples, the method is likely to give poor performances.
- SVMs do not directly provide probability estimates, these are
calculated using an expensive five-fold cross-validation
(see :ref:`Scores and probabilities <scores_probabilities>`, below).
The support vector machines in scikit-learn support both dense
(``numpy.ndarray`` and convertible to that by ``numpy.asarray``) and
sparse (any ``scipy.sparse``) sample vectors as input. However, to use
an SVM to make predictions for sparse data, it must have been fit on such
data. For optimal performance, use C-ordered ``numpy.ndarray`` (dense) or
``scipy.sparse.csr_matrix`` (sparse) with ``dtype=float64``.
.. _svm_classification:
Classification
==============
:class:`SVC`, :class:`NuSVC` and :class:`LinearSVC` are classes
capable of performing multi-class classification on a dataset.
.. figure:: ../auto_examples/svm/images/sphx_glr_plot_iris_001.png
:target: ../auto_examples/svm/plot_iris.html
:align: center
:class:`SVC` and :class:`NuSVC` are similar methods, but accept
slightly different sets of parameters and have different mathematical
formulations (see section :ref:`svm_mathematical_formulation`). On the
other hand, :class:`LinearSVC` is another implementation of Support
Vector Classification for the case of a linear kernel. Note that
:class:`LinearSVC` does not accept keyword ``kernel``, as this is
assumed to be linear. It also lacks some of the members of
:class:`SVC` and :class:`NuSVC`, like ``support_``.
As other classifiers, :class:`SVC`, :class:`NuSVC` and
:class:`LinearSVC` 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]``::
>>> from sklearn import svm
>>> X = [[0, 0], [1, 1]]
>>> y = [0, 1]
>>> clf = svm.SVC()
>>> clf.fit(X, y) # doctest: +NORMALIZE_WHITESPACE
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
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 vectors
can be found in members ``support_vectors_``, ``support_`` and
``n_support``::
>>> # get support vectors
>>> clf.support_vectors_
array([[ 0., 0.],
[ 1., 1.]])
>>> # get indices of support vectors
>>> clf.support_ # doctest: +ELLIPSIS
array([0, 1]...)
>>> # get number of support vectors for each class
>>> clf.n_support_ # doctest: +ELLIPSIS
array([1, 1]...)
.. _svm_multi_class:
Multi-class classification
--------------------------
:class:`SVC` and :class:`NuSVC` implement the "one-against-one"
approach (Knerr et al., 1990) for multi- class classification. If
``n_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, the
``decision_function_shape`` option allows to aggregate the results of the
"one-against-one" classifiers to a decision function of shape ``(n_samples,
n_classes)``::
>>> X = [[0], [1], [2], [3]]
>>> Y = [0, 1, 2, 3]
>>> clf = svm.SVC(decision_function_shape='ovo')
>>> clf.fit(X, Y) # doctest: +NORMALIZE_WHITESPACE
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovo', degree=3, gamma='auto', kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
>>> dec = clf.decision_function([[1]])
>>> dec.shape[1] # 4 classes: 4*3/2 = 6
6
>>> clf.decision_function_shape = "ovr"
>>> dec = clf.decision_function([[1]])
>>> dec.shape[1] # 4 classes
4
On the other hand, :class:`LinearSVC` implements "one-vs-the-rest"
multi-class strategy, thus training n_class models. If there are only
two classes, only one model is trained::
>>> lin_clf = svm.LinearSVC()
>>> lin_clf.fit(X, Y) # doctest: +NORMALIZE_WHITESPACE
LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,
intercept_scaling=1, loss='squared_hinge', max_iter=1000,
multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,
verbose=0)
>>> dec = lin_clf.decision_function([[1]])
>>> dec.shape[1]
4
See :ref:`svm_mathematical_formulation` for a complete description of
the decision function.
Note that the :class:`LinearSVC` also implements an alternative multi-class
strategy, the so-called multi-class SVM formulated by Crammer and Singer, by
using 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 results
are mostly similar, but the runtime is significantly less.
For "one-vs-rest" :class:`LinearSVC` 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 the
order of the "one" class.
In the case of "one-vs-one" :class:`SVC`, the layout of the attributes
is a little more involved. In the case of having a linear kernel,
The layout of ``coef_`` and ``intercept_`` is similar to the one
described for :class:`LinearSVC` described above, except that the shape of
``coef_`` is ``[n_class * (n_class - 1) / 2, n_features]``, corresponding to as
many binary classifiers. The order for classes
0 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 ``dual_coef_`` is ``[n_class-1, n_SV]`` with
a somewhat hard to grasp layout.
The columns correspond to the support vectors involved in any
of 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 coefficients
for these classifiers.
This might be made more clear by an example:
Consider a three class problem with class 0 having three support vectors
:math:`v^{0}_0, v^{1}_0, v^{2}_0` and class 1 and 2 having two support vectors
:math:`v^{0}_1, v^{1}_1` and :math:`v^{0}_2, v^{1}_2` respectively. For each
support vector :math:`v^{j}_i`, there are two dual coefficients. Let's call
the coefficient of support vector :math:`v^{j}_i` in the classifier between
classes :math:`i` and :math:`k` :math:`\alpha^{j}_{i,k}`.
Then ``dual_coef_`` looks like this:
+------------------------+------------------------+------------------+
|:math:`\alpha^{0}_{0,1}`|:math:`\alpha^{0}_{0,2}`|Coefficients |
+------------------------+------------------------+for SVs of class 0|
|:math:`\alpha^{1}_{0,1}`|:math:`\alpha^{1}_{0,2}`| |
+------------------------+------------------------+ |
|:math:`\alpha^{2}_{0,1}`|:math:`\alpha^{2}_{0,2}`| |
+------------------------+------------------------+------------------+
|:math:`\alpha^{0}_{1,0}`|:math:`\alpha^{0}_{1,2}`|Coefficients |
+------------------------+------------------------+for SVs of class 1|
|:math:`\alpha^{1}_{1,0}`|:math:`\alpha^{1}_{1,2}`| |
+------------------------+------------------------+------------------+
|:math:`\alpha^{0}_{2,0}`|:math:`\alpha^{0}_{2,1}`|Coefficients |
+------------------------+------------------------+for SVs of class 2|
|:math:`\alpha^{1}_{2,0}`|:math:`\alpha^{1}_{2,1}`| |
+------------------------+------------------------+------------------+
.. _scores_probabilities:
Scores and probabilities
------------------------
The :class:`SVC` method ``decision_function`` gives per-class scores
for each sample (or a single score per sample in the binary case).
When the constructor option ``probability`` is set to ``True``,
class membership probability estimates
(from the methods ``predict_proba`` and ``predict_log_proba``) are enabled.
In the binary case, the probabilities are calibrated 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 scaling
is 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 scores
may not be the argmax of the probabilities.
(E.g., in binary classification,
a sample may be labeled by ``predict`` as belonging to a class
that 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 ``decision_function`` instead of ``predict_proba``.
.. topic:: References:
* Wu, Lin and Weng,
`"Probability estimates for multi-class classification by pairwise coupling"
<http://www.csie.ntu.edu.tw/~cjlin/papers/svmprob/svmprob.pdf>`_,
JMLR 5:975-1005, 2004.
Unbalanced problems
--------------------
In problems where it is desired to give more importance to certain
classes or certain individual samples keywords ``class_weight`` and
``sample_weight`` can be used.
:class:`SVC` (but not :class:`NuSVC`) implement a keyword
``class_weight`` in the ``fit`` method. It's a dictionary of the form
``{class_label : value}``, where value is a floating point number > 0
that sets the parameter ``C`` of class ``class_label`` to ``C * value``.
.. figure:: ../auto_examples/svm/images/sphx_glr_plot_separating_hyperplane_unbalanced_001.png
:target: ../auto_examples/svm/plot_separating_hyperplane_unbalanced.html
:align: center
:scale: 75
:class:`SVC`, :class:`NuSVC`, :class:`SVR`, :class:`NuSVR` and
:class:`OneClassSVM` implement also weights for individual samples in method
``fit`` through keyword ``sample_weight``. Similar to ``class_weight``, these
set the parameter ``C`` for the i-th example to ``C * sample_weight[i]``.
.. figure:: ../auto_examples/svm/images/sphx_glr_plot_weighted_samples_001.png
:target: ../auto_examples/svm/plot_weighted_samples.html
:align: center
:scale: 75
.. topic:: Examples:
* :ref:`sphx_glr_auto_examples_svm_plot_iris.py`,
* :ref:`sphx_glr_auto_examples_svm_plot_separating_hyperplane.py`,
* :ref:`sphx_glr_auto_examples_svm_plot_separating_hyperplane_unbalanced.py`
* :ref:`sphx_glr_auto_examples_svm_plot_svm_anova.py`,
* :ref:`sphx_glr_auto_examples_svm_plot_svm_nonlinear.py`
* :ref:`sphx_glr_auto_examples_svm_plot_weighted_samples.py`,
.. _svm_regression:
Regression
==========
The method of Support Vector Classification can be extended to solve
regression problems. This method is called Support Vector Regression.
The model produced by support vector classification (as described
above) depends only on a subset of the training data, because the cost
function for building the model does not care about training points
that lie beyond the margin. Analogously, the model produced by Support
Vector Regression depends only on a subset of the training data,
because the cost function for building the model ignores any training
data close to the model prediction.
There are three different implementations of Support Vector Regression:
:class:`SVR`, :class:`NuSVR` and :class:`LinearSVR`. :class:`LinearSVR`
provides a faster implementation than :class:`SVR` but only considers
linear kernels, while :class:`NuSVR` implements a slightly different
formulation than :class:`SVR` and :class:`LinearSVR`. See
:ref:`svm_implementation_details` for further details.
As with classification classes, the fit method will take as
argument vectors X, y, only that in this case y is expected to have
floating 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) # doctest: +NORMALIZE_WHITESPACE
SVR(C=1.0, cache_size=200, coef0=0.0, degree=3, epsilon=0.1, gamma='auto',
kernel='rbf', max_iter=-1, shrinking=True, tol=0.001, verbose=False)
>>> clf.predict([[1, 1]])
array([ 1.5])
.. topic:: Examples:
* :ref:`sphx_glr_auto_examples_svm_plot_svm_regression.py`
.. _svm_outlier_detection:
Density estimation, novelty detection
=======================================
One-class SVM is used for novelty detection, that is, given a set of
samples, it will detect the soft boundary of that set so as to
classify new points as belonging to that set or not. The class that
implements this is called :class:`OneClassSVM`.
In this case, as it is a type of unsupervised learning, the fit method
will only take as input an array X, as there are no class labels.
See, section :ref:`outlier_detection` for more details on this usage.
.. figure:: ../auto_examples/svm/images/sphx_glr_plot_oneclass_001.png
:target: ../auto_examples/svm/plot_oneclass.html
:align: center
:scale: 75
.. topic:: Examples:
* :ref:`sphx_glr_auto_examples_svm_plot_oneclass.py`
* :ref:`sphx_glr_auto_examples_applications_plot_species_distribution_modeling.py`
Complexity
==========
Support Vector Machines are powerful tools, but their compute and
storage requirements increase rapidly with the number of training
vectors. The core of an SVM is a quadratic programming problem (QP),
separating support vectors from the rest of the training data. The QP
solver used by this `libsvm`_-based implementation scales between
:math:`O(n_{features} \times n_{samples}^2)` and
:math:`O(n_{features} \times n_{samples}^3)` depending on how efficiently
the `libsvm`_ cache is used in practice (dataset dependent). If the data
is very sparse :math:`n_{features}` should be replaced by the average number
of non-zero features in a sample vector.
Also note that for the linear case, the algorithm used in
:class:`LinearSVC` by the `liblinear`_ implementation is much more
efficient than its `libsvm`_-based :class:`SVC` counterpart and can
scale almost linearly to millions of samples and/or features.
Tips on Practical Use
=====================
* **Avoiding data copy**: For :class:`SVC`, :class:`SVR`, :class:`NuSVC` and
:class:`NuSVR`, if the data passed to certain methods is not C-ordered
contiguous, and double precision, it will be copied before calling the
underlying C implementation. You can check whether a given numpy array is
C-contiguous by inspecting its ``flags`` attribute.
For :class:`LinearSVC` (and :class:`LogisticRegression
<sklearn.linear_model.LogisticRegression>`) any input passed as a numpy
array will be copied and converted to the liblinear internal sparse data
representation (double precision floats and int32 indices of non-zero
components). If you want to fit a large-scale linear classifier without
copying a dense numpy C-contiguous double precision array as input we
suggest to use the :class:`SGDClassifier
<sklearn.linear_model.SGDClassifier>` class instead. The objective
function can be configured to be almost the same as the :class:`LinearSVC`
model.
* **Kernel cache size**: For :class:`SVC`, :class:`SVR`, :class:`nuSVC` and
:class:`NuSVR`, the size of the kernel cache has a strong impact on run
times for larger problems. If you have enough RAM available, it is
recommended to set ``cache_size`` to a higher value than the default of
200(MB), such as 500(MB) or 1000(MB).
* **Setting C**: ``C`` is ``1`` by default and it's a reasonable default
choice. If you have a lot of noisy observations you should decrease it.
It corresponds to regularize more the estimation.
* Support Vector Machine algorithms are not scale invariant, so **it
is highly recommended to scale your data**. For example, scale each
attribute on the input vector X to [0,1] or [-1,+1], or standardize it
to have mean 0 and variance 1. Note that the *same* scaling must be
applied to the test vector to obtain meaningful results. See section
:ref:`preprocessing` for more details on scaling and normalization.
* Parameter ``nu`` in :class:`NuSVC`/:class:`OneClassSVM`/:class:`NuSVR`
approximates the fraction of training errors and support vectors.
* In :class:`SVC`, if data for classification are unbalanced (e.g. many
positive and few negative), set ``class_weight='balanced'`` and/or try
different penalty parameters ``C``.
* The underlying :class:`LinearSVC` implementation uses a random
number generator to select features when fitting the model. It is
thus not uncommon, to have slightly different results for the same
input data. If that happens, try with a smaller tol parameter.
* Using L1 penalization as provided by ``LinearSVC(loss='l2', penalty='l1',
dual=False)`` yields a sparse solution, i.e. only a subset of feature
weights 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) can
be calculated using :func:`l1_min_c`.
.. _svm_kernels:
Kernel functions
================
The *kernel function* can be any of the following:
* linear: :math:`\langle x, x'\rangle`.
* polynomial: :math:`(\gamma \langle x, x'\rangle + r)^d`.
:math:`d` is specified by keyword ``degree``, :math:`r` by ``coef0``.
* rbf: :math:`\exp(-\gamma |x-x'|^2)`. :math:`\gamma` is
specified by keyword ``gamma``, must be greater than 0.
* sigmoid (:math:`\tanh(\gamma \langle x,x'\rangle + r)`),
where :math:`r` is specified by ``coef0``.
Different kernels are specified by keyword kernel at initialization::
>>> linear_svc = svm.SVC(kernel='linear')
>>> linear_svc.kernel
'linear'
>>> rbf_svc = svm.SVC(kernel='rbf')
>>> rbf_svc.kernel
'rbf'
Custom Kernels
--------------
You can define your own kernels by either giving the kernel as a
python function or by precomputing the Gram matrix.
Classifiers with custom kernels behave the same way as any other
classifiers, except that:
* Field ``support_vectors_`` is now empty, only indices of support
vectors 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 the
use of ``fit()`` and ``predict()`` you will have unexpected results.
Using Python functions as kernels
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can also use your own defined kernels by passing a function to the
keyword ``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 classifier
instance 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)
.. topic:: Examples:
* :ref:`sphx_glr_auto_examples_svm_plot_custom_kernel.py`.
Using the Gram matrix
~~~~~~~~~~~~~~~~~~~~~
Set ``kernel='precomputed'`` and pass the Gram matrix instead of X in the fit
method. At the moment, the kernel values between *all* training vectors and the
test 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) # doctest: +NORMALIZE_WHITESPACE
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape=None, degree=3, gamma='auto',
kernel='precomputed', max_iter=-1, probability=False,
random_state=None, shrinking=True, tol=0.001, verbose=False)
>>> # predict on training examples
>>> clf.predict(gram)
array([0, 1])
Parameters of the RBF Kernel
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When training an SVM with the *Radial Basis Function* (RBF) kernel, two
parameters must be considered: ``C`` and ``gamma``. The parameter ``C``,
common to all SVM kernels, trades off misclassification of training examples
against simplicity of the decision surface. A low ``C`` makes the decision
surface smooth, while a high ``C`` aims at classifying all training examples
correctly. ``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. One
is advised to use :class:`sklearn.model_selection.GridSearchCV` with
``C`` and ``gamma`` spaced exponentially far apart to choose good values.
.. topic:: Examples:
* :ref:`sphx_glr_auto_examples_svm_plot_rbf_parameters.py`
.. _svm_mathematical_formulation:
Mathematical formulation
========================
A support vector machine constructs a hyper-plane or set of hyper-planes
in a high or infinite dimensional space, which can be used for
classification, regression or other tasks. Intuitively, a good
separation is achieved by the hyper-plane that has the largest distance
to the nearest training data points of any class (so-called functional
margin), since in general the larger the margin the lower the
generalization error of the classifier.
.. figure:: ../auto_examples/svm/images/sphx_glr_plot_separating_hyperplane_001.png
:align: center
:scale: 75
SVC
---
Given training vectors :math:`x_i \in \mathbb{R}^p`, i=1,..., n, in two classes, and a
vector :math:`y \in \{1, -1\}^n`, SVC solves the following primal problem:
.. math::
\min_ {w, b, \zeta} \frac{1}{2} w^T w + C \sum_{i=1}^{n} \zeta_i
\textrm {subject to } & y_i (w^T \phi (x_i) + b) \geq 1 - \zeta_i,\\
& \zeta_i \geq 0, i=1, ..., n
Its dual is
.. math::
\min_{\alpha} \frac{1}{2} \alpha^T Q \alpha - e^T \alpha
\textrm {subject to } & y^T \alpha = 0\\
& 0 \leq \alpha_i \leq C, i=1, ..., n
where :math:`e` is the vector of all ones, :math:`C > 0` is the upper bound,
:math:`Q` is an :math:`n` by :math:`n` positive semidefinite matrix,
:math:`Q_{ij} \equiv y_i y_j K(x_i, x_j)`, where :math:`K(x_i, x_j) = \phi (x_i)^T \phi (x_j)`
is the kernel. Here training vectors are implicitly mapped into a higher
(maybe infinite) dimensional space by the function :math:`\phi`.
The decision function is:
.. math:: \operatorname{sgn}(\sum_{i=1}^n y_i \alpha_i K(x_i, x) + \rho)
.. note::
While SVM models derived from `libsvm`_ and `liblinear`_ use ``C`` as
regularization parameter, most other estimators use ``alpha``. The relation
between both is :math:`C = \frac{n\_samples}{alpha}`.
.. TODO multiclass case ?/
This parameters can be accessed through the members ``dual_coef_``
which holds the product :math:`y_i \alpha_i`, ``support_vectors_`` which
holds the support vectors, and ``intercept_`` which holds the independent
term :math:`\rho` :
.. topic:: References:
* `"Automatic Capacity Tuning of Very Large VC-dimension Classifiers"
<http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.17.7215>`_,
I. Guyon, B. Boser, V. Vapnik - Advances in neural information
processing 1993.
* `"Support-vector networks"
<http://link.springer.com/article/10.1007%2FBF00994018>`_,
C. Cortes, V. Vapnik - Machine Learning, 20, 273-297 (1995).
NuSVC
-----
We introduce a new parameter :math:`\nu` which controls the number of
support vectors and training errors. The parameter :math:`\nu \in (0,
1]` is an upper bound on the fraction of training errors and a lower
bound of the fraction of support vectors.
It can be shown that the :math:`\nu`-SVC formulation is a reparametrization
of the :math:`C`-SVC and therefore mathematically equivalent.
SVR
---
Given training vectors :math:`x_i \in \mathbb{R}^p`, i=1,..., n, and a
vector :math:`y \in \mathbb{R}^n` :math:`\varepsilon`-SVR solves the following primal problem:
.. math::
\min_ {w, b, \zeta, \zeta^*} \frac{1}{2} w^T w + C \sum_{i=1}^{n} (\zeta_i + \zeta_i^*)
\textrm {subject to } & y_i - w^T \phi (x_i) - b \leq \varepsilon + \zeta_i,\\
& w^T \phi (x_i) + b - y_i \leq \varepsilon + \zeta_i^*,\\
& \zeta_i, \zeta_i^* \geq 0, i=1, ..., n
Its dual is
.. math::
\min_{\alpha, \alpha^*} \frac{1}{2} (\alpha - \alpha^*)^T Q (\alpha - \alpha^*) + \varepsilon e^T (\alpha + \alpha^*) - y^T (\alpha - \alpha^*)
\textrm {subject to } & e^T (\alpha - \alpha^*) = 0\\
& 0 \leq \alpha_i, \alpha_i^* \leq C, i=1, ..., n
where :math:`e` is the vector of all ones, :math:`C > 0` is the upper bound,
:math:`Q` is an :math:`n` by :math:`n` positive semidefinite matrix,
:math:`Q_{ij} \equiv K(x_i, x_j) = \phi (x_i)^T \phi (x_j)`
is the kernel. Here training vectors are implicitly mapped into a higher
(maybe infinite) dimensional space by the function :math:`\phi`.
The decision function is:
.. math:: \sum_{i=1}^n (\alpha_i - \alpha_i^*) K(x_i, x) + \rho
These parameters can be accessed through the members ``dual_coef_``
which holds the difference :math:`\alpha_i - \alpha_i^*`, ``support_vectors_`` which
holds the support vectors, and ``intercept_`` which holds the independent
term :math:`\rho`
.. topic:: References:
* `"A Tutorial on Support Vector Regression"
<http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.114.4288>`_,
Alex J. Smola, Bernhard Schölkopf - Statistics and Computing archive
Volume 14 Issue 3, August 2004, p. 199-222.
.. _svm_implementation_details:
Implementation details
======================
Internally, we use `libsvm`_ and `liblinear`_ to handle all
computations. These libraries are wrapped using C and Cython.
.. _`libsvm`: http://www.csie.ntu.edu.tw/~cjlin/libsvm/
.. _`liblinear`: http://www.csie.ntu.edu.tw/~cjlin/liblinear/
.. topic:: References:
For a description of the implementation and details of the algorithms
used, please refer to
- `LIBSVM: A Library for Support Vector Machines
<http://www.csie.ntu.edu.tw/~cjlin/papers/libsvm.pdf>`_.
- `LIBLINEAR -- A Library for Large Linear Classification
<http://www.csie.ntu.edu.tw/~cjlin/liblinear/>`_.
|