一、SVM简介
- 支持向量机(SVM:Support Vector Machine)是机器学习中常见的一种分类算法。
- 线性分类器,也可以叫做感知机,其中机表示的是一种算法。
- 在实际应用中,我们往往遇到这样的问题:
- 给定一些数据点,它们分别属于两个不同的类。我们现在要找到一个线性分类器把这些数据分成AB两类。最简单的办法当然是,画一条线,然后将它们分成两类。线的一侧,属于A类,另一侧,则属于B类。SVM算法可以让我们找到这样一个最佳的线(超平面),来划分数据。相比于KNN之类的算法,SVM算法只需要计算一次,得出最佳线(超平面)即可。面对测试数据,只需要判断数据点落在线的哪一侧,就可以知道该数据点所属分类了。比起KNN每次都需要计算一遍邻居点的分类,SVM算法显得简单无比。
二、感知机简介
感知机(preceptron)是线性分类的二分类模型,输入为实例的特征向量,输出为实例的类别,分别用 1 和 -1 表示。感知机将输入空间(特征空间)中的实例划分为正负两类分离的超平面,旨在求出将训练集进行线性划分的超平面,为此,导入基于误分类的损失函数,利用梯度下降法对损失函数进行极小化,求得最优解。感知机是神经网络和支持向量机的基础。
三、超平面
- 当我们的数据点集是二维的时候(意味着有两个特征),我们只需要用一根线,就可以将数据分成两个部分。
- 当我们的数据点集是三维的时候(意味着有三个特征),我们需要一个二维的平面,才能把数据分成两个部分。
- 当我们的数据点集为N维的时候(意味着有N个特征),此时我们需要一个N-1维的超平面,才可以把数据分成两个部分。
- 我们有无数个超平面可以将数据集分成两个部分,我们应该怎么找到最佳的分割线呢?https://www.kesci.com/home/project/5cf08e4dc84534002b03cdfd
-
虚线中心的绿色实线,就是我们在保持超平面方向不变的时候,得到的最佳超平面。
-
两条虚线之间的垂直距离,代表这这个超平面的分类间隔。
-
改变超平面的方向的时候,我们会得到不同方向的最佳超平面。
- “分类间隔”最大的那个超平面,就是真正的最佳超平面。即最佳超平面为两条虚线的中轴线
- 该平面所对应的两侧虚线穿过的样本点,就是SVM中的支持样本点,被称为“支持向量”
四、核函数
以上的讨论针对的都是线性可分的数据集。但是在实际生活中,我们会碰到很多线性不可分的数据集,将其放在一个高维空间中去就有可能变得可分。如图所示:
理论上任意的数据样本都能够找到一个合适的映射,使得这些在低维空间不能划分的样本到高维空间中之后能够线性可分。以二维平面的数据为例,我们可以找到一个映射,将二维平面的点映射到三维平面之中。
常见的核函数有:
-
- Linear Kernel 线性核函数
- Polynomial Kernel 多项式核函数
- Radial Basis Function (RBF) kernel 径向基核函数(RBF) …………
常用核函数公式如下:
五、乳腺癌数据集(选取2特征)实验
1 import numpy as np 2 import matplotlib.pyplot as plt 3 from sklearn import svm 4 from sklearn.datasets import make_blobs,load_breast_cancer 5 6 print(load_breast_cancer().keys()) 7 # dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename']) 8 data1 = load_breast_cancer().data 9 target1 = load_breast_cancer().target 10 11 print('data1,target1',data1.shape,target1.shape) 12 # data1,target1 (569, 30) (569,) 13 #一共有三十列特征,可以任意选择特征的数目,这里以二维为例 14 data = load_breast_cancer().data[:, 0:2] 15 target = load_breast_cancer().target 16 print(np.unique(target)) 17 18 #创建SVM模型 19 #选择核函数为'linear' 20 #C: 目标函数的惩罚系数C,用来平衡分类间隔margin和错分样本的,default C = 1.0; 21 #kernel:参数选择有RBF, Linear, Poly, Sigmoid, 默认的是"RBF" 22 23 model = svm.SVC(kernel='linear',C=10000) 24 25 #使用模型训练数据集 26 model.fit(data, target) 27 28 #绘制数据集散点图 29 # plt.scatter(data[:, 0], data[:, 1], c=target) 30 plt.scatter(data[:, 0], data[:, 1], c=target, s=30, cmap=plt.cm.prism) 31 32 #创建坐标轴刻度线 33 axis = plt.gca() 34 x_limit = axis.get_xlim() 35 y_limit = axis.get_ylim() 36 37 x = np.linspace(x_limit[0], x_limit[1], 50) 38 y = np.linspace(y_limit[0], y_limit[1], 50) 39 print('x,y',x.shape,y.shape)#x,y (50,) (50,) 40 X, Y = np.meshgrid(x, y) 41 print('X, Y ',X.shape, Y.shape )#X, Y (50, 50) (50, 50) 42 xy = np.c_[X.ravel(), Y.ravel()] 43 print('xy',xy.shape)#xy (2500, 2) 44 45 46 # 创建最佳分割线 47 decision_line = model.decision_function(xy).reshape(Y.shape) 48 49 # 绘制分割线的图 50 axis.contour(X, Y, decision_line, colors = 'k', levels=[0], 51 linestyles=['-']) 52 53 # 展示一下支持向量点 54 plt.scatter(model.support_vectors_[:, 0], model.support_vectors_[:, 1], s=100, 55 linewidth=1, facecolors='none', edgecolors='k') 56 plt.show()
拉格朗日乘子法
总结
在分类问题中,SVM是一种很优秀的机器学习算法。
优点
-
-
- 可以有效的分离高维度的数据
- 更节省内存空间,因为只需要用向量来创建最佳超平面
- 是针对于可分离数据集的最佳方法
-
缺点
-
-
- 当数据量级较大的时候,分类效果不好
- 针对于不可分类的数据集,效果有些不太好
-