http://blog.sina.com.cn/s/blog_6646924501018fqc.html
主要就是講解利用libsvm-mat工具箱建立分類(回歸模型)后,得到的模型model里面參數的意義都是神馬?以及如果通過model得到相應模型的表達式,這里主要以分類問題為例子。
測試數據使用的是libsvm-mat自帶的heart_scale.mat數據(270*13的一個屬性據矩陣,共有270個樣本,每個樣本有13個屬性),方便大家自己測試學習。
首先上一個簡短的測試代碼:
- %% ModelDecryption
- % by faruto @ faruto's Studio~
- % http://blog.sina.com.cn/faruto
- % Email:faruto@163.com
- % http://www.matlabsky.com
- % http://www.mfun.la
- % http://video.ourmatlab.com
- % last modified by 2011.01.06
- %% a litte clean work
- tic;
- close all;
- clear;
- clc;
- format compact;
- %%
- % 首先載入數據
- load heart_scale;
- data = heart_scale_inst;
- label = heart_scale_label;
- % 建立分類模型
- model = svmtrain(label,data,'-s 0 -t 2 -c 1.2 -g 2.8');
- model
- % 利用建立的模型看其在訓練集合上的分類效果
- [PredictLabel,accuracy] = svmpredict(label,data,model);
- accuracy
- %%
- toc;
運行結果:
- model =
- Parameters: [5x1 double]
- nr_class: 2
- totalSV: 259
- rho: 0.0514
- Label: [2x1 double]
- ProbA: []
- ProbB: []
- nSV: [2x1 double]
- sv_coef: [259x1 double]
- SVs: [259x13 double]
- Accuracy = 99.6296% (269/270) (classification)
- accuracy =
- 99.6296
- 0.0148
- 0.9851
- Elapsed time is 0.040155 seconds.
這里面為了簡單起見沒有將測試數據進行訓練集和測試集的划分,這里僅僅是為了簡單明了而已,分類結果估計可以不要管,參數優化也不要管,另有帖子講解。
下面我們就看看 model這個結構體里面的各種參數的意義都是神馬,model如下:
model =
Parameters: [5x1 double]
nr_class: 2
totalSV: 259
rho: 0.0514
Label: [2x1 double]
ProbA: []
ProbB: []
nSV: [2x1 double]
sv_coef: [259x1 double]
SVs: [259x13 double]
model.Parameters
我們先來看一下model.Parameters里面承裝的都是什么:
- >> model.Parameters
- ans =
- 0
- 2.0000
- 3.0000
- 2.8000
- 0
重要知識點:
model.Parameters參數意義從上到下依次為:
-s svm類型:SVM設置類型(默認0)
-t 核函數類型:核函數設置類型(默認2)
-d degree:核函數中的degree設置(針對多項式核函數)(默認3)
-g r(gama):核函數中的gamma函數設置(針對多項式/rbf/sigmoid核函數) (默認類別數目的倒數)
-r coef0:核函數中的coef0設置(針對多項式/sigmoid核函數)((默認0)
即在本例中通過model.Parameters我們可以得知 –s 參數為0;-t 參數為 2;-d 參數為3;-g 參數為2.8(這也是我們自己的輸入);-r 參數為0。
關於libsvm參數的一點小說明:
Libsvm中參數設置可以按照SVM的類型和核函數所支持的參數進行任意組合,如果設置的參數在函數或SVM類型中沒有也不會產生影響,程序不會接受該參數;如果應有的參數設置不正確,參數將采用默認值。
model.Label model.nr_class
- >> model.Label
- ans =
- 1
- -1
- >> model.nr_class
- ans =
- 2
重要知識點:
model.Label表示數據集中類別的標簽都有什么,這里是 1,-1;
model.nr_class表示數據集中有多少類別,這里是二分類。
model.totalSV model.nSV
- >> model.totalSV
- ans =
- 259
- >> model.nSV
- ans =
- 118
- 141
重要知識點:
model.totalSV代表總共的支持向量的數目,這里共有259個支持向量;
model.nSV表示每類樣本的支持向量的數目,這里表示標簽為1的樣本的支持向量有118個,標簽為-1的樣本的支持向量為141。
注意:這里model.nSV所代表的順序是和model.Label相對應的。
model.ProbA model.ProbB
關於這兩個參數這里不做介紹,使用-b參數時才能用到,用於概率估計。
-b probability_estimates: whether to train a SVC or SVR model for probability estimates, 0 or 1 (default 0)
model.sv_coef model.SVs model.rho
- sv_coef: [259x1 double]
- SVs: [259x13 double]
- model.rho = 0.0514
重要知識點:
model.sv_coef是一個259*1的矩陣,承裝的是259個支持向量在決策函數中的系數;
model.SVs是一個259*13的稀疏矩陣,承裝的是259個支持向量。
model.rho是決策函數中的常數項的相反數(-b)
在這里首先我們看一下 通過 –s 0 參數(C-SVC模型)得到的最終的分類決策函數的表達式是怎樣的?
這里如果有關於C-SVC模型不懂的地方,請看這個pdf文件:
libsvm_library.pdf
附件:
最終的決策函數為:
在由於我們使用的是RBF核函數(前面參數設置 –t 2),故這里的決策函數即為:
其中|| x-y ||是二范數距離 ;
這里面的
b就是-model.rho(一個標量數字);
b = -model.rho;
n代表支持向量的個數即 n = model.totalSV(一個標量數字);
對於每一個i:
wi =model.sv_coef(i); 支持向量的系數(一個標量數字)
xi = model.SVs(i,:) 支持向量(1*13的行向量)
x 是待預測標簽的樣本 (1*13的行向量)
gamma 就是 -g 參數
好的下面我們通過model提供的信息自己建立上面的決策函數如下:
- %% DecisionFunction
- function plabel = DecisionFunction(x,model)
- gamma = model.Parameters(4);
- RBF = @(u,v)( exp(-gamma.*sum( (u-v).^2) ) );
- len = length(model.sv_coef);
- y = 0;
- for i = 1:len
- u = model.SVs(i,:);
- y = y + model.sv_coef(i)*RBF(u,x);
- end
- b = -model.rho;
- y = y + b;
- if y >= 0
- plabel = 1;
- else
- plabel = -1;
- end
有了這個決策函數,我們就可以自己預測相應樣本的標簽了:
- %%
- plable = zeros(270,1);
- for i = 1:270
- x = data(i,:);
- plabel(i,1) = DecisionFunction(x,model);
- end
- %% 驗證自己通過決策函數預測的標簽和svmpredict給出的標簽相同
- flag = sum(plabel == PredictLabel)
- over = 1;
最終可以看到 flag = 270 ,即自己建立的決策函數是正確的,可以得到和svmpredict得到的一樣的樣本的預測標簽,事實上svmpredict底層大體也就是這樣實現的。
最后我們來看一下,svmpredict得到的返回參數的意義都是什么
在下面這段代碼中 :
- %%
- % 首先載入數據
- load heart_scale;
- data = heart_scale_inst;
- label = heart_scale_label;
- % 建立分類模型
- model = svmtrain(label,data,'-s 0 -t 2 -c 1.2 -g 2.8');
- model
- % 利用建立的模型看其在訓練集合上的分類效果
- [PredictLabel,accuracy] = svmpredict(label,data,model);
- accuracy
運行可以看到
- model =
- Parameters: [5x1 double]
- nr_class: 2
- totalSV: 259
- rho: 0.0514
- Label: [2x1 double]
- ProbA: []
- ProbB: []
- nSV: [2x1 double]
- sv_coef: [259x1 double]
- SVs: [259x13 double]
- Accuracy = 99.6296% (269/270) (classification)
- accuracy =
- 99.6296
- 0.0148
- 0.9851
這里面要說一下返回參數accuracy的三個參數的意義。
重要的知識點:
返回參數accuracy從上到下依次的意義分別是:
分類准率(分類問題中用到的參數指標)
平均平方誤差(MSE (mean squared error)) [回歸問題中用到的參數指標]
平方相關系數(r2 (squared correlation coefficient))[回歸問題中用到的參數指標]
其中mse 和r2的計算公式分別為:
插圖:
寫在后面的話,至此關於model中相應參數的一些意義,以及到底如果得到決策函數的表達式或者計算方式的就算是說的很明了了。
可能還有的同學會問,如何得到分類決策函數中的那個alpha系數【這個肯定會有人問】,還是再磨嘰說一下吧:
上面的wi其實是alpha和支持向量的類別標簽(1或-1的乘積),原始決策函數的表達式如下:
插圖:
上面的yi是支持向量的類別標簽(1或者-1),在libsvm中將yi和alpha的乘積放在一起用model.sv_coef(w)來承裝。
都說到這份上,應該能明白了嗎?
再說點廢話:就是在關於SVM的學習中,我發現很多朋友都不主動思考和嘗試,老是在問,這樣很不好,這樣很被動,上面這些也沒有人教我,都是我自己思考出來,然后編程驗證,如果出現不合理的地方就再繼續思考,反正道理和書籍里面都有講解,總能洞穿的啊。O(∩_∩)O•
