**支持向量机(SVM-- Support Vector Machine)**是一种非常好的分类算法,是公认的在线性和非线性分类中效果较好的一种分类器。现在有非常多的关于SVM的资料,支持向量机的理论较为复杂,并不是非常容易理解,这里主要介绍支持向量机算法的思想,对于太复杂的公式理论,有些现成的结论就直接进行调用而不再这里进行详细的推导。如果需要进一步了解公式理论的话,可以参考相应的资料。
在收集的数据中,本身知道这些数据的分类,如下红黑点是已知的,利用这些已知的数据来估计未来的一些点,预估的数据并不知道具体的分类,需要通过已知的数据估计出这些点的分类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mApFV2fR-1649987773840)(/images/kuxue/machine_learning/svm1.png)]
在logistic回归中,如果数据符合线性关系可以分为整正类和负类,在已知的红黑点的情况下去确定x,y的线性关系,形成一条直线或为超平面,能够最好的把红黑点分开,算法的思想是把这条直线映射到0,1之间,如果概率大于0.5则为正类,如果小于0.5则为负类。
映射函数为: 1 1 + e θ x \frac{1}{1+e^{\theta x}} 1+eθx1,不管在何值最终规划在0,1下。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VOuJ1xSa-1649987773841)(/images/kuxue/machine_learning/svm2.png)]
在推导最后结论的时候,使用的是极大似然法,也就是最大限度的满足所有点的条件。这里就不展开来说logistic回归了。
回想logistic回归中在极大似然法的时候,使用是所有观察点的乘积,目标函数考虑的是所有的点,但这有没有必要呢?是否可以考虑某些特殊的点,而其他的点只要满足某些条件就可以了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1jPVbEPF-1649987773842)(/images/kuxue/machine_learning/svm3.png)]
一个群组中,有一些点在和另一个群组的区分起到关键的作用。越是互相靠近的不同类的点,分离更开就好。如在红黑两组的数据中,带绿色圈子的点在区分群组里,起到了关键点的作用,支持了两个群组的分类,其他的一些点,只要满足一些条件就可以。如其他所有的红点,只要在两个带圈红点的下方就可行,其他的黑点只要在带圈黑点的上方就可以。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KHDbOiS7-1649987773842)(/images/kuxue/machine_learning/svm4.png)]
这种方式先确定关键的点,其他的点满足某一个条件,只要把关键的点分开,其他的点自然而然就分开了。
跟logistic不一样的是并不需要所有的点都满足某一条件,只需要一些关键点满足特定的严格的条件,而其他点符合一些简单的条件就行。
SVM的算法推导过程,就是在寻找这些特殊点,也就是支持分类的这些点,找到了这些支持点,问题就解决了一大步。
为了比较清楚的写清算法的过程,这里使用的示例为直线分割,用数学的过程来表示SVM的思想。
假设我们已经找到了支持向量的点,如图所示,在这些点上可以找到两条直线分别为:
$\overrightarrow w \bullet \overrightarrow x + b = -1 和 和 和\overrightarrow w \bullet \overrightarrow x + b = +1 , 这 两 条 直 线 可 以 当 做 为 区 分 两 组 数 据 的 边 缘 线 , 这 两 条 直 线 是 平 行 的 , 而 其 他 的 点 符 合 ,这两条直线可以当做为区分两组数据的边缘线,这两条直线是平行的,而其他的点符合 ,这两条直线可以当做为区分两组数据的边缘线,这两条直线是平行的,而其他的点符合\overrightarrow w \bullet \overrightarrow x +b -1 > 0 , 保 证 其 他 的 点 在 直 线 的 两 边 。 这 里 看 似 有 三 个 条 件 , ,保证其他的点在直线的两边。这里看似有三个条件, ,保证其他的点在直线的两边。这里看似有三个条件,\overrightarrow w \bullet \overrightarrow x + b = -1 $ $\overrightarrow w \bullet \overrightarrow x + b = +1 , 和 , 引 入 一 条 中 间 线 为 : ,和,引入一条中间线为: ,和,引入一条中间线为:\overrightarrow w \bullet \overrightarrow x + b =0 , 使 得 特 征 点 到 直 线 ,使得特征点到直线 ,使得特征点到直线\overrightarrow w \bullet \overrightarrow x + b =0 距 离 最 大 , 这 样 表 示 更 容 易 分 开 。 这 样 在 求 解 的 过 程 中 把 三 个 条 件 降 为 了 两 个 条 件 , 条 件 一 : 特 征 点 到 直 线 距离最大,这样表示更容易分开。这样在求解的过程中把三个条件降为了两个条件,条件一:特征点到直线 距离最大,这样表示更容易分开。这样在求解的过程中把三个条件降为了两个条件,条件一:特征点到直线\overrightarrow w \bullet \overrightarrow x + b =0 距 离 最 大 , 条 件 二 : 所 有 的 点 满 足 距离最大,条件二:所有的点满足 距离最大,条件二:所有的点满足\overrightarrow w \bullet \overrightarrow x + b -1 > 0 $。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzlGUYsm-1649987773843)(/images/kuxue/machine_learning/svm5.png)]
用数学的形式来表达条件一,复习一下点到直线的距离:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-usBaBZyu-1649987773844)(/images/kuxue/machine_learning/svm6.png)]
推导的过程,有多种方式,其中一种是通过l直线的斜率确定通过p和他垂直的直线,计算两直线的交点Q,求出P和Q之间的距离即可:
d = ∣ A x 0 + B y 0 + c A 2 + B 2 ∣ d=|\frac{Ax_0+By_0+c}{\sqrt{ A^2+B^2}}| d=∣A2+B2Ax0+By0+c∣
有了点到线的公示后,扩展到其他维数,点到超平面的距离为, d = w → x → + b ∣ ∣ w ∣ ∣ d=\frac{\overrightarrow w \overrightarrow x +b}{||w||} d=∣∣w∣∣wx+b,基础的公式有了以后,可以开始推导SVM了。
支持分类的点在超平面上 d = w → x → + b = − 1 d=\overrightarrow w \overrightarrow x +b = -1 d=wx+b=−1或者 d = w → x → + b = + 1 d=\overrightarrow w \overrightarrow x +b = +1 d=wx+b=+1上,距离可写成
d = ∣ ∣ w → x 1 + b ∣ ∣ ∣ ∣ w ∣ ∣ + ∣ ∣ w → x 2 + b ∣ ∣ ∣ ∣ w ∣ ∣ = 1 ∣ ∣ w ∣ ∣ + ∣ ∣ − 1 ∣ ∣ ∣ ∣ w ∣ ∣ = 2 w d=\frac {||\overrightarrow w x_1 +b ||}{||w||} + \frac {||\overrightarrow w x_2 +b ||}{||w||}=\frac {1}{||w||}+\frac {||-1||}{||w||}=\frac {2}{w} d=∣∣w∣∣∣∣wx1+b∣∣+∣∣w∣∣∣∣wx2+b∣∣=∣∣w∣∣1+∣∣w∣∣∣∣−1∣∣=w2
求解SVM的问题可以转换为:
m a x 2 ∣ ∣ w ∣ ∣ max \frac{2}{||w||} max∣∣w∣∣2
s . t y i ( w x i + b ) ≥ 0 i = 1 , 2 , . . . , N s.t yi(w xi+b) \ge 0 i=1,2,...,N s.tyi(wxi+b)≥0i=1,2,...,N
最大化 2 ∣ ∣ w ∣ ∣ \frac{2}{||w||} ∣∣w∣∣2和最小化 1 2 ∣ ∣ w ∣ ∣ 2 \frac{1}{2}||w||^2 21∣∣w∣∣2是等价的,问题再次变为:
m i n 1 2 ∣ ∣ w ∣ ∣ 2 min \frac{1}{2}||w||^2 min21∣∣w∣∣2
s . t y i ( w x i + b ) ≥ 0 i = 1 , 2 , . . . , N s.t yi(w xi+b) \ge 0 i=1,2,...,N s.tyi(wxi+b)≥0i=1,2,...,N
到这里SVM算法的过程如下:
1.从约束最优化问题求解:
m i n 1 2 ∣ ∣ w ∣ ∣ 2 min \frac {1}{2} ||w||^2 min21∣∣w∣∣2
s . t y i ( w x i + b ) ≥ 0 i = 1 , 2 , . . . , N s.t yi(w xi+b) \ge 0 i=1,2,...,N s.tyi(wxi+b)≥0i=1,2,...,N
求得最优解 w ⋆ , b ⋆ w^\star,b^\star w⋆,b⋆
由此得到分离超平面: w ⋆ ∙ x + b ⋆ = 0 w^\star \bullet x + b^\star = 0 w⋆∙x+b⋆=0
2.分类决策函数:
f ( x ) = s i g n ( w ⋆ ∙ x + b ⋆ ) f(x)=sign(w^\star \bullet x + b^\star ) f(x)=sign(w⋆∙x+b⋆)
求解得到 w ⋆ , b ⋆ w^\star,b^\star w⋆,b⋆,就可以进行分类了,这里只能把结果分为正例和负例,通过sign进行分组。
知道了SVM分类的步骤,但是怎么样求解 w ⋆ , b ⋆ w^\star,b^\star w⋆,b⋆还不清楚,这个过程需要有非常的多数学知识作为支撑,有些推导并不容易,涉及到太多的推导过程,可以参考具体的文献。
推导过程会涉及到拉格朗日函数,KKT条件,对偶问题求解,最后用的是SMO算法。
这里直接给出SMO算法的具体步骤:
最终需要求解的变量是:w和b
初始化 α j , b \alpha_j,b αj,b,其中 α j \alpha_j αj可以看做是各个已知点的权重,权重大的即为支持点。
1:计算误差,其中 x i , y i x_i,y_i xi,yi为观察到的数据点,即为已知的数据。
E i = f ( x i ) − y i = ∑ ( j = 1 ) n α j y j x i x j + b − y i E_i=f(x_i)-y_i = \sum_{(j=1)}^n\alpha _j y_j x_i x_j + b - y_i Ei=f(xi)−yi=(j=1)∑nαjyjxixj+b−yi
2:求得上界H和下界L,其中C为常数
{ L = m a x ( 0 , α j o l d − α i o l d ) , H = m i n ( C , C + α j o l d − α i o l d ) i f y i ≠ y j L = m a x ( 0 , α j o l d + α i o l d − C ) , H = m i n ( C , C + α j o l d + α i o l d ) i f y i = y j \begin{cases} L=max(0,\alpha _j ^{old} - \alpha _i ^{old}),H=min(C,C+\alpha _j ^{old} - \alpha _i ^{old}) if y_i \not= y_j \\ L=max(0,\alpha _j ^{old} + \alpha _i ^{old} -C),H=min(C,C+\alpha _j ^{old} + \alpha _i ^{old}) if y_i = y_j \\ \end{cases} {L=max(0,αjold−αiold),H=min(C,C+αjold−αiold)ifyi=yjL=max(0,αjold+αiold−C),H=min(C,C+αjold+αiold)ifyi=yj
在这里就能比较明显的看出,SMO的算法主要是两个数两个数来算的,$\alpha _i ,\alpha _j $每次算一对数据,不停的迭代。
3:计算中间变量 η \eta η
η = x i T x i + x j T x j − 2 x i T x j \eta = x_i^Tx_i+x_j^Tx_j-2x_i^Tx_j η=xiTxi+xjTxj−2xiTxj
4:更新 α j \alpha _j αj
α j n e w = α j o l d + y i ( E i − E j ) η \alpha _j ^{new}=\alpha _j ^{old}+ \frac {y_i(E_i-E_j)}{\eta} αjnew=αjold+ηyi(Ei−Ej)
5:对 α j \alpha _j αj进行修剪
α n e w , c l i p p e d { H i f α j n e w ≥ H α j n e w i f α j n e w ≤ H L i f α j n e w ≤ L \alpha^{new,clipped}\begin{cases} H \ if \ \alpha _j ^{new} \ge H\\ \alpha _j ^{new} \ if \ \alpha _j ^{new} \le H\\ L \ if \ \alpha _j ^{new} \le L\\ \end{cases} αnew,clipped⎩⎪⎨⎪⎧H if αjnew≥Hαjnew if αjnew≤HL if αjnew≤L
6:更新 α j \alpha _j αj
a i n e w = a i n e w + y i y j ( α j o l d − α j n e w , c l i p p e d ) a_i^{new}=a_i^{new}+y_iy_j(\alpha _j^{old}-\alpha _j^{new,clipped}) ainew=ainew+yiyj(αjold−αjnew,clipped)
7:更新中间变量b1和b2从而更新b:
b 1 n e w = b o l d − E i − y i ( α i n e w − α i o l d ) x i T x i − y i ( α j n e w − α j o l d ) x j T x i b_1^{new}=b^{old}-E_i-y_i(\alpha _i^{new}-\alpha _i^{old})x_i^Tx_i-y_i(\alpha _j^{new}-\alpha _j^{old})x_j^Tx_i b1new=bold−Ei−yi(αinew−αiold)xiTxi−yi(αjnew−αjold)xjTxi
b 2 n e w = b o l d − E i − y i ( α i n e w − α i o l d ) x i T x i − y i ( α j n e w − α j o l d ) x j T x i b_2^{new}=b^{old}-E_i-y_i(\alpha _i^{new}-\alpha _i^{old})x_i^Tx_i-y_i(\alpha _j^{new}-\alpha _j^{old})x_j^Tx_i b2new=bold−Ei−yi(αinew−αiold)xiTxi−yi(αjnew−αjold)xjTxi
则:
b = { b 1 0 < α i n e w < C b 2 0 < α j n e w < C b 1 + b 2 2 o t h e r w i s e b=\begin{cases} b_1 \ 0<\alpha_i^{new}
8:通过不停的迭代得到 α i \alpha_i αi和b,通过 α i \alpha_i αi求得w:
w = ∑ i = 1 N α i y i x i w=\sum_{i=1}{N} \alpha_iy_ix_i w=i=1∑Nαiyixi
这样所有的参数就都能求得。求解的过程就很容易用python进行编写了,这是一段从《机器学习实践》中摘抄的代码,描述了这一个过程。
求解 α i \alpha_i αi和b的过程如下:
def smoSimple(dataMatIn, classLabels, C, toler, maxIter):
dataMatrix = mat(dataMatIn); labelMat = mat(classLabels).transpose()
b = 0; m,n = shape(dataMatrix)
alphas = mat(zeros((m,1)))
iter = 0
while (iter < maxIter):
alphaPairsChanged = 0
for i in range(m):
fXi = float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[i,:].T)) + b
Ei = fXi - float(labelMat[i])#if checks if an example violates KKT conditions
if ((labelMat[i]*Ei < -toler) and (alphas[i] < C)) or ((labelMat[i]*Ei > toler) and (alphas[i] > 0)):
j = selectJrand(i,m)
fXj = float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[j,:].T)) + b
Ej = fXj - float(labelMat[j])
alphaIold = alphas[i].copy(); alphaJold = alphas[j].copy();
if (labelMat[i] != labelMat[j]):
L = max(0, alphas[j] - alphas[i])
H = min(C, C + alphas[j] - alphas[i])
else:
L = max(0, alphas[j] + alphas[i] - C)
H = min(C, alphas[j] + alphas[i])
if L==H: print "L==H"; continue
eta = 2.0 * dataMatrix[i,:]*dataMatrix[j,:].T - dataMatrix[i,:]*dataMatrix[i,:].T - dataMatrix[j,:]*dataMatrix[j,:].T
if eta >= 0: print "eta>=0"; continue
alphas[j] -= labelMat[j]*(Ei - Ej)/eta
alphas[j] = clipAlpha(alphas[j],H,L)
if (abs(alphas[j] - alphaJold) < 0.00001): print "j not moving enough"; continue
alphas[i] += labelMat[j]*labelMat[i]*(alphaJold - alphas[j])#update i by the same amount as j
#the update is in the oppostie direction
b1 = b - Ei- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[i,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[i,:]*dataMatrix[j,:].T
b2 = b - Ej- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[j,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[j,:]*dataMatrix[j,:].T
if (0 < alphas[i]) and (C > alphas[i]): b = b1
elif (0 < alphas[j]) and (C > alphas[j]): b = b2
else: b = (b1 + b2)/2.0
alphaPairsChanged += 1
print "iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged)
if (alphaPairsChanged == 0): iter += 1
else: iter = 0
print "iteration number: %d" % iter
return b,alphas
其中dataMatIn:输入, classLabels:输入的分类, C常数, toler学习率, maxIter最大迭代次数。
接着继续求解:
def calcWs(alphas,dataArr,classLabels):
X = mat(dataArr); labelMat = mat(classLabels).transpose()
m,n = shape(X)
w = zeros((n,1))
for i in range(m):
w += multiply(alphas[i]*labelMat[i],X[i,:].T)
return w
支持点和线性分类如下,w,b确定了线性方程, α i \alpha_i αi确定了支持点。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-025Nx5Z9-1649987773844)(/images/kuxue/machine_learning/svm7.png)]
在推导计算方法的时候,限制了两点,第一:线性可分,第二:只能分为两类,正例和负例。对于非线性和多分类SVM都能够做到。
这是sklearn在SVM的实例,可以直接采用现成的SVM算法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TOy4twuW-1649987773845)(/images/kuxue/machine_learning/svm8.png)]
参考:
1.Fast Training of Support Vector Machines using Sequential Minimal Optimization
2.支持向量机SVM(一)
3.支持向量机