如何使用libsvm進行分類
http://www.matlabsky.com/thread-12379-1-1.html
(出處: MATLAB技術論壇)
這帖子就是初步教教剛接觸libsvm(svm)的同學如何利用libsvm進行分類預測,關於參數尋優的問題在這裏姑且不談,另有帖子詳述。
其實使用libsvm進行分類很簡單,只需要有屬性矩陣和標籤,然後就可以建立分類模型(model),然後利用得到的這個model進行分類預測了。
那神馬是屬性矩陣?神馬又是標籤呢?我舉一個直白的不能在直白的例子:
說一個班級裏面有兩個男生(男生1、男生2),兩個女生(女生1、女生2),其中
男生1 身高:176cm 體重:70kg;
男生2 身高:180cm 體重:80kg;
女生1 身高:161cm 體重:45kg;
女生2 身高:163cm 體重:47kg;
如果我們將男生定義爲1,女生定義爲-1,並將上面的數據放入矩陣data中,即
- data = [176 70;
- 180 80;
- 161 45;
- 163 47];
在label中存入男女生類別標籤(1、-1),即
- label = [1;1;-1;-1];
這樣上面的data矩陣就是一個屬性矩陣,行數4代表有4個樣本,列數2表示屬性有兩個,label就是標籤(1、-1表示有兩個類別:男生、女生)。
Remark:這裏有一點廢話一些(因爲我看到不止一個朋友問我這個相關的問題):
上面我們將男生定義爲1,女生定義爲-1,那定義成別的有影響嗎?
這個肯定沒有影響啊!(用腳趾頭都能想出來,我不知道爲什麼也會有人問),這裏面的標籤定義就是區分開男生和女生,怎麼定義都可以的,只要定義成數值型的就可以。
比如我可將將男生定義爲2,女生定義爲5;後面的label相應爲label=[2;2;5;5];
比如我可將將男生定義爲18,女生定義爲22;後面的label相應爲label=[18;18;22;22];
爲什麼我說這個用腳趾頭都能想怎麼定義都可以呢?學過數學的應該都會明白,將男生定義爲1,女生定義爲-1和將男生定義爲2,女生定義爲5本質是一樣的,應爲可以找到一個映射將(2,5)轉換成(1,-1),so所以本質都是一樣的,後面的18、22本質也是一樣的。
這裏要多說一些,如果你原本的數據集合的標籤不是數值型的(比如a、b、c)那麼你完全可以通過某種轉換映射將不是數值型的標籤轉換成數值型的。
現在迴歸正題,有了上面的屬性矩陣data,和標籤label就可以利用libsvm建立分類模型了,簡要代碼如下:
- model = svmtrain(label,data);
有了model我們就可以做分類預測,比如此時該班級又轉來一個新學生,其
身高190cm,體重85kg
我們想通過上面這些信息就給出其標籤(想知道其是男【1】還是女【-1】)
比如 令 testdata = [190 85]; 由於其標籤我們不知道,我們假設其標籤爲-1(也可以假設爲1)
Remark:這裏又有一點廢話一些(因爲我看到不止一個朋友問我這個相關的問題):
如果測試集合的標籤沒有怎麼辦?測試集合的標籤就應該沒有,否則測試集合的標籤都有了,還預測你妹啊!?沒有是正確的,就像上面一樣,新來的學生其標籤咱不應知道,就想通過其屬性矩陣來預測其標籤,這纔是預測分類的真正目的。
之所以平時做測試時,測試集合的標籤一般都有,那是因爲一般人們想要看看自己的分類器的效果如何,效果的評價指標之一就是分類預測的準確率,這就需要有測試集的本來的真實的標籤來進行分類預測準確率的計算。
話歸正傳,即
testdatalabel = -1;
然後利用libsvm來預測這個新來的學生是男生還是女生,代碼如下:
- [predictlabel,accuracy] = svmpredict(testdatalabel,testdata,model)
下面我們整體運行一下上面這段惡 搞[e gao]的背景數據和代碼(你別笑,這個是真能運行的,也有結果的):
- data = [176 70;
- 180 80;
- 161 45;
- 163 47];
- label = [1;1;-1;-1];
- model = svmtrain(label,data);
- testdata = [190 85];
- testdatalabel = -1;
- [predictlabel,accuracy] = svmpredict(testdatalabel,testdata,model);
- predictlabel
運行結果如下:
- Accuracy = 0% (0/1) (classification)
- predictlabel =
- 1
哎,我們看到,通過預測我們得知這個新來的學生的標籤是1(男生),由於原本我們假設其標籤爲-1,假設錯誤,所以分類準確率爲0%。
好,通過上面的講解,不知道諸位看官對於利用libsvm進行分類是否有了一定了解【誰要是這麼通俗的例子還搞不清楚怎麼使用libsvm進行分類,那我真無語啦】,下面使用libsvm工具箱本身帶的測試數據heart_scale來實際進行一下測試:
- %% HowToClassifyUsingLibsvm
- % by faruto @ faruto's Studio~
- % http://blog.sina.com.cn/faruto
- % Email:[email protected]
- % http://www.MATLABsky.com
- % http://www.mfun.la
- % http://video.ourmatlab.com
- % last modified by 2010.12.27
- %% a litte clean work
- tic;
- close all;
- clear;
- clc;
- format compact;
- %%
- % 首先載入數據
- load heart_scale;
- data = heart_scale_inst;
- label = heart_scale_label;
- % 選取前200個數據作爲訓練集合,後70個數據作爲測試集合
- ind = 200;
- traindata = data(1:ind,:);
- trainlabel = label(1:ind,:);
- testdata = data(ind+1:end,:);
- testlabel = label(ind+1:end,:);
- % 利用訓練集合建立分類模型
- model = svmtrain(trainlabel,traindata,'-s 0 -t 2 -c 1.2 -g 2.8');
- % 分類模型model解密
- model
- Parameters = model.Parameters
- Label = model.Label
- nr_class = model.nr_class
- totalSV = model.totalSV
- nSV = model.nSV
- % 利用建立的模型看其在訓練集合上的分類效果
- [ptrain,acctrain] = svmpredict(trainlabel,traindata,model);
- % 預測測試集合標籤
- [ptest,acctest] = svmpredict(testlabel,testdata,model);
- %%
- toc;
運行結果:
- model =
- Parameters: [5x1 double]
- nr_class: 2
- totalSV: 197
- rho: 0.0583
- Label: [2x1 double]
- ProbA: []
- ProbB: []
- nSV: [2x1 double]
- sv_coef: [197x1 double]
- SVs: [197x13 double]
- Parameters =
- 0
- 2.0000
- 3.0000
- 2.8000
- 0
- Label =
- 1
- -1
- nr_class =
- 2
- totalSV =
- 197
- nSV =
- 89
- 108
- Accuracy = 99.5% (199/200) (classification)
- Accuracy = 68.5714% (48/70) (classification)
- Elapsed time is 0.040873 seconds.
- >>
上面的代碼基本我不想多說什麼。
只是說一下參數輸入的意義:
-s svm類型:SVM設置類型(默認0)
0 -- C-SVC
1 --v-SVC
2 – 一類SVM
3 -- e -SVR
4 -- v-SVR
-t 核函數類型:核函數設置類型(默認2)
0 – 線性:u'v
1 – 多項式:(r*u'v + coef0)^degree
2 – RBF函數:exp(-r|u-v|^2)
3 –sigmoid:tanh(r*u'v + coef0)
-g r(gama):核函數中的gamma函數設置(針對多項式/rbf/sigmoid核函數)
-c cost:設置C-SVC,e -SVR和v-SVR的參數(損失函數)(默認1)
更多關於libsvm 參數的說明請看
libsvm 參數說明【中英文雙語版本】
http://www.matlabsky.com/thread-12380-1-1.html
還有關於建立的分類模型model
- model =
- Parameters: [5x1 double]
- nr_class: 2
- totalSV: 197
- rho: 0.0583
- Label: [2x1 double]
- ProbA: []
- ProbB: []
- nSV: [2x1 double]
- sv_coef: [197x1 double]
- SVs: [197x13 double]
因爲好多朋友反映說,比如想得到支持向量,還有model中的一些參看看不懂等等等等一些列問題,會在後面的
分類模型model解密詳解中說明
利用libsvm-mat建立分類模型model參數解密【by faruto】
http://www.matlabsky.com/thread-12649-1-1.html
所以也希望諸位看官尤其是對svm感興趣的朋友多多關注我。O(∩_∩)O~
如果對於標籤設置問題您還沒有搞懂可以再看看這個:
【轉】Matlab中使用libsvm進行分類預測時的標籤問題再次說明
http://www.matlabsky.com/thread-12396-1-1.html
更多關於SVM的東西請看:
關於SVM的那點破事[長期更新整理 by faruto]
http://www.matlabsky.com/thread-10966-1-1.html