【python库学习】 sklearn中的支持向量模型svm模块

原理

SVM 支持向量的原型最开始是从一个二分类任务得到的.有一个二分类,标签y取值{+1,-1},想要进行分类,则要在样本中寻找一个超平面可以将样本分为两类,该超平面可以定义为 w x + b = 0 wx+b=0 wx+b=0 其中w是法向量,则任意样本到超平面的距离为 γ = ∣ w x + b ∣ ∥ w ∥ \gamma=\frac {|wx+b|}{\| w\|} γ=wwx+b,该公式是由向量投影推导出点到直线的距离公式.
我们希望全部正确分类,则有 y ( w x + b ) > = 1 y(wx+b)>=1 y(wx+b)>=1由此样本到超平面的最小距离为 γ = 1 ∥ w ∥ \gamma=\frac {1}{\| w\|} γ=w1.为了分类效果最佳,我们的目标就是使得这个最小距离最大,即 max ⁡ 1 ∥ w ∥ s . t    y ( w x + b ) − 1 > = 0 \max \frac {1}{\| w\|}\\s.t \space\space y(wx+b)-1>=0 maxw1s.t  y(wx+b)1>=0 等价于最小化 min ⁡ 1 2 ∥ w ∥ 2 s . t    y ( w x + b ) − 1 > = 0 \min \frac {1}{2}{\| w\|}^2 \\ s.t \space\space {y(wx+b)-1>=0} min21w2s.t  y(wx+b)1>=0
接下来就是求解,引入拉格朗日式子,求导等于0,将w,b进行替换就得到了上面式子的对偶问题 min ⁡   ∑ i = 1 n α i − 1 2 ∑ i = 1 n ∑ j = 1 n α i α j y i y j x j T x i K K T : { α i ≥ 0 y i f ( x i ) − 1 ≥ 0 α i ( y i f ( x i ) − 1 ) = 0 \min \space \displaystyle\sum_{i=1}^n \alpha_i -\frac 1 2 \displaystyle\sum_{i=1}^n \displaystyle\sum_{j=1}^n \alpha_i \alpha_j y_i y_j x_j^Tx_i \\ KKT:\begin{cases} \alpha_i \ge0 \\ y_if(x_i)-1 \ge0 \\ \alpha_i(y_if(x_i)-1)=0 \end{cases} min i=1nαi21i=1nj=1nαiαjyiyjxjTxiKKT: αi0yif(xi)10αi(yif(xi)1)=0其中约束条件转化为KKT条件.条件中 f ( x i ) = w x i + b f(x_i)=wx_i+b f(xi)=wxi+b.KKT最后一个条件 α = 0 \alpha=0 α=0时表明样本被忽略,不为0时,式子 y i f ( x i ) − 1 = 0 y_if(x_i)-1=0 yif(xi)1=0支持向量.
通过SMO等求解算法得到拉格朗日算子 α \alpha α的解,由此得到最优解 w ∗ w^* w,代入一个支持向量就可以得到 b ∗ b^* b.至此该模型的求解就完成了,原型也如上所示.
通过上述原理也可以得到该模型的决策函数由支持向量决定,模型的决策函数为 f ( x ) = s g n ( w ∗ T x + b ∗ ) = s g n ( ∑ i = 1 n α i y i x i T x + b ∗ ) f(x)=sgn( w^{*T}x+b^*)\\=sgn(\displaystyle\sum_{i=1}^n \alpha_i y_i x_i^Tx+b^* ) f(x)=sgn(wTx+b)=sgn(i=1nαiyixiTx+b)其中取 α i > 0 \alpha_i>0 αi>0下对应的支持向量,sgn为阶跃函数,大于0输出1,等于0输出0,小于0输出-1.
在这里插入图片描述

软间隔

说完原理,我们看到上面的假设是严格分类,有时较难求出最优解,若允许部分样本超过最小间隔,当然希望尽可能减少越过的样本数,则目标函数变为下方形式 min ⁡ 1 2 ∥ w ∥ 2 + C ∑ i = 1 n m a x ( 0 , 1 − y i ( w i x + b ) ) − − ( 1 ) \min \frac 1 2 \|w\|^2+C\displaystyle\sum_{i=1}^n max(0,1-y_i(w_ix+b)) --(1)\\ min21w2+Ci=1nmax(0,1yi(wix+b))(1)
引入松弛变量则该式子表示为
min ⁡ 1 2 ∥ w ∥ 2 + C ∑ i = 1 n ξ i s . t .    { y i ( w x i + b ) + ξ i − 1 ≥ 0   , i ∈ [ 1 , n ] ξ i ≥ 0   , i ∈ [ 1 , n ] \min \frac 1 2 \|w\|^2+C\displaystyle\sum_{i=1}^n \xi_i\\ \\s.t. \space\space \begin{cases}y_i(wx_i+b)+\xi_i-1\ge0 \space ,i\in [1,n] \\ \xi_i\ge0 \space ,i\in [1,n]\end{cases} min21w2+Ci=1nξis.t.  {yi(wxi+b)+ξi10 ,i[1,n]ξi0 ,i[1,n]
该公式(1)从另外一角度也可以理解为经验风险项+正则化项.经验风险项可以选择其它形式,即当前常见的损失函数形式,公式中的形式为Hinge损失函数.接下来按正常流程进行求解.

核函数

当遇到线性不可分的场景,考虑将其转化到高纬空间使其可分.由此需要对样本进行转化,则x变为 ϕ ( x ) \phi(x) ϕ(x),原公式中X进行相应的切换.该难点是很难确定具体的 ϕ ( x ) \phi(x) ϕ(x)是什么样的,因此定义核函数为 k ( x i , x j ) = ϕ ( x i ) T ϕ ( x j ) k(x_i,x_j)=\phi(x_i)^T\phi(x_j) k(xi,xj)=ϕ(xi)Tϕ(xj),核矩阵为
在这里插入图片描述
其中能成为核函数的要求是核矩阵总是半正定的,如此总能找到一个与核函数对应的 ϕ ( x ) \phi(x) ϕ(x).
常见的核函数有
在这里插入图片描述

回归

用于回归任务时,其最小间隔就不是1了,而是f(x)与y偏差 ϵ \epsilon ϵ,同样为简化表示,引入松弛变量
min ⁡ 1 2 ∥ w ∥ 2 + C ∑ i = 1 n ( ξ i + ξ i ∗ ) s . t .    { y i − f ( x i ) ≥ ξ i + ϵ   , i ∈ [ 1 , n ] f ( x i ) − y i ≥ ξ i ∗ + ϵ   , i ∈ [ 1 , n ] ξ i ≥ 0 , ξ i ∗ ≥ 0   , i ∈ [ 1 , n ] \min \frac 1 2 \|w\|^2+C\displaystyle\sum_{i=1}^n (\xi_i+ \xi_i^*)\\ \\s.t. \space\space \begin{cases}y_i-f(x_i)\ge\xi_i+\epsilon \space ,i\in [1,n] \\ f(x_i)-y_i\ge\xi_i^*+\epsilon \space ,i\in [1,n] \\ \xi_i\ge0 ,\xi_i^*\ge0\space ,i\in [1,n]\end{cases} min21w2+Ci=1n(ξi+ξi)s.t.   yif(xi)ξi+ϵ ,i[1,n]f(xi)yiξi+ϵ ,i[1,n]ξi0,ξi0 ,i[1,n]

优缺点

支持向量机模型可以用于分类,回归以及异常识别任务,具有以下优点

  1. 高维空间有效,特征维度高于样本数时仍然有效
  2. 内存占用小(存储支持向量集)
  3. 可扩展性好,支持不同核函数以应用不同场景,如下图所示

在这里插入图片描述
当然也具有一些限制:

  1. 当特征维度远大于样本数时,效果变差
  2. 该模型分类时不提供概率值,如需要获取概率,需要再进行一次转换(如softmax,平台缩放),添加额外的计算,且概率为近似值。
  3. 应用核函数遇到样本量大时,计算量过大,不适用。
  4. 难以选择合适的核函数
  5. 对缺失值敏感

1.分类

当前模有方法SVC,NuSVC与LinearSVC,NuSVC与SVC的区别在于使用了参数V来控制训练误差的上限与支持向量的下限,而SVC的正则参数是C。该模块方法使用如下,可以通过其属性support_vectors_查看重要的支持向量信息。

>>> from sklearn import svm
>>> # 训练集 X【样本数,特征】
>>> X = [[0, 0], [1, 1]]
>>> # 标签 y【样本数】
>>> y = [0, 1]
>>> clf = svm.SVC()
>>> clf.fit(X, y)  
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)
>>> # get support vectors
>>> clf.support_vectors_
array([[ 0.,  0.],
       [ 1.,  1.]])
>>> # get indices of support vectors
>>> clf.support_ 
array([0, 1]...)
>>> # get number of support vectors for each class
>>> clf.n_support_ 
array([1, 1]...)

1.1多分类

方法SVC,NuSVC通过一VS一的方式进行分类,这意味着n类需要训练n*(n-1)/2 个分类器,而LinearSVC 采用的是一VS其余,n类训练n个分类器。为了使用中接口的统一,提供了参数decision_function_shape来进行选择。当使用一VS其余方法时遇到平局时,默认返回它们中的第一类,要想不使用默认需在predict方法中设置break_ties=True,但需注意的是该设置需消耗一定计算量。

>>> X = [[0], [1], [2], [3]]
>>> Y = [0, 1, 2, 3]
>>> clf = svm.SVC(decision_function_shape='ovo')
>>> clf.fit(X, Y) 
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

1.2得分与概率

SVC,NuSCV下的方法decision_function 给出来每个样本在每类上的得分,使用方法decision_function得到概率。在二分类中,使用Platt 缩放法实现,该方法使用SVC模型输出作为训练集,构建sigmod函数,原标签仍为标签,进行拟合参数求解,由此得到了概率输出。该方法,在遇到大数据集时,计算消耗会过大;且该概率与得分并不保持完全的正相关关系;可能还会出现模型输出为1类,而概率输出小于0.5的情况。在实际使用中建议不要使用概率输出而采用得分输出。

# 输出概率
>>> clf.predict_proba(X)

1.3 不平衡问题

当需要对某一类或某些样本给更多权重时,可以通过参数 class_weight 和 sample_weight进行设置。SVC 两个均支持设置,其他支持使用sample_weight进行设置,其中class_weight设置形式与生效效果对比如下

#{1:10} 中1表示为类,10表示权重值
wclf = svm.SVC(kernel="linear", class_weight={1: 10})
wclf.fit(X, y)

在这里插入图片描述
sample_weight设置与使用效果如下

#sample_weight_last_ten 为维度等于样本数的一位数组,元素初始均为1
# and bigger weights to some outliers
sample_weight_last_ten[15:] *= 5
# Fit the models.
# This other model takes into account some dedicated sample weights.
clf_weights = svm.SVC(gamma=1)
clf_weights.fit(X, y, sample_weight=sample_weight_last_ten)

在这里插入图片描述

2.回归

本库对回归实现有三个方法 SVR, NuSVR and LinearSVR,可以调用。三者实现上稍微有所不同,其中LinearSVR如其名所示只支持线性核。其使用方法与分类基本一致不再展开。

3.密度估计与异常识别

本库中的安排了类 OneClassSVM应用异常识别,这该部分放到异常识别方法集中进行讲解

复杂度为 O ( n s a m p l e s 2 × n f e a t u r e s )   O ( n s a m p l e s 3 × n f e a t u r e s ) O(n_samples^2 × n_ features) ~ O(n_samples^3 × n_ features) O(nsamples2×nfeatures) O(nsamples3×nfeatures)

4.实践注意事项

常用参数列表

SVC类共14个参数,其具体含义与使用建议如下:

参数名参数含义使用说明
C正则系数默认为1,惩罚力度与大小成反比,必须为正数
kernel核函数{‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’} or callable, default=’rbf’
degree多项式次数与多项式核函数配对使用
gamma核函数系数{‘scale’, ‘auto’} or float, default=’scale’,‘rbf’, ‘poly’ and ‘sigmoid’中使用
coef0核函数偏差系数在‘poly’ and ‘sigmoid’中重要
shrinking缩放系数默认True,使用见第5条
probability是否输出概率值默认为False,使用见第7条,为true时需要额外的计算量
tol损失函数阈值default=1e-3,到达该阈值停止迭代
cache_size缓存大小使用见第2条
class_weight类权重使用见第6条以及前文
max_iter最大迭代次数默认-1,不做限制
decision_function_shape多分类方法参数{‘ovo’, ‘ovr’}, default=’ovr’对应1V1,1v其他
break_ties解绑参数见1.1多分类
random_state随机状态使用见第7条
  1. 避免数据复制,当数据不是次序连续和双精度的时候,底层实现会复制数据集转成该格式,若数据集大,且无法避免复制时,推荐使用 SGDClassifier,其功能与LinearSVR基本类似。
  2. 若内存RAM允许,建议 cache_size设置 500(MB) or 1000(MB),默认是200M;来加快运算速度。
  3. 惩罚系数C默认为1,在没有太多异常值时,建议使用默认设置
  4. 建议对数据进行归一化或者标准化处理;
  5. 参数shrinking,在迭代次数很多时设置该参数可加快训练速度;而如果设置更大的停止阈值,建议不设置该参数会更快
  6. 遇到类别不平衡,可以设置 class_weight=‘balanced’ 或者尝试不同数值的惩罚系数C.
  7. 随机性:一、如果输出概率probability is set to True时,其底层实现会生成随机数来打乱数据集来估计概率;可以通过random_state 来控制随机状态。二、如果dual设置为True时,LinearSVR在训练时会采用随机特征选择策略,可以通过random_state 来控制随机状态。
  8. LinearSVR使用1阶惩罚项时( LinearSVC(penalty=‘l1’, dual=False)),可以产生更稀疏的决策函数,通过设置惩罚系数C进行稀疏程度控制,其中C越大,所得模型越复杂;为保证模型不为空,可以通过sklearn.svm.l1_min_c获取模型不为空下的C的最低阈值,来指导C的设置。
  9. 模型 NuSVC/OneClassSVM/NuSVR参数nu 区间在0到1之间,该参数给出样本越过边界误差占比的上限,即样本中支持向量占比的下限。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值