采用的测试数据:参考上一篇博客4.1部分
https://www.cnblogs.com/hhjing/p/14340924.html
1、
import numpy as np import matplotlib.pyplot as plt %matplotlib inline #定义函数 def linear_svm(X,y,lam,max_iter=2000): w=np.zeros(X.shape[1])#初始化 support_vectors=[]#创建空列表保存支持向量 for t in range(max_iter):#进行died learning_rate=1/(lam*(t+1))#计算本轮迭代的学习率 i=np.random.randint(len(X))#从训练集中随机抽取一个样本 ywx=w.T.dot(X.values[1])*y[i]#计算y_i w^T x_i if ywx<1:#进行指示函数的判断 w=w-learning_rate*lam*w+learning_rate*y[i]*X.values[i]#更新参数 else: w=w-learning_rate*lam*w for i in range(len(X)): ywx=w.T.dot(X.values[i])*y[i] if ywx<=1:#根据样本是否位于间隔附近判断是否为支持向量 support_vectors.append(X.values[i]) return w,support_vectors
2、线性支持向量机的正则化项通常不包括截距项,可以将数据进行中心化,再调用上述代码
#对训练集数据进行归一化,则模型无需再计算截距项 X=data[["x1","x2"]].apply(lambda x:x-x.mean()) #训练集标签 y=data["label"] w,support_vectors=linear_svm(X,y,lam=0.05,max_iter=5000)
3、将得到的超平面可视化,同时将两个函数间隔为1的线也绘制出来,对于所有不满足约束条件的样本,使用圆圈标记出来
plt.figure(figsize=(8,8))#设置图片尺寸 #绘制两类样本点 X_pos=X[y==1] X_neg=X[y==-1] plt.scatter(data_pos["x1"],data_pos["x2"],c="#E4007F",marker="^")#类别为1的数据绘制成洋红色 plt.scatter(data_neg["x1"],data_neg["x2"],c="#007979",marker="o")#类别为-1的数据绘制成深绿色 #绘制超平面 x1=np.linspace(-6,6,50) x2=-w[0]*x1/w[1] plt.plot(x1,x2,c="gray") #绘制两个间隔超平面 plt.plot(x1,-(w[0]*x1+1)/w[1],"--",c="#007979") plt.plot(x1,-(w[0]*x1-1)/w[1],"--",c="#E4007E") #标注支持向量 for x in support_vectors: plt.plot(x[0],x[1],"ro",linewidth=2,markersize=12,markerfacecolor='none') #添加轴标签,限制轴范围 plt.xlabel("$x_1$")#设置横轴标签 plt.ylabel("$x_2$")#设置纵轴标签 plt.xlim(-6,6)#设置横轴显示范围 plt.ylim(-2,2)#设置纵轴显示范围