SVM算法是基于统计学习理论的一种机器学习方法,通过寻求结构化风险最小化来提高学习器泛化能力。常用于对小样本、非线性及高维数据进行模式识别、分类以及回归分析。
正例与反例,SVM是个二分类的分类模型。正例和反例分别对应正负样本点,是样本的集合。
超平面,将特征空间划分为正类和负类的分类边界,一般将任何维度的分类边界都统称超平面。
规范超平面,在线性可分时是唯一且必然存在的一种特殊平面,满足
{ y i [ ( w T ⋅ a i ) + b ] ⩾ 0 , m i n ∣ ( w T ⋅ a i ) + b ∣ = 1 , i = 1 , . . . , l \begin{cases} y_i[(w^T\cdot a_i)+b]\geqslant0,\\ min\ |(w^T\cdot a_i)+b|=1, \end{cases} \ i=1,...,l {yi[(wT⋅ai)+b]⩾0,min ∣(wT⋅ai)+b∣=1, i=1,...,l
分类边界,即 ( w ⋅ x ) + b = ± 1 (w\cdot x)+b=\pm1 (w⋅x)+b=±1。
学习的目标就是在特征空间寻找到一个超平面 w T x + b = 0 w^Tx+b=0 wTx+b=0,使之与正样本集合负样本集间距最大,即中间的线最可信。
对于训练集 T T T,若 ∃ ω ∈ R n , b ∈ R n \exist \omega\in R^n,b\in R^n ∃ω∈Rn,b∈Rn和正数 ϵ , \epsilon, ϵ,使得对所有正例都有 w T a i + b ⩾ ϵ w^Ta_i+b\geqslant \epsilon wTai+b⩾ϵ,对所有的反例都有 w T a i + b ⩽ − ϵ w^Ta_i+b\leqslant -\epsilon wTai+b⩽−ϵ,则称训练集 T T T线性可分,称相应的分类问题是线性可分的。
定理 当训练集 T T T线性可分时,存在唯一的规范超平面 ( w T ⋅ x ) + b = 0 (w^T\cdot x)+b=0 (wT⋅x)+b=0,使得
{ ( w ⋅ a i ) + b ⩾ 1 , y i = 1 , ( w ⋅ a i ) + b ⩽ − 1 , y i = 1 。 \begin{cases} (w\cdot a_i)+b\geqslant 1,y_i=1,\\ (w\cdot a_i)+b\leqslant -1,y_i=1。 \end{cases} {(w⋅ai)+b⩾1,yi=1,(w⋅ai)+b⩽−1,yi=1。
满足 ( w T ⋅ a i ) + b = ± 1 (w^T\cdot a_i)+b=\pm1 (wT⋅ai)+b=±1的 a i a_i ai称为普通支持向量。规范超平面与正反例之间的间隔为 1 ∣ w ∣ \frac{1}{|w|} ∣w∣1,正反普通支持向量之间的间隔为 2 ∣ w ∣ \frac{2}{|w|} ∣w∣2。从而求最优超平面的问题就是最大化 2 ∣ w ∣ \frac{2}{|w|} ∣w∣2。于是寻找最优超平面的问题可以转化为如下的二次规划问题:
m i n 1 2 ∣ w ∣ 2 , s . t . y i [ ( w T ⋅ a i ) + b ] ⩾ 1 , i = 1 , . . . , l 。 min\ \frac{1}{2}|w|^2,\\ s.t.\ y_i[(w^T\cdot a_i)+b]\geqslant1,i=1,...,l。 min 21∣w∣2,s.t. yi[(wT⋅ai)+b]⩾1,i=1,...,l。
引入Lagrange函数
L ( w , b , α ) = 1 2 ∣ w ∣ 2 + ∑ i = 1 l α i { 1 − y i [ ( w ⋅ a i ) + b ] } , L(w,b,\alpha)=\frac{1}{2}|w|^2+\sum^l_{i=1}\alpha_i\{1-y_i[(w\cdot a_i)+b]\}, L(w,b,α)=21∣w∣2+i=1∑lαi{1−yi[(w⋅ai)+b]},
式中: α = [ α 1 , . . . , α l ] T ∈ R l + \alpha=[\alpha_1,...,\alpha_l]^T\in R^{l+} α=[α1,...,αl]T∈Rl+为aLagrange乘子。
根据对偶的定义,通过对原问题中各变量的偏导置零,得
∂ L ∂ w = 0 ⟹ w = ∑ i = 1 l α i y i a i , ∂ L ∂ b = 0 ⟹ ∑ i = 1 l α i , \frac{\partial L}{\partial w}=0\ \Longrightarrow \ w=\sum_{i=1}^l\alpha_iy_ia_i,\\ \frac{\partial L}{\partial b}=0\ \Longrightarrow \ \sum_{i=1}^l\alpha_i, ∂w∂L=0 ⟹ w=i=1∑lαiyiai,∂b∂L=0 ⟹ i=1∑lαi,
代入Lagrange函数化为原问题的Lagrange对偶问题:
m a x − 1 2 ∑ i = 1 l ∑ j = 1 l y i y j α i α j ( a i ⋅ a j ) + ∑ i = 1 l α i , s . t . { ∑ i = 1 l y i α i = 0 , α i ⩾ 0 , i = 1 , . . . , l 。 max\ -\frac{1}{2}\sum_{i=1}^l\sum_{j=1}^{l}y_iy_j\alpha_i\alpha_j(a_i\cdot a_j)+\sum_{i=1}^{l}\alpha_i,\\ s.t.\begin{cases} \sum_{i=1}^{l}y_i\alpha_i=0,\\ \alpha_i\geqslant0,i=1,...,l。 \end{cases} max −21i=1∑lj=1∑lyiyjαiαj(ai⋅aj)+i=1∑lαi,s.t.{∑i=1lyiαi=0,αi⩾0,i=1,...,l。
求解上述最优化问题,得到最优解 α ∗ = [ α 1 ∗ , . . . , α l ∗ ] T , \alpha^*=[\alpha_1^*,...,\alpha_l^*]^T, α∗=[α1∗,...,αl∗]T,计算
w ∗ = ∑ i = 1 l α i ∗ y i a i , w^*=\sum_{i=1}^l\alpha_i^*y_ia_i, w∗=i=1∑lαi∗yiai,
由KKT互补条件Link知
α i ∗ { 1 − y i [ ( w ∗ ⋅ a i ) + b ∗ ] } = 0 , \alpha_i^*\{1-y_i[(w^*\cdot a_i)+b^*]\}=0, αi∗{1−yi[(w∗⋅ai)+b∗]}=0,
可得只有当 a i a_i ai为支持向量的时候,对应的 α i ∗ \alpha_i^* αi∗才为正,否则皆为0。选择 α ∗ \alpha^* α∗的一个正分量 α j ∗ , \alpha_j^*, αj∗,并以此计算
b ∗ = y j − ∑ i = 1 l y i α i ∗ ( a i ⋅ a j ) 。 b^*=y_j-\sum_{i=1}^ly_i\alpha_i^*(a_i\cdot a_j)。 b∗=yj−i=1∑lyiαi∗(ai⋅aj)。
%该算法是通过二次规划quadprog函数求解的只能求出omega,b
%https://blog.csdn.net/sinat_32741771/article/details/52882428
clc,clear;
load('SVM.mat');
data=SVM.VarName1(:);
data=[data SVM.VarName2(:)];
label=SVM.VarName3(:);
%输入随情况而改变,这里只给出某种特例
[num_data,d] = size(data);
输入H;%H是个n+1的对角为1的方阵,第n+1是0,n是数据除标签后的维度
f=zeros(n+1,1);
C=-ones(num_data,1);
A=[-label.*data,-label];
D=quadprog(h,f,A,C);
硬间隔支持向量机是一个严格的线性模型,即用一个超平面将数据分隔为两部分。但数据一般情况下很少是严格线性可分的,难以找到一个超平面可以完美地隔开这些数据,即使在训练模型的时候隔开了,当训练集或实际数据落入特征空间后,也很难说会被正确隔开(过拟合)。而且,如果模型把一些噪声当成了支持向量,那也会得到错误的结果。
软间隔支持向量机允许部分样本不满足 y i [ ( ω ⋅ a i ) + b ] ⩾ 1 y_i[(\omega\cdot a_i)+b]\geqslant1 yi[(ω⋅ai)+b]⩾1,并引入松弛变量 ξ i ⩾ 0 , i = 1 , . . . , l 。 \xi_i\geqslant0,i=1,...,l。 ξi⩾0,i=1,...,l。得到软化的松弛条件 y i [ ( ω ⋅ a i ) + b ] ⩾ 1 − ξ i , i = 1 , . . . , l 。 ξ i y_i[(\omega\cdot a_i)+b]\geqslant1-\xi_i,i=1,...,l。\xi_i yi[(ω⋅ai)+b]⩾1−ξi,i=1,...,l。ξi越大样本点越容易满足条件,为此在目标函数中引入惩罚参数 C C C避免 ξ i \xi_i ξi取太大,得到如下二次规划问题:
m i n 1 2 ∣ w ∣ 2 + C ∑ i = 1 l ξ i , s . t . { y i [ ( w T ⋅ a i ) + b ] ⩾ 1 − ξ i , ξ i ⩾ 0 , i = 1 , . . . , l 。 min\ \frac{1}{2}|w|^2+C\sum_{i=1}^l\xi_i,\\ s.t.\begin{cases} y_i[(w^T\cdot a_i)+b]\geqslant1-\xi_i,\\ \xi_i\geqslant0, \ \ \ \ \ i=1,...,l。 \end{cases} min 21∣w∣2+Ci=1∑lξi,s.t.{yi[(wT⋅ai)+b]⩾1−ξi,ξi⩾0, i=1,...,l。
同样的将原问题转换成Lagrange对偶问题:
m a x − 1 2 ∑ i = 1 l ∑ j = 1 l y i y j α i α j ( a i ⋅ a j ) + ∑ i = 1 l α i , s . t . { ∑ i = 1 l y i α i = 0 , 0 ⩽ α i ⩽ C , i = 1 , . . . , l 。 max\ -\frac{1}{2}\sum_{i=1}^l\sum_{j=1}^{l}y_iy_j\alpha_i\alpha_j(a_i\cdot a_j)+\sum_{i=1}^{l}\alpha_i,\\ s.t.\begin{cases} \sum_{i=1}^{l}y_i\alpha_i=0,\\ 0\leqslant\alpha_i\leqslant C,i=1,...,l。 \end{cases} max −21i=1∑lj=1∑lyiyjαiαj(ai⋅aj)+i=1∑lαi,s.t.{∑i=1lyiαi=0,0⩽αi⩽C,i=1,...,l。
求解上述最优化问题,得到最优解 α ∗ = [ α 1 ∗ , . . . , α l ∗ ] T , \alpha^*=[\alpha_1^*,...,\alpha_l^*]^T, α∗=[α1∗,...,αl∗]T,计算
w ∗ = ∑ i = 1 l α i ∗ y i a i , b ∗ = y j − ∑ i = 1 l y i α i ∗ ( a i ⋅ a j ) 。 w^*=\sum_{i=1}^l\alpha_i^*y_ia_i,\\ b^*=y_j-\sum_{i=1}^ly_i\alpha_i^*(a_i\cdot a_j)。 w∗=i=1∑lαi∗yiai,b∗=yj−i=1∑lyiαi∗(ai⋅aj)。
%采用了SMO算法,随机选取α,第一个α是按顺序遍历所有的α,第二个α是在剩下的α中在随机选一个。当第二个α选了iter次还没有发现不满足KKT条件的,就退出循环。同样的,可以用quadprog计算omega,b
clc,clear;
load('SVM.mat');
data=SVM.VarName1(:);
data=[data SVM.VarName2(:)];
label=SVM.VarName3(:);
[num_data,d] = size(data);
alphas=zeros(num_data,1);
b=0;C=10;
iter=0;max_iter=40;
while iter < max_iter
alpha_change = 0;
for i = 1:num_data
pre_Li = (alphas.*label)'*(data*data(i,:)') + b;
Ei = pre_Li - label(i);
if (label(i)*Ei<-0.001 && alphas(i)0.001 && alphas(i)>0)
j = randi(num_data,1);
if j == i
temp = 1;
while temp
j = randi(num_data,1);
if j ~= i
temp = 0;
end
end
end
pre_Lj = (alphas.*label)'*(data*data(j,:)') + b;
Ej = pre_Lj - label(j);
if label(i) ~= label(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));
end
if L==H
continue;end
eta = 2*data(i,:)*data(j,:)'- data(i,:)*data(i,:)' - ...
data(j,:)*data(j,:)';
alphasI_old = alphas(i);
alphasJ_old = alphas(j);
alphas(j) = alphas(j) - label(j)*(Ei-Ej)/eta;
if alphas(j) > H
alphas(j) = H;
elseif alphas(j) < L
alphas(j) = L;
end
if abs(alphas(j) - alphasJ_old)<1e-4
continue;end
alphas(i) = alphas(i) + label(i)*label(j)*(alphasJ_old-alphas(j));
b1 = b - Ei - label(i)*(alphas(i)-alphasI_old)*data(i,:)*data(i,:)'-...
label(j)*(alphas(j)-alphasJ_old)*data(i,:)*data(j,:)';
b2 = b - Ej - label(i)*(alphas(i)-alphasI_old)*data(i,:)*data(j,:)'-...
label(j)*(alphas(j)-alphasJ_old)*data(j,:)*data(j,:)';
if alphas(i)>0 && alphas(i)0 && alphas(j)
参考资料:https://www.jiqizhixin.com/articles/2018-10-17-20
https://blog.csdn.net/sinat_32741771/article/details/52882428