matlab-SVM(支持向量機)—轉


http://blog.csdn.net/jiejinquanil/article/details/52270178(機器學習常用算法總結

http://www.jianshu.com/p/55a67c12d3e9(輕松看懂機器學習十大常用算法)

機器學習&數據挖掘筆記_16(常見面試之機器學習算法思想簡單梳理)

http://www.cnblogs.com/darkknightzh/p/5554551.html

http://www.cnblogs.com/lwflourish/p/4121892.html

http://blog.csdn.net/u010412719/article/details/46794051

http://blog.sina.com.cn/s/blog_631a4cc40101df0f.html

http://blog.csdn.net/wenyusuran/article/details/35987813

http://blog.sina.com.cn/s/blog_71152aa70101tl62.html

 

可分離數據:SVM可以用於將已知數據分為兩類,SVM分類器主要是找到兩類之間最佳的超平面,將兩類徹底分開,

  1.   用已知數據去訓練SVM分類器
SVMstruct =svmtrain(data,groups,'Kernel_Function','rbf');

data :數據點矩陣,每一行代表一個觀測對象,每一列代表每一個觀測對象提取的特征;

groups:

kernel_Function:默認為用超平面將數據線性分開.’rbf’用了高斯徑向基函數;建議首先用‘rbf’嘗試;

SVMstruct的結果結構體包含從SVM算法中獲得的最佳參數值,因而可以用於將一些新的數據分開; 

2.將待測數據用SVM分類器分開:

newClasses=svmclassify(SVMstruct,newData)

newClasses 產生的結果代表了在新數據里面每一行的分類;

3.調整SVM分類器

Hsu,chang and Lin建議遵循如下的方案,調整分類器的參數:

1. 首先使用‘rbf’kernel 函數;

2. 嘗試使用不同的參數進行訓練,然后通過交叉檢驗驗證得到的最合適的參數

3. 最重要的嘗試改變的參數:

boxconstraint-盡量以等比數列的方式去調整約束參數值;

rbf-sigma-盡量以等比數列的方式去調整RBF的sigma約束參數值;

4. 不同的參數設置,通過交叉檢驗去檢測結果,通過crossval

5. 當獲得合理的初始化參數值時,你可能想要重新定義你的參數去火的更加好的准確率,以更加小的等比的公因子,去調整參數,最優化你的參數,通過fminsearch,

 

 

支持向量機(SVM)的matlab的實現

支持向量機是一種分類算法之一,matlab中也有相應的函數來對其進行求解;下面貼一個小例子,這個例子來源於我們實際的項目。

clc;
clear;
N=10; %下面的數據是我們實際項目中的訓練樣例(樣例中有8個屬性) correctData=[0,0.2,0.8,0,0,0,2,2]; errorData_ReversePharse=[1,0.8,0.2,1,0,0,2,2]; errorData_CountLoss=[0.2,0.4,0.6,0.2,0,0,1,1]; errorData_X=[0.5,0.5,0.5,1,1,0,0,0]; errorData_Lower=[0.2,0,1,0.2,0,0,0,0]; errorData_Local_X=[0.2,0.2,0.8,0.4,0.4,0,0,0]; errorData_Z=[0.53,0.55,0.45,1,0,1,0,0]; errorData_High=[0.8,1,0,0.8,0,0,0,0]; errorData_CountBefore=[0.4,0.2,0.8,0.4,0,0,2,2]; errorData_Local_X1=[0.3,0.3,0.7,0.4,0.2,0,1,0]; sampleData=[correctData;errorData_ReversePharse;errorData_CountLoss;errorData_X;errorData_Lower;errorData_Local_X;errorData_Z;errorData_High;errorData_CountBefore;errorData_Local_X1];%訓練樣例 type1=1;%正確的波形的類別,即我們的第一組波形是正確的波形,類別號用 1 表示 type2=-ones(1,N-2);%不正確的波形的類別,即第2~10組波形都是有故障的波形,類別號用-1表示 groups=[type1 ,type2]';%訓練所需的類別號 j=1; %由於沒有測試數據,因此我將錯誤的波形數據輪流從訓練樣例中取出作為測試樣例 for i=2:10 tempData=sampleData; tempData(i,:)=[]; svmStruct = svmtrain(tempData,groups); species(j) = svmclassify(svmStruct,sampleData(i,:)); j=j+1; end species

輸出結果如下:

 -1 -1 -1 -1 -1 -1 -1 1 -1

從結果可以看出:只有第九個被誤判,其它的都是正確的。

上面只是用於說明matlab中支持向量機中函數的用法,因為在訓練集中我只用了一個正確的波形和九組有故障的波形作為訓練集,因此這種超平面的選取可能不好。但是,在我們的實際的項目中,我們是用到了許多的訓練集的。

上面是調用matlab中的函數實現多維屬性中的支持向量機對其進行分類。

下面是自己實現此功能,不調用matlab中的支持向量機的函數。代碼如下:

%主函數 clear all; clc; C = 10; kertype = 'linear'; %訓練樣本 n = 50; randn('state',6);%可以保證每次每次產生的隨機數一樣 x1 = randn(2,n); %2行N列矩陣 y1 = ones(1,n); %1*N個1 x2 = 5+randn(2,n); %2*N矩陣 y2 = -ones(1,n); %1*N個-1 figure; plot(x1(1,:),x1(2,:),'bx',x2(1,:),x2(2,:),'k.'); axis([-3 8 -3 8]); xlabel('x軸'); ylabel('y軸'); hold on; X = [x1,x2]; %訓練樣本d*n矩陣,n為樣本個數,d為特征向量個數,在這里,X為一個2*100的數組 Y = [y1,y2]; %訓練目標1*n矩陣,n為樣本個數,值為+1或-1,在這里,Y為一個1*100的數組 svm = svmTrain(X,Y,kertype,C); plot(svm.Xsv(1,:),svm.Xsv(2,:),'ro'); %測試 [x1,x2] = meshgrid(-2:0.05:7,-2:0.05:7); %x1和x2都是181*181的矩陣 [rows,cols] = size(x1); nt = rows*cols; Xt = [reshape(x1,1,nt);reshape(x2,1,nt)]; Yt = ones(1,nt); result = svmTest(svm, Xt, Yt, kertype); Yd = reshape(result.Y,rows,cols); contour(x1,x2,Yd,'m'); 

訓練集函數如下:

function svm = svmTrain(X,Y,kertype,C) options = optimset; % Options是用來控制算法的選項參數的向量 options.LargeScale = 'off';%LargeScale指大規模搜索,off表示在規模搜索模式關閉 options.Display = 'off';%這樣設置意味着沒有輸出 n = length(Y);%數組Y的長度 H = (Y'*Y).*kernel(X,X,kertype);%調用kernel函數, f = -ones(n,1); %f為1*n個-1,f相當於Quadprog函數中的c A = []; b = []; Aeq = Y; %相當於Quadprog函數中的A1,b1 beq = 0; lb = zeros(n,1); %相當於Quadprog函數中的LB,UB ub = C*ones(n,1); a0 = zeros(n,1); % a0是解的初始近似值 [a,fval,eXitflag,output,lambda] = quadprog(H,f,A,b,Aeq,beq,lb,ub,a0,options); epsilon = 1e-8; sv_label = find(abs(a)>epsilon); %0<a<a(max)則認為x為支持向量 svm.a = a(sv_label); svm.Xsv = X(:,sv_label); svm.Ysv = Y(sv_label); svm.svnum = length(sv_label); %svm.label = sv_label;

 

核函數如下:

function K = kernel(X,Y,type) %X 維數*個數 switch type case 'linear' K = X'*Y; case 'rbf' delta = 5; delta = delta*delta; XX = sum(X'.*X',2);%sum(a,2)代碼中參數2的意思是將a矩陣a中的按“行”為單位進行求和 YY = sum(Y'.*Y',2); XY = X'*Y; K = abs(repmat(XX,[1 size(YY,1)]) + repmat(YY',[size(XX,1) 1]) - 2*XY); K = exp(-K./delta); end

測試函數如下

function result = svmTest(svm, Xt, Yt, kertype) temp = (svm.a'.*svm.Ysv)*kernel(svm.Xsv,svm.Xsv,kertype); total_b = svm.Ysv-temp; b = mean(total_b); w = (svm.a'.*svm.Ysv)*kernel(svm.Xsv,Xt,kertype); result.score = w + b; Y = sign(w+b); result.Y = Y; result.accuracy = size(find(Y==Yt))/size(Yt);

要說明的是,上面的代碼是實現的關於我們樣本只有2個屬性的情況;當我們的樣本用多個屬性時,我們需要修改部分代碼即可。

 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

學習支持向量機SVM及其代碼

學習支持向量機SVM及其代碼

    先簡要說一下支持向量機(support vector machine, SVM)吧。感知機(perceptron)是二分類的線性模型,但是由於不同初值或選取不同的樣本順序,解是不同的,也就是不唯一的。在此基礎上svm引入間隔最大化(margin maximization)不僅是樣本更容易分開,而且解是唯一的。之后,為了容忍奇異點(outlier)引入松弛變量(slack variable)(注:引入松弛變量之后w依然是唯一的,但是b不是唯一的)。但是並不是所有問題都是線性的,所以用kernel track變成非線性模型。
     在求解SVM的時候一般都用其對偶形式,主要有兩個優點,其一提供了一種方便的方法去解決約束問題,其二對偶問題中的點積能夠很好地處理kernel function。而這個對偶函數又是一個二次規划問題。所以我們可以說求解SVM的本質就是在再生核希爾伯特空間(RKHS)上的二次優化問題。
     如果你想詳細了解,我建議看《支持向量機——理論、算法與拓展》鄧乃揚 田英傑著。
     這篇博文的主要是目的是把svm的matlab代碼貼出來,供大家學習,代碼有一部分是在網上找的一部分是我寫的,解二次規划是用matlab的自帶函數。把下面的代碼直接復制就可運行,能夠提高你對svm的理解。運行以下程序就能得到上面的圖。
 
%主函數
clear all;
close all;
C = 10;
kertype = 'linear';
%訓練樣本
n = 50;
randn('state',6);
x1 = randn(2,n);    %2行N列矩陣
y1 = ones(1,n);       %1*N個1
x2 = 5+randn(2,n);   %2*N矩陣
y2 = -ones(1,n);      %1*N個-1
 
figure;
plot(x1(1,:),x1(2,:),'bx',x2(1,:),x2(2,:),'k.'); 
axis([-3 8 -3 8]);
hold on;
 
X = [x1,x2];        %訓練樣本d*n矩陣,n為樣本個數,d為特征向量個數
Y = [y1,y2];        %訓練目標1*n矩陣,n為樣本個數,值為+1或-1
svm = svmTrain(X,Y,kertype,C);
plot(svm.Xsv(1,:),svm.Xsv(2,:),'ro');
 
%測試
[x1,x2] = meshgrid(-2:0.05:7,-2:0.05:7);  %x1和x2都是181*181的矩陣
[rows,cols] = size(x1);  
nt = rows*cols;                  
Xt = [reshape(x1,1,nt);reshape(x2,1,nt)];
Yt = ones(1,nt);
result = svmTest(svm, Xt, Yt, kertype);
 
Yd = reshape(result.Y,rows,cols);
contour(x1,x2,Yd,'m');
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function svm = svmTrain(X,Y,kertype,C)
 
options = optimset;    % Options是用來控制算法的選項參數的向量
options.LargeScale = 'off';
options.Display = 'off';
 
n = length(Y);
H = (Y'*Y).*kernel(X,X,kertype);
f = -ones(n,1); %f為1*n個-1,f相當於Quadprog函數中的c
A = [];
b = [];
Aeq = Y; %相當於Quadprog函數中的A1,b1
beq = 0;
lb = zeros(n,1); %相當於Quadprog函數中的LB,UB
ub = C*ones(n,1);
a0 = zeros(n,1);  % a0是解的初始近似值
[a,fval,eXitflag,output,lambda]  = quadprog(H,f,A,b,Aeq,beq,lb,ub,a0,options);
 
epsilon = 1e-8;                     
sv_label = find(abs(a)>epsilon);  %0<a<a(max)則認為x為支持向量     
svm.a = a(sv_label);
svm.Xsv = X(:,sv_label);
svm.Ysv = Y(sv_label);
svm.svnum = length(sv_label);
%svm.label = sv_label;
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function result = svmTest(svm, Xt, Yt, kertype)
temp = (svm.a'.*svm.Ysv)*kernel(svm.Xsv,svm.Xsv,kertype);
total_b = svm.Ysv-temp;
b = mean(total_b);
w = (svm.a'.*svm.Ysv)*kernel(svm.Xsv,Xt,kertype);
result.score = w + b;
Y = sign(w+b);
result.Y = Y;
result.accuracy = size(find(Y==Yt))/size(Yt);
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function K = kernel(X,Y,type)
%X 維數*個數
switch type
case 'linear'
    K = X'*Y;
case 'rbf'
    delta = 5;
    delta = delta*delta;
    XX = sum(X'.*X',2);
    YY = sum(Y'.*Y',2);
    XY = X'*Y;
    K = abs(repmat(XX,[1 size(YY,1)]) + repmat(YY',[size(XX,1) 1]) - 2*XY);
    K = exp(-K./delta);
end

 

第八講. 支持向量機進行機器學習——Support Vector Machine

 

===============================

(一)、SVM 的 Cost Function

(二)、SVM —— Large Margin Classifier

(三)、數學角度解析為什么SVM 能形成 Large Margin Classifier(選看)

(四)、SVM Kernel 1 —— Gaussian Kernel

(五)、SVM 中 Gaussian Kernel 的使用

(六)、SVM的使用與選擇

 

 

本章內容為支持向量機Support Vector Machine(SVM)的導論性講解,在一般機器學習模型的理解上,引入SVM的概念。原先很多人,也包括我自己覺得SVM是個很神奇的概念,讀完本文你會覺得,其實只是擁有不同的目標函數, 不同的模型而已,Machine Learning的本質還沒有變,呵呵~

完成本文花了我很長時間,為了搞懂后面還有程序方便和參考網站大家實驗,希望對大家有所幫助。

 

 

 

=====================================

(一)、SVM 的 Cost Function

 

前面的幾章中我們分別就linear regressionlogistic regression以及神經網絡的cost function進行了講解。這里我們通過logistic regression的cost function引入SVM。

首先回憶一下logistic regression的模型:

 

還是原先的假設,suppose我們只有兩個類,y=0和y=1。那么根據上圖h(x)的圖形我們可以看出,

當y=1時,希望h(x)≈1,即z>>0;

當y=0時,希望h(x)≈0,即z<<0;

那么邏輯回歸的cost function公式如下:

cost function我們之前已經講過了,這里不予贅述。現在呢,我們來看看下面的兩幅圖,這兩幅圖中灰色的curve是logistic regression的cost function分別取y=1和y=0的情況,

y=1時,隨着z↑,h(x)逐漸逼近1,cost逐漸減小。

y=0時,隨着z↓,h(x)逐漸逼近0,cost逐漸減小。

這正是圖中灰色曲線所示的曲線。

ok,現在我們來看看SVM中cost function的定義。請看下圖中玫瑰色的曲線,這就是我們希望得到的cost function曲線,和logistic regression的cost function非常相近,但是分為兩部分,下面呢,我們將對這個cost function進行詳細講解。

logistic regression的cost function:

現在呢,我們給出SVM的目標函數(cost function)定義:

該式中,cost0和cost1分別對應y=0和y=1時的目標函數定義,最后一項regularization項和logistic regression中的類似。感覺系數少了什么?是的,其實它們的最后一項本來是一樣的,但是可以通過線性變換化簡得到SVM的歸一化項。

 

 

 

 

 

=====================================

(二)、SVM —— Large Margin Classifier

 

本節給出一個簡單的結論——SVM是一個large margin classifier。什么是margin呢?下面我們做詳細講解,其理論證明將在下一節中給出。

 

在引入margin之前,我們回顧一下上一節中的SVM cost function curve,如下圖所示分別是y取1和0時的情況。先給出一個結論,常數C取一個很大的值比較好(比如100000),這是為什么呢?

我們來看哈,C很大,就要求[]中的那部分很小(令[]中的那部分表示為W),不如令其為0,這時來分析里面的式子:

※需求1:

y=1時,W只有前一項,令W=0,就要求Cost1Tx)=0,由右圖可知,這要求θTx>=1;

y=0時,W只有后一項,令W=0,就要求Cost0Tx)=0,由右圖可知,這要求θTx<=-1;

 

由以上說明可知,對C的取值應該在分類是否犯錯和margin的大小上做一個平衡。那么C取較大的值會帶來什么效果呢?就是我們開頭說的結論——SVM是一個large margin classifier。那么什么是margin?在第三章中我們已經講過了decision boundary,它是能夠將所有數據點進行很好地分類的h(x)邊界。如下圖所示,我們可以把綠線、粉線、藍線或者黑線中的任意一條線當做decision boundary,但是哪一條最好呢?這里我們可以看出,綠色、粉色、藍色這三類boundary離數據非常近,i.e.我們再加進去幾個數據點,很有可能這個boundary就能很好的進行分類了,而黑色的decision boundary距離兩個類都相對較遠,我們希望獲得的就是這樣的一個decision boundary。margin呢,就是將該boundary進行平移所得到的兩條藍線的距離,如圖中所指。

相對比:

C小,decision boundary則呈現為黑線;若C很大,就呈現粉線;

這個結論大家可以記住,也可以進行數學上的分析,下一節中我們將從數學角度分析,為什么SVM選用大valeu的C會形成一個large margin classifier。


再給出一個數學上對geometry margin的說明:

任意一個點x到分類平面的距離γ的表示如上圖所示,其中y是{+1,-1}表示分類結果,x0是分類面上距x最短的點,分類平面的方程為wx+b=0,將x0帶入該方程就有上面的結果了。對於一個數據集x,margin就是這個數據及所有點的margin中離hyperplane最近的距離,SVM的目的就是找到最大margin的hyperplane。

 

 

練習:

 

 

 

 

 

 

=====================================

(三)、數學角度解析為什么SVM 能形成 Large Margin Classifier(選看)

 

這一節主要為了證明上一節中的結論,為什么SVM是Large Margin Classification,能形成很好的decision boundary,如果僅僅處於應用角度考慮的朋友可以略過此節。

首先我們來看兩個向量內積的表現形式。假設向量uv均為二維向量我們知道u,v的內積uTv=u1v1+u2v2。表現在坐標上呢,就如下圖左邊所示:

首先將v投影至u向量,記其長度為p(有正負,與u同向為正,反相為負,標量),則兩向量的內積uTv = ||u|| · ||v|| · cosθ = ||u|| · p = u1v1+u2v2。

 

 

這樣一來,我們來看SVM的cost function:

由於將C設的很大,cost function只剩下后面的那項。采取簡化形式,意在說明問題即可,設θ0=0,只剩下θ1和θ2

則cost function J(θ)=1/2×||θ||^2

 


而根據上面的推導,有θTx=p·||θ||,其中p是x在θ上的投影,則

※需求2:

y=1時,W只有前一項,令W=0,就要求Cost1Tx)=0,由右圖可知,這要求p·||θ||>=1;

 

y=0時,W只有后一項,令W=0,就要求Cost0Tx)=0,由右圖可知,這要求p·||θ||<=-1;

如下圖所示:

 

 

我們集中精力看為什么SVM的decision boundary有large margin(這里稍微有點兒復雜,好好看哈):

對於一個給定數據集,依舊用X表示正樣本,O表示負樣本,綠色的線表示decision boundary,藍色的線表示θ向量的方向,玫瑰色表示數據在θ上的投影。

我們已知boundary的角度和θ向量呈的是90°角(自己畫一下就知道了)。

先看這個圖,對於這樣一個decision boundary(沒有large margin),θ與其呈90°角如圖所示,這樣我們可以畫出數據集X和O在θ上的投影,如圖所示,非常小;如果想滿足[需求2]中說的

對正樣本p·||θ||>=1,

對負樣本p·||θ||<=-1,

就需要令||θ||很大,這就和cost function的願望(min 1/2×||θ||^2)相違背了,因此SVM的不出來這個圖中所示的decision boundary結果。

 

那么再來看下面這個圖,

它選取了上一節中我們定義的“比較好的”decision boundary,兩邊的margin都比較大。看一下兩邊數據到θ的投影,都比較大,這樣就可以使||θ||相對較小,滿足SVM的cost function。因此按照SVM的cost function進行求解(optimization)得出的decision boundary一定是有large margin的。說明白了吧?!

練習:

分析:由圖中我們可以看出,decision boundary的最優解是y=x1,這時所有數據集中的數據到θ上的投影最小值為2,換言之,想滿足

 

對正樣本p·||θ||>=1,

對負樣本p·||θ||<=-1,

只需要

對正樣本2·||θ||>=1,

對負樣本(-2)·||θ||<=-1,

因此需要||θ||>=1/2,本着令cost function最小的原則,我們可知||θ||=1/2.

 

 

 

 

 

=====================================

(四)、SVM Kernel 1 —— Gaussian Kernel

 

對於一個非線性Decision boundary,我們之前利用多項式擬合的方法進行預測:

  • f1, f2, ... fn為提取出來的features。
  • 定義預測方程hθ(x)為多項式的sigmod函數值:hθ(x)=g(θ0f01f1+…+θnfn),其中fn為x的冪次項組合(如下圖)
  • 當θ0f01f1+…+θnfn>=0時hθ(x)=1;else hθ(x)=0;

那么,除了將fn定義為x的冪次項組合,還有沒有其他方法表示 f 呢?本節就引入了Kernel,核的概念。即用核函數表示f。

對於上圖的非線性擬合,我們通過計算輸入原始向量與landmark之間的相似度來計算核值f:

發現相似度計算公式很像正態分布(高斯分布)對不對?是的!這就是高斯核函數。由下圖可以看出,

x和l越相似,f越接近於1;

x與l相差越遠,f越接近於0;

下圖中的橫縱坐標為x的兩個維度值,高為f(new feature)。制高點為x=l的情況,此時f=1。

隨着x與l的遠離,f逐漸下降,趨近於0.

 

下面我們來看SVM核分類預測的結果:

引入核函數后,代數上的區別在於f變了,原來f是x1/x1^2/...,即xi冪次項乘積

引入核函數后,幾何上來說可以更直觀的表示是否應該歸為該類了(如下圖)

  • 比如我們想將坐標上的所有數據點分為兩類(如下圖中)紅色圈內希望預測為y=1;圈外希望預測為y=0。通過訓練數據集呢,我們得到了一組θ值(θ0,θ1,θ2,θ3)=(-0.5,1,1,0)以及三個點(L1,L2,L3),(具體怎么訓練而成的大家先不要過分糾結,后面會講)
  • 對於每個test數據集中的點,我們首先計算它到(L1,L2,L3)各自的相似度,也就是核函數的值(f1,f2,f3),然后帶入多項式θ0f01f1+…+θnfn計算,當它>=0時,預測結果為類內點(正樣本,y=1),else預測為負樣本,y=0

 

 

 

 

 

 

 

 

=====================================

(五)、SVM 中 Gaussian Kernel 的使用

 

§5.1.    landmark的選取和參數向量θ的求解

 

上一節中我們遺留了兩個問題,一個是一些L點的選取,一個是向量θ計算。這一節我們就來講講這兩個問題。

首先來看L的選取。上一節中一提到Gaussian kernel fi 的計算:

這里呢,我們選擇m個訓練數據,並取這m個訓練數據為m個landmark(L)點(不考慮證樣本還是負樣本),如下圖所示:

 

PS:那么在這m個訓練數據中,每一個訓練數據x(i)所得的特征向量(核函數)f中,總有一維向量的值為1(因為這里x(i)=l(i))

於是,每個特征向量f有m+1維(m維訓練數據[f1,f2,...,fm]附加一維f0=1)

在SVM的訓練中,將Gaussian Kernel帶入cost function,通過最小化該函數就可與得到參數θ,並根據該參數θ進行預測:

θTf>=0,predicty=1;

else predict y=0;

如下圖所示,這里與之前講過的cost function的區別在於用kernel f 代替了x。

 

 

 

§5.2.    landmark的選取和參數向量θ的求解

 

好了,至此Landmark點和θ的求取都解決了,還有一個問題,就是cost function中兩個參數的確定:C和σ2

 

對於C,由於C=1/λ,所以

C大,λ小,overfit,產生low bias,high variance

C小,λ大,underfit,產生high bias,low variance

詳細原因請參考第六章中關於bias和variance的講解。

 

對於方差σ2,和正態分布中的定義一樣,

σ2大,x-f 圖像較為扁平;

σ2小,x-f 圖像較為窄尖;

 

關於C和σ2的選取,我們來做個練習:

 

 

解析,過擬合說明應該適當加強cost function中的正則項所起的作用,因此應增大λ,即減小C;同時,過擬合是的只有一小部分范圍內的x享有較大f,或者說x的覆蓋面太窄了,所以應當增大σ2

 

 

 

 

 

 

=====================================

(六)、SVM 的 使用與選擇

 

本節中主要介紹SVM在matlab中用libsvm中的應用,給大家一個用SVM進行實踐的平台。

 

前面幾節中我們已知用SVM進行機器學習的過程就是一個optimize參數θ的過程,這里呢,我們首先介紹一個 Chih-Chung Chang 和 Chih-Jen Lin 做的 matlab/C/Ruby/Python/Java...中通用的機器學習tool,libsvm,其基本講解和測試我以前講過(在這里),算是入門篇,並不詳細,這里呢,我們將結合本章課程近一步學習,並用matlab實現。

 

首先大家來看看,想要進行SVM學習,有哪兩類:

 

一種是No kernel(linear kernel),hθ(x)=g(θ0x01x1+…+θnxn),predict y=1 if θTx>=0;

另一種是使用kernel f(比如Gaussian Kernel),hθ(x)=g(θ0f01f1+…+θnfn),這里需要選擇方差參數σ2

如下圖所示:

 

需要注意的是,不管用那種方法,都需要在ML之前進行Normalization歸一化!

當然,除了Gaussian kernel,我們還有很多其他的kernel可以用,比如polynomial kernel等,如下圖所示,但andrew表示他本人不會經常去用(或者幾乎不用)以下"more esoteric"中的核,一個原因是其他的核不一定起作用。我們講一下polynomial kernel:

polynomial 核形如 K(x,l)= (xTl+c)d,也用來表示兩個object的相似度

首先給大家引入一個數據集,在該數據集中,我們可以進行初步的libsvm訓練和預測,如這篇文章中所說,這個也是最基本的no kernel(linear kernel)。

然后呢,給大家一個reference,這是libsvm中traing基本的語法:

 

 

[cpp]  view plain copy
 
  1. Usage: model = svmtrain(training_label_vector, training_instance_matrix, 'libsvm_options');  
  2. libsvm_options:  
  3. -s svm_type : set type of SVM (default 0)  
  4.     0 -- C-SVC  
  5.     1 -- nu-SVC  
  6.     2 -- one-class SVM  
  7.     3 -- epsilon-SVR  
  8.     4 -- nu-SVR  
  9. -t kernel_type : set type of kernel function (default 2)  
  10.     0 -- linear: u'*v  
  11.     1 -- polynomial: (gamma*u'*v + coef0)^degree  
  12.     2 -- radial basis function: exp(-gamma*|u-v|^2)  
  13.     3 -- sigmoid: tanh(gamma*u'*v + coef0)  
  14.     4 -- precomputed kernel (kernel values in training_instance_matrix)  
  15. -d degree : set degree in kernel function (default 3)  
  16. -g gamma : set gamma in kernel function (default 1/num_features)  
  17. -r coef0 : set coef0 in kernel function (default 0)  
  18. -c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1)  
  19. -n nu : set the parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5)  
  20. -p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)  
  21. -m cachesize : set cache memory size in MB (default 100)  
  22. -e epsilon : set tolerance of termination criterion (default 0.001)  
  23. -h shrinking : whether to use the shrinking heuristics, 0 or 1 (default 1)  
  24. -b probability_estimates : whether to train a SVC or SVR model for probability estimates, 0 or 1 (default 0)  
  25. -wi weight : set the parameter C of class i to weight*C, for C-SVC (default 1)  
  26. -v n : n-fold cross validation mode  
  27. -q : quiet mode (no outputs)  


下面給大家一個例子:

 

 

[cpp]  view plain copy
 
  1. function [ output_args ] = Nonlinear_SVM( input_args )  
  2. %NONLINEAR_SVM Summary of this function goes here  
  3. %   Detailed explanation goes here  
  4.   
  5. %generate data1  
  6. r=sqrt(rand(100,1));%generate 100 random radius  
  7. t=2*pi*rand(100,1);%generate 100 random angles, in range [0,2*pi]  
  8. data1=[r.*cos(t),r.*sin(t)];%points  
  9.   
  10. %generate data2  
  11. r2=sqrt(3*rand(100,1)+1);%generate 100 random radius  
  12. t2=2*pi*rand(100,1);%generate 100 random angles, in range [0,2*pi]  
  13. data2=[r2.*cos(t2),r2.*sin(t2)];%points  
  14.   
  15. %plot datas  
  16.  plot(data1(:,1),data1(:,2),'r.')  
  17.  hold on  
  18. plot(data2(:,1),data2(:,2),'b.')  
  19. ezpolar(@(x)1);%在極坐標下畫ρ=1,θ∈[0,2π]的圖像,即x^2+y^2=1  
  20. ezpolar(@(x)2);  
  21. axis equal %make x and y axis with equal scalar  
  22. hold off  
  23.   
  24. %build a vector for classification  
  25. data=[data1;data2];     %merge the two dataset into one  
  26. datalabel=ones(200,1);  %label for the data  
  27. datalabel(1:100)=-1;  
  28.   
  29. %train with Non-linear SVM classifier use Gaussian Kernel  
  30.   
  31. model=svmtrain(datalabel,data,'-c 100 -g 4');   
  32.   
  33. end  



該例中我們分別生成了100個正樣本和100個負樣本,如下圖所示,因為kernel type default=2(即Gaussian kernel),通過svmtrain(datalabel,data,'-c 100 -g 4')我們設置了第五節中獎的參數——C(c)和 2σ2(g)分別為100和4。

運行結果:

 

[cpp]  view plain copy
 
  1. >> Nonlinear_SVM  
  2. *  
  3. optimization finished, #iter = 149  
  4. nu = 0.015538  
  5. obj = -155.369263, rho = 0.634344  
  6. nSV = 33, nBSV = 0  
  7. Total nSV = 33  



 

 

最后,我們比較一下logistic regresion和 SVM:

用n表示feature個數,m表示training exampl個數。

 

①當n>=m,如n=10000,m=10~1000時,建議用logistic regression, 或者linear kernel的SVM

②如果n小,m不大不小,如n=1~1000,m=10~10000,建議用Gaussian Kernel的SVM

③如果n很小,m很大,如n=1~1000,m>50000,建議增加更多的feature並使用logistic regression, 或者linear kernel的SVM

原因,①模型簡單即可解決,③如果還用Gaussian kernel會導致很慢,所以還選擇logistic regression或者linear kernel

神經網絡可以解決以上任何問題,但是速度是一個很大的問題。

 

詳見下圖:

 

 

 

我們可以把所有數據分為testset和training set兩部分進行訓練,example:

 

[cpp]  view plain copy
 
  1. load heart_scale  
  2. [N D] = size(heart_scale_inst);  
  3.   
  4. % Determine the train and test index,select top 200 as training data  
  5. else as test data  
  6. trainIndex = zeros(N,1); trainIndex(1:200) = 1;  
  7. testIndex = zeros(N,1); testIndex(201:N) = 1;  
  8. trainData = heart_scale_inst(trainIndex==1,:);  
  9. trainLabel = heart_scale_label(trainIndex==1,:);  
  10. testData = heart_scale_inst(testIndex==1,:);  
  11. testLabel = heart_scale_label(testIndex==1,:);  
  12.   
  13. % Train the SVM  
  14. model = svmtrain(trainLabel, trainData, '-c 1 -g 0.07 -b 1');  
  15. % Use the SVM model to classify the data  
  16. [predict_label, accuracy, prob_values] = svmpredict(testLabel, testData, model, '-b 1'); % run the SVM model on the test data  



運行結果:

 

[cpp]  view plain copy
 
    1. optimization finished, #iter = 87  
    2. nu = 0.426369  
    3. obj = -56.026822, rho = -0.051128  
    4. nSV = 77, nBSV = 62  
    5. Total nSV = 77  
    6. *  
    7. optimization finished, #iter = 99  
    8. nu = 0.486493  
    9. obj = -64.811759, rho = 0.328505  
    10. nSV = 87, nBSV = 68  
    11. Total nSV = 87  
    12. *  
    13. optimization finished, #iter = 101  
    14. nu = 0.490332  
    15. obj = -64.930603, rho = 0.424679  
    16. nSV = 87, nBSV = 67  
    17. Total nSV = 87  
    18. *  
    19. optimization finished, #iter = 121  
    20. nu = 0.483649  
    21. obj = -64.046644, rho = 0.423762  
    22. nSV = 87, nBSV = 65  
    23. Total nSV = 87  
    24. *  
    25. optimization finished, #iter = 93  
    26. nu = 0.470980  
    27. obj = -63.270339, rho = 0.458209  
    28. nSV = 83, nBSV = 67  
    29. Total nSV = 83  
    30. *  
    31. optimization finished, #iter = 137  
    32. nu = 0.457422  
    33. obj = -76.730867, rho = 0.435233  
    34. nSV = 104, nBSV = 81  
    35. Total nSV = 104  
    36. Accuracy = 81.4286% (57/70) (classification)  
    37. >>  

    38.  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM