从示例中理解SVM算法(附代码)

2018 年 5 月 10 日 论智 Sunil Ray
作者:Sunil Ray
编译:Bot

编者按:掌握机器学习算法并不是什么神话。对于大多数机器学习初学者来说,回归算法是很多人接触到的第一类算法,它易于理解、方便使用,堪称学习工作中的一大神器,但它真的是万能的吗?通过这篇文章,论智希望大家明白,有时候,生活中的一些万金油工具其实并不是我们的唯一选择。

如果把机器学习看做是一个堆满刀、剑、斧、弓等兵器的军械库,里面有成千上万种工具,我们的选择余地的确很大,但我们应该学会在正确的时间和场合使用正确的武器。如果把回归算法看作是其中的剑,它可以轻松刺穿敌人(数据)的坚甲,但不能被庖丁用来解牛。对于这类问题高度复杂的数据处理任务,一把锋利的“小刀”——支持向量机(SVM)往往更有效——它可以在较小的数据集上工作,并构建出更强大的模型。

目录

1. 什么是支持向量机?

2. SVM的工作原理

3. 如何在Python和R中实现SVM

4. 如何调整SVM参数

5. SVM的优点和缺点

1. 什么是支持向量机?

在机器学习领域中,支持向量机”(SVM)是一种可用于分类和回归任务监督学习算法,在实践中,它的主要应用场景是分类。为了解释这个算法,首先我们可以想象一大堆数据,其中每个数据是高维空间中的一个点,数据的特征有多少,空间的维数就有多少。相应的,数据的位置就是其对应各特征的坐标值。为了用一个超平面尽可能完美地分类这些数据点,我们就要用SVM算法来找到这个超平面。

在这个算法中,所谓“支持向量”指的是那些在间隔区边缘的训练样本点,而“机”则是用于分类的那个最佳决策边界(线/面/超平面)。

2. SVM的工作原理

下面我们用图像演示如何找出正确的超平面的几种方法。

情景1

下图中有三个超平面:A、B和C。那么其中哪个是正确的边界呢?只需记住一点:SVM选择的是能分类两种数据的决策边界。很显然,相比A和C,B更好地分类了圆和星,所以它是正确的超平面。

情景2

下图中同样有A、B、C三个超平面,和情景1不同,这次三个超平面都很好地完成了分类,那么其中哪个是正确的超平面呢?对此,我们再修改一下之前的表述:SVM选择的是能更好地分类两种数据的决策边界。

在这里,我们可以绘制数据到决策边界的距离来辅助判断。如下图所示,无论是星还是圆,它们到C的距离都是最远的,因此这里C就是我们要找的最佳决策边界。

之所以选择边距更远的超平面,是因为它更稳健,容错率更高。如果选择A或C,如果后期我们继续输入样本,它们发生错误分类的可能性会更高。

情景3

这里我们先看图,试着用上一情景的结论做出选择。

也许有些读者最终选择了B,因为两类数据和它的边距较A更远。但是其中有个问题,就是B没有正确分类,而A正确分类了。那么在SVM算法面前,正确分类和最大边距究竟孰重孰轻?很显然,SVM首先考虑的是正确分类,其次才是优化数据到决策边界的距离。情景3的正确超平面是A。

情景4

在前几个例子里,虽然我们把决策边界表述为超平面,但它们在图像中都是一条直线,这其实是不符合现实的。如在下图中,我们就无法用直线进行分类。

红色的圆点之间出现了一颗蓝色的星,并且它和其他同类数据不在同一侧。那么我们是否要绘制一条曲线来分类?或者说,是否要把它单独氛围一类?答案是否定的。

对比情景3,我们可以推断此处的星是一个异常值,所以在这里SVM算法不受分类前提困扰,可以直接在圆和星之间找出一个最合适的超平面进行分类。换句话说,SVM对于异常值是有效的

情景5

让我们继续关注直线这个话题。在下图中,两类数据之间已经不具备直线边界了,那么SVM算法会怎么分类?请想象电视剧中大侠拍桌震起酒杯的画面。图中目前只有X和Y两个特征,为了分类,我们可以添加一个新特征Z = X2 + Y2,并绘制数据点在X轴和Z轴上的位置。

数据点被“震起来”后,星和圆在Z轴上出现了一个清晰的决策边界,它在上图中表示为一条二维的线,这里有几个注意点:

  • Z的所有值都是正的,因为它是X和Y的平方和;

  • 在原图中,圆的分布比星更靠近坐标轴原点,这也是它们在Z轴上的值较低的原因。

在SVM中,我们通过增加空间维度能很轻易地在两类数据间获得这样的线性超平面,但另一个亟待解决的问题是,像Z = X2 + Y2这样的新特征是不是都得由我们手动设计?不需要,SVM中有一种名为kernel的函数,它们能把低维输入映射进高维空间,把原本线性不可分的数据变为线性可分,我们也称它们为核函数。

核函数主要用于非线性分离问题。简而言之,它会自动执行一些非常复杂的数据转换,然后根据你定义的标签或输出找出分离数据的过程。

当我们把数据点从三维压缩回二维后,这个超平面就成了一个圆圈:

3. 如何在Python和R中实现SVM

在Python中,scikit-learn是一个受众极广的方便又强大的机器学习算法库,所以我们可以直接在scikit-learn里找到SVM。

  
    
    
    
  1. #Import Library

  2. from sklearn import svm

  3. #Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset

  4. # Create SVM classification object

  5. model = svm.svc(kernel='linear', c=1, gamma=1)

  6. # there is various option associated with it, like changing kernel, gamma and C value. Will discuss more # about it in next section.Train the model using the training sets and check score

  7. model.fit(X, y)

  8. model.score(X, y)

  9. #Predict Output

  10. predicted= model.predict(x_test)

对于R语言,e1071软件包可用于轻松创建SVM,它具有辅助函数以及Naive Bayes分类器的代码,和Python大体相同。

  
    
    
    
  1. #Import Library

  2. require(e1071) #Contains the SVM

  3. Train <- read.csv(file.choose())

  4. Test <- read.csv(file.choose())

  5. # there are various options associated with SVM training; like changing kernel, gamma and C value.

  6. # create model

  7. model <- svm(Target~Predictor1+Predictor2+Predictor3,data=Train,kernel='linear',gamma=0.2,cost=100)

  8. #Predict Output

  9. preds <- predict(model,Test)

  10. table(preds)


4. 如何调整SVM参数

在机器学习中,调参是提高模型性能额一种有效做法,我们先来看看SVM中的可用参数。

  
    
    
    
  1. sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3, gamma=0.0, coef0=0.0, shrinking=True, probability=False,tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, random_state=None)

这里我们只介绍几个重要参数的调参方法。

kernel:之前我们已经介绍了kernel是什么,关于它,我们可以挑选各种函数:线性的、RBF核的、poly函数等(默认值为RBF核)。对非线性超平面来说,后两种核函数效果显著。以下是几个例子:

例1:线性核函数

  
    
    
    
  1. import numpy as np

  2. import matplotlib.pyplot as plt

  3. from sklearn import svm, datasets

  
    
    
    
  1. # import some data to play with

  2. iris = datasets.load_iris()

  3. X = iris.data[:, :2] # we only take the first two features. We could

  4. # avoid this ugly slicing by using a two-dim dataset

  5. y = iris.target

  
    
    
    
  1. # we create an instance of SVM and fit out data. We do not scale our

  2. # data since we want to plot the support vectors

  3. C = 1.0 # SVM regularization parameter

  4. svc = svm.SVC(kernel='linear', C=1,gamma=0).fit(X, y)

  
    
    
    
  1. # create a mesh to plot in

  2. x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1

  3. y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1

  4. h = (x_max / x_min)/100

  5. xx, yy = np.meshgrid(np.arange(x_min, x_max, h),

  6. np.arange(y_min, y_max, h))

  
    
    
    
  1. plt.subplot(1, 1, 1)

  2. Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])

  3. Z = Z.reshape(xx.shape)

  4. plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)

  
    
    
    
  1. plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)

  2. plt.xlabel('Sepal length')

  3. plt.ylabel('Sepal width')

  4. plt.xlim(xx.min(), xx.max())

  5. plt.title('SVC with linear kernel')

  6. plt.show()

例2:RBF核函数

把核函数类型更改为rbf,然后从图中观察变化。

  
    
    
    
  1. svc = svm.SVC(kernel ='rbf',C = 1,gamma = 0).fit(X,y)

如果你有大量特征(> 1000),我建议你选择线性内核,因为它们在高维空间内线性可分的概率更高。除此之外,那rbf就是个不错的选择,但是不要忘记交叉验证其参数来避免过拟合。

gamma:rbf、poly和sigmoid的核系数。gamma值越高,模型就回更努力地拟合训练数据集,所以它也是导致过拟合的一个要因。

例3:gamma = 0.01和100

  
    
    
    
  1. svc = svm.SVC(kernel ='rbf',C = 1,gamma = 0).fit(X,y)

C: 误差项的惩罚参数C,它还控制着决策边界的平滑与否和正确分类训练点之间的权衡。

例4:C = 100和1000

自始自终,我们都要记得用交叉验证来有效组合这些参数,防止模型过拟合。

5. SVM的优点和缺点

优点

  • 效果很好,分类边界清晰;

  • 在高维空间中特别有效;

  • 在空间维数大于样本数的情况下很有效;

  • 它使用的是决策函数中的一个训练点子集(支持向量),所以占用内存小,效率高。

缺点

  • 如果数据量过大,或者训练时间过长,SVM会表现不佳;

  • 如果数据集内有大量噪声,SVM效果不好;

  • SVM不直接计算提供概率估计,所以我们要进行多次交叉验证,代价过高。

小结

本文介绍了什么是支持向量机、SVM的工作原理、如何在Python和R中实现SVM、如何调参以及它的的优点和缺点。希望读者能在阅读完毕后动手试一试,不要受近年来出现的“有DL还要学SVM吗?”的说法的影响,经典的算法总有其可贵之处,它也是进公司面试时的一大热门题目。

如果不知道从何开始,可以尝试做做论智的这道题:

原文地址:www.analyticsvidhya.com/blog/2017/09/understaing-support-vector-machine-example-code/

登录查看更多
9

相关内容

在机器学习中,支持向量机(SVM,也称为支持向量网络)是带有相关学习算法的监督学习模型,该算法分析用于分类和回归分析的数据。支持向量机(SVM)算法是一种流行的机器学习工具,可为分类和回归问题提供解决方案。给定一组训练示例,每个训练示例都标记为属于两个类别中的一个或另一个,则SVM训练算法会构建一个模型,该模型将新示例分配给一个类别或另一个类别,使其成为非概率二进制线性分类器(尽管方法存在诸如Platt缩放的问题,以便在概率分类设置中使用SVM)。SVM模型是将示例表示为空间中的点,并进行了映射,以使各个类别的示例被尽可能宽的明显间隙分开。然后,将新示例映射到相同的空间,并根据它们落入的间隙的侧面来预测属于一个类别。

知识荟萃

精品入门和进阶教程、论文和代码整理等

更多

查看相关VIP内容、论文、资讯等
【实用书】Python机器学习Scikit-Learn应用指南,247页pdf
专知会员服务
264+阅读 · 2020年6月10日
最新《自动微分手册》77页pdf
专知会员服务
100+阅读 · 2020年6月6日
专知会员服务
139+阅读 · 2020年5月19日
干净的数据:数据清洗入门与实践,204页pdf
专知会员服务
161+阅读 · 2020年5月14日
干货书《数据科学数学系基础》2020最新版,266页pdf
专知会员服务
318+阅读 · 2020年3月23日
【经典书】精通机器学习特征工程,中文版,178页pdf
专知会员服务
354+阅读 · 2020年2月15日
【新书】Pro 机器学习算法Python实现,379页pdf
专知会员服务
198+阅读 · 2020年2月11日
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
【收藏】支持向量机原理详解+案例+代码!【点击阅读原文下载】
机器学习算法与Python学习
10+阅读 · 2018年9月13日
SVM大解密(附代码和公式)
机器学习算法与Python学习
6+阅读 · 2018年5月22日
K近邻算法入门
论智
5+阅读 · 2018年3月18日
动手写机器学习算法:SVM支持向量机(附代码)
七月在线实验室
12+阅读 · 2017年12月5日
支持向量机分类实战
全球人工智能
4+阅读 · 2017年10月18日
机器学习(18)之支持向量机原理(三)线性不可分支持向量机与核函数
机器学习算法与Python学习
3+阅读 · 2017年9月23日
机器学习(16)之支持向量机原理(二)软间隔最大化
机器学习算法与Python学习
6+阅读 · 2017年9月8日
机器学习(15)之支持向量机原理(一)线性支持向量机
机器学习算法与Python学习
6+阅读 · 2017年9月1日
Python · SVM(三)· 核方法
机器学习研究会
7+阅读 · 2017年8月8日
A Probe into Understanding GAN and VAE models
Arxiv
9+阅读 · 2018年12月13日
Arxiv
7+阅读 · 2018年1月10日
Arxiv
4+阅读 · 2016年12月29日
VIP会员
相关VIP内容
【实用书】Python机器学习Scikit-Learn应用指南,247页pdf
专知会员服务
264+阅读 · 2020年6月10日
最新《自动微分手册》77页pdf
专知会员服务
100+阅读 · 2020年6月6日
专知会员服务
139+阅读 · 2020年5月19日
干净的数据:数据清洗入门与实践,204页pdf
专知会员服务
161+阅读 · 2020年5月14日
干货书《数据科学数学系基础》2020最新版,266页pdf
专知会员服务
318+阅读 · 2020年3月23日
【经典书】精通机器学习特征工程,中文版,178页pdf
专知会员服务
354+阅读 · 2020年2月15日
【新书】Pro 机器学习算法Python实现,379页pdf
专知会员服务
198+阅读 · 2020年2月11日
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
相关资讯
【收藏】支持向量机原理详解+案例+代码!【点击阅读原文下载】
机器学习算法与Python学习
10+阅读 · 2018年9月13日
SVM大解密(附代码和公式)
机器学习算法与Python学习
6+阅读 · 2018年5月22日
K近邻算法入门
论智
5+阅读 · 2018年3月18日
动手写机器学习算法:SVM支持向量机(附代码)
七月在线实验室
12+阅读 · 2017年12月5日
支持向量机分类实战
全球人工智能
4+阅读 · 2017年10月18日
机器学习(18)之支持向量机原理(三)线性不可分支持向量机与核函数
机器学习算法与Python学习
3+阅读 · 2017年9月23日
机器学习(16)之支持向量机原理(二)软间隔最大化
机器学习算法与Python学习
6+阅读 · 2017年9月8日
机器学习(15)之支持向量机原理(一)线性支持向量机
机器学习算法与Python学习
6+阅读 · 2017年9月1日
Python · SVM(三)· 核方法
机器学习研究会
7+阅读 · 2017年8月8日
Top
微信扫码咨询专知VIP会员