本文大部分来自Felomeng的翻译,原文是《Felomeng翻译:libsvm2.88之函数库的使用》。
2.88版本的README文件和libsvm3.0的README文件差不多,3.0版本的README见这里: http://sdudata.appspot.com/4001-libsvm3.0_README
Library Usage
=============
这些函数和结构都在头文件“svm.h”中有声名。你需要在你的C/C++源文件中添加#include “svm.h”语句,在连接时需要将你的程序与svm.cpp连接。具体使用方法可以参考“svm-train.c”和“svm-predict.c”的使用示例。在文件svm.h中使用LIBSVM_VERSION定义了版本号,以便读者查阅。
在对测试数据进行分类之前,需要先使用训练数据建立一个支持向量模型。模型可以以文件的形式存储以备以后使用。一旦建立好了支持向量机模型,就可以用它来对新的数据进行分类了。
-函数:struct svm_model *svm_train(const struct svm_problem *prob, const struct svm_parameter *param);
这个函数根据给定的参数和训练数 据构建并返回一个支持向量机模型。
结构体svm_problem将问题形式化:
struct svm_problem
{
int l;
double *y;
struct svm_node **x;
};
其中“l”表示训练数据的实例数,而“y”是一个数组,用于存放它们的目标值。(类型值用整型数据,回归值用实数)“x”是一个数组指针,每一个指针指向一个稀疏的训练向量(即一个svm_node数组)。
例如,如果我们有如下的训练数 据:
LABEL ATTR1 ATTR2 ATTR3 ATTR4 ATTR5
----- ----- ----- ----- ----- -----
1 0 0.1 0.2 0 0
2 0 0.1 0.3 -1.2 0
1 0.4 0 0 0 0
2 0 0.1 0 1.4 0.5
3 -0.1 -0.2 0.1 1.1 0.1
于是svm_problem的构成如下:
l = 5
y -> 1 2 1 2 3
x -> [ ] -> (2,0.1) (3,0.2) (-1,?)
[ ] -> (2,0.1) (3,0.3) (4,-1.2) (-1,?)
[ ] -> (1,0.4) (-1,?)
[ ] -> (2,0.1) (4,1.4) (5,0.5) (-1,?)
[ ] -> (1,-0.1) (2,-0.2) (3,0.1) (4,1.1) (5,0.1) (-1,?)
其中(索引,值)存储在结构“svm_node”中:
struct svm_node
{
int index;
double value;
};
当索引为-1时表示已经到达向量的末端。注意索引必须“升序”排列。
结构体svm_parameter描述了一个支持向量机的参数:
struct svm_parameter
{
int svm_type;
int kernel_type;
int degree; /* for poly */
double gamma; /* for poly/rbf/sigmoid */
double coef0; /* for poly/sigmoid */
/* these are for training only */
double cache_size; /* in MB */
double eps; /* stopping criteria */
double C; /* for C_SVC, EPSILON_SVR, and NU_SVR */
int nr_weight; /* for C_SVC */
int *weight_label; /* for C_SVC */
double* weight; /* for C_SVC */
double nu; /* for NU_SVC, ONE_CLASS, and NU_SVR */
double p; /* for EPSILON_SVR */
int shrinking; /* use the shrinking heuristics */
int probability; /* do probability estimates */
};
svm_type可以是C_SVC、NU_SVC、ONE_CLASS、EPSILON_SVR或NU_SVR其中的一种。
C_SVC: C-SVM 分类
NU_SVC: nu-SVM 分类
ONE_CLASS: one-class-SVM
EPSILON_SVR: epsilon-SVM回归
NU_SVR: nu-SVM回归
kernel_type可以是LINEAR、POLY、RBF、SIGMOID其中一种。
LINEAR: u'*v
POLY: (gamma*u'*v + coef0)^degree
RBF: exp(-gamma*|u-v|^2)
SIGMOID: tanh(gamma*u'*v + coef0)
PRECOMPUTED:训练 集文件中的核心值
cache_size是核心缓 存的大小,单位为MB。C是违背约束成本(惩罚值)。eps是结束条件。(一般地,我们在nu-SVC模型中使用0.00001,在其它模型中使用0.001)。nu是nu-SVM、nu-SVR与one-class-SVM中的一个参数。p 是epsilon-SVM回归中对epsilon不敏感函数的epsilon值。shirnking = 1表示使用压缩,否则 = 0。 probability = 1表示得到带概率信息的模型,否则 = 0。
nr_weight、weight_label和weight(权重)用于改变某些类的惩罚因子(如果一个类的权重不变,则将权重值设定为1)这在使用不均衡输入数据或使用不均匀错误成本训练分类器时尤其有用。
nr_weight是数组weight_label和weight中的元素个数。每个weight[i]对应一个weight_label[i],表示类weight_label[i]的惩罚是由因子weight[i]确定的。
如果不想改变任何类的惩罚因子, 那么只需要将nr_weight设定为0。
*注意*因为svm_model含有指向svm_problem的指针,如果仍要使用由svm_train()产生的svm_model,那么就不要释放svm_problem的内存。
*注意*为了避免错误的参数,在调用svm_train()之前应该先调用svm_check_parameter()。
-函数:double svm_predict(const struct svm_model *model,
const struct svm_node *x);
在给定模型的前提下,这个函数可 以用来对测试向量x进行分类或回归。
分类模型返回的是x的预测类。
回归模型返回使用该模型计算所得 的x函数值。one-class模型返回+1或-1。
-函数:void svm_cross_validation(const struct svm_problem *prob,
const struct svm_parameter *param, int nr_fold, double *target);
这个函数用于交叉验证。数据会分 成nr_fold个部分。在给定的参数下,顺序地对每一部分数据用其余部分数据训练成的模型进行验证。在验证过程 中,预测标签(所有prob的实例)存放到一个名为target(目标)的数组。
svm_prob的格式与svm_train()的相同。
-函数:int svm_get_svm_type(const struct svm_model *model);
这个函数用于确定模型的svm_type。可能的svm_type值已在svm.h中定义。
-函数:int svm_get_nr_class(const svm_model *model);
对于分类模型,本函数用于得到类 的数量。回归或one-class模型的返回值是2。
-函数:void svm_get_labels(const svm_model *model, int* label)
对于分类模型,这个函数输出名称 标签到一个名为label的数组。对于回归或one-class模型,label的值保护不变。
-函数:double svm_get_svr_probability(const struct svm_model *model);
对于带有概率信息的回归模型,此 函数将输出一个值sigma>0。对于测试数据,我 们考虑概率模型:目标值 = 预测值 + z,z:拉普拉斯分布e^(-|z|/sigma)/(2sigma)
如果不是svr模型,或者不含有需要的信息,则返回0。
-函数:void svm_predict_values(const svm_model *model,
const svm_node *x, double* dec_values)
在给定模型的前提下,这个函数可 以用来给出测试向量x的决策值。
对于有nr_class个类的分类模型,这个函数给出nr_class*(nr_class-1)/2个决策值,并存到数组dec_values中,其中nr_class可以通过函数svm_get_nr_class得到。序列是label[0] vs. label[1], …, label[0] vs. label[nr_class – 1], label[1] vs. label[2], …, label[nr_class-2] vs. label[nar_class-1], 其中label可以通过函数svm_get_lables得到。
回归模型中,label[0]表 示使用该模型计算所得的x函数值。one-class模型中,label[0]是+1或-1。
-函数:double svm_predict_probability(const struct svm_model *model,
const struct svm_node *x, double* prob_estimates);
在给定带概率信息的模型的前提下,这个函数可以用来对测试向量x进行分类或回归。
对于带有概率信息的分类模型,这个函数会把nr_class概率期望输出到数组prob_estimates中。 nr_class可以通过函数svm_get_nr_class得到。返回值是概率值最高的类。对于回归或one-class支持向量机,数组prob_estimates保持不变,而返回值与svm_predict的返回值相同。
-函数:const char *svm_check_parameter(const struct svm_problem *prob,
const struct svm_parameter *param);
本函数检验对于当前问题,参数是否合法。在调用svm_train()和svm_cross_validation()之前应该调用此函数。如果参数合法,则返回NULL,如果不合法,则返回错误信息。
-函数:int svm_check_probability_model(const struct svm_model *model);
此函数用于判断当前模型是否含有进行概率期望运算所需要的信息。如果含有则返回+1。否则返回0。在调用sv svm_get_svr_probability和svm_predict_probability之前应该调用此函数。
-函数:int svm_save_model(const char *model_file_name,
const struct svm_model *model);
此函数用于将训练好的模型保存到文件中,如果保存成功则返回0,如果发生错误则返回-1。
-函数:struct svm_model *svm_load_model(const char *model_file_name);
此函数从文件中读取模型并返回指向该模型的指针,如果读取失败则回返空指针。
//这是2.88版本的,3.0版本这个函数有所变化
-函数:void svm_destroy_model(struct svm_model *model);
此函数用于释放指定模型的内存。
//3.0版本函数
-函数: void svm_free_and_destroy_model(struct svm_model **model_ptr_ptr);
此函数释放指定模型的内存并删除该模型。这个函数等价于之前版本中的svm_destroy_model,在3.0版本以后不赞成使用后者。
-函数:void svm_destroy_param(struct svm_parameter *param);
此函数用于释放指定参数集的内存。
//这部分是我翻译的,与Felomeng无关
Java Version
============
预编译的java类文件保存在“libsvm.jar”中,源代码在java文件夹中。
要运行此程序,以下命令:
java -classpath libsvm.jar svm_train <arguments>
java -classpath libsvm.jar svm_predict <arguments>
java -classpath libsvm.jar svm_toy
java -classpath libsvm.jar svm_scale <arguments>
//我感觉这里的介绍多此一举,如果使用命令行的话直接使用window版本的libsvm就可以了,当然java具有平台无关性,在其他系统中也可以使用上面的命令行。如果我们使用开发工具例如eclipse建立项目的话,只要把libsvm.jar包含进去,然后在对应的类中import一下就行了。
注意你需要Java 1.5(5.0)或更高版本的支持。
你可能需要向classpath中添加runtime库(例如classes.zip)。
你也可能需要增加Java堆的最大值。
java版本函数库的使用与C版本的类似,这些函数可共使用:
public class svm {
public static final int LIBSVM_VERSION=300;
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);
}
函数库包含在“libsvm”包中。
注意在java版本中,svm_node[]并不是以index = -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);