原文: http://blog.csdn.net/abcjennifer/article/details/7849812php
本欄目(Machine learning)包括單參數的線性迴歸、多參數的線性迴歸、Octave Tutorial、Logistic Regression、Regularization、神經網絡、機器學習系統設計、SVM(Support Vector Machines 支持向量機)、聚類、降維、異常檢測、大規模機器學習等章節。全部內容均來自Standford公開課machine learning中Andrew老師的講解。(https://class.coursera.org/ml/class/index)html
第八講. 支持向量機進行機器學習——Support Vector Machine網絡
===============================dom
(一)、SVM 的 Cost Function機器學習
(二)、SVM —— Large Margin Classifier函數
(三)、數學角度解析爲何SVM 能造成 Large Margin Classifier(選看)學習
(四)、SVM Kernel 1 —— Gaussian Kernel測試
(五)、SVM 中 Gaussian Kernel 的使用網站
(六)、SVM的使用與選擇ui
本章內容爲支持向量機Support Vector Machine(SVM)的導論性講解,在通常機器學習模型的理解上,引入SVM的概念。原先不少人,也包括我本身以爲SVM是個很神奇的概念,讀完本文你會以爲,其實只是擁有不一樣的目標函數, 不一樣的模型而已,Machine Learning的本質尚未變,呵呵~
完成本文花了我很長時間,爲了搞懂後面還有程序方便和參考網站你們實驗,但願對你們有所幫助。
=====================================
(一)、SVM 的 Cost Function
前面的幾章中咱們分別就linear regression、logistic 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,就要求Cost1(θTx)=0,由右圖可知,這要求θTx>=1;
y=0時,W只有後一項,令W=0,就要求Cost0(θTx)=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,若是僅僅處於應用角度考慮的朋友能夠略過此節。
首先咱們來看兩個向量內積的表現形式。假設向量u,v均爲二維向量,咱們知道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,就要求Cost1(θTx)=0,由右圖可知,這要求p·||θ||>=1;
y=0時,W只有後一項,令W=0,就要求Cost0(θTx)=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,咱們以前利用多項式擬合的方法進行預測:
那麼,除了將fn定義爲x的冪次項組合,還有沒有其餘方法表示 f 呢?本節就引入了Kernel,核的概念。即用核函數表示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冪次項乘積
引入核函數後,幾何上來講能夠更直觀的表示是否應該歸爲該類了(以下圖)
=====================================
(五)、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(θ0x0+θ1x1+…+θnxn),predict y=1 if θTx>=0;
另外一種是使用kernel f(好比Gaussian Kernel),hθ(x)=g(θ0f0+θ1f1+…+θ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基本的語法:
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)
下面給你們一個例子:
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。
運行結果:
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
神經網絡能夠解決以上任何問題,可是速度是一個很大的問題。
詳見下圖:
test:
咱們能夠把全部數據分爲testset和training set兩部分進行訓練,example:
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
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 >>
Reference:
1.How to build a custom Kernel function and use it with Libsvm in C?