《libsvm分类小例c++》由会员分享,可在线阅读,更多相关《libsvm分类小例c++(7页珍藏版)》请在金锄头文库上搜索。
1、使用 libSVM 求解分类问题的 C+小例1. libSVM 简介训练模型的结构体struct svm_problem /储存参加计算的所有样本int l; /记录样本总数double *y; /指向样本类别的组数struct svm_node *x;/数据样本;当样本类别事先已经被告知时,可以通过数字来给样本数据进行标识(如果是两类通常以 1 与-1 来表示)。如果不清楚样本类别可以用样本个数编号来设置,这时候分类的准确率也就无法判定了。数据样本是一个二维数组,其中每个单元格储存的是一个 svm_node,y 与样本数据的对应关系为:数据节点的结构体struct svm_node /储存单
2、一向量的单个特征int index; /索引double value; /值;如果需要储存向量 ,就可以使用 6 个 svm_node 来=(1, 121, 12321, 121, 1)保存,内存映像为:index 1 2 3 4 5 -1value 1 121 12321 121 1 NULL注意:向量是以索引值为 -1 的元素为结束标志位的。如果没有标志位将导致程序崩溃。SVM 模型类型枚举enum C_SVC, NU_SVC, ONE_CLASS, EPSILON_SVR, NU_SVR ; C_SVC:C 表示惩罚因子, C 越大表示对错误分类的惩罚越大 NU_SVC:和 C_SVC
3、相同。 ONE_CLASS:不需要类标号,用于支持向量的密度估计和聚类. EPSILON_SVR: -不敏感损失函数,对样本点来说,存在着一个不为目标函数提供任何损失值的区域,即 -带。 NU_SVR:由于 EPSILON_SVR 需要事先确定参数 ,然而在某些情况下选择合适的参数却不是一件容易的事情。而 NU_SVR 能够自动计算参数 。注意: C_SVC 与 NU_SVC 其实采用的模型相同,但是它们的参数 C 的范围不同 C_SVC 采用的是 0 到正无穷, NU_SVC 是 0,1。核函数类型枚举enum LINEAR, POLY, RBF, SIGMOID, PRECOMPUTED
4、; LINEAR:线性核函数(linear kernel) POLY:多项式核函数(ploynomial kernel) RBF:径向机核函数(radical basis function) SIGMOID: 神经元的非线性作用函数核函数(Sigmoid tanh) PRECOMPUTED:用户自定义核函数计算模型参数结构体struct svm_parameterint svm_type; /支持向量机模型类型int kernel_type; /核函数类型int degree; /* 使用于POLY模型 */double gamma; /* for poly/rbf/sigmoid */dou
5、ble coef0; /* for poly/sigmoid */* these are for training only */double cache_size; /* 缓存块大小(MB) */double eps; /* 终止条件(默认0.001) */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
6、NU_SVC, ONE_CLASS, and NU_SVR */double p; /* for EPSILON_SVR */int shrinking; /*指明训练过程是否使用压缩 */int probability; /*指明是否要做概率估计*/;结构体 svm_model用于保存训练后的训练模型,当然原来的训练参数也必须保留。struct svm_modelstruct svm_parameter param; /*训练参数 */int nr_class; /*类别数, = 2 in regression/one class svm */int l; /*支持向量数 */struct
7、svm_node *SV; /*支持向量的指针 */double *sv_coef; /*相当于判别函数中的alpha */double *rho; /*相当于判别函数中的b */double *probA; /* pariwise probability information */double *probB; /* for classification only */int *label; /* label of each class (labelk) */int *nSV; /* number of SVs for each class (nSVk) */* nSV0 + nSV1 +
8、. + nSVk-1 = l */int free_sv;/* 1 if svm_model is created by svm_load_model*/* 0 if svm_model is created by svm_train */;2. 程序代码实现这里定义 SVMExample 类,类主要成员变量为:struct svm_parameter param; /模型参数struct svm_problem prob;/struct svm_model *model; /struct svm_node *x_space; /构造函数构造函数里主要进行参数的初始化,和基本函数的调用para
9、m.svm_type = C_SVC;param.kernel_type = LINEAR;param.degree = 3;param.gamma = 0; / 1/num_featuresparam.coef0 = 0;param.nu = 0.5;param.cache_size = 1;/缓存块大小param.C = 1;param.eps = 1e-3;param.p = 0.1;param.shrinking = 1;param.probability = 0;param.nr_weight = 0;param.weight_label = NULL;param.weight =
10、NULL;cross_validation = 0;核函数的选取直接影响到分类的结果,如何正确选取核函数就需要使用者对数据的特性有所了解,根据实际情况,这里的核函数选用的是线性的。成员函数一:初始化样本数据样本选取是学生的身高和体重:男1:身高:190cm,体重:70kg;男2:身高:180cm,体重:80kg;女1:身高:161cm,体重:80kg;女2:身高:161cm,体重:47kg;这里由于事先已经知道样本有男女类别之分,所以设置男生标签为-1,女生标签为1,相对于程序中的y值。void SVMExample:initliazeData()struct svm_node *_node
11、= Malloc(struct svm_node*, 4);x_space = Malloc(svm_node, 3);x_space0.index = 1;x_space0.value = 190;x_space1.index = 2;x_space1.value = 70;x_space2.index = -1;_node0 = x_space;x_space = Malloc(svm_node, 3);x_space0.index = 1;x_space0.value = 180;x_space1.index = 2;x_space1.value = 80;x_space2.index
12、= -1;_node1 = x_space;x_space = Malloc(svm_node, 3);x_space0.index = 1;x_space0.value = 161;x_space1.index = 2;x_space1.value = 45;x_space2.index = -1;_node2 = x_space;x_space = Malloc(svm_node, 3);x_space0.index = 1;x_space0.value = 163;x_space1.index = 2;x_space1.value = 47;x_space2.index = -1;_no
13、de3 = x_space;double *y1 = Malloc(double, 4);y10 = -1;y11 = -1;y12 = 1;y13 = 1;prob.l = 4;prob.x = _node;prob.y = y1;成员函数二:训练样本数据,得出模型void SVMExample:analysisData()const char *error_msg;error_msg = svm_check_parameter(if(error_msg)fprintf(stderr, nerror:%sn, error_msg);exit(1);/如果有必要可以进行交叉性检验/*if(cr
14、oss_validation)do_cross_validation();*/model = svm_train(成员函数三:预测数据预测数据1:身高180cm,体重85kg;预测数据2:身高161cm,体重50kg;void SVMExample:displayResult()/进行预报struct svm_node *node1 = Malloc(svm_node, 3);node10.index = 1;node10.value = 180;node11.index = 2;node11.value = 85;node12.index = -1;double r1 = svm_predi
15、ct(model, node1);printf(预测值r1:%fn , r1);free(node1);struct svm_node *node2 = Malloc(svm_node, 3);node20.index = 1;node20.value = 161;node21.index = 2;node21.value = 50;node22.index = -1;double r2 = svm_predict(model, node2);printf(预测值r2:%fn , r2);free(node2);预测结果得出分类结果:预测样本1的输出为-1(男),预测样本2的输出为1(女)。如果有需要的话请联系: