# Support Vector Machine

[SVM](https://en.wikipedia.org/wiki/Support_vector_machine) is trying to find biggest distance between the points, so there is as much separation as possible. That said, SVM works well with less data where the separation is obvious (there are big margins between the data points). So, SVM does not work well for data sets with a lot of points and with data sets with a lot of noice.

Taken from [An Idiot’s guide to Support vector machines (SVMs)](http://web.mit.edu/6.034/wwwbob/svm.pdf):

> Two independent developments within last decade:
>
> * New efficient separability of non-linear regions that use “[kernel functions](https://www.quora.com/What-are-Kernels-in-Machine-Learning-and-SVM)” : generalization of ‘similarity’ to new kinds of similarity measures based on dot products
> * Use of [quadratic optimization problem](http://www.solver.com/linear-quadratic-programming) to avoid ‘[local minimum](https://www.whitman.edu/mathematics/calculus_online/section05.01.html)’ issues with neural nets
> * The resulting learning algorithm is an optimization algorithm rather than a greedy search

![](https://463299088-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3wXpaYFUfPiqG2WRb2%2F-M3wY0wnXPvGBdZ6_Cbt%2F-M3wY4ziXktqea-YRWtS%2FScreen%20Shot%202017-05-21%20at%209.50.59%20PM.png?generation=1585858861463550\&alt=media)

> * SVMs maximize the margin (Winston terminology: the ‘street’) around the separating [hyperplane](https://en.wikipedia.org/wiki/Hyperplane).
> * The decision function is fully specified by a (usually very small) subset of training samples, the support vectors.
> * This becomes a [Quadratic programming](https://en.wikipedia.org/wiki/Quadratic_programming) problem that is easy to solve by standard methods
>
> General input/output for SVMs just like for neural nets, but for one important addition...
>
> **Input**: set of (input, output) training pair samples; call the input sample features _x1, x2...xn_, and the output result _y_.Typically, there can be lots of input features _x(i)_.
>
> **Output**: set of weights w(or _w(i)_), one for each feature, whose [linear combination](https://en.wikipedia.org/wiki/Linear_combination) predicts the value of _y_.(So far, just like neural nets...)
>
> **Important difference**: we use the optimization of maximizing the margin (‘street width’) to reduce the number of weights that are nonzero to just a few that correspond to the important features that ‘matter’ in deciding the separating line ([hyperplane](https://en.wikipedia.org/wiki/Hyperplane))...these nonzero weights correspond to the support vectors (because they ‘support’ the separating hyperplan
>
> * Support vectors are the elements of the training set that would change the position of the dividing hyperplane if removed.
> * Support vectors are the critical elements of the training set
> * The problem of finding the optimal hyper plane is an optimization problem and can be solved by optimization techniques (we use Lagrange multipliers to get this problem into a form that can be solved analytically).![](https://463299088-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3wXpaYFUfPiqG2WRb2%2F-M3wY0wnXPvGBdZ6_Cbt%2F-M3wY4zkvi0I1Pc5_RQw%2Fsvm-vectors.png?generation=1585858861859255\&alt=media)
> * Moving a support vector moves the decision boundary
> * Moving the other vectors has no effect

Nice video explaining SVM is [here](https://www.youtube.com/watch?v=_PwhiWxHK8o).

Here is another picture showing basic concept in SVM, finding separating line by finding biggest margin.

![](https://463299088-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3wXpaYFUfPiqG2WRb2%2F-M3wY0wnXPvGBdZ6_Cbt%2F-M3wY4zm07K2Js1nUOfE%2Fsvm1.png?generation=1585858859847734\&alt=media)

## Outliers

What should SVM do with this data set? It should ignore that outlier. These points are called outliers.

![](https://463299088-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3wXpaYFUfPiqG2WRb2%2F-M3wY0wnXPvGBdZ6_Cbt%2F-M3wY4zoZ_abjEe4oF6M%2Fsvm2.png?generation=1585858862456252\&alt=media)

Here is an example from [SVM documentation](http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html).

```
import numpy as np
X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1]])
y = np.array([1, 1, 2, 2])
from sklearn.svm import SVC
clf = SVC()
clf.fit(X, y)

print(clf.predict([[-0.8, -1]]))
```

The result is:

```
[1]
```

## Not separable data and kernel parameter

In case the data are no separable at the first sight, we can calculate a new feature. We need to create a linear line.

![](https://463299088-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3wXpaYFUfPiqG2WRb2%2F-M3wY0wnXPvGBdZ6_Cbt%2F-M3wY4zq5KCyqDo3EEQU%2Fsvm-newfeature.png?generation=1585858860941474\&alt=media)

We do not have to calculate new features. We can change 'kernel' parameter to force SVM to create linear separator. There are other parameters we can configure for SVM. There are to more that are important, it is C and gamma.

## C parameter

Here is what C does. Bigger C value causes more points to be correctly separated, but it also costs more. There must be a balance between algorithm accuracy and speed.

![](https://463299088-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3wXpaYFUfPiqG2WRb2%2F-M3wY0wnXPvGBdZ6_Cbt%2F-M3wY4zsC1wNbQQOUczH%2Fsvm-c.png?generation=1585858861466686\&alt=media)

## Overfitting

If the lines separating data points are too complex, it is called overfitting. The black curve on the chart below is example of overfitting. The green line, show how the good separation could look like. We can change C, gamma or kernel to tune separation and get rid of overfitting (do not take all the data too seriously).

![](https://463299088-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3wXpaYFUfPiqG2WRb2%2F-M3wY0wnXPvGBdZ6_Cbt%2F-M3wY4zu5-89v47HfgFK%2Fsvm-overfitting.png?generation=1585858860486448\&alt=media)

## Visualize hyperplane

Here is a nice example from documentation. First we generate 5 points for each label. Then we use linear SVC and fit the created points. Then see how separation line is calculated, together with another two lines that make margin easily observable. Hyper plane has always one less dimension than the space it exists (e.g. for 2D system, 1D line is hyperplane).

```
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm

np.random.seed(0)
X = np.r_[np.random.randn(5, 2) - [2, 2], np.random.randn(5, 2) + [2, 2]]
Y = [0] * 5 + [1] * 5
print X
print Y

# fit the model
clf = svm.SVC(kernel='linear')
clf.fit(X, Y)

# get the separating hyperplane
w = clf.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(-5, 5)
yy = a * xx - (clf.intercept_[0]) / w[1]

# plot the parallels to the separating hyperplane that pass through the
# support vectors
b = clf.support_vectors_[0]
yy_down = a * xx + (b[1] - a * b[0])
b = clf.support_vectors_[-1]
yy_up = a * xx + (b[1] - a * b[0])

# plot the line, the points, and the nearest vectors to the plane
plt.plot(xx, yy, 'k-')
plt.plot(xx, yy_down, 'k--')
plt.plot(xx, yy_up, 'k--')

plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],
            s=80, facecolors='none')
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.Paired)

plt.axis('tight')
plt.show()
```

Here is the chart with the separation lines and another two "margin" lines.

![](https://463299088-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3wXpaYFUfPiqG2WRb2%2F-M3wY0wnXPvGBdZ6_Cbt%2F-M3wY4zwpxGlSIFwv70m%2Fsvm-separation-lines.png?generation=1585858870878315\&alt=media)

Here is the data used in the chart.

```
Features: 
[[-0.23594765 -1.59984279]
 [-1.02126202  0.2408932 ]
 [-0.13244201 -2.97727788]
 [-1.04991158 -2.15135721]
 [-2.10321885 -1.5894015 ]
 [ 2.14404357  3.45427351]
 [ 2.76103773  2.12167502]
 [ 2.44386323  2.33367433]
 [ 3.49407907  1.79484174]
 [ 2.3130677   1.14590426]]

Labels:
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
```
