1 內容
本文首先介紹SVM的原理,隨後給出SVM的公式推導、並使用Matlab的二次規劃函數進行求解。
2 SVM原理
我們前面學過了線性迴歸和線性分類器。我們來回顧一下。
2.1 線性迴歸
線性迴歸試圖找到一條線,讓每個點在Y方向上離線越接近越好。就是說,每個數據點做一條垂直的線相較於迴歸直線,這些線段(圖中紅色線段)的長度的平方和最小就是要最優化的函數。如圖。
我們要找到一個合適的w和b使得$J(w,b)最小。
2.2 線性分類器
再回顧一下線性分類器。設有數據集
我們的目標是想找出一條線
這個公式的意義在於, 當y_i爲1的時候,
找到這樣一組w和b後,將新的數據x帶入
2.3 SVM
滿足線性分類器條件的線有很多種,那麼哪一種是最好的呢? 我們應當如何評價一個線是好還是壞呢?
上圖中給出了同一組數據的三種劃分方式。每一種劃分方式都可以達到100%的分類準確率。但他們應對誤差的能力是不同的。在實際問題中,採集數據是有誤差的。那麼哪一個劃分方法能更好的應對誤差呢? 可以看到是第三組圖。第三組圖有什麼特徵呢? 分割帶最胖!
我們如何用數學來描述“分隔帶最胖”這個說法? 每個點都與分割線(或者分割平面)有一個距離。所有點中距離的最小值如果最大,那麼這就是分隔帶最胖。在圖三中,兩個x和一個o是距離分割線最近的,他們距離分割線最遠,那麼這個分割線就是最優的分割線。
這個選取“最胖”的線作爲分割線(分割面)的方法就是支持向量機。
3 公式推導
3.1 點到直線的距離
設有
兩式相減,得到
因爲x’和x”都是超平面上的點,那麼x’-x”這個向量就是超平面上的向量。 這個向量與w^T的內積爲0,說明w和x’-x” 相互垂直,
任意一點x到平面的距離 就是 x-x’這個向量在w方向上的投影的長度。如圖
對於可以正確分類的超平面,都滿足線性分類器的條件,即
那麼就可以去掉上述公式中的絕對值。
上述“最胖”的概念就可以用下面的公式表示
假定距離超平面最近的點爲
有
所以,不失一般性,可以認爲對於距離最近的點
上述條件中,
另外,
這樣我們就得到了
我們不喜歡
這個
這個東西就是一個二次規劃問題,我們就可以用二次規劃工具求解了。
轉化爲二次規劃的標準型
二次規劃的標準型爲以下形式
將SVM公式,轉化爲上述形式,令u爲w的增廣形式
舉個例子
H = [
0 0 0 ;
0 1 0 ;
0 0 1
]
這樣
令
讓一次項爲0。
matlab的 quadprog
quadprog Quadratic programming.
X = quadprog(H,f,A,b) attempts to solve the quadratic programming
problem:
min 0.5*x'*H*x + f'*x subject to: A*x <= b
x
X = quadprog(H,f,A,b,Aeq,beq) solves the problem above while
additionally satisfying the equality constraints Aeq*x = beq.
X = quadprog(H,f,A,b,Aeq,beq,LB,UB) defines a set of lower and upper
bounds on the design variables, X, so that the solution is in the
range LB <= X <= UB. Use empty matrices for LB and UB if no bounds
exist. Set LB(i) = -Inf if X(i) is unbounded below; set UB(i) = Inf if
X(i) is unbounded above.
X = quadprog(H,f,A,b,Aeq,beq,LB,UB,X0) sets the starting point to X0.
X = quadprog(H,f,A,b,Aeq,beq,LB,UB,X0,OPTIONS) minimizes with the
default optimization parameters replaced by values in the structure
OPTIONS, an argument created with the OPTIMSET function. See OPTIMSET
for details.
X = quadprog(PROBLEM) finds the minimum for PROBLEM. PROBLEM is a
structure with matrix 'H' in PROBLEM.H, the vector 'f' in PROBLEM.f,
the linear inequality constraints in PROBLEM.Aineq and PROBLEM.bineq,
the linear equality constraints in PROBLEM.Aeq and PROBLEM.beq, the
lower bounds in PROBLEM.lb, the upper bounds in PROBLEM.ub, the start
point in PROBLEM.x0, the options structure in PROBLEM.options, and
solver name 'quadprog' in PROBLEM.solver. Use this syntax to solve at
the command line a problem exported from OPTIMTOOL. The structure
PROBLEM must have all the fields.
[X,FVAL] = quadprog(H,f,A,b) returns the value of the objective
function at X: FVAL = 0.5*X'*H*X + f'*X.
[X,FVAL,EXITFLAG] = quadprog(H,f,A,b) returns an EXITFLAG that
describes the exit condition of quadprog. Possible values of EXITFLAG
and the corresponding exit conditions are
All algorithms:
1 First order optimality conditions satisfied.
0 Maximum number of iterations exceeded.
-2 No feasible point found.
-3 Problem is unbounded.
Interior-point-convex only:
-6 Non-convex problem detected.
Trust-region-reflective only:
3 Change in objective function too small.
-4 Current search direction is not a descent direction; no further
progress can be made.
Active-set only:
4 Local minimizer found.
-7 Magnitude of search direction became too small; no further
progress can be made. The problem is ill-posed or badly
conditioned.
[X,FVAL,EXITFLAG,OUTPUT] = quadprog(H,f,A,b) returns a structure
OUTPUT with the number of iterations taken in OUTPUT.iterations,
maximum of constraint violations in OUTPUT.constrviolation, the
type of algorithm used in OUTPUT.algorithm, the number of conjugate
gradient iterations (if used) in OUTPUT.cgiterations, a measure of
first order optimality (large-scale algorithm only) in
OUTPUT.firstorderopt, and the exit message in OUTPUT.message.
[X,FVAL,EXITFLAG,OUTPUT,LAMBDA] = quadprog(H,f,A,b) returns the set of
Lagrangian multipliers LAMBDA, at the solution: LAMBDA.ineqlin for the
linear inequalities A, LAMBDA.eqlin for the linear equalities Aeq,
LAMBDA.lower for LB, and LAMBDA.upper for UB.
See also linprog, lsqlin.
Reference page in Help browser
doc quadprog
matlab求解SVM
function test_svm()
t1 = 5+4*randn(2,10);
t2 = 20+4*randn(2,10);
X = [t1 t2]
X = [t1 t2];
Y = [ones(10,1) ; -ones(10,1)]
plot(t1(1,:),t1(2,:),'ro');
hold on;
plot(t2(1,:),t2(2,:),'bx');
u = svm(X,Y)
x = [-u(1)/u(2) , 0];
y = [0 , -u(1)/u(3)];
plot(x,y);
end
function u = svm( X,Y )
%SVM Summary of this function goes here
% Detailed explanation goes here
[K,N] = size(X);
u0= rand(K+1,1); % u= [b ; w];
A = - repmat(Y,1,K+1).*[ones(N,1) X'];
b = -ones(N,1);
H = eye(K);
H = [zeros(1,K);H];
H = [zeros(K+1,1) H];
p = zeros(K+1,1);
lb = -10*ones(K+1,1);
rb = 10*ones(K+1,1);
options = optimset; % Options是用來控制算法的選項參數的向量
options.LargeScale = 'off';
options.Display = 'off';
options.Algorithm = 'active-set';
[u,val] = quadprog(H,p,A,b,[],[],lb,rb,u0,options)
end
ans =
-0.7964 6.3340
6.5654 6.8067
4.4789 5.7348
3.0954 8.4481
-0.4468 6.8201
1.6052 3.6605
7.2111 9.1564
0.5294 10.0426
7.6406 4.7285
4.2191 4.1296
18.7876 20.0922
20.2052 23.3043
26.1079 21.8677
19.1611 22.5008
20.7329 15.8809
23.7969 21.2282
20.5407 22.0610
21.0456 16.2341
19.3506 19.4158
17.8720 26.7284
Y =
1
1
1
1
1
1
1
1
1
1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
Optimization terminated.
u =
2.3951
-0.1186
-0.0590
val =
0.0088
感想
這個程序看起來非常的簡單,但也調試了好久,主要是當時
不足
其一、 這是一個線性分類器,對於線性不可分的情況不能解決。那麼怎麼辦呢? 將當前的x,通過一個函數映射到其他空間,使得在新的空間線性可分。如上圖左,使用一個圓可以很簡單的將黑色的×和紅色的圈分隔開,但圓不是線性的。樣本
其二、這個分類器不允許有錯誤,要求必須每一個數據都分對,如果找不到這樣的線,那麼就不能得到正確的解。 實際問題中,常常因爲數據採集誤差,或者模型本身問題而無法達到所有數據都正確分類的結果。如右圖中,有一個×在右上角,不論選取何種曲線,都無法將其線性分類,所以最好的辦法就是對少量錯誤視而不見。這時候就需要一個軟分隔的SVM,它應能容忍少量的錯誤。
這兩個問題都會在後續的博客中解釋。