目录
-
支持向量机的基本概念
-
1.概念
支持向量机(SVM)是一类按监督学习方式对数据进行二元分类的广义线性分类器,其决策边界是对学习样本求解的最大边距超平面,可以将问题化为一个求解凸二次规划的问题。与逻辑回归和神经网络相比,支持向量机,在学习复杂的非线性方程时提供了一种更为清晰,更加强大的方式。
具体来说就是在线性可分时,在原空间寻找两类样本的最优分类超平面。在线性不可分时,加入松弛变量并通过使用非线性映射将低维度输入空间的样本映射到高维度空间使其变为线性可分,这样就可以在该特征空间中寻找最优分类超平面。
SVM使用准则:n为特征数,m为训练样本数。
如果相较于m而言,n要大许多,即训练集数据量不够支持我们训练一个复杂的非线性模型,我们选用逻辑回归模型或者不带核函数的支持向量机。
如果n较小,而且m大小中等,例如n在 1-1000 之间,而m在10-10000之间,使用高斯核函数的支持向量机。
如果n较小,而m较大,例如n在1-1000之间,而m大于50000,则使用支持向量机会非常慢,解决方案是创造、增加更多的特征,然后使用逻辑回归或不带核函数的支持向量机。
2.支持向量机的不同功能
3.优缺点
优点:
支持向量机算法可以解决小样本情况下的机器学习问题,简化了通常的分类和回归等问题。
由于采用核函数方法克服了维数灾难和非线性可分的问题,所以向高维空间映射时没有增加计算的复杂性。换句话说,由于支持向量计算法的最终决策函数只由少数的支持向量所确定,所以计算的复杂性取决于支持向量的数目,而不是样本空间的维数。
支持向量机算法利用松弛变量可以允许一些点到分类平面的距离不满足原先要求,从而避免这些点对模型学习的影响。
缺点:
支持向量机算法对大规模训练样本难以实施。这是因为支持向量机算法借助二次规划求解支持向量,这其中会涉及m阶矩阵的计算,所以矩阵阶数很大时将耗费大量的机器内存和运算时间。
经典的支持向量机算法只给出了二分类的算法,而在数据挖掘的实际应用中,一般要解决多分类问题,但支持向量机对于多分类问题解决效果并不理想。
SVM算法效果与核函数的选择关系很大,往往需要尝试多种核函数,即使选择了效果比较好的高斯核函数,也要调参选择恰当的 γ参数。另一方面就是现在常用的SVM理论都是使用固定惩罚系数 C,但正负样本的两种错误造成的损失是不一样的。
线性SVM损失函数
问题的关键:就是扩大边际d。
w是参数,垂直与决策边界,x是特征向量,与数据集有关,b是截距。
为什么这三条线的右侧是1,0,-1?
由于w和b都是参数,所以为了使式子更加简洁,两侧同时除以常数,参数只是做了一个变换。新w和新b仍然可以做为变量。
通过一定的数学推导可以求出,边际d=,而边际越大越好,所以有了损失函数越小越好,如果不加平方,取模运算会导致计算量变大,所以增加了平方的运算。
损失函数计算公式:
约束条件形式:(αi是拉格朗日乘数)
核函数
核函数可以将m维空间的内积运算转化为低维空间的核函数计算,从而解决了在高维特征空间上计算“维度诅咒”的灾难。
在Sklearn中就是参数kernel,常用的核函数有Linear线性,poly多项式,rbf径向基核函数,sigmoid核函数等。
常见的核函数计算公式:
不同核函数的特点:
线性核函数:简单,求解快,奥卡姆剃刀,可解释性强
多项式核函数:可解决非线性问题,参数较多,对大数量级特征不适用
径向基核函数:可以映射到无限维,决策边界更多样,只有一个参数,更容易选择,特征多时会选用。但可解释性差,容易过拟合,计算速度较慢。
sklearn中进行可视化
1.导入模块
from sklearn.datasets import make_blobs #生成聚类数据集
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np
2、实例化数据集,可视化
x,y=make_blobs(n_samples=100,centers=2,random_state=0,cluster_std=0.6)
plt.scatter(x[:,0],x[:,1],c=y,s=50,cmap='rainbow')
plt.show()
3、网格点制作
制作若干个连续的固定的网格点,为了方便后续决策边界的计算和可视化。
xlim=ax.get_xlim() #返回上面图的x轴的最小值和最大值
ylim=ax.get_ylim() #返回上面图的y轴的最小值和最大值
#print(xlim,ylim) #(-0.7425578984849813, 3.3721920271976598) (-0.41872382476349596, 5.754870487889891)
axisx=np.linspace(xlim[0],xlim[1],30) #根据xlim和ylim绘制网格点
axisy=np.linspace(ylim[0],ylim[1],30)
print(axisx,axisy)
axisx,axisy=np.meshgrid(axisx,axisy) #将axisx和axisy分别向y轴和x轴进行扩充(广播)
xy=np.vstack([axisx.ravel(),axisy.ravel()]).T #扩充为30*30的坐标点,后面基于这900个点绘制决策边界
plt.scatter(xy[:,0],xy[:,1],s=1,cmap="rainbow")
plt.show()
4、建立模型并绘制决策边界和超平面
clf=SVC(kernel='linear').fit(x,y) #建模
z=clf.decision_function(xy).reshape(axisx.shape) #每个样本所对应的到决策边界的距离
ax=plt.gca() #如果不写将不会生成决策边界
ax.contour(axisx,axisy,z,
colors='k',
levels=[-1,0,1], #代表两个过支持向量的超平面和决策边界
alpha=0.5,
linestyles=['--','-','--']) #超平面使用虚线--,决策边界使用实线-
ax.set_xlim(xlim)
ax.set_ylim(ylim)
plt.scatter(x[:,0],x[:,1],c=y,s=50,cmap='rainbow')
plt.show()
可以对制作网格点和绘制决策边界和超平面做一个封装函数。
def plot_svc_decision_funtion(model,ax=None):
if ax is None:
ax=plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
x=np.linspace(xlim[0],xlim[1],30)
y=np.linspace(ylim[0],ylim[1],30)
y,x=np.meshgrid(y,x)
xy=np.vstack([x.ravel(),y.ravel()]).T
P = model.decision_function(xy).reshape(x.shape)
ax.contour(x,y,P,colors='k',
levels=[-1,0,1],
alpha=0.5,
linestyles=['--','-','--'])
ax.set_xlim(xlim)
ax.set_ylim(ylim)
plt.show()
当建模,并绘图时只需要使用如下的代码:
plt.scatter(x[:,0],x[:,1],c=y,s=50,cmap='rainbow')
plot_svc_decision_funtion(clf)
绘制效果: