【机器学习入门】推导超级详细,一文讲清楚支持向量机(SVM)【从原理到代码】
支持向量机(SVM)是机器学习中非常经典的一个模型,所以我就把这个作为第二个深入学习的机器学习模型,然后发现居然还挺难的(调包侠流下无能泪水)。
参考了很多博客,但是大部分博客都是讲一部分,要么数学部分比较详细,要么后面的推导部分比较详细,本篇汇集了百家之长,其中我也尽量详细通俗给出了我的一些理解,特在此记录一下。
其中可能存在一些错误,或者有些地方我也理解的不到位,在这些地方我都给出了参考博客,可以参考这些博客。
文章目录
1.原理部分
1.1.SVM
首先直接抛出SVM的核心假设:SVM面向二分类,假设一组点为线性可分,也就是可以一个被超平面分为两部分。SVM要找的就是这样的超平面,这个超平面使得正类和负类相距此平面最近的点和最远,最近的点被称为支持向量,也可以理解找到一个平面,使得两类中在这个平面的垂直方向的最短的距离最大(最小值最大问题),这样来了一个新样本,那么就可以以更大的概率分类正确。
如下图,SVM就是要找到中间那条线(实际是n维的一个超平面),把两部分样本分开。
1.2.优化目标
基于目标,可以写出优化方程: m a x ( 2 d ) max(2d) max(2d),其中d就是作为支持向量的点到超平面的距离,2d就是最短的支持向量距离(垂直于超平面方向)。
在空间 R n R^n Rn中,点到超平面的距离可以表达为:
w T x + b ∣ ∣ w ∣ ∣ \frac{w^Tx+b}{||w||} ∣∣w∣∣wTx+b其中, w , x w,x w,x都是 n × 1 n×1 n×1向量, x x x是移项后表达式的所有参数,在二维中,该式子表示为 a x + b y + c a 2 + b 2 \frac{ax+by+c}{\sqrt{a^2+b^2}} a2+b2ax+by+c,对应于上面就是 w T = ( a , b ) , x T = ( x , y ) w^T=(a,b),x^T=(x,y) wT=(a,b),xT=(x,y),本质是一样的。
知道了表达式后,就可以对上面提到的 d d d进行转化,假设超平面为 w T x + b = 0 w^Tx+b=0 wTx+b=0,如下:
m a x ( 2 d ) = > m a x ( 2 ∣ w T x + b ∣ ∣ ∣ w ∣ ∣ ) max(2d)\\=>max(2\frac{|w^Tx+b|}{||w||}) max(2d)=>max(2∣∣w∣∣∣wTx+b∣)因为 w , b w,b w,b同时放缩不会影响到超平面,也不会影响d的值,所以通过适当的放缩,该式子可表达为 m a x ( 2 1 ∣ ∣ w ∣ ∣ ) max(2\frac{1}{||w||}) max(2∣∣w∣∣1),这有利于后续的优化,进一步转化:
m a x ( 2 1 ∣ ∣ w ∣ ∣ ) = > m i n ( ∣ ∣ w ∣ ∣ 2 ) = > m i n ( ∣ ∣ w ∣ ∣ 2 2 ) max(2\frac{1}{||w||})\\=>min(\frac{||w||}{2})\\=>min(\frac{||w||^2}{2}) max(2∣∣w∣∣1)=>min(2∣∣w∣∣)=>min(2∣∣w∣∣2)最后一步是为了去掉根号,方便计算,其中 ∣ ∣ w ∣ ∣ = w T w ||w||=w^Tw ∣∣w∣∣=wTw。
任意一点到超平面的距离其实也可以表达为 y i ( w T x + b ) ∣ ∣ w ∣ ∣ \frac{y_i(w^Tx+b)}{||w||} ∣∣w∣∣yi(wTx+b),因为 y i ( w T x + b ) y_i(w^Tx+b) yi(wTx+b)的 y = ± 1 y=±1 y=±1,始终与 ( w T x + b ) (w^Tx+b) (wTx+b)同号,因此 y i ( w T x + b ) = ∣ ( w T x + b ) ∣ y_i(w^Tx+b)=|(w^Tx+b)| yi(wTx+b)=∣(wTx+b)∣,上面提到了 ∣ ( w T x + b ) ∣ = 1 |(w^Tx+b)|=1 ∣(wTx+b)∣=1,那么对于所有的向量,距离超平面的函数距离都要大于等于1(函数距离就是分子|(w^Tx+b)|,除了 ∣ ∣ w ∣ ∣ ||w|| ∣∣w∣∣之后是几何距离),存在:
y i ( w T x + b ) ≥ 1 y_i(w^Tx+b)≥1 yi(wTx+b)≥1此时可列出目标和约束条件:
m i n ( ∣ ∣ w ∣ ∣ 2 2 ) s . t . y i ( w T x + b ) ≥ 1 min(\frac{||w||^2}{2})\\ s.t.\;y_i(w^Tx+b)≥1 min(2∣∣w∣∣2)s.t.yi(wTx+b)≥1
1.3.数学知识补充
1.3.1.拉格朗日和kkt
下面介绍拉格朗日乘子和kkt。求解优化目标时,如果约束条件是等式,那么可以使用拉格朗日乘子法转为不带约束条件的优化,形如:
m i n ( f ( x ) ) s . t . φ i ( x ) = 0 , i = 1 , 2 , . . . , n min(f(x))\\ s.t.\; φ_i(x)=0,i=1,2,...,n min(f(x))s.t.φi(x)=0,i=1,2,...,n上式可化为
L ( x , λ ) = f ( x ) + ∑ i = 1 n λ i φ i ( x ) L(x,λ)=f(x)+∑_{i=1}^{n}λ_iφ_i(x) L(x,λ)=f(x)+i=1∑nλiφi(x)此时令 L L L对 x x x分别求偏导,解得的结果是极小值的必要条件(也就是可能是,也有可能不是),可以用于验证一个点是否是,如果为极值点那么一定满足上式。
但是如果约束条件条件包含不等式约束,此时可以使用kkt条件,kkt条件使用的情形如下:
m i n ( f ( x ) ) s . t . φ i ( x ) = 0 , i = 1 , 2 , . . . , n g j ( x ) ≤ 0 , j = 1 , 2 , . . . , m min(f(x))\\ s.t.\;φ_i(x)=0,i=1,2,...,n\\ g_j(x)≤0,j=1,2,...,m min(f(x))s.t.φi(x)=0,i=1,2,...,ngj(x)≤0,j=1,2,...,m此时,再写出拉格朗日函数:
L ( x , λ , β ) = f ( x ) + ∑ i = 1 n λ i φ i ( x ) + ∑ i = 1 m β j g j ( x ) L(x,λ,β)=f(x)+∑_{i=1}^{n}λ_iφ_i(x)+∑_{i=1}^{m}β_jg_j(x) L(x,λ,β)=f(x)+i=1∑nλiφi(x)+i=1∑mβjgj(x)
上式称为原始问题,需要进一步转化,下面介绍拉格朗日对偶性,这也是比较难理解的地方。
约束 β ≥ 0 \beta≥0 β≥0,此时因为 g ( x ) ≤ 0 g(x)≤0 g(x)≤0,那么 ∑ i = 1 m β j g j ( x ) ≤ 0 ∑_{i=1}^{m}β_jg_j(x)≤0 ∑i=1mβjgj(x)≤0,因此 L ( x , λ , β ) ≤ f ( x ) L(x,λ,\beta)≤f(x) L(x,λ,β)≤f(x), f ( x ) f(x) f(x)为求解目标,为了使得 L ( x , λ , β ) L(x,λ,β) L(x,λ,β)趋向于 f ( x ) f(x) f(x),那么要求 m a x ( L ( x , λ , β ) ) max(L(x,λ,β)) max(L(x,λ,β)),即 max β ≥ 0 , λ ( L ( x , λ , β ) ) \max\limits_{β≥0,λ}(L(x,λ,β)) β≥0,λmax(L(x,λ,β))。
该式只是对 λ , β λ,β λ,β进行约束,而 g ( x ) g(x) g(x)是要约束 x x x才能满足 g ( x ) ≤ 0 g(x)≤0 g(x)≤0,因此 g ( x ) > 0 g(x)>0 g(x)>0可能成立,从而使得:
max β ≥ 0 , λ ( L ( x , λ , β ) ) = { f ( x ) , ∀ g j ( x ) ≤ 0 [ f ( x ) , + ∞ ] , ∃ g j ( x ) > 0 \max\limits_{β≥0,λ}(L(x,λ,β))=\left\{ \begin{array}{cc} f(x),{\forall}\;g_j(x)≤0 & \\ [f(x),+∞],{\exists}\;g_j(x)>0 \end{array} \right. β≥0,λmax(L(x,λ,β))={f(x),∀gj(x)≤0[f(x),+∞],∃gj(x)>0
(这里有一个问题就是:为什么不满足约束的时候不考虑h(x)≠0?这一点我也不是很清楚,参考的几篇博客并没有提到,也有可能是我没理解到位吧!)
也就是无论如何 max β ≥ 0 , λ ( L ( x , λ , β ) ) \max\limits_{β≥0,λ}(L(x,λ,β)) β≥0,λmax(L(x,λ,β))的下限都是 f ( x ) f(x) f(x),也就是求解目标,那么只要再对其求 m i n min min即 min x max β ≥ 0 , λ ( L ( x , λ , β ) ) \min\limits_{x}\max\limits_{β≥0,λ}(L(x,λ,β)) xminβ≥0,λmax(L(x,λ,β)),那么原始问题可转化为原始代价函数:
J d = m i n ( f ( x ) ) = min x max β ≥ 0 , λ ( L ( x , λ , β ) ) J_d=min(f(x))=\min\limits_{x}\max\limits_{β≥0,λ}(L(x,λ,β)) Jd=min(f(x))=xminβ≥0,λmax(L(x,λ,β))最后补充一点,**max(.)**为凸函数,**min(.)为凹函数,与括号内的.***形式无关,这和下面进一步转化有关。(证明参见)
1.3.2.对偶方法
对于原函数,构造一个新的函数,也就是将 L ( x , λ , β ) L(x,\lambda,\beta) L(x,λ,β)前面的 m i n min min和 m a x max max顺序反一反,条件不变,得到一个新函数:
min x ( L ( x , λ , β ) ) = min x ( f ( x ) + ∑ i = 1 n λ i φ i ( x ) + ∑ i = 1 m β j g j ( x ) ) \min\limits_{x}(L(x,\lambda,\beta))=\min\limits_{x}(f(x)+∑_{i=1}^{n}λ_iφ_i(x)+∑_{i=1}^{m}β_jg_j(x)) xmin(L(x,λ,β))=xmin(f(x)+i=1∑nλiφi(x)+i=1∑mβjgj(x))该函数满足下式:
min x ( L ( x , λ , β ) ) = { min x ( f ( x ) ) , ∀ g j ( x ) ≤ 0 [ − ∞ , min x ( f ( x ) ) ] , ∃ g j ( x ) > 0 \min\limits_{x}(L(x,λ,β))=\left\{ \begin{array}{cc} \min\limits_{x}(f(x)),{\forall}\;g_j(x)≤0 & \\ [-∞,\min\limits_{x}(f(x))],{\exists}\;g_j(x)>0 \end{array} \right. xmin(L(x,λ,β))={xmin(f(x)),∀gj(x)≤0[−∞,xmin(f(x))],∃gj(x)>0
(这里有个问题:我感觉满足条件的时候βg(x)s∈[-∞,0],不满足的时候是[-∞,+∞],所以满足的时候最小值为什么是f(x)最小值?这部分来自博客)。
可见最大值都是 f ( x ) f(x) f(x),那么类似上面取 m a x max max。
J p = max β ≥ 0 , λ min x ( L ( x , λ , β ) ) J_p=\max\limits_{β≥0,λ}\min\limits_{x}(L(x,λ,β)) Jp=β≥0,λmaxxmin(L(x,λ,β))假设 J d , J p J_d,J_p Jd,Jp对应的极值(极小值和极大值)分别是 d ∗ 和 p ∗ d^*和p^* d∗和p∗,那么满足:
d ∗ ≥ p ∗ d^*≥p^* d∗≥p∗根据Slater定理,如果问题为凸问题(凹问题可以转为凸问题),那么** p ∗ = d ∗ p^*=d^* p∗=d∗,此时称为强对偶性**(与之对应的是弱对偶性,满足的是上面的不等式)。
1.4.优化目标转化
下面回到原问题上来,原优化问题如:
m i n ( ∣ ∣ w ∣ ∣ 2 2 ) s . t . y i ( w T x + b ) − 1 ≥ 0 min(\frac{||w||^2}{2})\\ s.t.\;y_i(w^Tx+b)-1≥0 min(2∣∣w∣∣2)s.t.yi(wTx+b)−1≥0上面的不等式约束是≥0,要满足标准kkt,转为下式:
m i n ( ∣ ∣ w ∣ ∣ 2 2 ) s . t . − ( y i ( w T x + b ) − 1 ) ≤ 0 min(\frac{||w||^2}{2})\\ s.t.\;-(y_i(w^Tx+b)-1)≤0 min(2∣∣w∣∣2)s.t.−(yi(wTx+b)−1)≤0写出拉格朗日函数:
L ( w , b , β ) = ∣ ∣ w ∣ ∣ 2 2 − ∑ i = 1 m β i [ y i ( w T x i + b ) − 1 ] L(w,b,β)=\frac{||w||^2}{2}-∑_{i=1}^{m}β_i[y_i(w^Tx_i+b)-1] L(w,b,β)=2∣∣w∣∣2−i=1∑mβi[yi(wTxi+b)−1]
该问题为原始问题,满足 β > 0 β>0 β>0(kkt条件),转为原始代价函数:
J d = m i n ( f ( w ) ) = min w , b max β ≥ 0 ( L ( w , b , β ) ) J_d=min(f(w))=\min\limits_{w,b}\max\limits_{β≥0}(L(w,b,β)) Jd=min(f(w))=w,bminβ≥0max(L(w,b,β))该函数为凸函数( m i n min min),转为对偶问题:
min w , b max β ≥ 0 ( L ( w , b , β ) ) = max β ≥ 0 min w , b ( L ( w , b , β ) ) \min\limits_{w,b}\max\limits_{β≥0}(L(w,b,β))=\max\limits_{β≥0}\min\limits_{w,b}(L(w,b,β)) w,bminβ≥0max(L(w,b,β))=β≥0maxw,bmin(L(w,b,β))写出完整的表达式:
max β ≥ 0 min w , b ( L ( w , b , β ) ) = max β ≥ 0 min w , b ( ∣ ∣ w ∣ ∣ 2 2 − ∑ i = 1 m β i [ y i ( w T x i + b ) − 1 ] ) \max\limits_{β≥0}\min\limits_{w,b}(L(w,b,β))=\max\limits_{β≥0}\min\limits_{w,b}(\frac{||w||^2}{2}-∑_{i=1}^{m}β_i[y_i(w^Tx_i+b)-1]) β≥0maxw,bmin(L(w,b,β))=β≥0maxw,bmin(2∣∣w∣∣2−i=1∑mβi[yi(wTxi+b)−1])先求里面部分,分别对 w , b w,b w,b求偏导,得到下式:
{ ∂ L ∂ w = w − ∑ i = 1 m y i x i β i ∂ L ∂ b = − ∑ i = 1 m y i β i \left\{ \begin{array}{cc} \frac{\partial L}{\partial w}=w-∑_{i=1}^{m}y_ix_iβ_i \\ \frac{\partial L}{\partial b}=-∑_{i=1}^{m}y_iβ_i \end{array} \right. {∂w∂L=w−∑i=1myixiβi∂b∂L=−∑i=1myiβi
分别令其为0,得到:
w = ∑ i = 1 m y i x i β i ∑ i = 1 m y i β i = 0 w=∑_{i=1}^{m}y_ix_iβ_i\\ ∑_{i=1}^{m}y_iβ_i=0 w=i=1∑myixiβii=1∑myiβi=0注意:这里的 x i , w x_i,w xi,w都是一个向量。
带入原式,变为:
max β ≥ 0 ( 1 2 w T w − ∑ i = 1 m β i [ y i ( w T x i + b ) − 1 ] ) = max β ≥ 0 ( 1 2 w T w − ∑ i = 1 m β i y i w T w − b ∑ i = 1 m β i y i + ∑ i = 1 m β i ) = max β ≥ 0 ( 1 2 w T ∑ i = 1 m y i x i β i − w T ∑ i = 1 m y i x i β i + ∑ i = 1 m β i ) = max β ≥ 0 ( ∑ i = 1 m β i − 1 2 w T ∑ i = 1 m y i x i β i ) \max\limits_{β≥0}(\frac{1}{2}w^Tw-∑_{i=1}^{m}β_i[y_i(w^Tx_i+b)-1])\\ =\max\limits_{β≥0}(\frac{1}{2}w^Tw-∑_{i=1}^{m}β_iy_iw^Tw-b∑_{i=1}^{m}β_iy_i+∑_{i=1}^{m}β_i)\\ =\max\limits_{β≥0}(\frac{1}{2}w^T∑_{i=1}^{m}y_ix_iβ_i-w^T∑_{i=1}^{m}y_ix_iβ_i+∑_{i=1}^{m}β_i)\\ =\max\limits_{β≥0}(∑_{i=1}^{m}β_i-\frac{1}{2}w^T∑_{i=1}^{m}y_ix_iβ_i) β≥0max(21wTw−i=1∑mβi[yi(wTxi+b)−1])=β≥0max(21wTw−i=1∑mβiyiwTw−bi=1∑mβiyi+i=1∑mβi)=β≥0max(21wTi=1∑myixiβi−wTi=1∑myixiβi+i=1∑mβi)=β≥0max(i=1∑mβi−21wTi=1∑myixiβi)上面是带入了 w w w,然后进行化简得到。下面要进一步带入 w T w^T wT,这个就是 w w w的转置,注意维度的变化:
max β ≥ 0 ( ∑ i = 1 m β i − 1 2 w T ∑ i = 1 m y i x i β i ) = max β ≥ 0 ( ∑ i = 1 m β i − 1 2 ∑ j = 1 m β j T x j T y j T ∑ i = 1 m y i x i β i ) = max β ≥ 0 ( ∑ i = 1 m β i − 1 2 ∑ i , j = 1 m β j β i y j y i x j T x i ) \max\limits_{β≥0}(∑_{i=1}^{m}β_i-\frac{1}{2}w^T∑_{i=1}^{m}y_ix_iβ_i)\\ =\max\limits_{β≥0}(∑_{i=1}^{m}β_i-\frac{1}{2}∑_{j=1}^{m}β_j^Tx_j^Ty_j^T∑_{i=1}^{m}y_ix_iβ_i)\\ =\max\limits_{β≥0}(∑_{i=1}^{m}β_i-\frac{1}{2}∑_{i,j=1}^{m}β_jβ_iy_jy_ix_j^Tx_i) β≥0max(i=1∑mβi−21wTi=1∑myixiβi)=β≥0max(i=1∑mβi−21j=1∑mβjTxjTyjTi=1∑myixiβi)=β≥0max(i=1∑mβi−21i,j=1∑mβjβiyjyixjTxi)此时问题被转化为了
max β ≥ 0 ( ∑ i = 1 m β i − 1 2 ∑ i , j = 1 m β j β i y j y i x j T x i ) s . t . ∑ i = 1 m y i β i = 0 \max\limits_{β≥0}(∑_{i=1}^{m}β_i-\frac{1}{2}∑_{i,j=1}^{m}β_jβ_iy_jy_ix_j^Tx_i)\\ s.t. \;∑_{i=1}^{m}y_iβ_i=0 β≥0max(i=1∑mβi−21i,j=1∑mβjβiyjyixjTxi)s.t.i=1∑myiβi=0
1.5.SMO求解β
【推荐】知乎,主要是介绍SMO,在α的介绍部分比较容易理解
上面的转化得到了一个关于 β β β的优化函数,下面介绍利用SMO算法求解 β β β。
SMO算法类似于坐标上升算法,假设存在要求 m i n ( f ( x 1 , x 2 ) ) min(f(x_1,x_2)) min(f(x1,x2)),首先固定 x 1 x_1 x1(将其看做一个常数),然后计算关于 x 2 x_2 x2的偏导,然后可以得到此时对应的最优 x 2 x_2 x2,然后固定 x 2 x_2 x2,求解 x 1 x_1 x1,不断迭代直到收敛。
SMO的思路大致类似,每次选取尽量少的变量来优化。回到SVM问题中,在上面得到了需要求解的函数:
max β ≥ 0 ( ∑ i = 1 m β i − 1 2 ∑ i , j = 1 m β j β i y j y i x j T x i ) s . t . ∑ i = 1 m y i β i = 0 \max\limits_{β≥0}(∑_{i=1}^{m}β_i-\frac{1}{2}∑_{i,j=1}^{m}β_jβ_iy_jy_ix_j^Tx_i)\\ s.t. \;∑_{i=1}^{m}y_iβ_i=0 β≥0max(i=1∑mβi−21i,j=1∑mβjβiyjyixjTxi)s.t.i=1∑myiβi=0这是一个关于 β β β的函数, β β β是一个 n × 1 n\times 1 n×1的向量,并且存在约束条件,直接求解复杂度很高,SMO将其分解为多个二次规划问题求解,每次针对其中两个 β = < β i , β j > β=<β_i,β_j> β=<βi,βj>进行优化,大大减少了运算量。
1.5.1.不限制β
首先抛开对于β的限制,选取需要优化的两个参数记为 β 1 , β 2 β_1,β_2 β1,β2,剩下的若干 β β β固定,作为常数处理。
为了简便表达,这里设 k i , j k_{i,j} ki,j上面的 x i T x j x_i^Tx_j xiTxj,容易得到 k i , j = k j , i k_{i,j}=k_{j,i} ki,j=kj,i,同时设 h i , j = β j β i y j y i x j T x i = β j β i y j y i k i , j h_{i,j}=β_jβ_iy_jy_ix_j^Tx_i=β_jβ_iy_jy_ik_{i,j} hi,j=βjβiyjyixjTxi=βjβiyjyiki,j,满足 h i , j = h j , i h_{i,j}=h_{j,i} hi,j=hj,i(这是为了方便查看带入的规则)。
记优化目标为 W ( β ) W(β) W(β),把与 β 1 , β 2 β_1,β_2 β1,β2有关的提取出来,其他记为 C C C,可得:
W ( β 1 , β 2 ) = ∑ i = 1 m β i − 1 2 ∑ i , j = 1 m h i , j = β 1 + β 2 − 1 2 h 1 , 1 − 1 2 h 1 , 2 − 1 2 h 1 , 1 − 1 2 h 2 , 2 − 1 2 ∑ i = 3 m h i , 1 − 1 2 ∑ i = 3 m h 1 , i − 1 2 ∑ i = 3 m h i , 2 − 1 2 ∑ i = 3 m h 2 , i + C = β 1 + β 2 − h 1 , 2 − 1 2 h 1 , 1 − 1 2 h 2 , 2 − ∑ i = 3 m h 1 , i − ∑ i = 3 m h 2 , i + C W(β_1,β_2)=∑_{i=1}^{m}β_i-\frac{1}{2}∑_{i,j=1}^{m}h_{i,j}\\ =β_1+β_2-\frac{1}{2}h_{1,1}-\frac{1}{2}h_{1,2}-\frac{1}{2}h_{1,1}-\frac{1}{2}h_{2,2}-\\ \frac{1}{2}∑_{i=3}^{m}h_{i,1}-\frac{1}{2}∑_{i=3}^{m}h_{1,i}-\frac{1}{2}∑_{i=3}^{m}h_{i,2}-\frac{1}{2}∑_{i=3}^{m}h_{2,i}+C\\ =β_1+β_2-h_{1,2}-\frac{1}{2}h_{1,1}-\frac{1}{2}h_{2,2}-∑_{i=3}^{m}h_{1,i}-∑_{i=3}^{m}h_{2,i}+C W(β1,β2)=i=1∑mβi−21i,j=1∑mhi,j=β1+β2−21h1,1−21h1,2−21h1,1−21h2,2−21i=3∑mhi,1−21i=3∑mh1,i−21i=3∑mhi,2−21i=3∑mh2,i+C=β1+β2−h1,2−21h1,1−21h2,2−i=3∑mh1,i−i=3∑mh2,i+C带入 h i , j h_{i,j} hi,j得到:
β 1 + β 2 − 1 2 k 1 , 1 α 1 2 − 1 2 k 2 , 2 α 2 2 − 1 2 k 1 , 2 α 1 α 2 − ∑ i = 3 m k 1 , i β 1 β i y 1 y i − ∑ i = 3 m k 2 , i β 2 β i y 2 y i + C β_1+β_2-\frac{1}{2}k_{1,1}α_1^2-\frac{1}{2}k_{2,2}α_2^2-\frac{1}{2}k_{1,2}α_1α_2-∑_{i=3}^{m}k_{1,i}β_1β_iy_1y_i-∑_{i=3}^{m}k_{2,i}β_2β_iy_2y_i+C β1+β2−21k1,1α12−21k2,2α22−21k1,2α1α2−i=3∑mk1,iβ1βiy1yi−i=3∑mk2,iβ2βiy2yi+C进一步,因为对于每个 ∑ i = 3 m ∑_{i=3}^{m} ∑i=3m,其中的 β 1 , β 1 , y 1 , y 2 β_1,β_1,y_1,y_2 β1,β1,y1,y2都是一样的,所以可以提取出来,得到:
β 1 + β 2 − 1 2 k 1 , 1 α 1 2 − 1 2 k 2 , 2 α 2 2 − 1 2 k 1 , 2 α 1 α 2 − β 1 y 1 ∑ i = 3 m k 1 , i β i y i − β 2 y 2 ∑ i = 3 m k 2 , i β i y i + C β_1+β_2-\frac{1}{2}k_{1,1}α_1^2-\frac{1}{2}k_{2,2}α_2^2-\frac{1}{2}k_{1,2}α_1α_2-β_1y_1∑_{i=3}^{m}k_{1,i}β_iy_i-β_2y_2∑_{i=3}^{m}k_{2,i}β_iy_i+C β1+β2−21k1,1α12−21k2,2α22−21k1,2α1α2−β1y1i=3∑mk1,iβiyi−β2y2i=3∑mk2,iβiyi+C
β 1 , β 2 β_1,β_2 β1,β2是满足一定约束条件的,即 ∑ i = 1 m y i β i = 0 ∑_{i=1}^{m}y_iβ_i=0 ∑i=1myiβi=0,设 y 1 β 1 + y 2 β 2 = γ y_1β_1+y_2β_2=γ y1β1+y2β2=γ,那么存在:
β 1 = y 1 ( γ − β 2 y 2 ) β_1=y_1(γ-β_2y_2) β1=y1(γ−β2y2)设:
v 1 = ∑ i = 3 m k 1 , i β i y i v 2 = ∑ i = 3 m k 2 , i β i y i v_1=∑_{i=3}^{m}k_{1,i}β_iy_i\\v_2=∑_{i=3}^{m}k_{2,i}β_iy_i v1=i=3∑mk1,iβiyiv2=i=3∑mk2,iβiyi带入 β 1 β_1 β1后,那么此时 W ( β 1 , β 2 ) W(β_1,β_2) W(β1,β2)就变为了关于 β 2 β_2 β2的函数,注意 y i 2 = 1 y_i^2=1 yi2=1,如下:
W ( β 2 ) = y 1 ( γ − β 2 y 2 ) + β 2 − 1 2 k 1 , 1 ( γ − β 2 y 2 ) 2 − 1 2 k 2 , 2 β 2 2 − k 1 , 2 β 2 ( γ − β 2 y 2 ) y 2 − v 1 ( γ − β 2 y 2 ) − v 2 y 2 β 2 + C W(β_2)=y_1(γ-β_2y_2)+β_2-\frac{1}{2}k_{1,1}(γ-β_2y_2)^2\\ -\frac{1}{2}k_{2,2}β_2^2-k_{1,2}β_2(γ-β_2y_2)y_2-v1(γ-β_2y_2)-v_2y_2β_2+C W(β2)=y1(γ−β2y2)+β2−21k1,1(γ−β2y2)2−21k2,2β22−k1,2β2(γ−β2y2)y2−v1(γ−β2y2)−v2y2β2+C然后对 β 2 β_2 β2求导:
∂ W ∂ β 2 = − y 1 y 2 + y 2 2 − k 1 , 1 y 2 ( γ − β 2 y 2 ) − k 2 , 2 α 2 − k 1 , 2 γ y 2 − 2 k 1 , 2 β 2 + v 1 y 2 − v 2 y 2 = ( 2 k 1 , 2 − k 1 , 1 − k 2 , 2 ) β 2 + ( k 1 , 1 − k 1 , 2 ) γ y 2 + y 2 ( v 1 − v 2 ) − y 2 ( y 1 − y 2 ) \frac{\partial W}{\partial β_2}=-y_1y_2+y_2^2-k_{1,1}y_2(γ-β_2y_2)-k_{2,2}α_2-k_{1,2}γy_2-2k_{1,2}β_2+v_1y_2-v_2y_2\\ =(2k_{1,2}-k_{1,1}-k_{2,2})β_2+(k_{1,1}-k_{1,2})γy_2+y_2(v_1-v_2)-y_2(y_1-y_2) ∂β2∂W=−y1y2+y22−k1,1y2(γ−β2y2)−k2,2α2−k1,2γy2−2k1,2β2+v1y2−v2y2=(2k1,2−k1,1−k2,2)β2+(k1,1−k1,2)γy2+y2(v1−v2)−y2(y1−y2)下面的步骤将消除 γ γ γ,计算出更新后的值 β n e w β^{new} βnew和原来的值 β o l d β^{old} βold的关系,这和更新参数有关。
首先可以知道,对于一个输入样本 x x x,其预测值为 f ( x ) = w T x + b f(x)=w^Tx+b f(x)=wTx+b,带入前面计算出的 w w w(在问题求解部分)可得:
f ( x j ) = ∑ i = 1 m y i β i x i T x j + b = ∑ i = 1 m y i β i k i , j + b f(x_j)=∑_{i=1}^{m}y_iβ_ix_i^Tx_j+b\\=∑_{i=1}^{m}y_iβ_ik_{i,j}+b f(xj)=i=1∑myiβixiTxj+b=i=1∑myiβiki,j+b可以发现这个式子和前面的 v 1 , v 2 v_1,v_2 v1,v2形式类似,带入 x 1 x_1 x1,可得 f ( x 1 ) = ∑ i = 1 m y i β i k i , 1 + b f(x_1)=∑_{i=1}^{m}y_iβ_ik_{i,1}+b f(x1)=∑i=1myiβiki,1+b,用 f ( x ) f(x) f(x)的形式表达出 v 1 , v 2 v_1,v_2 v1,v2:
v 1 = f ( x 1 ) − y 1 β 1 o l d k 1 , 1 − y 2 β 2 o l d k 2 , 1 − b v 2 = f ( x 2 ) − y 1 β 1 o l d k 2 , 1 − y 2 β 2 o l d k 2 , 2 − b v_1=f(x_1)-y_1β_1^{old}k_{1,1}-y_2β_2^{old}k_{2,1}-b\\ v_2=f(x_2)-y_1β_1^{old}k_{2,1}-y_2β_2^{old}k_{2,2}-b v1=f(x1)−y1β1oldk1,1−y2β2oldk2,1−bv2=f(x2)−y1β1oldk2,1−y2β2oldk2,2−b这里是 β o l d β^{old} βold是因为这是基于已知的预测值的,所以是上一次的参数,也就是旧参数。
替换掉前面求导得到的式子 v 1 − v 2 v_1-v_2 v1−v2:
v 1 − v 2 = f ( x 1 ) − f ( x 2 ) + ( k 1 , 1 + k 2 , 2 − 2 k 1 , 2 ) β 2 o l d y 2 + γ ( k 1 , 2 − k 1 , 1 ) v1-v2=f(x_1)-f(x_2)+(k_{1,1}+k_{2,2}-2k_{1,2})β_2^{old}y_2+γ(k_{1,2}-k_{1,1}) v1−v2=f(x1)−f(x2)+(k1,1+k2,2−2k1,2)β2oldy2+γ(k1,2−k1,1)带入得:
∂ W ∂ β 2 = ( 2 k 1 , 2 − k 1 , 1 − k 2 , 2 ) β 2 n e w + ( k 1 , 1 − k 1 , 2 ) γ y 2 + y 2 ( f ( x 1 ) − f ( x 2 ) + ( k 1 , 1 + k 2 , 2 − 2 k 1 , 2 ) β 2 o l d y 2 + γ ( k 1 , 2 − k 1 , 1 ) ) − y 2 ( y 1 − y 2 ) = ( 2 k 1 , 2 − k 1 , 1 − k 2 , 2 ) β 2 n e w − ( 2 k 1 , 2 − k 1 , 1 − k 2 , 2 ) β 2 o l d + y 2 ( ( f ( x 1 ) − y 1 ) − ( f ( x 2 ) − y 2 ) ) \frac{\partial W}{\partial β_2}=(2k_{1,2}-k_{1,1}-k_{2,2})β_2^{new}+(k_{1,1}-k_{1,2})γy_2\\ +y_2(f(x_1)-f(x_2)+(k_{1,1}+k_{2,2}-2k_{1,2})β_2^{old}y_2+γ(k_{1,2}-k_{1,1}))-y_2(y_1-y_2)\\ =(2k_{1,2}-k_{1,1}-k_{2,2})β_2^{new}-(2k_{1,2}-k_{1,1}-k_{2,2})β_2^{old}+y_2((f(x_1)-y_1)-(f(x_2)-y_2)) ∂β2∂W=(2k1,2−k1,1−k2,2)β2new+(k1,1−k1,2)γy2+y2(f(x1)−f(x2)+(k1,1+k2,2−2k1,2)β2oldy2+γ(k1,2−k1,1))−y2(y1−y2)=(2k1,2−k1,1−k2,2)β2new−(2k1,2−k1,1−k2,2)β2old+y2((f(x1)−y1)−(f(x2)−y2))
设 e i = f ( x i ) − y i , K = 2 k 1 , 2 − k 1 , 1 − k 2 , 2 e_i=f(x_i)-y_i,K=2k_{1,2}-k_{1,1}-k_{2,2} ei=f(xi)−yi,K=2k1,2−k1,1−k2,2:
∂ W ∂ β 2 = K β 2 n e w − K β 2 o l d + y 2 ( e 1 − e 2 ) \frac{\partial W}{\partial β_2}=Kβ_2^{new}-Kβ_2^{old}+y_2(e_1-e_2) ∂β2∂W=Kβ2new−Kβ2old+y2(e1−e2)要满足极值点,那么 ∂ W ∂ β 2 = 0 \frac{\partial W}{\partial β_2}=0 ∂β2∂W=0,得到:
β 2 n e w = β 2 o l d − y 2 ( e 1 − e 2 ) / K β_2^{new}=β_2^{old}-y_2(e_1-e_2)/K β2new=β2old−y2(e1−e2)/K因为 β 1 n e w = y 1 ( γ − β 2 n e w y 2 ) β_1^{new}=y_1(γ-β_2^{new}y_2) β1new=y1(γ−β2newy2),而 γ = β 2 o l d y 1 + β 1 o l d y 2 γ=β_2^{old}y_1+β_1^{old}y_2 γ=β2oldy1+β1oldy2,由此可以解出新的 β 1 n e w β_1^{new} β1new。
1.5.2.β裁剪
下面要对β进行裁剪,也就是考虑限制 β β β。
实际的 β β β是有范围的,限定为 0 ≤ β ≤ C 0≤β≤C 0≤β≤C, C C C表示软间隔常数。
因为 β 1 y 1 + β 2 y 2 = γ β_1y_1+β_2y_2=γ β1y1+β2y2=γ,这个关系始终成立,无论是 β n e w β^{new} βnew还是 β o l d β^{old} βold,又因为 y = ± 1 y=±1 y=±1,下面分两种情况讨论 y 1 , y 2 y_1,y_2 y1,y2的情况并分析 β 2 n e w β_2^{new} β2new约束条件:
- y 1 y 2 < 0 y_1y_2<0 y1y2<0:
此时存在 β 2 − β 1 β_2-β_1 β2−β1为常数,那么 β 2 n e w − β 1 n e w = β 2 o l d − β 1 o l d β_2^{new}-β_1^{new}=β_2^{old}-β_1^{old} β2new−β1new=β2old−β1old,那么存在:
0 ≤ β 1 n e w = β 2 n e w − ( β 2 o l d − β 1 o l d ) ≤ C = > m a x ( 0 , β 2 o l d − β 1 o l d ) ≤ β 2 n e w ≤ m i n ( C , C + ( β 2 o l d − β 1 o l d ) ) 0≤β_1^{new}=β_2^{new}-(β_2^{old}-β_1^{old})≤C\\ =>max(0,β_2^{old}-β_1^{old})≤β_2^{new}≤min(C,C+(β_2^{old}-β_1^{old})) 0≤β1new=β2new−(β2old−β1old)≤C=>max(0,β2old−β1old)≤β2new≤min(C,C+(β2old−β1old)) - y 1 y 2 > 0 y_1y_2>0 y1y2>0:
此时存在 β 2 + β 1 β_2+β_1 β2+β1为常数,那么 β 2 n e w + β 1 n e w = β 2 o l d + β 1 o l d β_2^{new}+β_1^{new}=β_2^{old}+β_1^{old} β2new+β1new=β2old+β1old,那么存在:
0 ≤ β 1 n e w = ( β 2 o l d + β 1 o l d ) − β 2 n e w ≤ C = > m a x ( 0 , ( β 2 o l d + β 1 o l d ) − C ) ≤ β 2 n e w ≤ m i n ( C , β 2 o l d + β 1 o l d ) 0≤β_1^{new}=(β_2^{old}+β_1^{old})-β_2^{new}≤C\\=>max(0,(β_2^{old}+β_1^{old})-C)≤β_2^{new}≤min(C,β_2^{old}+β_1^{old}) 0≤β1new=(β2old+β1old)−β2new≤C=>max(0,(β2old+β1old)−C)≤β2new≤min(C,β2old+β1old)
若计算得到的 β 2 n e w β_2^{new} β2new超出了这个范围,那么就置为对应的边界值,记上界为 H H H,下界为 L L L,那么 β β β的更新可以写为:
β n e w = { H , β n e w > H β n e w , L ≤ β n e w ≤ L L , β n e w < L β^{new}=\left\{ \begin{array}{cc} H,\;\;\;\;\;\;β^{new}>H \\ β^{new},\;\;L≤β^{new}≤L\\ L,\;\;\;\;\;\;β^{new}<L \end{array} \right. βnew=⎩ ⎨ ⎧H,βnew>Hβnew,L≤βnew≤LL,βnew<L到这里,就可以完成对一对参数的更新。
1.5.3.b的更新
b b b是超平面的偏置,每次更新参数后,也要改变 b b b。
根据一开始的假设,若一个点为支持向量,存在 y ( w T x + b ) = 1 y(w^Tx+b)=1 y(wTx+b)=1,两边同乘以 y i y_i yi并移项,得到 b = y − w T x b=y-w^Tx b=y−wTx,进一步带入 w T w^T wT,得到:
b j = y j − ∑ i = 1 m y i β i k i , j b_j=y_j-∑_{i=1}^{m}y_iβ_ik_{i,j} bj=yj−i=1∑myiβiki,j带入 j = 1 j=1 j=1得到:
b 1 n e w = y 1 − ∑ i = 1 m y i β i k i , 1 = y 1 − ∑ i = 3 m y i β i k i , 1 − y 1 β 1 n e w k 1 , 1 − y 2 β 2 n e w k 1 , 2 = y 1 − f ( x 1 ) + y 1 β 1 o l d k 1 , 1 + y 2 β 2 o l d k 2 , 1 + b 1 o l d − y 1 β 1 n e w k 1 , 1 − y 2 β 2 n e w k 1 , 2 = − e 1 + y 1 k 1 , 1 ( β 1 o l d − β 1 n e w ) + y 2 k 1 , 2 ( β 2 o l d − β 2 n e w ) + b o l d b_1^{new}=y_1-∑_{i=1}^{m}y_iβ_ik_{i,1}\\ =y_1-∑_{i=3}^{m}y_iβ_ik_{i,1}-y_1β_1^{new}k_{1,1}-y_2β_2^{new}k_{1,2}\\ =y_1-f(x_1)+y_1β_1^{old}k_{1,1}+y_2β_2^{old}k_{2,1}+b_1^{old}-y_1β_1^{new}k_{1,1}-y_2β_2^{new}k_{1,2}\\ =-e_1+y_1k_{1,1}(β_1^{old}-β_1^{new})+y_2k_{1,2}(β_2^{old}-β_2^{new})+b^{old} b1new=y1−i=1∑myiβiki,1=y1−i=3∑myiβiki,1−y1β1newk1,1−y2β2newk1,2=y1−f(x1)+y1β1oldk1,1+y2β2oldk2,1+b1old−y1β1newk1,1−y2β2newk1,2=−e1+y1k1,1(β1old−β1new)+y2k1,2(β2old−β2new)+bold同理可得 b 2 b_2 b2:
b 2 n e w = − e 2 + y 1 k 1 , 2 ( β 1 o l d − β 1 n e w ) + y 2 k 2 , 2 ( β 2 o l d − β 2 n e w ) + b o l d b_2^{new}=-e_2+y_1k_{1,2}(β_1^{old}-β_1^{new})+y_2k_{2,2}(β_2^{old}-β_2^{new})+b^{old} b2new=−e2+y1k1,2(β1old−β1new)+y2k2,2(β2old−β2new)+bold由KKT条件可知,当 β i β_i βi满足 0 < β i ≤ C 0<β_i≤C 0<βi≤C时,此时该点为支持向量,此时可用上式计算,满足 b n e w = b 1 n e w = b 2 n e w b^{new}=b_1^{new}=b_2^{new} bnew=b1new=b2new。否则当 β i = 0 β_i=0 βi=0,两个乘子都在边界上,且两者边界大小不一致,此时 b 1 , b 2 b_1,b_2 b1,b2中间的值就是和KKT条件一致的阈值,SMO选取中间点作为新的阈值,即 b n e w = ( b 1 n e w + b 2 n e w ) / 2 b^{new}=(b_1^{new}+b_2^{new})/2 bnew=(b1new+b2new)/2,总之都是两个的均值。(这里不是很理解,感觉大致意思就是如果两个点都满足满足KKT条件,那么距离中间的超平面距离一定是一样的,所以大小一致,否则要更新?)
简单说一下利用松弛变量证明KKT条件(β和点是否为支持向量的关系)的思路(详细可以参考博客),针对不等式约束,通过添加正数因子将其转为等式约束:
β g ( w ) ≤ 0 = > β ( g ( w ) + a 2 ) = 0 β ≥ 0 g ( w ) = y i ( w T x + b ) − 1 βg(w)≤0=>β(g(w)+a^2)=0\\ \beta≥0\\ g(w)=y_i(w^Tx+b)-1 βg(w)≤0=>β(g(w)+a2)=0β≥0g(w)=yi(wTx+b)−1这个式子会出现在拉格朗日乘子中,求导后可以得到两个有关的公式:
∂ L ∂ a = 2 β a = 0 ∂ L ∂ β = g ( w ) + a 2 = 0 \frac{\partial L}{\partial a}=2βa=0\\ \frac{\partial L}{\partial β}=g(w)+a^2=0 ∂a∂L=2βa=0∂β∂L=g(w)+a2=0要求极值,因此令其为0,可得 β a = 0 βa=0 βa=0,此时有两种情况,分别是 a = 0 a=0 a=0或 β = 0 β=0 β=0
-
a = 0 , β ≠ 0 a=0,β≠0 a=0,β=0,此时 g ( w ) = 0 g(w)=0 g(w)=0,而 g ( w ) = 0 g(w)=0 g(w)=0就表示该点为支持向量。
-
a ≠ 0 , β = 0 a≠0,β=0 a=0,β=0,此时 g ( w ) < 0 g(w)<0 g(w)<0,不是支持向量。
因为 0 ≤ β ≤ C 0≤β≤C 0≤β≤C,因此就可以看做若 0 < β ≤ C 0<β≤C 0<β≤C,也就是不等于0,那么点为支持向量,否则不是支持向量,这也是KKT条件之一。
1.6.线性不可分
前面叙述的前提条件都是线性可分,但是实际情况中很多时候不存在线性可分的结果,那么此时就需要改进原函数使其能够适应这种异常情况。
此部分参考,知乎的详细说明
有两种不可分情况:样本线性不可分和问题线性不可分,前者是由于采样导致,后者是问题本身决定,解决方案分别是软间隔支持向量机(惩罚项)和广义线性化(核函数)。
1.6.1软间隔支撑向量机
未解决样本线性不可分的问题,这种向量机允许少数样本点在支持向量之间,通过加入松弛项 γ \gamma γ来优化求解:
y i ( w T x + b ) ≥ 1 − γ i y_i(w^Tx+b)≥1-γ_i yi(wTx+b)≥1−γi当然,这个值一定是越小越好,因此优化目标可写为:
m i n ( 1 2 ∣ ∣ w ∣ ∣ + C ∑ i = 1 m γ i ) s . t . y i ( w T x + b ) ≥ 1 − γ i min(\frac{1}{2}||w||+C∑_{i=1}^{m}γ_i)\\ s.t. \;y_i(w^Tx+b)≥1-γ_i min(21∣∣w∣∣+Ci=1∑mγi)s.t.yi(wTx+b)≥1−γi
这个 C C C就是惩罚的系数, C ∑ i = 1 m γ i C∑_{i=1}^{m}γ_i C∑i=1mγi为惩罚项,
- C C C越大,那么松弛变量的影响更加倾向于0,那么最终的结果越接近标准的线性支持向量机
- C C C越小,松弛变量可以有较大的影响,此时对于不在支持向量间的点有更高的容忍度。
1.6.2.广义线性化
这一篇写的比较好,举了一些例子
广义线性化主要是将特征映射到更高的维度,解决在根本上无法线性可分的问题,解决方法就是核函数。
可以知道, S V M SVM SVM的求解目标如下:
max β ≥ 0 ( ∑ i = 1 m β i − 1 2 ∑ i , j = 1 m β j β i y j y i x j T x i ) s . t . ∑ i = 1 m y i β i = 0 \max\limits_{β≥0}(∑_{i=1}^{m}β_i-\frac{1}{2}∑_{i,j=1}^{m}β_jβ_iy_jy_ix_j^Tx_i)\\ s.t. \;∑_{i=1}^{m}y_iβ_i=0 β≥0max(i=1∑mβi−21i,j=1∑mβjβiyjyixjTxi)s.t.i=1∑myiβi=0核函数主要是对 x T x x^Tx xTx部分进行替换,核函数需要满足:
φ ( x i ) φ ( x j ) = K ( x i , x j ) φ(x_i)φ(x_j)=K(x_i,x_j) φ(xi)φ(xj)=K(xi,xj)这个表达式左边的意思就是对两个点分别升维后进行点积操作,而右边的 K K K就是核函数,是一个关于 x i , x j x_i,x_j xi,xj的函数。这就相当于可以直接由原来未升维的点 x i , x j x_i,x_j xi,xj得到点积的结果,这样可以大大减少计算量。
常用的核函数有下面几种:
最常用的就是高斯核,这个是一个 n n n维的超圆,但是计算量比较大。(详细的介绍)
2.代码
下面是代码实现的部分,我实现了一个比较简单的版本(没考虑更复杂的核函数等),这里我先看了一遍知乎老哥的实现,然后全程自己写了一遍,最后调试通过了,应该没什么大问题。
下面的左边是初始的优化目标,右边是迭代30轮候的,可以看到基本不变化,也就是收敛了。
下面是对于训练样本的预测,其中加大的双环表示支持向量,绿色的和红色的支持向量应该距离中间的分类超平面有着相同距离。
有个问题是迭代次数设置多了,画出来的超平面有问题,我猜可能是过拟合?不是很清楚,有知道的可以评论区告诉我。
最后给出完整的代码,注释非常详细,大家可以自行体味。
# 尝试复现SVM
import numpy as np
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def load_data():
np.random.seed(0)
x1= np.random.uniform(1,6,(50)).reshape(-1,1)
np.random.seed(100)
x2= np.random.uniform(8,15,(50)).reshape(-1,1)
np.random.seed(100)
y1=1.5*x1+10
y2=1.9*x2-7
np.random.seed(200)
y1 += np.random.uniform(1, 3, (50)).reshape(-1,1)
np.random.seed(300)
y2 += np.random.uniform(2, 10, (50)).reshape(-1,1)
tmp1 = np.hstack((x1,y1,np.ones(50).reshape(-1,1)))
tmp2 = np.hstack((x2,y2,-np.ones(50).reshape(-1,1)))
data = np.vstack((tmp1,tmp2))
idx_list = np.random.choice(100,100,replace=False)
ans = np.zeros((100,3))
for i,idx in enumerate(idx_list):
ans[i]=data[idx]
return ans[:,:-1],ans[:,-1]
class MySVM():
def fit(self,x,y,epochs,C): # 训练
y = y.reshape(-1,1)
samples = x.shape[0] # 样本数,也就是m
features = x.shape[1] # 特征数
print('输入共%d个特征,样本数为%d'%(features,samples))
beta = np.zeros((samples,1)) # β
b = 0 # b
target = np.ones((1, samples)) @ beta
for i in range(samples):
for j in range(samples):
target -= 1 / 2 * beta[i] * beta[j] * y[i] * y[j] + x[i] @ x[j].T
print('初始优化目标:%.2f' % (target))
for epoch in range(epochs):
print('epoch:',epoch+1)
for i in range(samples): # 每次选取i和另一个数j作为更新数对
while True:
j = np.random.choice(samples,1,replace=False)[0] # 随机选择两个要更新的
if j!=i:
break
# print('当前优化,i=%d,j=%d'%(i,j))
w_T = (beta * y).T @ x # w^T=∑βyx=(βyx).T,β、y都是列向量,所以转置
# print(w_T.shape) # (1,2)
# 下面计算β_j^{new},把公式的2对应j,i对应1
k_i_i = x[i]@x[i].T
k_i_j = x[i]@x[j].T
k_j_j = x[j]@x[j].T
K = 2*k_i_j-k_i_i-k_j_j # 计算系数k
fx_i = w_T@x[i].T+b
fx_j = w_T@x[j].T+b
e_i = fx_i-y[i]
e_j = fx_j-y[j]
beta_old_i = beta[i]
beta_old_j = beta[j]
beta_new_j = beta_old_j-y[j]*(e_i-e_j)/K
# 裁剪beta_new_j
if y[i]==y[j]: # 同号
L = max(0,beta_old_i+beta_old_j-C)
H = min(C,beta_old_i+beta_old_j)
if beta_new_j<L:
beta_new_j=L
elif beta_new_j>H:
beta_new_j=H
else:
L = max(0, beta_old_j - beta_old_i)
H = min(C, C + beta_old_j - beta_old_i)
if beta_new_j < L:
beta_new_j = L
elif beta_new_j > H:
beta_new_j = H
# 因为β_1^{old}y_1+β_2^{old}y_2=β_1^{new}y_1+β_2^{new}y_2=γ => β_1^{new}=y_1(γ-β_2^{new}y_2)
# 可以基于此解出beta_new_i,因为上面的裁剪,可以保证下面解出来的一定在[0,C]之间
gamma = (beta_old_i*y[i]+beta_old_j*y[j])
beta_new_i = y[i]*(gamma-beta_new_j*y[j])
# 更新参数b
b_new_i = -e_i+y[i]*k_i_i*(beta_old_i-beta_new_i)+y[j]*k_i_j*(beta_old_j-beta_new_j)+b
b_new_j = -e_j+y[i]*k_i_j*(beta_old_i-beta_new_i)+y[j]*k_j_j*(beta_old_j-beta_new_j)+b
# b = (b_new_i+b_new_j)/2 # 一开始写的,发现好像不对,对照了参考博客
if beta[i] > 0:
b = b_new_i
elif beta[j] > 0:
b = b_new_j
else:
b = (b_new_i+b_new_j)/2
beta[i]=beta_new_i
beta[j]=beta_new_j
# 计算优化目标
target = np.ones((1,samples))@beta
for i in range(samples):
for j in range(samples):
target-=1/2*beta[i]*beta[j]*y[i]*y[j]+x[i]@x[j].T
print('优化目标:%.2f'%(target))
# print(beta)
self.beta = beta
self.w_T = w_T
self.b = b
def predict(self,x):
pred = np.sign(self.w_T@x.T+self.b).reshape(-1,1)
return pred
if __name__ == '__main__':
X,y = load_data() # 产生数据
svm = MySVM()
svm.fit(X,y,epochs=30,C=0.6) # C不知道怎么设置,随便设置一个,参考了博客
res=svm.predict(X)
cnt = 0
for i in range(X.shape[0]):
if res[i] != y[i]:
cnt+=1
print("预测错误%d个"%(cnt))
# 对每个数据点绘制,标出特殊的
beta = svm.beta
for i in range(X.shape[0]):
if res[i]==-1:
plt.scatter(X[i,0],X[i,1],marker='^',s=20,color='g',facecolors='none')
if beta[i]>0.0001: # 支持向量
plt.scatter(X[i,0],X[i,1],marker='^',s=100,color='g',facecolors='none')
else:
plt.scatter(X[i,0],X[i,1],marker='o',s=20,color='r',facecolors='none')
if beta[i]>0.0001: # 支持向量
plt.scatter(X[i,0],X[i,1],marker='o',s=100,color='r',facecolors='none')
# 解出两个在截距,也就是交于x1和x2
w_T = svm.w_T[0]
b=svm.b
b1 = -b/w_T[0] # x1轴
b2 = -b/w_T[1] # x2轴
k = -b2/b1 # y=kx+b,b就是b2
x = np.linspace(min(X[:,0]),max(X[:,0]),1000)
y = k*x+b2
plt.plot(x,y,linestyle='--')
plt.show()
总结一下,机器向量机的数学推导相对来说确实比较繁琐,好几个地方没有看懂,翻了很多博客才大概理解,有的地方我感觉也没有完全参透,在以后的学习中再慢慢体味吧!
下面是主要的参考博客:
1.知乎:SVM的推导和求解,但是感觉前面的推导有点冗余
2.CSDN,也是详解,前面的数学部分整理的很详细,后面的相对不够详细
3.微信,相对简略,省略了很多,前面的讲解比较好
4.知乎,主要是SMO部分,比较详细
5.CSDN,主要是介绍SMO,在α的介绍部分比较容易理解,有代码实现
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)