libsvm如何调用svm.cpp进行训练和预测的具体过程

原文链接: https://blog.csdn.net/u010005161/article/details/50526034

这里写下关于libsvm中,从MATLAB文件夹中的svmtrain.c和svmpredict.c入口,如何调用svm.cpp的过程进行详细的解析。当遇到比较重要的新的函数时,会在后面列出这个函数的作用和详细执行的过程,以便自己能看懂。

注:这里主要侧重调用C_SVC的情况,以及当置b=1时的情况分析。


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

首先列在前面的是,头文件中需要了解并在后面函数中会用到的两个结构。

struct svm_problem

{

int l;   样本个数

double *y;   类别

struct svm_node **x;   一条样本的特征

};

 

struct svm_node  一个特征节点

{

int index;   特征序号

double value;  特征值

};


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Svm整个过程:

一、训练过程(直接进入svm.cpp进行分析)

进入函数,进行执行,最后会输出一个model

svm_model *svm_train(const svm_problem *prob, const svm_parameter *param)

1.先对同label的进行归纳

svm_group_classes(prob,&nr_class,&label,&start,&count,perm);

2.对两两各个类进行计算:

1)选出两类的数据,由于pro=1,故执行

svm_binary_svc_probability(&sub_prob,param,weighted_C[i],weighted_C[j],probA[p],probB[p]);

这里填充probA,probB的值

2)decision_function svm_train_one(const svm_problem *prob, const svm_parameter *param,double Cp, double Cn) decision_function包含alpha/rho系数的系数)

其中的solve_c_svc(prob,param,alpha,&si,Cp,Cn);函数进行求解,得到alpha/rho系数。

最后进行模型model的属性赋值。

 

 

细节/需要改的地方具体分析:

函数:

static void svm_binary_svc_probability(

const svm_problem *prob, const svm_parameter *param,

double Cp, double Cn, double& probA, double& probB)

作用:

对该函数,输入参数和数据,对proA/proB进行训练并赋值。

解析该函数:

该函数默认进行5折交叉,先交叉,得到部分数据,进行部分训练,

struct svm_model *submodel = svm_train(&subprob,&subparam);

然后进行其他数据进行验证,

svm_predict_values(submodel,prob->x[perm[j]],&(dec_values[perm[j]]));

dec_values[perm[j]] *= submodel->label[0];

(输入刚刚训练好的模型,一个样本的特征,来得到决策值f(x),再求y*f(x)

最后,将得到的决策值,和样本输入,进行sigmoid训练,得到系数A.B的值

sigmoid_train(prob->l,dec_values,prob->y,probA,probB);

 

函数:

double svm_predict_values(const svm_model *model, const svm_node *x, double* dec_values)

作用:

给定model和一个样本的特征,得到决策值。返回的是投票最多的类别。

注:dec_values是一个数组,有nr_class*(nr_class-1)/2个值。

解析该函数:

对两两类的向量进行比较,找出比较的两个不同类别的向量(start是每类开始的位置,nSV是支持向量的个数)

sum += coef1[si+k] * kvalue[si+k];   将第一类的式子进行计算, alpha*K(X,xi)

最后得到,y=alpha*K(x,xi)-b的值dec_values

若要得到这个样本属于哪一类,则进行两两类测试,并投票,票数多的决定它的类别。

 

函数:

static void sigmoid_train(int l, const double *dec_values, const double *labels, double& A, double& B)

输入决策之和label,训练系数AB

 

 

 

 


 

二、预测过程

svmpredict.c文件中。进入predict函数

Pro=1,则执行函数

predict_label = svm_predict_probability(model, x, prob_estimates);

得到预测的label。也得到估计概率prob_estimates 若有三类,则prob_estimates有三个值。

然后将得到的概率值返回到 ptr_prob_estimates

ptr_prob_estimates[instance_index + i * testing_instance_number] = prob_estimates[i];

*ptr_prob_estimates指针指向tplhs[2]。(pro=1

*ptr_dec_values也指向tplhs[2]。(pro=0

给指针ptr_prob_estimates赋值就是给tplhs[2]赋值。而tplhs[2]赋值给plhs

plhs就是predict(int nlhs, mxArray *plhs[], const mxArray *prhs[], struct svm_model *model, const int predict_probability)中的参数。

Prhs 是从MATLAB输入的测试标记,测试特征。

plhs是从MATLAB返回的三个参数。

tplhs有三个参数,第一个是预测的label

Tplhs[0]  =  ptr_predict_label

Tplhs[1]  =  三个值 return accuracy, mean squared error, squared correlation coefficient

Tplhs[2]  =   ptr_prob_estimates(概率值) 或者 ptr_dec_values(预测值)

(注:该函数中,prhs[0]对应输入的测试标记Y_test,prhs[1]对应输入的预测特征。)

pro=0,则执行函数

predict_label = svm_predict_values(model, x, dec_values);

 

 

函数(在svm.cpp中):

double svm_predict_probability(const svm_model *model, const svm_node *x, double *prob_estimates)

作用:输入模型model,一个样本的特征,得到概率估计的值prob_estimates。同时返回该样本的label

解析该函数:

1. pro=1

1)则先调用svm_predict_values(model, x, dec_values);得到样本x对应的nr_class*(nr_class-1)/2个值。

2)然后进行两两类别,得到属于这两两类别的概率值,即调用static double sigmoid_predict(double decision_value, double A, double B)得到sigmoid的函数值。

注:进行的两两比较是这样进行的:如有三个类别0,1,2.则进行0->1,0->2,1->2.进行两两类别对峙。

3)然后调用函数

multiclass_probability(nr_class,pairwise_prob,prob_estimates);

得到每个类别的概率值,如prob_estimates有三个值,分别对应3个类别的概率值。

4)最后计算哪个类别的概率最大,返回该类别的值。

2. pro-0, 则调用double svm_predict(const svm_model *model, const svm_node *x),这个函数是调用函数double pred_result = svm_predict_values(model, x, dec_values); 得到最后属于哪个类别的值pred_result


至此,能够把整体的顺序过了一遍。这里只列出比较重点的函数分析,其他的函数和结构自己依照svm.cpp中的函数过程去看。


你可能感兴趣的:(libsvm如何调用svm.cpp进行训练和预测的具体过程)