目录
一、概述
二、线性可分支持向量机
2.1 SVM要解决的问题
2.2 距离计算
2.3 优化的目标
2.4 目标函数
2.5 SVM求解
2.6 SVM求解实例
2.7 支持向量机名字的本质
三、软间隔 soft-margin
三、核函数:低维不可分问题
3.1 高斯核函数
四、sklearn中的支持向量机
4.1 SVC参数
4.2 调节C参数 Soft Margin问题
4.3 gamma参数
一、概述
支持向量机(support vector machines)是一种二分类模型,它的目的是寻找一个超平面来对样本进行分割,分割的原则是间隔最大化,最终转化为一个凸二次规划问题来求解。由简至繁的模型包括:
二、线性可分支持向量机
如果一个线性函数能够将样本分开,称这些数据样本是线性可分的。那么什么是线性函数呢?其实很简单,在二维空间中就是一条直线,在三维空间中就是一个平面,以此类推,如果不考虑空间维数,这样的线性函数统称为超平面。我们看一个简单的二维空间的例子,O代表正类,X代表负类,样本是线性可分的,但是很显然不只有这一条直线可以将样本分开,而是有无数条,我们所说的线性可分支持向量机就对应着能将数据正确划分并且间隔最大的直线。
通俗解释:找到一个条线(w和b),使得离该线最近的点能够最远
要解决的问题:
决策边界:选出来离雷区最远的(雷区就是边界上的点,要Large Margin)
SVM中关键的就是离线最近的点能够最远,所以我们要求的是线(这个栗子是平面)到点的距离
假设空间中3点,X,X1,X11 因为X1,X11在同一个平面上,可以得到
距离distance是垂直这个平面的,可以得出:
就可以得出:
数据集:(X1,Y1)(X2,Y2)…(Xn,Yn)
Y为样本的类别:当X为正例时候Y = +1 当X为负例时候Y = -1
(这里不是x,而是Φ(x),原因是核变换。具体原因会在第三大点讲到,先把Φ(x)当做x,用心看下去,你会豁然开朗。)
放缩变换:对于决策方程(w,b)可以通过放缩使得其结果值|Y|>= 1
找到一个条线(w和b),使得离该线最近的点能够最远
常规套路:将求解极大值问题转换成极小值问题
(二分之一是为了好求导,平方是为了去掉绝对值)
如何求解:应用拉格朗日乘子法求解(默认有考研数学的基础)
拉格朗日乘子法带约束的优化问题:
由于对偶性质(先求min再求max ,等于先求max再求min)
极大值转换成求极小值:(加负号)
栗子数据:3个点,其中正例X1(3,3) ,X2(4,3) ,负例X3(1,1)
由上面的栗子可以知道,α1= 0.25,α2= 0,α3= 0.25 又
意思就是说:只要某一个α=0,则这个W也是0,那么这个样本点对于最后的结果就没有影响了。
只有边界上的样本α才不等于0 。
支持向量机中的机:就是分类边界
这个机是由一些α不等于0的样本点向量而支撑的
这个就是支持向量机的由来。
三、软间隔 soft-margin
软间隔:有时候数据中有一些噪音点,如果考虑它们咱们的线就不太好了
例如:
之前的方法要求要把两类点完全分得开,这个要求有点过于严格了,我们来放松一点!
当C趋近于很大时:意味着ξ小,分类严格不能有错误。当C趋近于很小时:意味着ξ大,可以有更大的错误容忍。
C是之后我们需要指定的一个参数。
现在求解法和2.4一样了。
拉格朗日乘子法:
三、核函数:低维不可分问题
核变换:既然低维的时候不可分,那我给它映射到高维
意思就是:当x在低维不可分时,可以通过核变换转化为高纬Φ(x),即可分。
我们来个栗子好理解:
还是先从一个小例子来闻述问题。假设我们有俩个数据,x=(x1x2,x3);y=(y1,y2,y3)
在3D空间已经不能对其经行线性划分了,那么我们通过一个函数将数据映射到更高维的空间。
比如平方映射成9维的话,那么f(x)=(X1X1,X1X2,X1X3,X2X1,X2X2,X3X1,X3X2,X3X3),
由于需要计算内积,所以在新的数据在9维空间,需要计算
在具体点,令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)
所以要求内集
似乎还能计算,但是如果将维数扩大到一个非常大数时候,计算起来可就不是一点问题了
但是发现,K ( x , y ) = ( < x , y > ) ^ 2
K ( x , y ) = (a + 10 + 18)^2 = 32 ^ 2 =1024
俩者相等,K ( x , y ) = ( < x , y > ) ^ 2=
也就是说只要用K(x,y)来计算,,效果和
所以使用核函数的好处就以在一个低维空间去完成高维度(或者无限维度)样本内积的计算。
先映射再求内集 = 先求内集再映射
比如K(x,y)=(4+10+18)^2的3D空间对比
很多同学还不知道为啥低维不可分,高维就可以分了呢?我们来看2张图。
刚刚的栗子是从3纬映射到9纬,但是一般情况下,你也不知道映射到几纬的,也不可能一个个去试。
所以就有了高斯核函数:
线性核函数和高斯核函数对比:
四、sklearn中的支持向量机
from sklearn.svm import SVC
'''
Support vector classifier
'''
SVC(C=1.0,
cache_size=200,
class_weight=None,
coef0=0.0,
decision_function_shape='ovr',
degree=3,
gamma='auto_deprecated',
kernel='rbf',
max_iter=-1,
probability=False,
random_state=None,
shrinking=True,
tol=0.001,
verbose=False)
参数含义:
错误项的惩罚系数。C越大,即对分错样本的惩罚程度越大,因此在训练样本中准确率越高,但是泛化能力降低,也就是对测试数据的分类准确率降低。相反,减小C的话,容许训练样本中有一些误分类错误样本,泛化能力强。对于训练样本带有噪声的情况,一般采用后者,把训练样本集中错误分类的样本作为噪声。
算法中采用的核函数类型,可选参数有:
‘linear’:线性核函数
‘poly’:多项式核函数
‘rbf’:径像核函数/高斯核函数
‘sigmod’:sigmod核函数
‘precomputed’:核矩阵
precomputed表示自己提前计算好核函数矩阵,这时候算法内部就不再用核函数去计算核矩阵,而是直接用你给的核矩阵。核矩阵为如下形式:
还有一点需要说明,除了上面限定的核函数外,还可以给出自己定义的核函数,其实内部就是用你自己定义的核函数来计算核矩阵。
这个参数只对多项式核函数有用,是指多项式核函数的阶数n
如果给的核函数参数是其他核函数,则会自动忽略该参数。
核函数系数,只对‘rbf’,‘poly’,‘sigmod’有效。
gamma参数越大,映射维度高,模型越复杂。gamma参数越小,映射维度低,模型越简单
如果gamma为auto,代表其值为样本特征数的倒数,即1/n_features.
核函数中的独立项,只有对‘poly’和‘sigmod’核函数有用,是指其中的参数c
是否启用概率估计。 这必须在调用fit()之前启用,并且会fit()方法速度变慢。
是否采用启发式收缩方式
svm停止训练的误差精度
指定训练所需要的内存,以MB为单位,默认为200MB。
给每个类别分别设置不同的惩罚参数C,如果没有给,则会给所有类别都给C=1,即前面参数指出的参数C.
如果给定参数‘balance’,则使用y的值自动调整权重,与输入数据中的类频率成反比的权重。
是否启用详细输出。 此设置利用libsvm中的每个进程运行时设置,如果启用,可能无法在多线程上下文中正常工作。一般情况都设为False,不用管它。
最大迭代次数,如果为-1,表示不限制
对数据进行概率估计时使用的伪随机数生成器的种子。如果为int,则随机数生成器使用的种子;如果为random state实例,则随机数生成器为random state;如果为none,则随机数生成器为np.random使用的random state实例。
★fit() 方法:用于训练SVM,具体参数已经在定义SVC对象的时候给出了,这时候只需要给出数据集X和X对应的标签y即可。
★predict() 方法: 基于以上的训练,对预测样本T进行类别预测,因此只需要接收一个测试集T,该函数返回一个数组表示个测试样本的类别。
★属性有哪些:
from sklearn.datasets.samples_generator import make_blobs
X, y = make_blobs(n_samples=100, centers=2,
random_state=0, cluster_std=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn');
不同的参数C:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
X, y = make_blobs(n_samples=100, centers=2,
random_state=0, cluster_std=0.8)
fig, ax = plt.subplots(1, 2, figsize=(16, 6))
fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)
for axi, C in zip(ax, [10.0, 0.1]):
model = SVC(kernel='linear', C=C).fit(X, y)
axi.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(model, axi)
axi.scatter(model.support_vectors_[:, 0],
model.support_vectors_[:, 1],
s=300, lw=1, facecolors='none');
axi.set_title('C = {0:.1f}'.format(C), size=14)
gamma参数越大,映射维度高,模型越复杂。gamma参数越小,映射维度低,模型越简单
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
X, y = make_blobs(n_samples=100, centers=2,
random_state=0, cluster_std=1.1)
fig, ax = plt.subplots(1, 2, figsize=(16, 6))
fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)
for axi, gamma in zip(ax, [10.0, 0.1]):
model = SVC(kernel='rbf', gamma=gamma).fit(X, y)
axi.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(model, axi)
axi.scatter(model.support_vectors_[:, 0],
model.support_vectors_[:, 1],
s=300, lw=1, facecolors='none');
axi.set_title('gamma = {0:.1f}'.format(gamma), size=14)