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系数α值