Libsvm使用说明(二)

时间:2021-01-13 16:03:08

库的使用

=======================

这些函数和结构在头文件 ‘svm.h’ 中已声明。你需要在你的 C/C++ 源文件中 #include "svm.h" 然后用‘svm.cpp’ 连接你的程序。你可以参见‘svm-train.c’和‘svm-predict.c’为例,它们展示了如何使用。我们定义了 LIBSVM_VERSION ,在‘svm.h’中用‘extern int libsvm_version;’语句声明,因此你可以检查版本号。

在你为测试数据分类之前,你需要用训练数据构建一个SVM模型(‘svm_model’)。一个模型也可以存储为一个文件将来使用。一旦SVM模式建立并可用,你可以用它来分类新的数据。

  • Function:
struct svm_model *svm_train(const struct svm_problem *prob,
const struct svm_parameter *param);

这个函数根据提供的训练数据和参数构建并返回一个SVM模型。

结构体 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,?)

(index,value)存储在‘svm_node’结构中:

        struct svm_node
{
int index;
double value;
};

index = -1 表示这个向量的结束。注意 indices 必须是单调增的顺序。

struct svm_parameter 描述SVM模式的参数:

     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 classification
NU_SVC: nu-SVM classification
ONE_CLASS: one-class-SVM
EPSILON_SVR: epsilon-SVM regression
NU_SVR: nu-SVM regression

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: kernel values in training_set_file

cache_size 是核缓存的大小,以MB为单位。
C 是违反约束的代价(惩罚因子)。
eps 是终止准则(我们通常在 nu-SVC 用 0.00001 ,其他时用 0.001 )。
nu 是 nu-SVM, nu-SVR, one-class-SVM 的参数。
p 是 epsilon-SVM 回归 epsilon-不敏感损失函数中的epsilon 。
shrinking = 1 意为 shrinking 被执行;否则为 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] 来衡量。

注意 因为 svm_model 包含指向 svm_problem 的指针,如果你仍在使用svm_train()产生的svm_model, 你可以不必释放svm_problem使用的内存。

注意 为了避免错误的参数,svm_check_parameter() 应该在 svm_train() 之前被调用。

结构体 svm_model 存储从训练步骤中获得的模型。不推荐直接访问结构中的条目。程序应该通过接口函数来获得这些值。

    struct svm_model
{
struct svm_parameter param; /* parameter */
int nr_class; /* number of classes, = 2 in regression/one class svm */
int l; /* total #SV */
struct svm_node **SV; /* SVs (SV[l]) */
double **sv_coef; /* coefficients for SVs in decision functions (sv_coef[k-1][l]) */
double *rho; /* constants in decision functions (rho[k*(k-1)/2]) */
double *probA; /* pairwise probability information */
double *probB;
int *sv_indices; /* sv_indices[0,...,nSV-1] are values in [1,...,num_traning_data] to indicate SVs in the training set */

/* for classification only */

int *label; /* label of each class (label[k]) */
int *nSV; /* number of SVs for each class (nSV[k]) */
/* nSV[0] + nSV[1] + ... + nSV[k-1] = l */
/* XXX */
int free_sv; /* 1 if svm_model is created by svm_load_model*/
/* 0 if svm_model is created by svm_train */
};

param 描述所获模型的参数。

nr_class 是类的数目。对于回归和 one-class SVM 其值为2 。

l 是支持向量的数目。SV 和 sv_coef 是分别是支持向量和相关系数。
假设有 k 类。对于 j 类中的数据,相应的 sv_coef 包括 (k-1) y*alpha 向量,
alpha’s 是解决下述二分问题的方法:
1 vs j, 2 vs j, …, j-1 vs j, j vs j+1, j vs j+2, …, j vs k
对于前面的 j-1 个向量 y=1,对于剩下的 k-j 个向量,y=-1 。
例如,如果有四类,sv_coef 和 SV 如下:

    +-+-+-+--------------------+
|1|1|1| |
|v|v|v| SVs from class 1 |
|2|3|4| |
+-+-+-+--------------------+
|1|2|2| |
|v|v|v| SVs from class 2 |
|2|3|4| |
+-+-+-+--------------------+
|1|2|3| |
|v|v|v| SVs from class 3 |
|3|3|4| |
+-+-+-+--------------------+
|1|2|3| |
|v|v|v| SVs from class 4 |
|4|4|4| |
+-+-+-+--------------------+

对于为 sv_coef 分配值的例子参见 svm_train() 。

rho 是偏项 (-b)。
probA 和 probB 是在输出中使用的概率的参数。如果有 k 类,有与 rho,probA,probB 的值一样的k*(k-1)/2 个二进制问题。它们按照二进制问题顺序排列:

1 vs 2, 1 vs 3, ..., 1 vs k, 2 vs 3, ..., 2 vs k, ..., k-1 vs k.

sv_indices[0,…,nSV-1] are values in [1,…,num_traning_data] to
indicate support vectors in the training set.

label 包含训练数据的 labels。

nSV 是每一类的支持向量的个数。

free_sv 是一个用来确认 SV 的空间是否应该在free_model_content(struct svm_model*)和free_and_destroy_model(struct svm_model**)被释放的标记。
如果模型产生于svm_train(),那么 SV 指向 svm_problem 中的数据并且不应被删除。
例如,free_sv 在 svm_model 是由 svm_train 产生的情况下是0,由 svm_load_model产生的情况下是1 。