1. SVM算法特性:

Image

     1.1 训练好的模型的算法复杂度是由支持向量的个数决定的,而不是由数据的维度决定的。所以SVM不太容易产生overfitting

     1.2 SVM训练出来的模型完全依赖于支持向量(Support Vectors), 即使训练集里面所有非支持向量的点都被去除,重复训练过程,结果仍然会得到完全一样的模型。

     1.3 一个SVM如果训练得出的支持向量个数比较小,SVM训练出的模型比较容易被泛化。

2. 线性不可分的情况 (linearly inseparable case)

Image [1]

 

 2.1 数据集在空间中对应的向量不可被一个超平面区分开

     2.2 两个步骤来解决:

          2.2.1 利用一个非线性的映射把原数据集中的向量点转化到一个更高维度的空间中

          2.2.2 在这个高维度的空间中找一个线性的超平面来根据线性可分的情况处理

main-qimg-de8f2ca9c807ee184e2509639fce066d

2.2.3 视觉化演示 https://www.youtube.com/watch?v=3liCbRZPrZA

.3 如何利用非线性映射把原始数据转化到高维中?
          2.3.1 例子:
                   3维输入向量:
Image [2]
转化到6维空间 Z 中去
QQ截图20170612173914
 新的决策超平面:

Image [5]

其中W和Z是向量,这个超平面是线性的
                   解出W和b之后,并且带入回原方程:
Image [6]
  2.3.2 思考问题:
                    2.3.2.1: 如何选择合理的非线性转化把数据转到高纬度中?
                    2.3.2.2: 如何解决计算内积时算法复杂度非常高的问题?
          2.3.3 使用核方法(kernel trick)
3. 核方法(kernel trick)
QQ截图20170612174609
   3.2  常用的核函数(kernel functions)
          h度多项式核函数(polynomial kernel of degree h):
Image [10]
          高斯径向基核函数(Gaussian radial basis function kernel):
Image [11]
          S型核函数(Sigmoid function kernel):
Image [12]
          如何选择使用哪个kernel?
          根据先验知识,比如图像分类,通常使用RBF,文字不使用RBF
          尝试不同的kernel,根据结果准确度而定
     3.3  核函数举例:
            假设定义两个向量: x = (x1, x2, x3); y = (y1, y2, y3)
            定义方程:f(x) = (x1x1, x1x2, x1x3, x2x1, x2x2, x2x3, x3x1, x3x2, x3x3)
            K(x, y ) = (<x, y>)^2
            假设x = (1, 2, 3); y = (4, 5, 6).

f(x) = (1, 2, 3, 2, 4, 6, 3, 6, 9)
f(y) = (16, 20, 24, 20, 25, 36, 24, 30, 36)
<f(x), f(y)> = 16 + 40 + 72 + 40 + 100+ 180 + 72 + 180 + 324 = 1024

 
 
           K(x, y) = (4  + 10 + 18 ) ^2 = 32^2 = 1024
 
           同样的结果,使用kernel方法计算容易很多
 
4. SVM扩展可解决多个类别分类问题
          对于每个类,有一个当前类和其他类的二类分类器(one-vs-rest)
 
          
示例 人脸识别
ImageNet 是一个计算机视觉系统识别项目, 是目前世界上图像识别最大的数据库。
import numpy as np
import pylab as pl
from sklearn import svm

# we create 40 separable points
X = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]]
Y = [0]*20 +[1]*20

#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])

print "w: ", w
print "a: ", a

# print "xx: ", xx
# print "yy: ", yy
print "support_vectors_: ", clf.support_vectors_
print "clf.coef_: ", clf.coef_

# switching to the generic n-dimensional parameterization of the hyperplan to the 2D-specific equation
# of a line y=a.x +b: the generic w_0x + w_1y +w_3=0 can be rewritten y = -(w_0/w_1) x + (w_3/w_1)


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

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

pl.axis('tight')
pl.show()

下载svm示例代码