首页 > 编程知识 正文

python实现svm二分类(SVM的原理和代码实现)

时间:2023-05-04 15:10:37 阅读:121252 作者:232

1.SVM介绍

支持向量机(support vector machines,SVM )是一种二分类模型,其基本模型为特征空间定义的间隔最大的线性分类器,间隔最宽,与感知机不同; SVM还包括核技巧,这成为实质上的非线性分类器。 SVM的学习策略是间隔最大化,可以形式化为求解凸二次规划的问题,等价于正则化最小化铰链损失函数的问题。 SVM的学习算法是求解凸二次规划的优化算法。

2.SVM算法原理

SVM学习的基本思想是求解能够正确分割训练数据集且几何间隔最大的分离超平面。 如下图所示,是分离超平面。 对于可线性分离的数据集来说,这种超平面是无限个,即有感知功能,但几何间隔最大的分离超平面是唯一的。

拉格朗日乘子法

首先,定义原始目标函数。 拉格朗日乘子法的基本思想是将约束条件转化为新的目标函数的一部分。 (关于的意思稍后说明)。 因此,约束优化问题成为我们习惯的无约束优化问题。 那么,为了使新目标函数的最佳解正好在可行解区域,该如何改造原始目标函数呢? 这就需要分析可行解领域中最优解的特征。

1 )最优解的特征分析

推论1 :“在其宿命的相遇点(即等式约束下优化问题的最优解)”上,原始目标函数的梯度向量必然与约束的切线方向垂直。 ”

推论2 :“函数的梯度方向也必然与函数自身的等值线切线方向垂直。 ”

推论3:"函数和函数的等值线在最佳解的点相接,也就是说两者点的梯度方向相同或相反"

2 )构造拉格朗日函数

3 ) KKT条件

不等式约束条件时,如图4所示,最佳解位于边界曲线上或可行解区域内满足不等式的地方有两种可能性。

第一种情况:最优解在边界上,相当于限制条件。 参照图4,请注意此时目标函数的最佳解在可行解区域之外。 因此,最佳解附近的函数的变化趋势是"在可执行解区域的内侧较大,在区域的外侧变小",与此相对,函数在可执行解区域小于0,在区域外大于0,所以在最佳解附近的变化趋势在内部较小,在外部变大这意味着目标函数的梯度方向与约束条件函数的梯度方向相反。 因此,能够根据式(3.1 )推测参数。

1KKT条件是对最优解的约束,原问题中的约束条件是对可行解的约束。

2KKT条件的推导对于后面介绍的拉格朗日对偶问题的推导至关重要。

拉格朗日对偶

4 )对偶问题同解的证明

3.smo算法

序列最小化(smo )数组最小化算法是一种用于SVM的有效优化算法。

但如何证明他的正确性:详见https://www.Jian Shu.com/p/0c 433 f6f 4141

4 .核函数

内核函数k(kernelfunction )是指k(x,y )=f (x,f ) y。 其中x和y是n维的输入值,f () )是n维到m维的映射(通常为mn )。 x、y也称为x与y的内积(inner product )、点积) )。

请注意,核函数和映射没有关系。内核函数是计算映射到高维空间的内积的简单方法。

5.SVM恢复(转载自https://www.cn blogs.com/white bear/p/13096398.html ) ) ) ) ) ) ) ) )。

SVM恢复任务在违反限制间隔的情况下,尽量防止“街道”上有更多的样本。 “街道”的宽度由超级参数控制

在随机生成的线性数据上,两个线性SVM回归模型具有一个较大间隔(=1.5=1.5 ),另一个较小间隔(=0.5=0.5 ),训练情况如下:

代码如下。

创建数据和培训:

NP.random.seed(42 ) m=50X=2 * np.random.randn(m ) m,1 ) y=)4*xNP.random.randn,1 ),ravel )

def find _ support _ vectors (SVM _ reg,x,y ) :y_pred=SVM_reg.predict(x ) off_margin=(NP.ABS )

_margin)svm_reg1.support_ = find_support_vectors(svm_reg1, X, y)svm_reg2.support_ = find_support_vectors(svm_reg2, X, y)eps_x1 = 1eps_y_pred = svm_reg1.predict([[eps_x1]])def plot_svm_regression(svm_reg, X, y, axes): x1s = np.linspace(axes[0], axes[1], 100).reshape(100, 1) y_pred = svm_reg.predict(x1s) plt.plot(x1s, y_pred, "k-", linewidth=2, label=r"$hat{y}$") plt.plot(x1s, y_pred + svm_reg.epsilon, "k--") plt.plot(x1s, y_pred - svm_reg.epsilon, "k--") plt.scatter(X[svm_reg.support_], y[svm_reg.support_], s=180, facecolors='#FFAAAA') plt.plot(X, y, "bo") plt.xlabel(r"$x_1$", fontsize=18) plt.legend(loc="upper left", fontsize=18) plt.axis(axes)plt.figure(figsize=(9, 4))plt.subplot(121)plot_svm_regression(svm_reg1, X, y, [0, 2, 3, 11])plt.title(r"$epsilon = {}$".format(svm_reg1.epsilon), fontsize=18)plt.ylabel(r"$y$", fontsize=18, rotation=0)#plt.plot([eps_x1, eps_x1], [eps_y_pred, eps_y_pred - svm_reg1.epsilon], "k-", linewidth=2)plt.annotate( '', xy=(eps_x1, eps_y_pred), xycoords='data', xytext=(eps_x1, eps_y_pred - svm_reg1.epsilon), textcoords='data', arrowprops={'arrowstyle': '<->', 'linewidth': 1.5} )plt.text(0.91, 5.6, r"$epsilon$", fontsize=20)plt.subplot(122)plot_svm_regression(svm_reg2, X, y, [0, 2, 3, 11])plt.title(r"$epsilon = {}$".format(svm_reg2.epsilon), fontsize=18)plt.show()

可视化展示:

非线性拟合

造数据

np.random.seed(42)m = 100X = 2 * np.random.rand(m, 1) - 1y = (0.2 + 0.1 * X + 0.5 * X**2 + np.random.randn(m, 1)/10).ravel() from sklearn.svm import SVRfrom sklearn.svm import SVRsvm_poly_reg1 = SVR(kernel="poly", degree=2, C=100, epsilon=0.1, gamma="auto")svm_poly_reg2 = SVR(kernel="poly", degree=2, C=0.01, epsilon=0.1, gamma="auto")svm_poly_reg1.fit(X, y)svm_poly_reg2.fit(X, y)

可视化编程

plt.figure(figsize=(9, 4))plt.subplot(121)plot_svm_regression(svm_poly_reg1, X, y, [-1, 1, 0, 1])plt.title(r"$degree={}, C={}, epsilon = {}$".format(svm_poly_reg1.degree, svm_poly_reg1.C, svm_poly_reg1.epsilon), fontsize=18)plt.ylabel(r"$y$", fontsize=18, rotation=0)plt.subplot(122)plot_svm_regression(svm_poly_reg2, X, y, [-1, 1, 0, 1])plt.title(r"$degree={}, C={}, epsilon = {}$".format(svm_poly_reg2.degree, svm_poly_reg2.C, svm_poly_reg2.epsilon), fontsize=18)plt.show()

可视化展示:

6.代码实现 

代码

from sklearn import svmimport numpy as npimport matplotlib.pyplot as plt#准备训练样本x=[[1,8],[3,20],[1,15],[3,35],[5,35],[4,40],[7,80],[6,49]]y=[1,1,-1,-1,1,-1,-1,1]##开始训练clf=svm.SVC() ##默认参数:kernel='rbf'clf.fit(x,y)#print("预测...")#res=clf.predict([[2,2]]) ##两个方括号表面传入的参数是矩阵而不是list##根据训练出的模型绘制样本点for i in x: res=clf.predict(np.array(i).reshape(1, -1)) if res > 0: plt.scatter(i[0],i[1],c='r',marker='*') else : plt.scatter(i[0],i[1],c='g',marker='*')##生成随机实验数据(15行2列)rdm_arr=np.random.randint(1, 15, size=(15,2))##回执实验数据点for i in rdm_arr: res=clf.predict(np.array(i).reshape(1, -1)) if res > 0: plt.scatter(i[0],i[1],c='r',marker='.') else : plt.scatter(i[0],i[1],c='g',marker='.')##显示绘图结果plt.show()

运行截图

代码

from sklearn import svmimport numpy as npimport matplotlib.pyplot as plt##设置子图数量fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(7, 7))ax0, ax1, ax2, ax3 = axes.flatten()# 准备训练样本x = [[1, 8], [3, 20], [1, 15], [3, 35], [5, 35], [4, 40], [7, 80], [6, 49]]y = [1, 1, -1, -1, 1, -1, -1, 1]##设置子图的标题titles = ['LinearSVC (linear kernel)', 'SVC with polynomial (degree 3) kernel', 'SVC with RBF kernel', ##这个是默认的 'SVC with Sigmoid kernel']##生成随机试验数据(15行2列)rdm_arr = np.random.randint(1, 15, size=(15, 2))def drawPoint(ax, clf, tn): ##绘制样本点 for i in x: ax.set_title(titles[tn]) res = clf.predict(np.array(i).reshape(1, -1)) if res > 0: ax.scatter(i[0], i[1], c='r', marker='*') else: ax.scatter(i[0], i[1], c='g', marker='*') ##绘制实验点 for i in rdm_arr: res = clf.predict(np.array(i).reshape(1, -1)) if res > 0: ax.scatter(i[0], i[1], c='r', marker='.') else: ax.scatter(i[0], i[1], c='g', marker='.')if __name__ == "__main__": ##选择核函数 for n in range(0, 4): if n == 0: clf = svm.SVC(kernel='linear').fit(x, y) drawPoint(ax0, clf, 0) elif n == 1: clf = svm.SVC(kernel='poly', degree=3).fit(x, y) drawPoint(ax1, clf, 1) elif n == 2: clf = svm.SVC(kernel='rbf').fit(x, y) drawPoint(ax2, clf, 2) else: clf = svm.SVC(kernel='sigmoid').fit(x, y) drawPoint(ax3, clf, 3) plt.show()

 运行截图

代码

from sklearn import svmimport numpy as npimport matplotlib.pyplot as plt##设置子图数量fig, axes = plt.subplots(nrows=1, ncols=2,figsize=(7,7))ax0, ax1 = axes.flatten()#准备训练样本x=[[1,8],[3,20],[1,15],[3,35],[5,35],[4,40],[7,80],[6,49]]y=[1,1,-1,-1,1,-1,-1,1]##设置子图的标题titles = ['SVC (linear kernel)', 'LinearSVC']##生成随机试验数据(15行2列)rdm_arr=np.random.randint(1, 15, size=(15,2))##画图函数def drawPoint(ax,clf,tn): ##绘制样本点 for i in x: ax.set_title(titles[tn]) res=clf.predict(np.array(i).reshape(1, -1)) if res > 0: ax.scatter(i[0],i[1],c='r',marker='*') else : ax.scatter(i[0],i[1],c='g',marker='*') ##绘制实验点 for i in rdm_arr: res=clf.predict(np.array(i).reshape(1, -1)) if res > 0: ax.scatter(i[0],i[1],c='r',marker='.') else : ax.scatter(i[0],i[1],c='g',marker='.')if __name__=="__main__": ##选择核函数 for n in range(0,2): if n==0: clf = svm.SVC(kernel='linear').fit(x, y) drawPoint(ax0,clf,0) else : clf= svm.LinearSVC().fit(x, y) drawPoint(ax1,clf,1) plt.show()

 运行截图

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。