libsvm是著名的SVM開源組件,目前有JAVA.C/C++,.NET 等多個版本,本人使用的是2.9
libsvm命名空間下主要使用類:
svm_model 為模型類,通過訓練或加載訓練好的模型文件獲得
svm_parameter 為參數類,主要為支持向量機設定參數,具體參數如下:
svm_parameter.svm_type
svm類型:SVM設置類型(默認svm_parameter.C_SVC)
svm_parameter.C_SVC -- C-SVC n(n>=2)分類器,允許用異常值懲罰因子C進行不完全分類。
svm_parameter.NU_SVC -- ν-SVC n類似然不完全分類的分類器。參數nu取代了c,其值在區間【0,1】中,nu越大,決策邊界越平滑。
svm_parameter.ONE_CLASS – 一類SVM 單分類器,所有的訓練數據提取自同一個類里,然後SVM建立了一個分界線以分割該類在特征空間中所占區域和其它類在特 征空間中所占區域。
svm_parameter.EPSILON_SVR -- ε -SVR 回歸。訓練集中的特征向量和擬合出來的超平面的距離需要小於p。異常值懲罰因子C被采用。
svm_parameter.NU_SVR -- ν-SVR 回歸;nu 代替了p
svm_parameter.kernel_type
核函數類型:核函數設置類型(svm_parameter.LINEAR)
svm_parameter.LINEAR – 線性:u'×v - 沒有任何向映射至高維空間,線性區分(或回歸)在原始特征空間中被完成,這是最快的選擇。 d(x,y) = x?y == (x,y)
svm_parameter.POLY– 多項式:(γ×u'×v + coef0)^degree - 多項式核: d(x,y) = (gamma*(x?y)+coef0)degree
svm_parameter.RBF – RBF函數:exp(-γ×|u-v|^2) - 徑向基,對於大多數情況都是一個較好的選擇:d(x,y) = exp(-gamma*|x-y|2)
svm_parameter.SIGMOID – sigmoid:tanh(γ×u'×v + coef0) - sigmoid函數被用作核函數: d(x,y) = tanh(gamma*(x?y)+coef0)
degree, gamma, coef0:都是核函數的參數,具體的參見上面的核函數的方程。
svm_parameter.degree
核函數中的degree設置(默認3)
svm_parameter.coef0
核函數中的coef0設置(默認0)
svm_parameter.shrinking
是否使用啟發式,0或1(默認1)
svm_parameter.nu
設置ν-SVC,一類SVM和ν- SVR的參數(默認0.5)
svm_parameter.C
設置C-SVC,ε -SVR和ν-SVR的參數(默認1)
svm_parameter.cache_size
設置cache內存大小,以MB為單位(默認40)
svm_problem 相當於訓練集合,可講需要訓練的數據加入該類傳遞給訓練器
svm_node 內部使用的數據結構,主要用於保存待訓練數據
svm 主調用程序中我們一般使用以下幾個方法:
svm.svm_train(svm_problem,svm_parameter) 該方法返回一個訓練好的svm_model
svm.svm_load_model(文件名); 該方法返回一個訓練好的svm_model
svm.svm_save_model(文件名,svm_model); 該方法將svm_model保存到文件中
svm.svm_predict_values(svm_model,svm_node,double); 該方法返回doule類值,svm_node對svm_model測試,返回值確定了svm_node在模型中的定位
=================================================================================================
LibSVM庫函數的調用
庫函數在"libsvm"包中。
在Java版中以下函數可以調用:
public class svm {
public static final int LIBSVM_VERSION=310;
public static svm_model svm_train(svm_problem prob, svm_parameter param);
public static void svm_cross_validation(svm_problem prob, svm_parameter param, int nr_fold, double[] target);
public static int svm_get_svm_type(svm_model model);
public static int svm_get_nr_class(svm_model model);
public static void svm_get_labels(svm_model model, int[] label);
public static double svm_get_svr_probability(svm_model model);
public static double svm_predict_values(svm_model model, svm_node[] x, double[] dec_values);
public static double svm_predict(svm_model model, svm_node[] x);
public static double svm_predict_probability(svm_model model, svm_node[] x, double[] prob_estimates);
public static void svm_save_model(String model_file_name, svm_model model) throws IOException
public static svm_model svm_load_model(String model_file_name) throws IOException
public static String svm_check_parameter(svm_problem prob, svm_parameter param);
public static int svm_check_probability_model(svm_model model);
public static void svm_set_print_string_function(svm_print_interface print_func);
}
注意在Java版中svm_node[]的最后一個元素的索引不是-1.
用戶可以自定義自己的輸出格式,通過:
your_print_func = new svm_print_interface()
{
public void print(String s)
{
// your own format
}
};
svm.svm_set_print_string_function(your_print_func);
====================================================================================================
LIBSVM使用的一般步驟是:
1) 按照LIBSVM軟件包所要求的格式准備數據集;
2) 對數據進行簡單的縮放操作;
3) 考慮選用RBF核函數
4) 采用交叉驗證選擇最佳參數C與γ;
5) 采用最佳參數C與γ對整個訓練集進行訓練獲取支持向量機模型; 6) 利用獲取的模型進行測試與預測。
svm_type c_svc % 訓練所采用的svm類型,此處為CSVC−
kernel_type rbf % 訓練采用的核函數類型,此處為RBF核
gamma 0.047619 % 與操作參數設置中的γ含義相同
nr_class 2 % 分類時的類別數,此處為兩分類問題
total_sv 604 % 總共的支持向量個數
rho -0.337784 % 決策函數中的常數項b
label 0 1 % 類別標簽
nr_sv 314 290 % 各類別標簽對應的支持向量個數
SV % 以下為支持向量
1 1:-0.963808 2:0.906788 ... 19:-0.197706 20:-0.928853 21:-1 1 1:-0.885128 2:0.768219 ... 19:-0.452573 20:-0.980591 21:-1 ... ... ...
1 1:-0.847359 2:0.485921 ... 19:-0.541457 20:-0.989077 21:-1
% 對於分類問題,上面的支持向量的各列含義與訓練數據集相同;對於回歸問題,略有不同,與訓練數據中的標簽label(即y值)所對應的位置在模型文件的支持向量中現在存放的是Lagrange系數α值