-
以前接觸過libsvm,現在算在實際的應用中學習
-
LIBSVM 使用的一般步驟是:
- 1)按照LIBSVM軟件包所要求的格式准備數據集;
- 2)對數據進行簡單的縮放操作;
- 3)首要考慮選用RBF 核函數;
- 4)采用交叉驗證選擇最佳參數C與g ;
- 5)采用最佳參數C與g 對整個訓練集進行訓練獲取支持向量機模型;
- 6)利用獲取的模型進行測試與預測。
參數認識
- LIBSVM使用的數據格式該軟件使用的訓練數據和檢驗數據文件格式如下:
[label] [index1]:[value1] [index2]:[value2] ...
[label] [index1]:[value1] [index2]:[value2] ...
- 考慮選用RBF 核函數,訓練數據形成模型(model),實質是算出了wx+b=0中的w,b. Svmtrain的用法:svmtrain [options] training_set_file [model_file];其中options涵義如下:
-s svm類型:設置SVM 類型,默認值為0,可選類型有:
0 -- C- SVC
1 -- nu - SVC
2 -- one-class-SVM
3 -- e - SVR
4 -- nu-SVR
-t 核函數類型:設置核函數類型,默認值為2,可選類型有:
0 -- 線性核:u'*v
1 -- 多項式核:(g*u'*v+ coef0)degree
2 -- RBF 核:exp(-||u-v||*||u-v||/g*g)
3 -- sigmoid 核:tanh(g*u'*v+ coef 0)
-d degree:核函數中的degree設置,默認值為3;
-g r(gama):核函數中的函數設置(默認1/ k);
-r coef 0:設置核函數中的coef0,默認值為0;
-c cost:設置C- SVC、e - SVR、n - SVR中從懲罰系數C,默認值為1;
-n nu :設置nu - SVC、one-class-SVM 與nu - SVR 中參數nu ,默認值0.5;
-p e :核寬,設置e - SVR的損失函數中的e ,默認值為0.1;
-m cachesize:設置cache內存大小,以MB為單位(默認40):
-e e :設置終止准則中的可容忍偏差,默認值為0.001;
-h shrinking:是否使用啟發式,可選值為0 或1,默認值為1;
-b 概率估計:是否計算SVC或SVR的概率估計,可選值0 或1,默認0;
-wi weight:對各類樣本的懲罰系數C加權,默認值為1;
-v n:n折交叉驗證模式。
-
其中-g選項中的k是指輸入數據中的屬性數。操作參數 -v 隨機地將數據剖分為n 部分並計算交叉檢驗准確度和均方根誤差。以上這些參數設置可以按照SVM 的類型和核函數所支持的參數進行任意組合,如果設置的參數在函數或SVM 類型中沒有也不會產生影響,程序不會接受該參數;如果應有的參數設置不正確,參數將采用默認值。training_set_file是要進行訓練的數據集;model_file是訓練結束后產生的模型文件,該參數如果不設置將采用默認的文件名,也可以設置成自己慣用的文件名。
-
舉個例子如下:
*
optimization finished, #iter = 162
nu = 0.431029
obj = -100.877288, rho = 0.424462
nSV = 132, nBSV = 107
Total nSV = 132
現簡單對屏幕回顯信息進行說明:
#iter為迭代次數,
nu 與前面的操作參數-n nu 相同,
obj為SVM文件轉換為的二次規划求解得到的最小值,
rho 為判決函數的常數項b,
nSV 為支持向量個數,
nBSV為邊界上的支持向量個數,
Total nSV為支持向量總個數。
訓練后的模型保存為文件*.model,用記事本打開其內容如下:
svm_type c_svc % 訓練所采用的svm類型,此處為C- SVC
kernel_type rbf %訓練采用的核函數類型,此處為RBF核
gamma 0.0769231 %設置核函數中的g ,默認值為1/ k
nr_class 2 %分類時的類別數,此處為兩分類問題
total_sv 132 %總共的支持向量個數
rho 0.424462 %決策函數中的常數項b
label 1 -1%類別標簽
nr_sv 64 68 %各類別標簽對應的支持向量個數
SV %以下為支持向量
1 1:0.166667 2:1 3:-0.333333 4:-0.433962 5:-0.383562 6:-1 7:-1 8:0.0687023 9:-1 10:-0.903226 11:-1 12:-1 13:1
0.5104832128985164 1:0.125 2:1 3:0.333333 4:-0.320755 5:-0.406393 6:1 7:1 8:0.0839695 9:1 10:-0.806452 12:-0.333333 13:0.5
1 1:0.333333 2:1 3:-1 4:-0.245283 5:-0.506849 6:-1 7:-1 8:0.129771 9:-1 10:-0.16129 12:0.333333 13:-1
1 1:0.208333 2:1 3:0.333333 4:-0.660377 5:-0.525114 6:-1 7:1 8:0.435115 9:-1 10:-0.193548 12:-0.333333 13:1
采用交叉驗證選擇最佳參數C與g
- 通常而言,比較重要的參數是 gamma (-g) 跟 cost (-c) 。而 cross validation (-v)的參數常用5。那么如何去選取最優的參數c和g呢?libsvm 的 python 子目錄下面的 grid.py 可以幫助我們。
-
我試驗了一下,這個對heart_scale分類問題,可以使用;但是我用在回歸問題上,效果不好!
-
這種方法網上也有很多方法: LIBSVM學習(五)grid.py參數選擇 -- LibSVM學習(六)——easy.py和grid.py的使用
采用的方法
- 網格參數尋優函數(分類問題):SVMcgForClass
[bestCVaccuracy,bestc,bestg]=SVMcgForClass(train_label,train,cmin,cmax,gmin,gmax,v,cstep,gstep,accstep)
輸入:
train_label:訓練集的標簽,格式要求與svmtrain相同。
train:訓練集,格式要求與svmtrain相同。
cmin,cmax:懲罰參數c的變化范圍,即在[2^cmin,2^cmax]范圍內尋找最佳的參數c,默認值為cmin=-8,cmax=8,即默認懲罰參數c的范圍是[2^(-8),2^8]。
gmin,gmax:RBF核參數g的變化范圍,即在[2^gmin,2^gmax]范圍內尋找最佳的RBF核參數g,默認值為gmin=-8,gmax=8,即默認RBF核參數g的范圍是[2^(-8),2^8]。
v:進行Cross Validation過程中的參數,即對訓練集進行v-fold Cross Validation,默認為3,即默認進行3折CV過程。
cstep,gstep:進行參數尋優是c和g的步進大小,即c的取值為2^cmin,2^(cmin+cstep),…,2^cmax,,g的取值為2^gmin,2^(gmin+gstep),…,2^gmax,默認取值為cstep=1,gstep=1。
accstep:最后參數選擇結果圖中准確率離散化顯示的步進間隔大小([0,100]之間的一個數),默認為4.5。
輸出:
bestCVaccuracy:最終CV意義下的最佳分類准確率。
bestc:最佳的參數c。
bestg:最佳的參數g。
- 網格參數尋優函數(回歸問題):SVMcgForRegress
[bestCVmse,bestc,bestg]=SVMcgForRegress(train_label,train,cmin,cmax,gmin,gmax,v,cstep,gstep,msestep)其輸入輸出與SVMcgForClass類似,這里不再贅述。
而當你訓練完了model,在用它做classification或regression之前,應該知道model中的內容,以及其含義。
用來訓練的是libsvm自帶的heart數據
model =
Parameters: [5x1 double]
nr_class: 2
totalSV: 259 % 支持向量的數目
rho: 0.0514 % b
Label: [2x1 double] % classification中標簽的個數
ProbA: []
ProbB: []
nSV: [2x1 double] % 每類支持向量的個數
sv_coef: [259x1 double] % 支持向量對應的Wi
SVs: [259x13 double] % 裝的是259個支持向量
model.Parameters參數意義從上到下依次為:
-s svm類型:SVM設置類型(默認0)
-t 核函數類型:核函數設置類型(默認2)
-d degree:核函數中的degree設置(針對多項式核函數)(默認3)
-g r(gama):核函數中的gamma函數設置(針對多項式/rbf/sigmoid核函數) (默認類別數目的倒數)
-r coef0:核函數中的coef0設置(針對多項式/sigmoid核函數)((默認0)
-
libsvm-mat-2.893[farutoultimate3.0] 源碼下載,里面還有一些libsvm的學習資料
-
回歸問題,簡單易用,且有可視化
function [mse,bestc,bestg] = SVMcgForRegress(train_label,train,cmin,cmax,gmin,gmax,v,cstep,gstep,msestep)
%SVMcg cross validation by faruto
%% 若轉載請注明:
% faruto and liyang , LIBSVM-farutoUltimateVersion
% a toolbox with implements for support vector machines based on libsvm, 2009.
% Software available at http://www.ilovematlab.cn
%
% Chih-Chung Chang and Chih-Jen Lin, LIBSVM : a library for
% support vector machines, 2001. Software available at
% http://www.csie.ntu.edu.tw/~cjlin/libsvm
%% about the parameters of SVMcg
if nargin < 10
msestep = 0.06;
end
if nargin < 8
cstep = 0.8;
gstep = 0.8;
end
if nargin < 7
v = 5;
end
if nargin < 5
gmax = 8;
gmin = -8;
end
if nargin < 3
cmax = 8;
cmin = -8;
end
%% X:c Y:g cg:acc
[X,Y] = meshgrid(cmin:cstep:cmax,gmin:gstep:gmax);
[m,n] = size(X);
cg = zeros(m,n);
eps = 10^(-4);
%% record acc with different c & g,and find the bestacc with the smallest c
bestc = 0;
bestg = 0;
mse = Inf;
basenum = 2;
for i = 1:m
for j = 1:n
cmd = ['-v ',num2str(v),' -c ',num2str( basenum^X(i,j) ),' -g ',num2str( basenum^Y(i,j) ),' -s 3 -p 0.1'];
cg(i,j) = svmtrain(train_label, train, cmd);
if cg(i,j) < mse
mse = cg(i,j);
bestc = basenum^X(i,j);
bestg = basenum^Y(i,j);
end
if abs( cg(i,j)-mse )<=eps && bestc > basenum^X(i,j)
mse = cg(i,j);
bestc = basenum^X(i,j);
bestg = basenum^Y(i,j);
end
end
end
%% to draw the acc with different c & g
[cg,ps] = mapminmax(cg,0,1);
figure;
[C,h] = contour(X,Y,cg,0:msestep:0.5);
clabel(C,h,'FontSize',10,'Color','r');
xlabel('log2c','FontSize',12);
ylabel('log2g','FontSize',12);
firstline = 'SVR參數選擇結果圖(等高線圖)[GridSearchMethod]';
secondline = ['Best c=',num2str(bestc),' g=',num2str(bestg), ...
' CVmse=',num2str(mse)];
title({firstline;secondline},'Fontsize',12);
grid on;
figure;
meshc(X,Y,cg);
% mesh(X,Y,cg);
% surf(X,Y,cg);
axis([cmin,cmax,gmin,gmax,0,1]);
xlabel('log2c','FontSize',12);
ylabel('log2g','FontSize',12);
zlabel('MSE','FontSize',12);
firstline = 'SVR參數選擇結果圖(3D視圖)[GridSearchMethod]';
secondline = ['Best c=',num2str(bestc),' g=',num2str(bestg), ...
' CVmse=',num2str(mse)];
title({firstline;secondline},'Fontsize',12);
- 分類問題,簡單易用,且有可視化
function [bestacc,bestc,bestg] = SVMcgForClass(train_label,train,cmin,cmax,gmin,gmax,v,cstep,gstep,accstep)
%SVMcg cross validation by faruto
%% 若轉載請注明:
% faruto and liyang , LIBSVM-farutoUltimateVersion
% a toolbox with implements for support vector machines based on libsvm, 2009.
% Software available at http://www.ilovematlab.cn
%
% Chih-Chung Chang and Chih-Jen Lin, LIBSVM : a library for
% support vector machines, 2001. Software available at
% http://www.csie.ntu.edu.tw/~cjlin/libsvm
%% about the parameters of SVMcg
if nargin < 10
accstep = 4.5;
end
if nargin < 8
cstep = 0.8;
gstep = 0.8;
end
if nargin < 7
v = 5;
end
if nargin < 5
gmax = 8;
gmin = -8;
end
if nargin < 3
cmax = 8;
cmin = -8;
end
%% X:c Y:g cg:CVaccuracy
[X,Y] = meshgrid(cmin:cstep:cmax,gmin:gstep:gmax);
[m,n] = size(X);
cg = zeros(m,n);
eps = 10^(-4);
%% record acc with different c & g,and find the bestacc with the smallest c
bestc = 1;
bestg = 0.1;
bestacc = 0;
basenum = 2;
for i = 1:m
for j = 1:n
cmd = ['-v ',num2str(v),' -c ',num2str( basenum^X(i,j) ),' -g ',num2str( basenum^Y(i,j) )];
cg(i,j) = svmtrain(train_label, train, cmd);
if cg(i,j) <= 55
continue;
end
if cg(i,j) > bestacc
bestacc = cg(i,j);
bestc = basenum^X(i,j);
bestg = basenum^Y(i,j);
end
if abs( cg(i,j)-bestacc )<=eps && bestc > basenum^X(i,j)
bestacc = cg(i,j);
bestc = basenum^X(i,j);
bestg = basenum^Y(i,j);
end
end
end
%% to draw the acc with different c & g
figure;
[C,h] = contour(X,Y,cg,70:accstep:100);
clabel(C,h,'Color','r');
xlabel('log2c','FontSize',12);
ylabel('log2g','FontSize',12);
firstline = 'SVC參數選擇結果圖(等高線圖)[GridSearchMethod]';
secondline = ['Best c=',num2str(bestc),' g=',num2str(bestg), ...
' CVAccuracy=',num2str(bestacc),'%'];
title({firstline;secondline},'Fontsize',12);
grid on;
figure;
meshc(X,Y,cg);
% mesh(X,Y,cg);
% surf(X,Y,cg);
axis([cmin,cmax,gmin,gmax,30,100]);
xlabel('log2c','FontSize',12);
ylabel('log2g','FontSize',12);
zlabel('Accuracy(%)','FontSize',12);
firstline = 'SVC參數選擇結果圖(3D視圖)[GridSearchMethod]';
secondline = ['Best c=',num2str(bestc),' g=',num2str(bestg), ...
' CVAccuracy=',num2str(bestacc),'%'];
title({firstline;secondline},'Fontsize',12);