Python 深入浅出支持向量机(SVM)算法
相比于逻辑回归,在很多情况下,SVM算法能够对数据计算从而产生更好的精度。而传统的SVM只能适用于二分类操作,不过却可以通过核技巧(核函数),使得SVM可以应用于多分类的任务中。
本篇文章只是介绍SVM的原理以及核技巧究竟是怎么一回事,最后会介绍sklearn svm各个参数作用和一个demo实战的内容,尽量通俗易懂。至于公式推导方面,网上关于这方面的文章太多了,这里就不多进行展开了~
1.SVM简介
支持向量机,能在N维平面中,找到最明显得对数据进行分类的一个超平面!看下面这幅图:
如上图中,在二维平面中,有红和蓝两类点。要对这两类点进行分类,可以有很多种分类方法,就如同图中多条绿线,都可以把数据分成两部分。
但SVM做的,是找到最好的那条线(二维空间),或者说那个超平面(更高维度的空间),来对数据进行分类。这个最好的标准,就是最大间距。
至于要怎么找到这个最大间距,要找到这个最大间距,这里大概简单说一下,两个类别的数据,到超平面的距离之和,称之为 间隔 。而要做的就是找到最大的间隔。
这最终就变成了一个最大化间隔的优化问题。
2.SVM的核技巧
核技巧,主要是为了解决线性SVM无法进行多分类以及SVM在某些线性不可分的情况下无法分类的情况。
比如下面这样的数据:
这种时候就可以使用核函数,将数据转换一下,比如这里,我们手动定义了一个新的点,然后对所有的数据,计算和这个新的点的欧式距离,这样我们就得到一个新的数据。而其中,离这个新点距离近的数据,就被归为一类,否则就是另一类。这就是核函数。
这是最粗浅,也是比较直观的介绍了。通过上面的介绍,是不是和Sigmoid有点像呢?都是通过将数据用一个函数进行转换,最终得到结果,其实啊,Sigmoid就是一钟核函数来着,而上面说的那种方式,是高斯核函数。
这里补充几点:
- 1.上面的图中只有一个点,实际可以有无限多个点,这就是为什么说SVM可以将数据映射到多维空间中。计算一个点的距离就是1维,2个点就是二维,3个点就是三维等等。。。
- 2.上面例子中的红点是直接手动指定,实际情况中可没办法这样,通常是用随机产生,再慢慢试出最好的点。
- 3.上面举例这种情况属于高斯核函数,而实际常见的核函数还有多项式核函数,Sigmoid核函数等等。
OK,以上就是关于核技巧(核函数)的初步介绍,更高级的这里也不展开了,网上的教程已经非常多了。
接下来我们继续介绍sklearn中SVM的应用方面内容。
3.sklearn中SVM的参数
sklearn-SVM参数,kernel特征选择
kernel:核函数选择,字符串类型,可选的有“linear”,“poly”,“rbf”,“sigmoid”,“precomputed”以及自定义的核函数,默认选择是“rbf”。各个核函数介绍如下:
“linear”:线性核函数,最基础的核函数,计算速度较快,但无法将数据从低维度演化到高维度
“poly”:多项式核函数,依靠提升维度使得原本线性不可分的数据变得线性可分
“rbf”:高斯核函数,这个可以映射到无限维度,缺点是计算量比较大
“sigmoid”:Sigmoid核函数,对,就是逻辑回归里面的那个Sigmoid函数,使用Sigmoid的话,其实就类似使用一个一层的神经网络
“precomputed”:提供已经计算好的核函数矩阵,sklearn不会再去计算,这个应该不常用
“自定义核函数”:sklearn会使用提供的核函数来进行计算
说这么多,那么给个不大严谨的推荐吧
样本多,特征多,二分类,选择线性核函数
样本多,特征多,多分类,多项式核函数
样本不多,特征多,二分类/多分类,高斯核函数
样本不多,特征不多,二分类/多分类,高斯核函数
当然,正常情况下,一般都是用交叉验证来选择特征,上面所说只是一个较为粗浅的推荐。
sklearn-SVM参数,多分类方案
其实这个在逻辑回归里面已经有说过了,这里还是多说一下。
原始的SVM是基于二分类的,但有些需求肯定是需要多分类。那么有没有办法让SVM实现多分类呢?那肯定是有的,还不止一种。
实际上二元分类问题很容易推广到多元逻辑回归。比如总是认为某种类型为正值,其余为0值。
举个例子,要分类为A,B,C三类,那么就可以把A当作正向数据,B和C当作负向数据来处理,这样就可以用二分类的方法解决多分类的问题,这种方法就是最常用的one-vs-rest,简称OvR。而且这种方法也可以方便得推广到其他二分类模型中(当然其他算法可能有更好的多分类办法)。
另一种多分类的方案是Many-vs-Many(MvM),它会选择一部分类别的样本和另一部分类别的样本来做二分类。
听起来很不可思议,但其实确实是能办到的。比如数据有A,B,C三个分类。
我们将A,B作为正向数据,C作为负向数据,训练出一个分模型。再将A,C作为正向数据,B作为负向数据,训练出一个分类模型。最后B,C作为正向数据,C作为负向数据,训练出一个模型。
通过这三个模型就能实现多分类,当然这里只是举个例子,实际使用中有其他更好的MVM方法。限于篇幅这里不展开了。
MVM中最常用的是One-Vs-One(OvO)。OvO是MvM的特例。即每次选择两类样本来做二元逻辑回归。
对比下两种多分类方法,通常情况下, Ovr比较简单,速度也比较快,但模型精度上没MvM那么高。MvM则正好相反,精度高,但速度上比不过Ovr。
4.sklearn SVM实战
我们还是使用鸢尾花数据集,不过这次只使用其中的两种花来进行分类。首先准备数据:
import matplotlib.pyplot as pltimport numpy as npfrom sklearn import svm,datasetsimport pandas as pdtem_X = iris.data[:, :2]tem_Y = iris.targetnew_data = pd.DataFrame(np.column_stack([tem_X,tem_Y]))#过滤掉其中一种类型的花new_data = new_data[new_data[2] != 1.0]#生成X和YX = new_data[[0,1]].valuesY = new_data[[2]].values
然后用数据训练,并生成最终图形
最终的SVM的分类结果如下: