sklearn中SVM的实现

这篇主要是针对SVM在实际应用中的实践。这个过程重点在于参数的选择,模型的选择。蛮有意思的。

参考的内容是sklearn官网的Example\Support Vector Machine
note:本文的顺序是按照模型的复杂程度,样本分类的复杂程度,维度的逐级增加进行。
Platform & Environment: python 3.6 (anaconda\spider)

import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.datasets import make_blobs
  • 线性完全可分问题 hard margin classfication

We can find such a "street" that the margin should be as wide as possible.

x, y = make_blobs(n_samples=40, centers=2, random_state=6)
#centers就是数据分布点,我们现在解决的是二分类问题,\
#那么就需要两个center,数据点都分别围绕着center进行分布
#random_state确定一个数字后,每次运行都会出现相同的随机数。
plt.scatter(x[:,0],x[:,1],c=y,s=30,cmap=plt.cm.Paired)
#plt.scatter中的c代表color,cmap代表colormap,可选
#s是size, c=y是标签分类和plt.cm.Paired联合使用

pic1.png

#选择kernel
clf=svm.SVC(kernel='linear', C=1000)
#惩罚参数C大就是要放大所有点到分隔区间的函数间隔,导致分隔区间变窄,\
#就是说更看重分类的效果,不允许分类错误
clf.fit(x,y)
clf.support_vectors_ #支持向量
clf.coef_ #w向量参数
clf.intercept_#截距b
clf.support_ #支持向量index
#plot hyperplane
ax=plt.gca()
xlim=ax.get_xlim()
ylim=ax.get_ylim()
xx=np.linspace(xlim[0],xlim[1],30)
yy=np.linspace(ylim[0],ylim[1],30)
XX,YY=np.meshgrid(xx,yy)
xy = np.vstack([XX.ravel(),YY.ravel()]).T #vstack垂直方向
Z=clf.decision_function(xy).reshape(XX.shape)
ax.contour(XX,YY,Z, colors='k',levels=[-1,0,1],alpha=0.5,linestyles=['--','-','--']) 
#这里的level是指函数间隔,我们可以选择不同的函数间隔进行可视化
#alpha是粗细

pic2.png

#显示出我们的支持向量
ax.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],s=600,linewidth=1,facecolors='none',edgecolors='y')

pic3.png

  • 非线性SVM

np.random.seed(0)
X=np.random.randn(300,2)
Y=np.logical_xor(X[:,0]>0, X[:,1]>0)
xx,yy = np.meshgrid(np.linspace(-3,3,500),np.linspace(-3,3,500))
#fit 
clf = svm.SVC() #所有参数采用默认
clf.fit(X,Y)
xy = np.vstack([xx.ravel(),yy.ravel()]).T
Z=clf.decision_function(xy).reshape(xx.shape)
plt.imshow(Z, interpolation='nearest',extent=(xx.min(),xx.max(), yy.min(),yy.max(),),aspect='auto',origin='lower',cmap=plt.cm.PuOr_r)  #这一段是背景设置
plt.contour(xx,yy,Z,levels=[0],linewidths=2,linestyle='--')
plt.scatter(X[:,0],X[:,1],s=30,c=Y,cmap=plt.cm.Paired, edgecolors='k')

可视化

 

pic4


在这里需要强调的是,sklearn中的案例用的是NuSVC,而我在这里直接用的SVC,这个我也纠结一下,实际上,NuSVC和SVC仅仅有一处差别,那就惩罚参数C,在NuSVC中是没有C的,而增加了一个变量Nu,官方定义就是通过Nu来控制错误率,并且给Nu赋予了一个取值范围(0,1],这实际上和我们所说的惩罚参数C类似,所以,不必纠结于此。
具体情况请参考这篇博文:https://www.cnblogs.com/pinard/p/6117515.html

 

这里的SVC我没有定义kernel使用的是默认的,在SVC模块里,默认的是rbf,也就是高斯核函数。

  • 不同kernel对同种数据的分类效果比对

#创造数据
X=np.c_[(.4,-.7),(-1.5,-1),(-1.4,-.9),(-1.3,-1.2),(-1.1,-.2),(-1.2,-.4),(-.5,1.2),(-1.5,2.1),(1,1),(1.3,.8),(1.2,.5),(.2,-2),(.5,-2.4),(.2,-2.3),(0,-2.7),(1.3,2.1)].T
Y=[0]*8+[1]*8
figurenum=1
for kernel in ('linear','poly','rbf'):
    clf = svm.SVC(kernel=kernel,gamma=1)
    clf.fit(X,Y)
    plt.subplot(2,2,figurenum)
    x_min=-3
    x_max=3
    y_min=-3
    y_max=3
    XX,YY=np.meshgrid(np.linspace(x_min,x_max,200),np.linspace(y_min,y_max,200))
    xy=np.vstack([XX.ravel(),YY.ravel()]).T
    Z=clf.decision_function(xy).reshape(XX.shape)
    plt.pcolormesh(XX, YY, Z > 0, cmap=plt.cm.Paired)
    plt.contour(XX,YY,Z,colors=['k','k','k'],levels=[-.5,0,.5],linestyles=['--','-','--'])
    plt.scatter(X[:,0],X[:,1],c =Y, s=30,cmap=plt.cm.Paired,  edgecolors='k')
    plt.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1], s=80,facecolors='none', edgecolors='k')
    plt.xlim(x_min, x_max)
    plt.ylim(y_min,y_max)
    plt.xticks(())
    plt.yticks(())
    figurenum+=1

首先kernel的参数gamma在这里调用
我们先用默认的gamma值,0.5(1/num_features)

 

gamma=0.5

 

我们发现欠拟合的特征。

 

gamma=2


完美拟合。

gamma=5


上图是过拟合的特征。

同时我们在算法里将函数间隔显示的是[-.5, .5],我们发现,gamma对于线性可分问题,影响几乎没有,这个我们在核函数的公式就可以知道;在'poly'核的应用中,gamma较小时会出现欠拟合的现象;在'rbf'高斯核的应用中,gamma值对其影响比较敏感,gamma太小会造成欠拟合,gamma太大又会造成过拟合。

小礼物走一走,来简书关注我



作者:在做算法的巨巨
链接:https://www.jianshu.com/p/6ebdfe0cf1a4
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值