机器学习之:SVM总结

SVM(Support Vector Machine即支持向量机)是一种有监督的学习方法,主要通过小样本数据的学习,其后进行分类和预测。类似的根据样本进行学习的方法还有决策树归纳算法等。在解决小样本非线性高维模式识别中SVM表现出许多特有优势

1、SVM核心思想

即构建一个超平面,使得该超平面能将不同类别的样本间隔开(单纯只是满足将不同类别样本隔开的超平面可能有很多),同时为了使模型具备更好的泛化能力。此处的超平面需要满足,使两侧距离平面最近的两类样本之间的距离最大且两类样本距离超平面的距离相等,以实现对线性可分样本的最优分类。
换个角度,我们可以设想存在一条足够宽的街道,使得不同类别的样本分别位于街道两侧,而我们就是要将这条街道中间的线作为分界线。
在通过计算得到超平面的时候,需借助于非线性约束条件下的最优化、KKT条件、拉格朗日对偶、最大间隔、最优下界、核函数等进行求解
软间隔与硬间隔:
硬间隔,严格区分不同样本,使其分别位于间隔街道(以最优分割超平面的中心的分割街道)的两侧。这会导致两个问题:其一,即使将分类问题非线性的投射到高维空间也存在线性不可分的情况;其二,模型对于异常值非常敏感
软间隔,即在保持街道宽阔和限制间隔违例(即位于街道之上,甚至在错误的一边的实例)之间找到良好的平衡,从而使得模型更加灵活。
在scikit-Learn的SVM类中,可以通过超参数C来控制该平衡。C越小,则街道越宽,同时间隔违例也越多

2、SVM理论基础(Cover定理)

将复杂的模式分类问题非线性地投射到高维空间,将比投射到低维空间更可能是线性可分的。故SVM利用核函数(sklearn中利用kernel参数控制)将低维空间映射至高维空间,从而实现线性可分。但是在映射过程中是没有增加计算量

3、支持向量

支持向量机中的支持向量(Support Vector)是指训练样本集中的某些训练点(及样本,通过向量来表示),这些点最靠近分类决策面,也是最难分类的数据点。SVM中最优分类标准就是这些点距离分类超平面的距离达到最大值,且这些点到超平面的距离相等;“机”(Machine)是机器学习领域对一些算法的统称,常把算法看做一个机器,或者学习函数。支持向量在SVM分类决策中起着决定性的作用

4、SVM优缺点

优点:
1、不需要很多样本,不需要有很多样本并不意味着训练样本的绝对量很少,而是说相对于其他训练分类算法比起来,同样的问题复杂度下,SVM需求的样本相对是较少的。并且由于SVM引入了核函数,所以对于高维的样本,SVM也能轻松应对。【小样本、高维】
2、结构风险最小。这种风险是指分类器对问题真实模型的逼近与问题真实解之间的累积误差。
3、非线性,是指SVM擅长应付样本数据线性不可分的情况,主要通过松弛变量(也叫惩罚变量)和核函数技术来实现,这一部分也正是SVM的精髓所在。
4、不容易过拟合
不足:
1、由于SVM是借助二次规划来求解支持向量,而求解二次规划将涉及m阶矩阵的计算(m为样本的个数),当m数目很大时该矩阵的存储和计算将耗费大量的机器内存和运算时间。
2、SVM主要用于解决二分类问题,在解决多分类问题时,存在困难,可以采用一对多的解决方案

5、实践经验

为了在实践中使SVM模型得到的结果更佳,需要
1、对数据进行归一化【重要】
2、核函数选择,在SVM的核函数中,高斯函数(简称RBF)是最常用的,从理论上讲RBF一定不比线性函数差,但是在实践中因为涉及到调参问题,若调试不好,结果可能就比线性函数差,故在实践中,通常先用线性(利用内积)核函数,之后再根据情况决定是否在利用非线性核,然后对结果加以对比。
3、借助网格搜索得到最优参数组合,主要包括核函数、C与g
4、支持向量机不直接提供概率估计,这些都是使用昂贵的五次交叉验算计算的. (详见Sklearn文档)
5、时间复杂度:
机器学习之:SVM总结_第1张图片

6、核函数及其选择

核函数:只要一个对称函数所对应的核矩阵半正定,那么它就可以作为核函数来使用
核函数是寻找一个函数,这个函数使得在低维空间中进行计算的结果和映射到高维空间中计算内积<Φ(x­1), Φ(x2)>的结果相同。这样就避开直接在高维空间中进行计算,而最后的结果却是等价的。
由于对任意数据集找到它合适的映射是困难的且没有必要,所以通常会从常用核函数中选择。
常用核函数例如:
1、线性核函数:这是最简单的核函数,它直接计算两个输入特征向量的内积。

  • 优点:简单高效,结果易解释,总能生成一个最简洁的线性分割超平面
  • 缺点:只适用线性可分的数据集

2、多项式核函数:通过多项式来作为特征映射函数

  • 优点:可以拟合出复杂的分割超平面。
  • 缺点:参数太多。有γ,c,n三个参数要选择,选择起来比较困难;另外多项式的阶数不宜太高否则会给模型求解带来困难。
  • 参数设置:有三个参数。-d用来设置多项式核函数的最高此项次数,也就是公式中的d,默认值是3。-g用来设置核函数中的gamma参数设置,也就是公式中的第一个r(gamma),默认值是1/k(k是类别数)。-r用来设置核函数中的coef0,也就是公式中的第二个r,默认值是0。

3、高斯核函数(常用):

  • 优点:可以把特征映射到无限多维,并且没有多项式计算那么困难,参数也比较好选择。
  • 缺点:不容易解释,计算速度比较慢,容易过拟合。
  • 参数设置:有一个参数。-g用来设置核函数中的gamma参数设置,也就是公式中的第一个r(gamma),默认值是1/k(k是类别数)。

核函数的选择
1、最一般的选择原则是针对数据量很大的时候,可以选择复杂一点的模型。虽然复杂模型容易过拟合,但由于数据量很大,可以有效弥补过拟合问题。如果数据集较小选择简单点的模型,否则很容易过拟合,此时特别要注意模型是否欠拟合,如果欠拟合可以增加多项式纠正欠拟合。

2、根据样本量m和特征量n进行选择:

  • 特征相比样本较大(如m=10~1000,n=10000):选逻辑回归或者线性函数SVM
  • 特征较少,样本量中(如m=10~10000,n=1~1000):选择高斯SVM
  • 特征量少,样本多(如m=50000+,n=1~1000):选多项式或高斯SVM(或,手动添加一些Feature,使得线性可分,然后选用LR或者线性核SVM)

7、利用sklearn三方库实现SVM

from sklearn import svm
from datetime import datetime
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer,load_digits
from sklearn.metrics import roc_auc_score

dataset = load_breast_cancer()     #2个类别
X = dataset.data
y = dataset.target

X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=42)

#使用SVM训练   probability  ,decision_function_shape='ovr'
svm_model = svm.SVC(gamma='scale',probability=True,random_state=42)  #probability=True计算类别概率
svm_model.fit(X_train,y_train)

y_pre = svm_model.predict(X_test)
y_pre_pro = svm_model.predict_proba(X_test)
print('AUC值是:{}'.format(roc_auc_score(y_test,svm_model.predict_proba(X_test)[:,1])))

8、参数说明

重要参数说明:
C(松弛变量):可以理解为对误差的宽容度,即在两个分界超平面内仍然存在样本。C越大,表示对错误例惩罚程度越大,即容错率越低,可能会导致模型过拟合。选择范围:10^t , t=[- 4,4]就是0.0001 到10000
gamma:是选择核函数作为kernel后,该函数自带的一个参数。隐含地决定了数据映射到新的特征空间后的分布,gamma越大,支持向量越少,gamma值越小,支持向量越多,同时单个实例的影响范围增大。支持向量的个数影响训练与预测的速度。sklearn中的SVC中gamma可取两个值:①auto: 1 / n_features②scale:1 / (n_features * X.std())
kernel:核函数

过拟合处理方案:gamma减小,C减小,
欠拟合处理方案:gamma增大,C增大,

sklearn.svm.SVC参数说明:
sklearn.svm.SVC(C=1.0, kernel=‘rbf’, degree=3, gamma=‘auto’, coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape=‘ovr’, random_state=None) 
  C: 惩罚系数,用来控制损失函数的惩罚系数,类似于LR中的正则化系数。C越大,相当于惩罚松弛变量,希望松弛变量接近0,即对误分类的惩罚增大,趋向于对训练集全分对的情况,这样会出现训练集测试时准确率很高,但泛化能力弱,容易导致过拟合。 C值小,对误分类的惩罚减小,容错能力增强,泛化能力较强,但也可能欠拟合。
  kernel: 算法中采用的和函数类型,核函数是用来将非线性问题转化为线性问题的一种方法。参数选择有RBF, Linear, Poly, Sigmoid,precomputed或者自定义一个核函数, 默认的是"RBF",即径向基核,也就是高斯核函数;而Linear指的是线性核函数,Poly指的是多项式核,Sigmoid指的是双曲正切函数tanh核;。
  degree: 当指定kernel为’poly’时,表示选择的多项式的最高次数,默认为三次多项式;若指定kernel不是’poly’,则忽略,即该参数只对’poly’有用。(多项式核函数是将低维的输入空间映射到高维的特征空间)
  gamma: 核函数系数,该参数是rbf,poly和sigmoid的内核系数;默认是’auto’,那么将会使用特征位数的倒数,即1 / n_features。(即核函数的带宽,超圆的半径)。gamma越大,σ越小,使得高斯分布又高又瘦,造成模型只能作用于支持向量附近,可能导致过拟合;反之,gamma越小,σ越大,高斯分布会过于平滑,在训练集上分类效果不佳,可能导致欠拟合。
  coef0: 核函数常数值(y=kx+b中的b值),只有‘poly’和‘sigmoid’核函数有,默认值是0。
  shrinking : 是否进行启发式。如果能预知哪些变量对应着支持向量,则只要在这些样本上训练就够了,其他样本可不予考虑,这不影响训练结果,但降低了问题的规模并有助于迅速求解。进一步,如果能预知哪些变量在边界上(即a=C),则这些变量可保持不动,只对其他变量进行优化,从而使问题的规模更小,训练时间大大降低。这就是Shrinking技术。 Shrinking技术基于这样一个事实:支持向量只占训练样本的少部分,并且大多数支持向量的拉格朗日乘子等于C。
  probability: 是否使用概率估计,默认是False。必须在 fit() 方法前使用,该方法的使用会降低运算速度。
  tol: 残差收敛条件,默认是0.0001,即容忍1000分类里出现一个错误,与LR中的一致;误差项达到指定值时则停止训练。
  cache_size: 缓冲大小,用来限制计算量大小,默认是200M。
  class_weight : {dict, ‘balanced’},字典类型或者’balance’字符串。权重设置,正类和反类的样本数量是不一样的,这里就会出现类别不平衡问题,该参数就是指每个类所占据的权重,默认为1,即默认正类样本数量和反类一样多,也可以用一个字典dict指定每个类的权值,或者选择默认的参数balanced,指按照每个类中样本数量的比例自动分配权值。如果不设置,则默认所有类权重值相同,以字典形式传入。 将类i 的参数C设置为SVC的class_weight[i]C。如果没有给出,所有类的weight 为1。‘balanced’模式使用y 值自动调整权重,调整方式是与输入数据中类频率成反比。如n_samples / (n_classes * np.bincount(y))。(给每个类别分别设置不同的惩罚参数C,如果没有给,则会给所有类别都给C=1,即前面参数指出的参数C。如果给定参数’balance’,则使用y的值自动调整与输入数据中的类频率成反比的权重。)
  verbose : 是否启用详细输出。在训练数据完成之后,会把训练的详细信息全部输出打印出来,可以看到训练了多少步,训练的目标值是多少;但是在多线程环境下,由于多个线程会导致线程变量通信有困难,因此verbose选项的值就是出错,所以多线程下不要使用该参数。
  max_iter: 最大迭代次数,默认是-1,即没有限制。这个是硬限制,它的优先级要高于tol参数,不论训练的标准和精度达到要求没有,都要停止训练。
  decision_function_shape : 原始的SVM只适用于二分类问题,如果要将其扩展到多类分类,就要采取一定的融合策略,这里提供了三种选择。‘ovo’ 一对一,为one v one,即将类别两两之间进行划分,用二分类的方法模拟多分类的结果,决策所使用的返回的是(样本数,类别数
(类别数-1)/2); ‘ovr’ 一对多,为one v rest,即一个类别与其他类别进行划分,返回的是(样本数,类别数),或者None,就是不采用任何融合策略。默认是ovr,因为此种效果要比oro略好一点。
  random_state: 在使用SVM训练数据时,要先将训练数据打乱顺序,用来提高分类精度,这里就用到了伪随机序列。如果该参数给定的是一个整数,则该整数就是伪随机序列的种子值;如果给定的就是一个随机实例,则采用给定的随机实例来进行打乱处理;如果啥都没给,则采用默认的 np.random实例来处理。

你可能感兴趣的:(机器学习,svm,机器学习)