SVM原理详细图文教程!一行代码自动选择核函数,还有实用工具
SVM 由线性分类开始
理解SVM,咱们必须先弄清楚一个概念:线性分类器。
给定一些数据点,它们分别属于两个不同的类,现在要找到一个线性分类器把这些数据分成两类。如果用x表示数据点,用y表示类别(y可以取1或者-1,分别代表两个不同的类),一个线性分类器的目标是要在n维的数据空间中找到一个超平面(hyper plane),将x的数据点分成两类,且超平面距离两边的数据的间隔最大。
![](https://pic.rmb.bdstatic.com/bjh/down/2af709a404e9f8ba18edd0aa58b4477b.gif)
这个超平面的方程可以表示为( wT中的T代表转置):
![](https://pics3.baidu.com/feed/4ec2d5628535e5dde6cb00597f1a49e9cc1b62b7.jpeg?token=d3c52b2310ab5d992ba7595eabeec99e)
△2维坐标系中,超平面是一条直线
当f(x)等于0的时候,x便是位于超平面上的点,而f(x)大于0的点对应 y=1 的数据点,f(x)小于0的点对应y=-1的点。
SVM 想要的就是找到各类样本点到超平面的距离最远,也就是找到最大间隔超平面。任意超平面可以用下面这个线性方程来描述:
![](https://pics2.baidu.com/feed/b8389b504fc2d562c11d84cb14cb7ee977c66ce4.jpeg?token=2fce1a6368897c226ddfa61e2f69a19c)
二维空间点(x,y)到直线Ax+By+C=0的距离公式是:
![](https://pics0.baidu.com/feed/d1a20cf431adcbef7e69decf4475c0dba1cc9fff.jpeg?token=c3efcc61eeee0cde6556ae8bc626c7e6)
扩展到n维空间后,点x=(x1,x2……xn)到直线wTx+b=0的距离为:
![](https://pics5.baidu.com/feed/0bd162d9f2d3572cf6affd7674c88d2163d0c32a.jpeg?token=83875c897493b41bbd1ab87d042a06ca)
其中 :
![](https://pics5.baidu.com/feed/0823dd54564e9258aea1e37c7b593f5ecebf4ee9.jpeg?token=f3518e3e4a3f2d4a404a1ddbaf1a7d28)
根据支持向量的定义,支持向量到超平面的距离为d,其他点到超平面的距离大于d。
于是有:
![](https://pics3.baidu.com/feed/e7cd7b899e510fb386c6c8c03ce82693d3430ce8.jpeg?token=cb179570ed71d2510053a18c25199f2c)
||w||d是正数,令它为 1(之所以令它等于 1,是为了方便推导和优化,且这样做对目标函数的优化没有影响),于是:
![](https://pics3.baidu.com/feed/d1a20cf431adcbefe7f741304675c0dba2cc9f22.jpeg?token=781cecabb785890242b7257a3923d2a0)
将两个方程合并,有:
![](https://pics4.baidu.com/feed/7a899e510fb30f2429115ffec0493f45af4b03a2.jpeg?token=ec47db77f23110ef5e1c6b4081fde62d)
至此,就得到了最大间隔超平面的上下两个超平面。
![](https://pics3.baidu.com/feed/c2fdfc039245d68867d9c4354e189318d01b24ad.jpeg?token=c22775e9e9e35060bff455251501119c)
每个支持向量到超平面的距离可以写为:
![](https://pics2.baidu.com/feed/9f510fb30f2442a76a6f9f682199434dd31302ff.jpeg?token=fd4b2299a0d74a9af3693d33e255d20a)
由 y(wTx+b)>1>0可以得到 y(wTx+b)=|wTx+b|,所以可以将支持向量到超平面距离改写为:
![](https://pics0.baidu.com/feed/9f510fb30f2442a7cbc12964d69f434dd3130202.jpeg?token=91bd9ba1c57620869347b2facead6156)
最大化这个距离:
![](https://pics5.baidu.com/feed/024f78f0f736afc3becc561054c205c2b54512e1.jpeg?token=ee41c417e0d730c83cfbdb3c5ddee530)
这里乘上 2 倍是为了后面推导方便,对目标函数没有影响。
带入一个支持向量,可以得到:
![](https://pics4.baidu.com/feed/50da81cb39dbb6fd1476763b08f8451e962b37e4.jpeg?token=b93f4da222286ec1847101b5f0a4261c)
所以得到的最优化问题是:
![](https://pics1.baidu.com/feed/29381f30e924b899cdfa87d991ddf393087bf674.jpeg?token=9af5ccb6558347e62dea23245fb5f4ad)
处理异常值
有时,对于某些点(x(i),y(i)),分类器可能会做出错误操作。
尽管在开发实际使用的SVM模型时,会设计冗余,避免过拟合,但仍然需要想办法将误差控制在一个较小的范围。
可以通过在模型中增加惩罚机制(用c表示)解决这个问题。
![](https://pics0.baidu.com/feed/0b7b02087bf40ad14fc0d332bff6ffd9a8ecce18.jpeg?token=1587772676e37217bb59b8dd689db50c)
![](https://pics0.baidu.com/feed/b2de9c82d158ccbf7afb3b71f3035238b035411c.jpeg?token=64465aefb3fc6f953fe72b45a7a75444)
设SVM输出结果为E,则上图中出现的E=0则没有惩罚。
若果c非常大,则模型分类更加精准,但支持向量到超平面距离小,容易出现过拟合。
若c=1,则支持向量到超平面距离最大化,尽管会出现一些分类误差,但这是一种较好的方案。
约束凸优化问题
为了克服约束凸优化问题,采用PEGASOS算法。
重新构造一个约束独立性方程:
![](https://pics0.baidu.com/feed/1f178a82b9014a906dfee3a742add714b11beece.jpeg?token=9d04e96196c1770b5ba955957f200076)
上式表示,如果点远离直线,则误差将为零,否则误差将为(1-t(i))。
我们需要最小化的是:
![](https://pics6.baidu.com/feed/0824ab18972bd4078f1cafd08b5270570eb30922.jpeg?token=d69c792bdf70867ecc576a58c9b25b5d)
由于消除了约束,因此可以采用梯度下降来最大程度地减少损失。
![](https://pics6.baidu.com/feed/0b46f21fbe096b63c3114ec7f2e86942eaf8ac7b.jpeg?token=df99110e05159a9ce75b219a58186aad)
梯度下降算法计算损失:
![](https://pics6.baidu.com/feed/d62a6059252dd42a1c107346eae1b5b3c8eab827.jpeg?token=80f882a2a9d5081df41f5e48aad1ab81)
在SVM上应用梯度下降:
![](https://pics6.baidu.com/feed/8644ebf81a4c510fc35792b66085cb2bd62aa5e9.jpeg?token=b7bfab981332d1d84f8bb8de58d087b6)
非线性分类
使用SVM对非线性数据进行分类,需要将数据投影到更高的维度,即通过增加低维数据的特征向量将其转换为高维数据。
![](https://pics5.baidu.com/feed/b3b7d0a20cf431ad73809753a0ec42a92fdd9868.jpeg?token=74c225992aec3f4cb3b6c4959547e33e)
增加数据特征向量需要消耗巨大的计算资源,这里采用核函数。
而这种思路最难的点,是为你自己的模型选择一个合适的核函数。
这里推荐一种自动调参方法GridSearch。
将多种核函数(线性、RBF、多项式、sigmoid等)等标号,依次调用,找到一个最合适自己模型的。
定义一个变量params:
params = [{‘kernel’:[‘linear’, ‘rbf’, ‘poly’, ‘sigmoid’], ‘c’:[0.1, 0.2, 0.5, 1.0, 2.0, 5.0]}
调用:
![](https://pics6.baidu.com/feed/f9198618367adab45ace0b52600e5d1a8601e4e2.jpeg?token=7b2352cb0f8a2238636b4204d63849d6)
以上详细介绍了SVM背后的数学原理,并提供了一些使用SVM模型时的问题解决办法。
其中,使用代码自动选择核函数的方法来自外国博主Daksh Trehan。
如果你对SVM的原理有更深刻的理解,或有其他实用的技巧,请留言分享给大家吧。
参考链接
https://medium.com/@dakshtrehan?source=post_page-----d46e94b23b9d----------------------