SVM多分類問題 libsvm在matlab中的應用


轉載自https://blog.csdn.net/lwwangfang/article/details/52355062

對於支持向量機,其是一個二類分類器,但是對於多分類,SVM也可以實現。主要方法就是訓練多個二類分類器。 
一、多分類方式 
1、一對所有(One-Versus-All OVA) 
給定m個類,需要訓練m個二類分類器。其中的分類器 i 是將 i 類數據設置為類1(正類),其它所有m-1個i類以外的類共同設置為類2(負類),這樣,針對每一個類都需要訓練一個二類分類器,最后,我們一共有 m 個分類器。對於一個需要分類的數據 x,將使用投票的方式來確定x的類別。比如分類器 i 對數據 x 進行預測,如果獲得的是正類結果,就說明用分類器 i 對 x 進行分類的結果是: x 屬於 i 類,那么,類i獲得一票。如果獲得的是負類結果,那說明 x 屬於 i 類以外的其他類,那么,除 i 以外的每個類都獲得一票。最后統計得票最多的類,將是x的類屬性。 
2、所有對所有(All-Versus-All AVA) 
給定m個類,對m個類中的每兩個類都訓練一個分類器,總共的二類分類器個數為 m(m-1)/2 .比如有三個類,1,2,3,那么需要有三個分類器,分別是針對:1和2類,1和3類,2和3類。對於一個需要分類的數據x,它需要經過所有分類器的預測,也同樣使用投票的方式來決定x最終的類屬性。但是,此方法與”一對所有”方法相比,需要的分類器較多,並且因為在分類預測時,可能存在多個類票數相同的情況,從而使得數據x屬於多個類別,影響分類精度。 
對於多分類在matlab中的實現來說,matlab自帶的svm分類函數只能使用函數實現二分類,多分類問題不能直接解決,需要根據上面提到的多分類的方法,自己實現。雖然matlab自帶的函數不能直接解決多酚類問題,但是我們可以應用libsvm工具包。libsvm工具包采用第二種“多對多”的方法來直接實現多分類,可以解決的分類問題(包括C- SVC、n - SVC )、回歸問題(包括e - SVR、n - SVR )以及分布估計(one-class-SVM )等,並提供了線性、多項式、徑向基和S形函數四種常用的核函數供選擇。

二、用libsvm在matlab中實現多分類(訓練函數svmtrain+預測函數svmpredict) 
對於libsvm中訓練模型的函數svmtrain來說,model = svmtrain(訓練數據類別, 訓練數據, ‘一系列參數’);其中參數的形式如‘-c 2 -g 0.02’在這當中,參數主要包括以下幾個方面: 
(1) -s —— 其表示SVM的類型,包括上面提到的(默認值為0): 
0 —— C-SVC 
1—— v-SVC 
2 —— 一類SVM 
3 —— e -SVR 
4 —— v-SVR 
(2)-t—— 其表示核函數類型(默認值為2) 
0 – 線性:u’v 
1 – 多項式:(r*u’v + coef0)^degree 
2 – RBF函數:exp(-gamma|u-v|^2) 
3 –sigmoid:tanh(r*u’v + coef0) 
(3)核函數參數設置 
-d ——核函數中的degree設置(針對多項式核函數)(默認3) 
-g ——核函數中的gamma函數設置(針對多項式/rbf/sigmoid 核函數)(默認1/ k,k為特征值個數) 
-r ——核函數中的coef0設置(針對多項式/sigmoid核函數)((默認0) 
-c ——設置C-SVC,e -SVR和v-SVR的參數(損失函數)(默認1) 
-n——設置nu-SVC,一類SVM和nu- SVR的參數(默認0.5) 
-p ——設置e -SVR 中損失函數p的值(默認0.1) 
-m ——設置cache內存大小,以MB為單位(默認40) 
-e ——設置允許的終止判據(默認0.001) 
-h ——是否使用啟發式,0或1(默認1) 
-b ——是否訓練一個SVC或者SVR模型,0或1(默認0) 
-wi ——設置第i類的參數C為weight*C(C-SVC中的C)(默認1) 
-v——n-fold交互檢驗模式,n為fold的個數,必須大於等於2(訓練中使用了-v參數進行交叉驗證時,返回的不是一個模型,而是交叉驗證的分類的正確率或者回歸的均方根誤差)

使用函數svmtrain訓練分類模型后,會返回一個結構體,其中包括數據: 
(1) parameters(一個5*1的數組) 
第一個元素:-s,SVM的類型(int默認為0) 
第二個元素:-t,核函數類型(默認為2) 
第三個元素:-d,核函數中的degree設置(針對多項式核函數)(默認3); 
第四個元素:-g,核函數中的r(gamma)函數設置(針對多項式/rbf/sigmoid核函數) (默認為類別數目的倒數); 
第五個元素:-r 核函數中的coef0設置(針對多項式/sigmoid核函數)((默認0) 
(2)-nr_class: 表示數據集中有多少個類(int) 
(3)-totalSV: 表示支持向量的總數。(int) 
(4)-rho: 決策函數wx+b中的常數偏置的相反數(-b)。 
(5)-Label: 表示數據集中類別的標簽 
(6)ProbA: 使用-b參數時用於概率估計的數值,否則為空。 
         ProbB: 使用-b參數時用於概率估計的數值,否則為空。 
(7)-nSV: 表示每類樣本的支持向量的數目,和Label的類別標簽對應。 
(8)-sv_coef: 表示每個支持向量在決策函數中的系數。 
(9)-SVs: 表示所有的支持向量,如果特征是n維的,支持向量一共有m個,則為m x n的稀疏矩陣。 
(10)nu: -n參數的顯示 
(11)iter: 迭代次數 
(12)obj: 表示SVM文件轉換的二次規划求解的最小值

svmpredict函數根據測試數據類屬性,測試數據,以及通過svmtrain函數獲得的模型來進行分類預測並計算分類精度,[predict_label, accuracy, dec_values]=svmpredict(測試數據類屬性,測試數據,分類模型),返回值介紹如下: 
(1)predicted_label:存儲着分類后樣本所對應的類屬性。 
(2)accuracy:一個3 * 1的數組,依次為:分類的正確率、回歸的均方根誤差、回歸的平方相關系數。 
(3)decision_values/prob_estimates:是一個表示概率的數組,對於一個m個數據,n個類的情況,如果指定“-b 1”參數(使用,則n x k的矩陣,每一行表示這個樣本分別屬於每一個類別的概率;如果沒有指定“-b 1”參數,則為n * n×(n-1)/2的矩陣,每一行表示n(n-1)/2個二分類SVM的預測結果。

三、 使用libsvm進行分類的步驟 
(1) 對數據做歸一化(simple scaling) 
對數據進行簡單的縮放處理(scaling),縮放的最主要優點是能夠避免大數值區間的屬性過分支配了小數值區間的屬性。另一個優點能避免計算過程中數值復雜度。(在試驗中發現,歸一化過程,分別對訓練數據和測試數據進行歸一化處理,比對訓練數據和測試數據整體進行歸一化處理獲得的分類精度要高) 
(2) 應用 RBF kernel 
(3) 選擇得到最優的c和g 
c是懲罰因子,是一個在訓練模型前需要自己設置的一個數值,它表示我們對類中的離群數據的重視程度,c的數值越大,表明我們越重視,越不想丟掉這些離群的數據;g是核函數中的gamma函數設置(針對多項式/rbf/sigmoid 核函數)(默認1/ k,k為特征值個數) 。c和g的選擇對分類精度影響很大,在本文的試驗中,用函數SVMcgForClass選擇完成c和g的選擇。 
(4) 用得到的最優c和g訓練分類模型 
使用libsvm中的svmtrain函數來訓練多分類模型 
(5)測試 
使用libsvm中的svmpredict函數來測試分類精度

四、實驗 
使用libsvm提供的數據進行多分類實驗,下載的wine數據,是關於葡萄酒種類,下載的數據包括三部分,分別是類數3,178個酒數據的13個屬性列表,178個酒數據對應的類屬性列表。代碼如下:

數據集下載:https://pan.baidu.com/s/1CYyZ4NPdsMqqiVB0wfa7EQ

function [ classfication ] = test( train,test )

load chapter12_wine.mat                       %下載數據

train=[wine(1:30,:);wine(60:95,:);wine(131:153,:)]; %選取訓練數據
train_group=[wine_labels(1:30);wine_labels(60:95); wine_labels(131:153)];%選取訓練數據類別標識
test=[wine(31:59,:);wine(96:130,:);wine(154:178,:)];%選取測試數據
test_group=[wine_labels(31:59);wine_labels(96:130); wine_labels(154:178)]; %選取測試數據類別標識

%數據預處理,用matlab自帶的mapminmax將訓練集和測試集歸一化處理[0,1]之間
[mtrain,ntrain]=size(train); 
[mtest,ntest]=size(test);
dataset=[train;test];
[dataset_scale,ps]=mapminmax(dataset',0,1);
dataset_scale=dataset_scale';
train=dataset_scale(1:mtrain,:);
test=dataset_scale((mtrain+1):(mtrain+mtest),:);
%尋找最優c和g %c 的變化范圍是 2^(-2),2^(-1.5),...,2^(4), g 的變化范圍是 2^(-4),2^(-3.5),...,2^(4) [bestacc,bestc,bestg] = SVMcgForClass(train_group,train,-2,4,-4,4,3,0.5,0.5,0.9); %訓練模型 cmd = ['-c ',num2str(bestc),' -g ',num2str(bestg)]; model=svmtrain(train_group,train,cmd); disp(cmd); %測試分類 [predict_label, accuracy, dec_values]=svmpredict(test_group,test,model); %打印測試分類結果 figure; hold on; plot(test_group,'o'); plot(predict_label,'r*'); legend('實際測試集分類','預測測試集分類'); title('測試集的實際分類和預測分類圖','FontSize',10); end

 


免責聲明!

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



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