【MATLAB】一行代碼實(shí)現(xiàn)機(jī)器學(xué)習(xí)之支持向量機(jī)(SVM)

首先明確一點(diǎn),支持向量機(jī)(Support Vector Machine:SVM)就是個二元分類器!所以不要被它看起來花里胡哨的名字嚇到。
上次我們說到樸素貝葉斯分類法,它是利用貝葉斯公式去計(jì)算在你有這些條件的情況下,你屬于某一類的概率是多大。比如已知我的粉絲群體是16-25歲居多,此時你是我的粉絲,你在16-25歲之間的概率就比較大。算法可能(如果不考慮其他變量)把你分類為“青年”。

這次說的支持向量機(jī)方法,相比貝葉斯方法,目的是一樣的,給數(shù)據(jù)分類;但原理是完全不一樣的。支持向量機(jī)方法的原理是非常直觀的:一組分布在空間中的點(diǎn),你要尋找一個平面,使得每個點(diǎn)到這個平面的距離的和,最大。也就是下面這張圖:

這個平面確定后,分類模型就確定了:平面的一側(cè)為一類,另一側(cè)為另一類。之后的新點(diǎn)都可以通過把它們的空間位置代入平面方程來判斷它們屬于哪類:如果是在平面上,則等于0,如果在某一側(cè),那么大于0,如果在另一側(cè),則小于0。
現(xiàn)在這個圖表示的是二維空間下的平面,學(xué)過基本的幾何知識可知,平面的表達(dá)式為:

其中(a1,a2,a3)為垂直于這個平面的法向量。
那么什么是超平面呢?我們注意到,對于一個三維空間,平面是一個二維幾何物體,其把三維空間分成了兩個三維空間。那么超平面就是,對于一個n維空間,一個(n-1)維的幾何體,將空間分成兩個n維空間。
例如,對于一個二維平面,超平面就是一維直線,將平面分成兩個部分;對于一個一維直線,超平面就是一個點(diǎn),將直線分成兩部分。
那么向上推廣,對于n維度空間:

我們同樣有超平面:

于是我們的分類器就是下圖公式,也就是把數(shù)據(jù)點(diǎn)的坐標(biāo)代入平面的公式,看它是大于0,還是小于0。y=sign(x)就是一個函數(shù),當(dāng)x大于0,y就等于1;當(dāng)x小于0,y就等于-1.

那么這個方法為什么叫“支持向量機(jī)”呢?原因就在于我們根據(jù)數(shù)據(jù)求解超平面系數(shù)的過程。
最開始我們說過:支持向量機(jī)的原理是給定一組分布在空間中的點(diǎn),你要尋找一個平面,使得每個點(diǎn)到這個平面的距離的和最大。
那么問題來了,對于高維度空間,我們?nèi)绾味x“距離”?我們可以仍然直觀地采用幾何距離,即數(shù)據(jù)到平面的垂直向量的長度。
即:

其中下標(biāo)i表示第i個數(shù)據(jù)點(diǎn)。||w||表示w的2范數(shù),也就是所謂平方相加開根號,也就是所謂“距離”。在N個坐標(biāo)點(diǎn)中,一定有一個距離超平面最小的距離,我們定義它為:

我們希望找到一個平面,使得這個最小值最大。
支持向量呢,就指的是距離超平面最近的點(diǎn)對應(yīng)的向量,它們決定了超平面的形狀。只要支持向量確定了,其他點(diǎn)的位置變動并不會影響超平面的形狀。

好了,所以一個數(shù)學(xué)問題就被提煉出來了:

這是一個約束最優(yōu)化問題,也就是在約束條件下,尋找最大或者最小值。這類問題可以使用拉格朗日乘子法解決。

好了,中間過程并不是很重要(寫上也不能一下子看懂,我也不覺得有人會認(rèn)真反復(fù)研讀一篇B站的文章),我直接出結(jié)果

其中a_i是引入的拉格朗日乘子,b是超平面的常數(shù)參數(shù)。x_i是訓(xùn)練集中的自變量,y_i是訓(xùn)練集中的分類標(biāo)簽。
稍微延伸一下,對于一個平面切不開的數(shù)據(jù)集怎么辦呢,我們可以對向量做拉伸和縮短,使得一個曲面可以被拉成一個“平面”,如圖所示:

其中每個向量都會有一個拉伸系數(shù)。
最后說一下matlab實(shí)現(xiàn)方法:
流程還是一樣的:讀取訓(xùn)練集→跑出模型→選擇測試集→看誤識別率
讀取數(shù)據(jù):
data=xlsread("data.xls",'A2:AJ500');
X=data(:,1:6);%自變量
Y=data(:,7);%分類標(biāo)簽
SVMModel = fitcsvm(X,Y,'Standardize',true,'KernelFunction','RBF',...
? ? 'KernelScale','auto');
resubLoss(SVMModel,'LossFun','ClassifErr')%誤識別率data_test=xlsread("data.xls",'A501:AJ1024');%驗(yàn)證集
X=data_test(:,1:6);%自變量
Y=data_test(:,7);%分類標(biāo)簽
loss(SVMModel,newX,newY)%驗(yàn)證模型對驗(yàn)證集的誤識別率
跑完以后我們看一下模型參數(shù)

Prior就是根據(jù)數(shù)據(jù)分類計(jì)算出的先驗(yàn)概率,Alpha就是前面提過的,用于模型構(gòu)建的拉格朗日乘子。Mu就是數(shù)據(jù)的均值,Sigma就是數(shù)據(jù)的標(biāo)準(zhǔn)差
全部系數(shù)解釋:
https://ww2.mathworks.cn/help/stats/classificationsvm.html
另外你還可以畫一下分類情況圖:
?isLabels1 = resubPredict(SVMModel);
ConfusionMat1 = confusionchart(Y,isLabels1);

對角部分就是分類正確的,非對角部分就是誤分類的。
參考資料:
MATLAB說明文檔
https://ww2.mathworks.cn/help/stats/fitcsvm.html
https://ww2.mathworks.cn/help/stats/fitcnb.html
https://ww2.mathworks.cn/help/stats/classificationsvm.html
維基百科