【机器学习入门】推导超级详细,一文讲清楚支持向量机(SVM)【从原理到代码】

news2024/11/15 21:07:37

支持向量机(SVM)是机器学习中非常经典的一个模型,所以我就把这个作为第二个深入学习的机器学习模型,然后发现居然还挺难的(调包侠流下无能泪水)。
参考了很多博客,但是大部分博客都是讲一部分,要么数学部分比较详细,要么后面的推导部分比较详细,本篇汇集了百家之长,其中我也尽量详细通俗给出了我的一些理解,特在此记录一下。
其中可能存在一些错误,或者有些地方我也理解的不到位,在这些地方我都给出了参考博客,可以参考这些博客。

文章目录

  • 1.原理部分
    • 1.1.SVM
    • 1.2.优化目标
    • 1.3.数学知识补充
      • 1.3.1.拉格朗日和kkt
      • 1.3.2.对偶方法
    • 1.4.优化目标转化
    • 1.5.SMO求解β​
      • 1.5.1.不限制β
      • 1.5.2.β裁剪
      • 1.5.3.b的更新
    • 1.6.线性不可分
      • 1.6.1软间隔支撑向量机
      • 1.6.2.广义线性化
  • 2.代码

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+b2 ax+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∣∣w2)最后一步是为了去掉根号,方便计算,其中 ∣ ∣ 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∣∣w2)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=1nλ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=1nλiφi(x)+i=1mβ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=1nλiφi(x)+i=1mβ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^* dp,那么满足:
d ∗ ≥ p ∗ d^*≥p^* dp根据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∣∣w2)s.t.yi(wTx+b)10上面的不等式约束是≥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∣∣w2)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∣∣w2i=1mβ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∣∣w2i=1mβ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. {wL=wi=1myixiβibL=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=1myixiβii=1myiβ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(21wTwi=1mβi[yi(wTxi+b)1])=β0max(21wTwi=1mβiyiwTwbi=1mβiyi+i=1mβi)=β0max(21wTi=1myixiβiwTi=1myixiβi+i=1mβi)=β0max(i=1mβi21wTi=1myixiβ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=1mβi21wTi=1myixiβi)=β0max(i=1mβi21j=1mβjTxjTyjTi=1myixiβi)=β0max(i=1mβi21i,j=1mβ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=1mβi21i,j=1mβjβiyjyixjTxi)s.t.i=1myiβ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=1mβi21i,j=1mβjβiyjyixjTxi)s.t.i=1myiβ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=1mβi21i,j=1mhi,j=β1+β221h1,121h1,221h1,121h2,221i=3mhi,121i=3mh1,i21i=3mhi,221i=3mh2,i+C=β1+β2h1,221h1,121h2,2i=3mh1,ii=3mh2,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+β221k1,1α1221k2,2α2221k1,2α1α2i=3mk1,iβ1βiy1yii=3mk2,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+β221k1,1α1221k2,2α2221k1,2α1α2β1y1i=3mk1,iβiyiβ2y2i=3mk2,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=3mk1,iβiyiv2=i=3mk2,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)+β221k1,1(γβ2y2)221k2,2β22k1,2β2(γβ2y2)y2v1(γβ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) β2W=y1y2+y22k1,1y2(γβ2y2)k2,2α2k1,2γy22k1,2β2+v1y2v2y2=(2k1,2k1,1k2,2)β2+(k1,1k1,2)γy2+y2(v1v2)y2(y1y2)下面的步骤将消除 γ γ γ,计算出更新后的值 β 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=1myiβixiTxj+b=i=1myiβ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,1y2β2oldk2,1bv2=f(x2)y1β1oldk2,1y2β2oldk2,2b这里是 β o l d β^{old} βold是因为这是基于已知的预测值的,所以是上一次的参数,也就是旧参数。
替换掉前面求导得到的式子 v 1 − v 2 v_1-v_2 v1v2
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}) v1v2=f(x1)f(x2)+(k1,1+k2,22k1,2)β2oldy2+γ(k1,2k1,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)) β2W=(2k1,2k1,1k2,2)β2new+(k1,1k1,2)γy2+y2(f(x1)f(x2)+(k1,1+k2,22k1,2)β2oldy2+γ(k1,2k1,1))y2(y1y2)=(2k1,2k1,1k2,2)β2new(2k1,2k1,1k2,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,2k1,1k2,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) β2W=Kβ2newKβ2old+y2(e1e2)要满足极值点,那么 ∂ W ∂ β 2 = 0 \frac{\partial W}{\partial β_2}=0 β2W=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=β2oldy2(e1e2)/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约束条件:

  1. 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)β2newmin(C,C+(β2oldβ1old))
  2. 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)β2newC=>max(0,(β2old+β1old)C)β2newmin(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,βnewHβnew,LβnewLL,βnewL到这里,就可以完成对一对参数的更新。

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=ywTx,进一步带入 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=yji=1myiβ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=y1i=1myiβiki,1=y1i=3myiβiki,1y1β1newk1,1y2β2newk1,2=y1f(x1)+y1β1oldk1,1+y2β2oldk2,1+b1oldy1β1newk1,1y2β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βiC时,此时该点为支持向量,此时可用上式计算,满足 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 aL=2βa=0βL=g(w)+a2=0要求极值,因此令其为0,可得 β a = 0 βa=0 βa=0,此时有两种情况,分别是 a = 0 a=0 a=0 β = 0 β=0 β=0

  1. 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就表示该点为支持向量。

  2. 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=1mγi)s.t.yi(wTx+b)1γi
这个 C C C就是惩罚的系数, C ∑ i = 1 m γ i C∑_{i=1}^{m}γ_i Ci=1mγi为惩罚项,

  1. C C C越大,那么松弛变量的影响更加倾向于0,那么最终的结果越接近标准的线性支持向量机
  2. 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=1mβi21i,j=1mβjβiyjyixjTxi)s.t.i=1myiβ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,在α的介绍部分比较容易理解,有代码实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1606041.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java面试八股之Iterator接口和Iterable接口

1. Java为什么不直接实现Iterator接口&#xff0c;而是实现Iterable? 这道题算是一道比较基础的题&#xff0c;面试官肯定也不是想让回答得多深入&#xff0c;只是考查对迭代器的了解程度&#xff0c;最好是看过源码&#xff0c;实际上迭代器的源码并不难。我们把注释折叠起来…

gpt-6有望成为通用工具

OpenAI CEO山姆奥特曼&#xff08;Sam Altman&#xff09;在最新的博客访谈中&#xff0c;提到gpt-6有望成为通用工具。 奥特曼还认为&#xff0c;目前的模型不够聪明&#xff0c;“使用GPT-2进行科学研究曾被认为是不切实际的想法。而如今&#xff0c;虽然人们使用GPT-4进行科…

C++异常学习

C语言传统的处理错误的方式 传统的错误处理机制&#xff1a; 终止程序&#xff0c;如assert&#xff0c;缺陷&#xff1a;用户难以接受。如发生内存错误&#xff0c;除0错误时就会终止程序。返回错误码&#xff0c;缺陷&#xff1a;需要程序员自己去查找对应的错误。如系统的…

【基础】在GCC中编译和链接不是一个命令

在 GCC&#xff08;GNU Compiler Collection&#xff09;中&#xff0c;编译和链接不是一个命令。编译是将源代码转换为目标代码的过程。它主要进行语法检查、词法分析、生成中间代码等操作。链接是将多个目标文件和库文件组合成一个可执行文件的过程。在 GCC 中&#xff0c;通…

Root mapping definition has unsupported parameters: [all : {analyzer=ik_max_wor

你们好&#xff0c;我是金金金。 场景 我正在使用Springboot整合elasticsearch&#xff0c;在创建索引(分词器) 运行报错&#xff0c;如下 排查 排查之前我先贴一下代码 import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; // 注意这个包SpringBootTe…

利用FFmpeg 转换课程vtt 字幕到 srt字幕

字幕转换工具 经常学习udemy 视频课程的&#xff0c;可能知道&#xff0c;从网络下载的udemy 课程文件里面有时候字幕是vtt 格式的&#xff0c;有时候想导入到百度网盘里面&#xff0c;怎奈百度网盘&#xff0c;不支持vtt 字幕格式。有字幕的时候&#xff0c;会比较好多了。既可…

Ollama、FastGPT大模型RAG知识库结合使用案例

参考: https://ollama.com/download/linux https://doc.fastai.site/docs/intro/ https://blog.csdn.net/m0_71142057/article/details/136738997 https://doc.fastgpt.run/docs/development/custom-models/m3e/ https://concise-eater-d47.notion.site/Ollama-Fastgpt-b170…

# 从浅入深 学习 SpringCloud 微服务架构(二)模拟微服务环境

从浅入深 学习 SpringCloud 微服务架构&#xff08;二&#xff09;模拟微服务环境&#xff08;1&#xff09; 段子手168 1、打开 idea 创建父工程 创建 artifactId 名为 spring_cloud_demo 的 maven 工程。 --> idea --> File --> New --> Project --> Ma…

树莓派使用总结

手上拿到了一块Raspberry Pi 4B板子。研究一下怎么用。 安装系统 直接到官网【Raspberry Pi 】下载在线安装助手 安装好后&#xff0c;打开软件&#xff0c;选择好板子型号、系统、TF卡&#xff0c;一路下一步就行。 树莓派接口 直接查看官方的资料【Raspberry Pi hardwar…

Docker Volume (存储卷)

什么是存储卷? 存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这就意味着&#xff0c;当我们在容器中的这个目录下写入数据时&#xff0c;容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的目录。在宿主机上…

接口压力测试 jmeter--增强篇(二)

前期准备 1. JMeter的插件的安装 下载Jmeter Plugins Manager对插件进行管理 &#xff08;1&#xff09;下载地址&#xff1a;https://jmeter-plugins.org/install/Install/ &#xff08;2&#xff09;下载后&#xff0c;将jar包放到jmeter包目录下/lib/ext目录下 &#xff0…

绝对隔离+底层限制,成就猎鹰蜜罐“牢不可破”的立体化安全

前言 自网络诞生以来&#xff0c;攻击威胁事件层出不穷&#xff0c;网络攻防对抗已成为信息时代背景下的无硝烟战争。然而&#xff0c;传统的网络防御技术如防火墙、入侵检测技术等都是一种敌暗我明的被动防御&#xff0c;难以有效应对攻击者随时随地发起的无处不在的攻击和威胁…

MySQL学习笔记3——条件查询和聚合函数

条件查询和聚合函数 一、条件查询语句二、聚合函数1、SUM&#xff08;&#xff09;2、AVG()、MAX()、MIN()3、COUNT&#xff08;&#xff09; 一、条件查询语句 WHERE 和 HAVING 的区别&#xff1a; WHERE是直接对表中的字段进行限定&#xff0c;来筛选结果&#xff1b;HAVIN…

BUG:vue表单验证校验不报错,必填都有信息,就是不能正常往下进行

vue表单验证未报错却出现异常 框架bug场景解决办法 框架 UI&#xff1a;element-UI 前端&#xff1a;vue2 bug场景 正常表单里面&#xff0c;有的信息要求必填或者加了一些限制&#xff0c;作为校验验证&#xff0c;只有走到校验才会执行其他行为&#xff0c;比如调用保存接…

在 Linux 终端中创建目录

目录 ⛳️推荐 前言 在 Linux 中创建一个新目录 创建多个新目录 创建多个嵌套的子目录 测试你的知识 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站 前言 在本系列的这一部…

微服务之CircuitBreaker断路器

一、概述 1.1背景 在一个分布式系统中&#xff0c;每个服务都可能会调用其它的服务器&#xff0c;服务之间是相互调用相互依赖。假如微服务A调用微服务B和微服务C&#xff0c;微服务B和微服务C又调用其他的微服务。这就是构成所谓“扇出”。 如果扇出的链路上某个微服务的调…

【详细的Kylin使用心得】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

【任务调度】Apache DolphinScheduler快速入门

Apache DolphinScheduler基本概念 概念&#xff1a;分布式、去中心化、易扩展的可视化DAG工作流任务调度系统。 作用&#xff1a;解决数据处理流程中错综复杂的依赖关系&#xff0c;使调度系统在数据处理流程中开箱即用。Apache DolphinScheduler是一款开源的调度工具&#xff…

高仿小米商城用户端

高仿小米商城用户端(分为商城前端&#xff08;tongyimall-vue)和商城后端(tongyimall-api)两部分)&#xff0c;是Vue SpringBoot的前后端分离项目&#xff0c;用户端包括首页门户、商品分类、首页轮播、商品展示、商品推荐、购物车、地址管理、下订单、扫码支付等功能模块。 …

邮箱群组是什么?怎么创建邮箱群组?

在我们群发邮件时&#xff0c;可能会遇到这样的状况&#xff0c;一个个输入邮箱地址效率很低&#xff0c;而且很容易就漏发。而对于一个企业来说&#xff0c;如果出现这样的问题&#xff0c;很有可能会影响公司的业务进展和团队协作。这个时候我们就需要邮箱群组这个功能&#…