设为首页 收藏本站
查看: 1652|回复: 0

[经验分享] 使用支持向量机(SVM) 算法进行分类

[复制链接]

尚未签到

发表于 2017-6-21 20:58:58 | 显示全部楼层 |阅读模式
1 支持向量机(SVM)的基本概念
    SVM是一种分类算法,其侧重于模式识别方面。使用SVM可以大大提高分类的准确性。
    分类相当于模式识别的子集合,模式识别重点在于对已知数据进行特征发现与提取。
    SVM重点在于解决线性可分的问题。但很多时候,实际的问题是线性不可分的。SVM的思想就是将线性不可分的问题转化线性可分的问题。那么如何来是实现呢?就是将空间映射到多维空间。如把二维空间映射到三维空间。以增加维数来减少方程的次数。
    比如,在二维空间中,不得不用 f(x)=ax^2+b^+c 这个曲线将两类样本分开,而不是用一条直线将它们分开,这样就是一个线性不可分的问题。为了解决这个问题,我们可以使用换元法将即 x^2=y1 , x=y2 , 这样一来替换为 z=a'y1+b'y2+c' 这个线性方程,从而转换到了高维空间,代价是维度的增加引入了更多的变量。这样我们就完成了从线性不可分问题到线性可分问题的转换。
    所谓支持向量,即在每一类样本集中,过离separating hyper plane 最近的样本做一个与separating hyper plane 平行的线/超平面。有几个分类,就有几个这种直线/超平面,这样的直线/超平面就叫做支持向量(Support Vector)。

DSC0000.jpg
2 核函数
    那么找到一个线/超平面来完成二分类成为问题的关键。这个线/超平面的函数被我们成为“核函数”。常见的核函数有:


  • 线性核函数————linear
  • 多项式核函数————poly
  • 径向基核函数————rbf(用得较多)
  • Sigmoid核函数————sigmoid
    那么如何来选择合适的核函数呢?答案就是比较不同核函数的分类的准确率。在实际处理分类问题时,分别计算几种核函数的分类性能,将准确率最高的核函数作为最终用于预测分类的核函数即可。在本文的例子中,我们使用画图的方式来判断分类性能的好坏。
    使用模型不同,转换的方式不同,在多维空间中的图形就不同,分类的效果就不同。
    网上关于SVM、线性可不可分、核函数的博文很多,如http://www.cnblogs.com/LeftNotEasy/archive/2011/05/02/basic-of-svm.html 。这里就不再赘述。

3 比较分类效果与子图的划分
    为了比较不同分类器的准确性,我们采用绘制散点图,然后人工观察来判断。我们将两个类的点在坐标系中用不同颜色表示出来,同时标出训练数据,看预测点与训练点的在图中的重叠情况。重叠越紧密,说明分类的效果越准确。
    在绘图的时候,我们希望在一个平面中同时展现多幅图片,这时使用matplotlib模块的子图(subplot)来展现。

subplot的参数
  

    subplot(横向划分个数,纵向划分个数,当前定位)  

    第一个参数代表的是横向要划分的子图个数,第二个参数代表的是纵向要划分的子图的个数,第三个参数表示当前的定位。
  使用示例一:

DSC0001.png   使用示例二:

DSC0002.png   使用示例三:

DSC0003.png
4 源码

应用场景
    假设在第一象限有10个点,它们分别是[0, 0], [1, 1], ... , [9, 9]。它们[0,0],[1,1],[2,2],[3,3]属于“0”这个类(类标签为0),另外6个点属于“1”这个类(类标签为1)。
  
  现在第一象限构造900*900个点,纵横坐标方向上相邻的点距离为0.01。
  [ 0.00, 0.00],[ 0.01, 0.00], [ 0.02, 0.00],..., [ 8.97, 8.99], [ 8.98, 8.99],[ 8.99, 8.99]
    这样,布满区间的点作为预测数据,用各种分类模型进行二分类。最后通过绘图模块给不同类的点上色以判断分类性能。
  

import numpy as npy  
import matplotlib.pyplot as plt
  
from sklearn import svm
  
x=[]#存储样本数据
  
y=[]#存储类标号
  
for i in range(0,10):#构造10个点作为训练数据
  if(i<=3):#if(i<=3 or i>=8):
  x.append([i,i])
  y.append(0)
  else:
  x.append([i,i])
  y.append(1)
  

  
train_x=npy.array(x)#转换为数组
  
train_y=npy.array(y)
  

  

  
'''
  
创建svm分类器的格式:
  
svm.SVC(kernel=某个核函数).fit(训练样本,类标签)
  
'''
  
#linear
  
linear_svc=svm.SVC(kernel="linear").fit(train_x,train_y)
  

  
#poly 要定义维度,degree决定了多项式的最高次幂.关于SVC参数的意义请参见文章后头的内容。
  
poly_svc=svm.SVC(kernel="poly",degree=4).fit(train_x,train_y)
  

  
#径向基核函数(这时SVC默认的核函数)
  
rbf_svc=svm.SVC().fit(train_x,y)
  

  
#Sigmoid
  
sigmoid_svc=svm.SVC(kernel="sigmoid").fit(train_x,train_y)
  

  
#下面就可以进行预测了
  
x1,x2=npy.meshgrid(npy.arange(train_x[:,0].min(),train_x[:,0].max(),0.01),npy.arange(train_x[:,1].min(),train_x[:,1].max(),0.01))
  

  
#先生成各个点。定义最小值和最大值后,定义隔多少值建立一个点。
  
#npy.arange(train_x[:,1].min(),train_x[:,1].max(),0.01))返回的是900个元素的数组
  
#meshgrid函数用来产生矩阵。上面的语句也是就是numpy.meshgrid(numpy.arange(0,9,0.01),numpy.arange(0,9,0.01))
  

  
'''
  
x1是矩阵
  [[ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99],
  [ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99],
  [ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99],
  ...,
  [ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99],
  [ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99],
  [ 0.  ,  0.01,  0.02, ...,  8.97,  8.98,  8.99]]
  

  
x2是矩阵
  [[ 0.  ,  0.  ,  0.  , ...,  0.  ,  0.  ,  0.  ],
  [ 0.01,  0.01,  0.01, ...,  0.01,  0.01,  0.01],
  [ 0.02,  0.02,  0.02, ...,  0.02,  0.02,  0.02],
  ...,
  [ 8.97,  8.97,  8.97, ...,  8.97,  8.97,  8.97],
  [ 8.98,  8.98,  8.98, ...,  8.98,  8.98,  8.98],
  [ 8.99,  8.99,  8.99, ...,  8.99,  8.99,  8.99]]
  
'''
  
splocation=1
  
for i in [linear_svc,poly_svc,rbf_svc,sigmoid_svc]:#遍历各个模型以便绘图,以看哪个核函数的准确率更高
  rst = i.predict(npy.c_[x1.ravel(),x2.ravel()])#横坐标和纵坐标的组合。x1.ravel()和x2.ravel()都是长度为810000的数组。c_[]用来将前后两个数组串联成一个810000行、2列的矩阵。
  

  #因为上面用到了四种分类模型,那么一个2×2的图就能够显示完全了。
  plt.subplot(2,2,splocation)#第一个参数代表的是横向要划分的子图个数,第二个参数代表的是纵向要划分的子图的个数,第三个参数表示当前的定位
  plt.contourf(x1,x2,rst.reshape(x1.shape))#contourf用来填充颜色。(当前横坐标,当前纵坐标,预测的分类结果(转为x1的规模维数))
  

  #训练数据的点也绘制出来
  for j in range(0,len(y)):
  if(int(y[j])==0):
  plt.plot(train_x[j:j+1,0],train_x[j:j+1],"yo")#y代表黄色,o代表散点图
  else:
  plt.plot(train_x[j:j+1,0],train_x[j:j+1],"ko")#类别为1填充为黑色。k代表黑色
  splocation+=1
  
plt.show()
  

  运行结果:

    可见,在比较这种分布下,径向基核函数表现出更好的分类性能。

5 SVC的参数
    具体参数的意义与使用请参见链接:http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html


  • C:目标函数的惩罚系数C,用来平衡分类间隔margin和错分样本的,default C = 1.0;
  C越大,相当于惩罚松弛变量,希望松弛变量接近0,即对误分类的惩罚增大,趋向于对训练集全分对的情况,这样对训练集测试时准确率很高,但泛化能力弱。C值小,对误分类的惩罚减小,允许容错,将他们当成噪声点,泛化能力较强。


  •   kernel :核函数,默认是rbf,可以是‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’

  •   degree :多项式poly函数的维度,默认是3,选择其他核函数时会被忽略。

  •   gamma : ‘rbf’,‘poly’ 和‘sigmoid’的核函数参数。默认是’auto’,则gamma=1/n_features

  •   coef0 :核函数的常数项。对于‘poly’和 ‘sigmoid’有用。

  •   probability :是否采用概率估计。默认为False。要采用的话必须先于调用fit,这个过程会增加用时。

  •   shrinking :是否采用shrinking heuristic方法,默认为true

  •   tol :停止训练的误差值大小,默认为1e-3

  •   cache_size :核函数cache缓存大小,默认为200

  •   class_weight :类别的权重,字典形式传递。设置第几类的参数C为weight*C(C-SVC中的C)

  •   verbose :允许冗余输出。跟多线程有关系。默认为False。

  •   max_iter :最大迭代次数。-1为无限制。

  •   decision_function_shape :是否返回模型中每一个类别的样本的ovr决策函数,或者ovo决策函数。 默认为None

  •   random_state :数据洗牌时的种子值,int值

  主要调节的参数有:C、kernel、degree、gamma、coef0。

6 推广
    官方文档是学习的绝佳利器。传送门:http://scikit-learn.org/dev/modules/svm.html

6.1 多分类
    SVM算法最初是为二值分类问题设计的,当处理多类问题时,就需要构造合适的多类分类器。目前,构造SVM多类分类器的方法主要有两类:一类是直接法,直接在目标函数上进行修改,将多个分类面的参数求解合并到一个最优化问题中,通过求解该最优化问题“一次性”实现多类分类。这种方法看似简单,但其计算复杂度比较高,实现起来比较困难,只适合用于小型问题中;另一类是间接法,主要是通过组合多个二分类器来实现多分类器的构造,常见的方法有one-against-one和one-against-all两种。


  • 一对多法(one-versus-rest,简称1-v-r SVMs)。训练时依次把某个类别的样本归为一类,其他剩余的样本归为另一类,这样k个类别的样本就构造出了k个SVM。分类时将未知样本分类为具有最大分类函数值的那类。
  • 一对一法(one-versus-one,简称1-v-1 SVMs)。其做法是在任意两类样本之间设计一个SVM,因此k个类别的样本就需要设计k(k-1)/2个SVM。当对一个未知样本进行分类时,最后得票最多的类别即为该未知样本的类别。Libsvm中的多类分类就是根据这个方法实现的。
  • 层次支持向量机(H-SVMs)。层次分类法首先将所有类别分成两个子类,再将子类进一步划分成两个次级子类,如此循环,直到得到一个单独的类别为止。 对c和d两种方法的详细说明可以参考论文《支持向量机在多类分类问题中的推广》(计算机工程与应用。2004)
  • 其他多类分类方法。除了以上几种方法外,还有有向无环图SVM(Directed Acyclic Graph SVMs,简称DAG-SVMs)和对类别进行二进制编码的纠错编码SVMs。
6.2 回归
    支持分类的支持向量机可以推广到解决回归问题,这种方法称为支持向量回归。
    支持向量分类所产生的模型仅仅依赖于训练数据的一个子集,因为构建模型的成本函数不关心在超出边界范围的点,类似的,通过支持向量回归产生的模型依赖于训练数据的一个子集,因为构建模型的函数忽略了靠近预测模型的数据集。
    有三种不同的实现方式:支持向量回归SVR,nusvr和linearsvr。linearsvr提供了比SVR更快实施但只考虑线性核函数,而nusvr实现比SVR和linearsvr略有不同。
  
作为分类类别,训练函数将X,y作为向量,在这种情况下y是浮点数

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-386546-1-1.html 上篇帖子: (转)Introduction to Gradient Descent Algorithm (along with variants) in Machine L 下篇帖子: http VS https
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表