当前位置: 首页 > 后端技术 > Python

机器学习算法(五):基于支持向量机的分类预测

时间:2023-03-26 10:54:18 Python

声明:数据鲸团队提供的学习资料,本文主要用于自学,代码由数据鲸团队提供,使用阿里云天池实验室和编辑器pycharm完成测试。支持向量机(SupportVectorMachine,SVM)是一种非常优雅的算法,有着非常完备的数学理论。常用于数据分类,也可用于数据回归预测。由于其优美的理论保证和使用核函数对线性不可分问题的处理技巧,在20世纪90年代左右,SVM大受欢迎。本文不会涉及很严密复杂的理论知识,力求通过直觉感受SVM。Demo实践Step1:库函数导入Step2:构建数据集和模型训练Step3:模型参数查看Step4:模型预测Step5:模型可视化学习目标*了解支持向量机的分类标准;*理解支持向量机的软区间分类;*理解支持向量机的非线性核函数分类;我们可以对比之前逻辑回归模型的决策边界,可以发现这两个决策边界存在一定的差异(可以比较两者在X轴和Y轴上的截距),这说明两者不同在同一个数据集上找到的判别线是不同的,造成不同的原因其实是两者选择的最优目标不一致。下面我们简单介绍一下SVM。支持向量机的介绍我们经常会遇到这样的问题。首先,我们会给你一些属于两类的数据。现在我们需要一个线性分类器来分离这些数据。我们可能有多种方法:那么现在有一个问题,两个分类器,哪个更好?为了判断好坏,我们需要引入一个标准:一个好的分类器不仅能很好的把已有的数据集分开,还能把未知的数据集一分为二。假设,现在有一个新的数据(3,2.8)属于可以看到的红色数据点。这时候黑线会对这个新的数据集进行错误分类,而蓝线不会。我们刚才举的例子可能有些主观。那么如何客观判断两条线的稳健性呢?此时,我们需要引入一个非常重要的概念:最大区间。最大区间描述了当前分类器和数据集之间的边界。以这两个分类器为例:可以看到蓝线的最大区间大于黑线。所以我们将选择蓝线作为我们的分类器。那么,我们当前的分类器是最优分类器吗?或者,有没有更好的分类器,它有更大的余量?答案是肯定的。总体代码:importnumpyasnpimportmatplotlib.pyplotaspltfromsklearn.datasetsimportmake_blobs#matplotlibinline#图片X,y=make_blobs(n_samples=60,centers=2,random_state=0,cluster_std=0.4)plt.scatter(X[:,0],X[:,1],c=y,s=60,cmap=plt.cm.Paired)#画散点图X,y=make_blobs(n_samples=60,centers=2,random_state=0,cluster_std=0.4)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt.cm.Paired)x_fit=np.linspace(0,3)#画数y_1=1*x_fit+0.8plt.plot(x_fit,y_1,'-c')y_2=-0.3*x_fit+3plt.plot(x_fit,y_2,'-k')#画散点图X,y=make_blobs(n_samples=60,centers=2,random_state=0,cluster_std=0.4)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt.cm.Paired)plt.scatter([3],[2.8],c='#cccc00',marker='<',s=100,cmap=plt.cm.Paired)x_fit=np.linspace(0,3)#画数y_1=1*x_fit+0.8plt.plot(x_fit,y_1,'-c')y_2=-0.3*x_fit+3plt.plot(x_fit,y_2,'-k')#画散点图X,y=make_blobs(n_samples=60,centers=2,random_state=0,cluster_std=0.4)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt.cm.Paired)x_fit=np.linspace(0,3)#绘制函数y_1=1*x_fit+0.8plt.plot(x_fit,y_1,'-c')#drawmarginplt.fill_between(x_fit,y_1-0.6,y_1+0.6,edgecolor='none',color='#AAAAAA',alpha=0.4)y_2=-0.3*x_fit+3plt.plot(x_fit,y_2,'-k')plt.fill_between(x_fit,y_2-0.4,y_2+0.4,edgecolor='none',color='#AAAAAA',alpha=0.4)#画散点图X,y=make_blobs(n_samples=60,centers=2,random_state=0,cluster_std=0.4)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt。cm.Paired)#drawingy_1=1*x_fit+0.8plt.plot(x_fit,y_1,'-c')#drawingmarginplt.fill_between(x_fit,y_1-0.6,y_1+0.6,edgecolor='none',color='#AAAAAA',alpha=0.4)fromsklearn.svmimportSVC#SVM函数clf=SVC(kernel='linear')clf.fit(X,y)#bestfunctionw=clf.coef_[0]a=-w[0]/w[1]y_3=a*x_fit-(clf.intercept_[0])/w[1]#下一个最大余量b_down=clf.support_vectors_[0]y_down=a*x_fit+b_down[1]-a*b_down[0]#最后一个b_up=的最大保证金clf.support_vectors_[-1]y_up=a*x_fit+b_up[1]-a*b_up[0]#绘制散点图X,y=make_blobs(n_samples=60,centers=2,random_state=0,cluster_std=0.4)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt.cm.Paired)#drawfunctionplt.plot(x_fit,y_3,'-c')#drawmarginplt.fill_between(x_fit,y_down,y_up,edgecolor='none',color='#AAAAAA',alpha=0.4)#绘制支持向量plt.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],edgecolor='b',s=80,facecolors='none')为了找到最优的分类器,我们今天需要介绍一下我们的主角:SVM的黑色边框的点就是距离当前分类器最近的点,我们称之为支持向量支持向量机为我们提供了多种可能的分类选择原则算法之间的关系确保了对未知数据集的更高泛化。软间隔有时是这样的例子:X,y=make_blobs(n_samples=60,centers=2,random_state=0,cluster_std=0.9)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt.cm.Paired)这样的最大区间不容易找到。所以我们有软间隔,与硬间隔相反,我们允许单个数据出现在间隔带中。我们知道,如果没有原则约束,就会有很多满足软区间的分类器。因此,有必要对错误分类的数据进行惩罚。在SVC函数中,有一个参数C是惩罚参数。惩罚参数越小,容忍度越大。以C=1为例,例如:X,y=make_blobs(n_samples=60,centers=2,random_state=0,cluster_std=0.9)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt.cm.Paired)#惩罚参数:C=1clf=SVC(C=1,kernel='linear')clf.fit(X,y)#最优函数w=clf.coef_[0]a=-w[0]/w[1]y_3=a*x_fit-(clf.intercept_[0])/w[1]#maximummarginnextb_down=clf.support_vectors_[0]y_down=a*x_fit+b_down[1]-a*b_down[0]#maximummarginlastb_up=clf.support_vectors_[-1]y_up=a*x_fit+b_up[1]-a*b_up[0]#绘制散点图图X,y=make_blobs(n_samples=60,centers=2,random_state=0,cluster_std=0.4)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt.cm.Paired)#drawfunctionplt.plot(x_fit,y_3,'-c')#drawmarginplt.fill_between(x_fit,y_down,y_up,edgecolor='none',color='#AAAAAA',alpha=0.4)#绘制支持向量plt.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],edgecolor='b',s=80,facecolors='none')当惩罚参数C=0.2,SVM将l更具包容性,兼容更多错误分类的样本:X,y=make_blobs(n_samples=60,centers=2,random_state=0,cluster_std=0.9)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt.cm.Paired)#惩罚参数:C=0.2clf=SVC(C=0.2,kernel='linear')clf.fit(X,y)x_fit=np.linspace(-1.5,4)#最佳函数w=clf.coef_[0]a=-w[0]/w[1]y_3=a*x_fit-(clf.intercept_[0])/w[1]#下一个最大边距b_down=clf.support_vectors_[10]y_down=a*x_fit+b_down[1]-a*b_down[0]#上一个最大边距b_up=clf.support_vectors_[1]y_up=a*x_fit+b_up[1]-a*b_up[0]#绘制散点图X,y=make_blobs(n_samples=60,centers=2,random_state=0,cluster_std=0.4)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt.cm.Paired)#绘制函数plt.plot(x_fit,y_3,'-c')#绘制边距plt.fill_between(x_fit,y_down,y_up,edgecolor='none',color='#AAAAAA',alpha=0.4)#绘制支持向量plt.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],edgecolor='b',s=80,facecolors='none')hyperplane如果遇到这样的数据集,没有办法使用线性分类器进行分类fromsklearn.datasets.samples_generatorimportmake_circlesX,y=make_circles(100,factor=.1,noise=.1,random_state=2019)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt.cm.Paired)clf=SVC(kernel='linear').fit(X,y)#最佳函数x_fit=np.linspace(-1.5,1.5)w=clf.coef_[0]a=-w[0]/w[1]y_3=a*X-(clf.intercept_[0])/w[1]plt.plot(X,y_3,'-c')我们可以将二维(低维)空间的数据映射到三维(高维)空间此时,我们可以将数据划分为一个超平面。因此,我们映射的目的是利用SVM的能力在高维空间中寻找超平面。从mpl_toolkits.mplot3d导入Axes3Dr=np.exp(-(X[:,0]**2+X[:,1]**2))ax=plt.subplot(projection='3d')ax.scatter3D(X[:,0],X[:,1],r,c=y,s=50,cmap=plt.cm.Paired)ax.set_xlabel('x')ax.set_ylabel('y')ax.set_zlabel('z')x_1,y_1=np.meshgrid(np.linspace(-1,1),np.linspace(-1,1))z=0.01*x_1+0.01*y_1+0.5ax.plot_surface(x_1,y_1,z,alpha=0.3)在SVC中,我们可以使用高斯核函数来实现这个功能:kernel='rbf'#drawX,y=make_circles(100,factor=.1,noise=.1,random_state=2019)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap=plt.cm.Paired)clf=SVC(kernel='rbf')clf。fit(X,y)ax=plt.gca()x=np.linspace(-1,1)y=np.linspace(-1,1)x_1,y_1=np.meshgrid(x,y)P=np.zeros_like(x_1)fori,xiinenumerate(x):forj,yjinenumerate(y):P[i,j]=clf.decision_function(np.array([[xi,yj]]))ax.contour(x_1,y_1,P,colors='k',levels=[-1,0,0.9],alpha=0.5,linestyles=['--','-','--'])plt.散点图(clf.support_vectors_[:,0],clf.support_vectors_[:,1],edgecolor='b',s=80,facecolors='none');