上海交通大学模式分析与机器智能实验室
LibSVM-2.6 程序代码注释
上海交通大学模式分析与机器智能实验室
我不经心地,服下你调好的毒
我知道今后我将万劫不复
但是你的红唇仍让我屈服
四月的樱花火红满天
我和你的梦,却要一以何处去缱绻?
虽然人间的情爱万万千千
世上已有太多崩毁的誓言
七个黑夜,七个白天
我为你写下的歌,彩绘的纸笺
却只能随着晚风
飘在大海的岸边
我仍愿服下你精心为我调好的毒
从你那深情的吻
吞下我与你在人间
最后的流光万千辗转朱颜……
上海交通大学模式分析与机器智能实验室
第一节: SVM.h 文件
struct svm_node
{
int index;
double value;
};
struct svm_node 用来存储单一向量中的单个特征,例如:
向量 x1={ 0.002, 0.345, 4, 5.677};
那么用 struct svm_node 来存储时就使用一个包含 5 个 svm_node 的数组来存储此 4 维向量,内存
映象如下:
1 2 3 4
-1
0.002 0.345
4.000
5.677
空
其中如果 value 为 0.00,该特征将不会被存储,其中(特征 3)被跳过:
1 2 4 5
-1
0.002 0.345
4.000
5.677
空
0.00 不保留的好处在于,做点乘的时候,可以加快计算速度,对于稀疏矩阵,更能充分体现这种
数据结构的优势。但做归一化时,操作就比较麻烦了。
(类型转换不再说明)
struct svm_problem
{
int l;
double *y;
struct svm_node **x;
};
struct svm_problem存储本次参加运算的所有样本(数据集),及其所属类别。在某些数据挖掘
实现中,常用DataSet来实现。
int l;记录样本总数
double *y;指向样本所属类别的数组。在多类问题中,因为使用了one-agianst-one方法,可能原始
样本中y[i]的内容是1.0,2.0,3.0,…,但参与多类计算时,参加分类的两类所对应的y[i]内容是+1,
和-1。
Struct svm_node **x;指向一个存储内容为指针的数组;
如下图,最右边的四个长条格同上表,存储三维数据。(黑边框的是最主要的部分)
Y[3]
Y[2]
Y[1]
Y[0]
L=4
Y*
X**
上海交通大学模式分析与机器智能实验室
这样的数据结构有一个直接的好处,可以用x[i][j]来访问其中的某一元素(如果value为0.00
的也全部保留的话)
私下认为其中有一个败笔,就是把svm_node* x_space放到结构外面去了。
enum { C_SVC, NU_SVC, ONE_CLASS, EPSILON_SVR, NU_SVR };/* svm_type */
enum { LINEAR, POLY, RBF, SIGMOID }; /* kernel_type */
struct svm_parameter
{
int svm_type;//SVM类型,见前enum
int kernel_type;//核函数
double 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 */
};
部分参数解释,(附核函数)
1、
j
T
iji
xxxxK =),(
2、
0,)(),( >+=
γγ
d
j
T
iji
rxxxxK
3、
0),exp(),(
2
>−−=
γγ
jiji
xxxxK
4、
)tanh(),( rxxxxK
j
T
iji
+=
γ
double degree;//就是2式中的d
double gamma; //就是2,3,4式中的gamma
double coef0;//就是2,4式中的r
double cache_size; /* in MB */ 制定训练所需要的内存,默认是40M,LibSVM2.5中是4M,所以自
己做开发选LibSVM2.5还是不错的!
double eps;见参考文献[1]中式3.13
double C;//没什么好说的,惩罚因子,越大训练的模型越那个…,当然耗的时间越多
上海交通大学模式分析与机器智能实验室
int nr_weight;//权重的数目,目前在实例代码中只有两个值,一个是默认0,另外一个是
svm_binary_svc_probability函数中使用数值2。
int *weight_label;//权重,元素个数由nr_weight决定.
double nu;// 没什么好说的,too
double p;// 没什么好说的,three
int shrinking;//指明训练过程是否使用压缩。
int probability;//新增,指明是否要做概率估计
struct svm_model
{
svm_parameter param; // parameter
int nr_class; // number of classes, = 2 in regression/one class svm
int l; // total #SV
svm_node **SV; // SVs (SV[l])
double **sv_coef; // coefficients for SVs in decision functions (sv_coef[n-1][l])
double *rho;
// constants in decision functions (rho[n*(n-1)/2])
double *probA; // pariwise probability information
double *probB;
// for classification only
int *label; // label of each class (label[n])
int *nSV; // number of SVs for each class (nSV[n])
// nSV[0] + nSV[1] + ... + nSV[n-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
};
结构体svm_model用于保存训练后的训练模型,当然原来的训练参数也必须保留。
svm_parameter param; // 训练参数
int nr_class;// 类别数
int l; // 支持向量数
svm_node **SV; // 保存支持向量的指针,至于支持向量的内容,如果是从文件中读取,内容会
额外保留;如果是直接训练得来,则保留在原来的训练集中。如果训练完成后需要预报,原来的
训练集内存不可以释放。
double **sv_coef;//相当于判别函数中的alpha
double *rho; //相当于判别函数中的b
double *probA; // pariwise probability information
double *probB;//均为新增函数
int *label; // label of each class (label[n])
int *nSV; // number of SVs for each class (nSV[n])
int free_sv;//见svm_node **SV的注释