支持向量机svm

1.背景

     1.1 最早是由 Vladimir N. Vapnik 和 Alexey Ya. Chervonenkis 在1963年提出
     1.2 目前的版本(soft margin)是由Corinna Cortes 和 Vapnik在1993年提出,并在1995年发表
     1.3 深度学*(2012)出现之前,SVM被认为机器学*中*十几年来最成功,表现最好的算法

2.机器学*的一般框架

  训练集 => 提取特征向量 => 结合一定的算法(分类器:比如决策树,KNN)=>得到结果

3.SVM介绍

 3.1 例子:

 
      
   两类?哪条线最好?
  假设提取了一些实例的向量,映射成空间中的一些点,一个超平面将两类点划分成两个区域

3.2 SVM寻找区分两类的超平面(hyper plane), 使边际(margin)最大

               总共可以有多少个可能的超平面?无数条
               
               如何选取使边际(margin)最大的超平面 (Max Margin Hyperplane)?
 
               超平面到一侧最*点的距离等于到另一侧最*点的距离,两侧的两个超平面平行

3.3 线性可区分(linear separable) 和 线性不可区分 (linear inseparable) 

线性可区分:一个平面能够完全划分两个区域

线性不可区分:一个平面不能够完全划分两个区域

4.定义与公式建立

  超平面可以定义为:
       W: weight vectot,, n 是特征值的个数
       X: 训练实例  
    b: bias(类似于点斜式中的截距)
          4.1 假设2维特征向量:X = (x1, X2)
                把 b 想象为额外的 wight
                超平面方程变为: 
                所有超平面右上方的点满足:
                所有超平面左下方的点满足:            
                调整weight,使超平面定义边际的两边:
    
                  综合以上两式,得到: (1)
                    
      所有坐落在边际的两边的的超平面上的被称作”支持向量(support vectors)"
    
    分界的超平面和H1或H2上任意一点的距离为
    

5.求解

     SVM如何找出最大边际的超平面呢(MMH)?

              利用一些数学推倒,以上公式 (1)可变为有限制的凸优化问题(convex quadratic optimization)
               利用 Karush-Kuhn-Tucker (KKT)条件和拉格朗日公式,可以推出MMH可以被表示为以下“决定边     
               界 (decision boundary)”          
          
   对于任何测试(要归类的)实例,带入以上公式,得出的符号是正还是负决定

6.例子:

 

 

Python实现SVM

(1)用内置模块解决上面例子

from sklearn import svm

x = [[2,0],[1,1],[2,3]]  #特征向量值矩阵,即三组坐标值组成的list
y = [0,0,1]  #对应X归类标记,超平面之上为1,之下为0
clf = svm.SVC(kernel='linear')  #建立线性和函数模型
clf.fit(x,y)
print(clf)

print(clf.support_vectors_)  #支持向量

print(clf.support_)  #支持向量点在x列表中的下标

print(clf.n_support_)   #支持向量点的数量

print(clf.predict([[2,0]]))

(2)用内置SVM解决稍微复杂数据集

import numpy as np  #导入支持矩阵计算的数据包
import pylab as pl  #提供画图功能的包
from sklearn import svm

np.random.seed(0)  #随机值参数为0程序重新运行随机值不变,填1可变
#np.random.randn()通过正态分布产生训练集,第一个参数为点个数,第二个为维度,-[2,2]表示点均值为2,在下方,方差也为2,在上方
X = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]]
Y = [0]*20 + [1]*20   #40个点归类标记

clf = svm.SVC(kernel='linear')
clf.fit(X,Y)  #建立模型

w = clf.coef_[0] #取w,w
a = -w[0]/w[1]  #直线斜率
xx = np.linspace(-5,5)  #从-5到5之间产生一些连续的x值
yy = a*xx-(clf.intercept_[0])/w[1]  #点斜式,intercept_[0]相当于b


#计算边际两条平行线
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])   #带入点斜式



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()

  

 

 

 

 
 
posted @ 2017-07-02 21:34  amchen  阅读(257)  评论(0)    收藏  举报