引言:LIBSVM是臺灣大學林智仁(Lin Chih-Jen)教授等開發設計的一個簡單、易於使用和快速有效的SVM模式識別與迴歸的軟件包,他不但提供了編譯好的可在Windows系列系統的執行文件,還提供了源代碼,方便改進、修改以及在其它操作系統上應用;該軟件對SVM所涉及的參數調節相對比較少,提供了很多的默認參數,利用這些默認參數可以解決很多問題;並提供了交互檢驗(Cross Validation)的功能。該軟件可以解決C-SVM、ν-SVM、ε-SVR和ν-SVR等問題,包括基於一對一算法的多類模式識別問題。
我們在進行科學研究的時候會經常使用SVM對數據進行分類,MATLAB自帶的SVM函數調參麻煩,且只支持分類問題,不支持迴歸問題。因此,林教授開發的功能更爲強大的LIBSVM就是我們的不二選擇。
LIBSVM支持MATLAB、Python、C等編譯語言,今天我將講解的是在MATLAB環境下調用LIBSVM。
其中:LIBSVM工具包下載:https://www.csie.ntu.edu.tw/~cjlin/libsvm/,具體安裝過程這裏就不詳細介紹了,大家可以參考其他博客。
一:LIBSVM的使用
模型訓練:model = svmtrain(label,data,'libsvm_options');
模型預測:[predicted_label,accuary] = svmpredict(label_test,data_test,model,'libsvm_options')
其中libsvm_options爲可選參數,其具體內容如下:
-s 設置svm類型:
0 – C-SVC
1 – v-SVC
2 – one-class-SVM
3 – ε-SVR
4 – n – SVR
-t 設置核函數類型, 默認值爲2
0 — 線性核: μ‘∗ν
1 — 多項式核: (γ∗μ‘∗ν+coef0)degree
2 — RBF核: exp(–γ∗∥μ−ν∥2)
3 — sigmoid 核: tanh(γ∗μ‘∗ν+coef0)
-d degree: 核函數中的degree設置(針對多項式核函數)(默認3);
-g r(gama): 核函數中的gamma函數設置(針對多項式/rbf/sigmoid核函數)(默認1/ k);
-r coef0: 核函數中的coef0設置(針對多項式/sigmoid核函數)((默認0);
-c cost: 設置C-SVC, e -SVR和v-SVR的參數(損失函數)(默認1);
-n nu: 設置v-SVC, 一類SVM和v- SVR的參數(默認0.5);
-p p: 設置e -SVR 中損失函數p的值(默認0.1);
-m cachesize: 設置cache內存大小, 以MB爲單位(默認40);
-e eps: 設置允許的終止判據(默認0.001);
-h shrinking: 是否使用啓發式, 0或1(默認1);
-wi weight: 設置第幾類的參數C爲weight*C (C-SVC中的C) (默認1);
-v n: n-fold交互檢驗模式, n爲fold的個數, 必須大於等於2;
-b 概率估計: 是否計算SVC或SVR的概率估計, 可選值0或1, 默認0;
例:
分類問題:
model = svmtrain(label_train,data_train,'-s 0 -t 2 -c 0.1 -g 0.1');
[predicted_label,accuray] = svmpredict(label_test,data_test,model)
迴歸問題:
model = svmtrain(label_train,data_train,'-s 3 -t 2-c 0.1 -g 0.1 -p 0.01')
predicted_label = svmpredict(label_test,data_test,model)
二:c、g參數尋優問題
針對SVM中的參數優化,Python環境下的LIBSVM中有尋優函數grid.py幫助大家尋找最優的c和g:
但是MATLAB環境下的LIBSVM卻沒有這個功能,因此今天這裏就給大家分享在MATLAB環境下實現LIBSVM參數c和g的自動尋優:
function [best_c,best_g,best_acc] = SvmSearchParas(data,label,c_max,c_min,c_step,g_max,g_min,g_step,v)
%--------------------------------------------------------------------------
%The function looks for the SVM's most important parameters c and g
%The Author:等等登登-Ande
%The Email:[email protected]
%The Blog:qq_35166974
%%
%Initialization parameter
if nargin < 9
v = 10;
end
if nargin < 8
v = 10;
g_step = 1;
end
if nargin < 7
v = 10;
g_step = 1;
c_step = 1;
end
if nargin < 6
v = 10;
g_step = 1;
c_step = 1;
g_min = -5;
end
if nargin < 5
v = 10;
g_step = 1;
c_step = 1;
g_min = -5;
g_max = 5;
end
if nargin < 4
v = 10;
g_step = 1;
c_step = 1;
g_min = -5;
g_max = 5;
c_min = -5;
end
if nargin < 3
v = 10;
g_step = 1;
c_step = 1;
g_min = -5;
g_max = 5;
c_min = -5;
c_max = 5;
end
if nargin < 2
warning('You did not enter enough parameters!');
end
%%
%Parameter optimization
[mesh1,mesh2] = meshgrid(c_min:c_step:c_max,g_min:g_step:g_max);
[raw,col] = size(mesh1);
acc = zeros(raw,col);
for i=1:raw
for j=1:col
cg_paras = ['-v ',num2str(v),'-c ',num2str(2.^mesh1(i,j)),' ','-g ',num2str(2.^mesh2(i,j))];
acc(i,j) = libsvmtrain(double(label),double(data),cg_paras);
end
end
best_acc = max(max(acc));
[label_i,label_j] = find(acc==best_acc);
best_c = 2.^mesh1(label_i,label_j);
best_g = 2.^mesh2(label_i,label_j);
figure
mesh(mesh1,mesh2,acc);
xlabel('log2c');
ylabel('log2g');
zlabel('Accuracy')