libsvm的安裝及使用

libsvm–下載臺灣林老師的版本,現在更新到libsvm3.21。當做一般的工具箱的使用方法就可以了。
1、保存路徑,選擇在D:\Program Files\MATLAB\R2015a\toolbox\libsvm-3.21。將這個路徑以及子文件夾添加到matlab路徑中。其實只要windows文件夾下的就可以,爲了方便吧,要是自己寫的一些擴展的相關庫函數捏。
2、libsvm-3.21\matlab\make.m運行,生成的.mexw64剪切進windows文件夾。
3、運行自帶有測試數據,爲軟件包根目錄下的heart_scale文件,可以用來測試LIBSVM是否安裝成功。這裏的heart_scale文件不能用Matlab的load進行讀取,需要使用libsvmread讀取。

[heart_scale_label, heart_scale_inst] = libsvmread('heart_scale');
model = libsvmtrain(heart_scale_label, heart_scale_inst, '-c 1 -g 0.07');
[predict_label, accuracy, dec_values] = libsvmpredict(heart_scale_label, heart_scale_inst, model);

%注,heart_scale用txt打開可以看到格式,這個格式和特徵矩陣和標籤之間的轉換,可以使用同學給的exe工具https://yunpan.cn/cSHvRW8JCTaBX 訪問密碼 4fa6。轉成libsvm的特徵格式就可以使用libsvm-3.21\tools中grid.py(網格尋參)、checkdata.py、easy.py、subset.py。grid.py參數尋優,是用來尋找RBF核中的C,gamma參數的。固定gamma,即可用來對線性核尋優。如c從2的-4次到2的0次

 grid.py -log2c -4,0,1 -log2g 1,1,1 -t 0 -svmtrain c:\svm-train.exe -gnuplot c:\gnuplot\binary\gnuplot.exe -v 4 hog1.dat

然而因爲python不太懂,沒有用libsvm自帶的tools,主要是用matlab,以下就是用matlab,libsvm的方法。

一、libsvmtrain訓練參數選擇
用默認參數訓練的效果如果不好的話(偶的數據集只有4.5%),就要試試尋參了,尋參之前先做歸一化。從網上dang了一個normalization的小程序:

function normal = normalization(x,kind)
%輸入:
%x:樣本數據,每列爲1個樣本,每行爲一類特徵(屬性)
% kind :1 or 2 表示第一類或第二類規範化。默認歸一化到[-1,1]

%輸出:
%normal:歸一化後的數據
if nargin < 2
    kind = 2;%kind = 1 or 2 表示第一類或第二類規範化
end

[m,n]  = size(x);
normal = zeros(m,n);
%% normalize the data x to [0,1]
if kind == 1
    for i = 1:m
        ma = max( x(i,:) );
        mi = min( x(i,:) );
        normal(i,:) = ( x(i,:)-mi )./( ma-mi );
    end
end
%% normalize the data x to [-1,1]
if kind == 2
    for i = 1:m
        mea = mean( x(i,:) );
        va = var( x(i,:) );
        normal(i,:) = ( x(i,:)-mea )/va;
    end
end
歸一化結束特徵就可以用網格尋參來尋找bestc,bestg了。因爲我用的feature維數是3772*655932,101類別,因爲樣本數<<特徵數,所以一般情況下不需要svm從低維到高維的映射,也應該能找到分類的超平面,所以是用線性核,只需要尋找bestc,懲罰係數,尋參就是遍歷c的不同值,測試當下的acc,尋找最高的acc對應的c,這裏面可能會有多個最優解,選擇min的c作爲bestc,因爲懲罰係數越大,train的結果的泛化能力越差,test的acc越低。貼下線性核函數的尋參代碼:
function [bestacc,bestc] = findcforlinearkenrl(groups,feature)
    cstep = 0.8;
    v = 5;
    cmax = 8;
    cmin = -8;
X = meshgrid(cmin:cstep:cmax);
[m,n] = size(X);
cg = zeros(m);
eps = 10^(-4);
%% record acc with different c & g,and find the bestacc with the smallest c
bestc = 1;
bestacc = 0;
basenum = 2;
for i = 1:m%c

        cmd = [' -c ',num2str( basenum^X(i) ),' -v ',num2str(v),' -t 0'];
        cg(i) = svmtrain(groups, feature, cmd);

        if cg(i) <= 55 
            continue;
        end

        if cg(i) > bestacc
            bestacc = cg(i);
            bestc = basenum^X(i);
        end        

        if abs( cg(i)-bestacc )<=eps && bestc > basenum^X(i) 
            bestacc = cg(i);
            bestc = basenum^X(i);
        end        

end

三、尋參結束以後就可以train和test,因爲對train和test的樣本沒有要求,所以是隨機選擇的。

[train,test] = crossvalind('holdOut',groups);
cp = classperf(groups);
svmStruct = svmtrain(normal_feature(train,:),groups(train),'-v 0 -c ');
%classes = svmclassify(svmStruct,feature(test,:));
[predict_label, accuracy, dec_values] =svmpredict(groups(test), normal_feature(test,:), svmStruct);

%%注:k-folder cross-validation(k折交叉驗證)
K-fold cross-validation (k-CV)則是Double cross-validation的延伸,做法是將數據集分成k個子集,每個子集均做一次測試集,其餘的作爲訓練集。k-CV交叉驗證重複k次,每次選擇一個子集作爲測試集,並將k次的平均交叉驗證識別率作爲結果。
優點:所有的樣本都被作爲了訓練集和測試集,每個樣本都被驗證一次。本文使用的是K=5。
抄了一段定義:交叉驗證(Cross validation)是一種評估統計分析、機器學習算法對獨立於訓練數據的數據集的泛化能力(generalize), 能夠避免過擬合問題。交叉驗證一般要儘量滿足:
1)訓練集的比例要足夠多,一般大於一半
2)訓練集和測試集要均勻抽樣
%%svm的多分類策略有one-vs-rest 和 one-vs-one,這裏顯然用的是後者,訓練很多分類器,再加上尋參c的遍歷,運行時間真是’棒棒’的,這裏估計要採取一些策略,但是我還不知道怎麼做合適。

libsvm的使用就結束了,但是調參和原理特別值得學習,經典的都是好的嘛。支持向量機的三重門,JUJY大神寫的,值得好好學習
http://blog.csdn.net/v_july_v/article/details/7624837
以及libsvm程序的註釋:
http://www.pami.sjtu.edu.cn/people/gpliu/document/libsvm_src.pdf

ps:附錄,便於以後查閱撒
1、訓練參數
Options:
-s svm類型:設置SVM模型類型(默認0)
0 – C-SVC
1 – nu-SVC
2 – one-class SVM
3 – epsilon-SVR
4 – nu-SVR
-t 核函數類型:核函數設置類型(默認2)
0 – 線性核函數: u’*v
1 – 多項式核函數: (gamma*u’*v + coef0)^degree
2 – RBF核函數: exp(-gamma*|u-v|^2)
3 – sigmoid核函數: tanh(gamma*u’*v + coef0)
4 – 預定義核函數(指定核矩陣)
-d degree:核函數中的degree設置(針對多項式核函數)(默認3)
-g gama:核函數中的gamma函數設置(針對多項式/rbf/sigmoid核函數)(默認1/num_features,即屬性數目的倒數)
-r coef0:核函數中的coef0設置(針對多項式/sigmoid核函數)(默認0)
-c cost:設置C-SVC,epsilon-SVR和nu-SVC的參數(損失函數)(默認1)
-n nu:設置nu-SVC,one-class SVM和nu-SVR的參數(默認0.5)
-p epsilon:設置epsilon-SVR中損失函數epsilon的值(默認0.1)
-m cachesize:設置cache內存大小,以MB爲單位(默認100)
-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
參數 -v 隨機地將數據剖分爲n部分並計算交互檢驗準確度和均方根誤差。
以上這些參數設置可以按照SVM的類型和核函數所支持的參數進行任意組合,如果設置的參數在函數或SVM類型中沒有也不會產生影響,程序不會接受該參數;如果應有的參數設置不正確,參數將採用默認值。
2、 訓練返回的內容
libsvmtrain函數返回訓練好的SVM分類器模型,可以用來對未知的樣本進行預測。這個模型是一個結構體,包含以下成員:

-Parameters: 一個5 x 1的矩陣,從上到下依次表示:
    -s SVM類型(默認0);
    -t 核函數類型(默認2)
    -d 核函數中的degree設置(針對多項式核函數)(默認3);
    -g 核函數中的r(gamma)函數設置(針對多項式/rbf/sigmoid核函數) (默認類別數目的倒數);
    -r 核函數中的coef0設置(針對多項式/sigmoid核函數)((默認0)
-nr_class: 表示數據集中有多少類別,比如二分類時這個值即爲2。
-totalSV: 表示支持向量的總數。
-rho: 決策函數wx+b中的常數項的相反數(-b)。
-Label: 表示數據集中類別的標籤,比如二分類常見的1和-1。
-ProbA: 使用-b參數時用於概率估計的數值,否則爲空。
-ProbB: 使用-b參數時用於概率估計的數值,否則爲空。
-nSV: 表示每類樣本的支持向量的數目,和Label的類別標籤對應。如Label=[1; -1],nSV=[63; 67],則標籤爲1的樣本有63個支持向量,標籤爲-1的有67個。
-sv_coef: 表示每個支持向量在決策函數中的係數。
-SVs: 表示所有的支持向量,如果特徵是n維的,支持向量一共有m個,則爲m x n的稀疏矩陣。
另外,如果在訓練中使用了-v參數進行交叉驗證時,返回的不是一個模型,而是交叉驗證的分類的正確率或者回歸的均方根誤差。

  1. 預測返回的內容
    libsvmtrain函數有三個返回值,不需要的值在Matlab可以用~進行代替。

-predicted_label:第一個返回值,表示樣本的預測類標號。
-accuracy:第二個返回值,一個3 x 1的數組,表示分類的正確率、迴歸的均方根誤差、迴歸的平方相關係數。
-decision_values/prob_estimates:第三個返回值,一個矩陣包含決策的值或者概率估計。對於n個預測樣本、k類的問題,如果指定“-b 1”參數,則n x k的矩陣,每一行表示這個樣本分別屬於每一個類別的概率;如果沒有指定“-b 1”參數,則爲n x k*(k-1)/2的矩陣,每一行表示k(k-1)/2個二分類SVM的預測結果。
4. 讀取或保存
libsvmread函數可以讀取以LIBSVM格式存儲的數據文件。

[label_vector, instance_matrix] = libsvmread(‘data.txt’);

這個函數輸入的是文件的名字,輸出爲樣本的類標和對應的特徵。

libsvmwrite函數可以把Matlab的矩陣存儲稱爲LIBSVM格式的文件。

libsvmwrite(‘data.txt’, label_vector, instance_matrix]

這個函數有三個輸入,分別爲保存的文件名、樣本的類標和對應的特徵(必須爲double類型的稀疏矩陣)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章