http://zllxsha.blog.163.com/blog/static/50555091201010981932412/ by piglet
在网上找了很久关于libsvm 在vc上的移植,网上大部分讲的都是两类的分类
在此分享下,我实现了多类的分类
代码对于提取的数据,可能在部分的地方需要修改,比如样本的个数等
当然,工程中需要包含svm.h,svm.cpp
代码如下:
#include <stdio.h> #include <ctype.h> #include <list> #include "svm.h" //包涵本目录下的SVM.H头文件 #include <fstream> #include <iostream> #include <string> using namespace std; void main() { /* struct svm_problem { int l; double *y; struct svm_node **x; }; struct svm_node { int index; double value; }; */ ifstream inFile; ifstream inFile1; ofstream outFile("out.txt"); ofstream outFile1("out2.txt"); svm_problem prob; //建立SVM数据 prob.l=2262; //80个样本,前40个为正样本,train.1.txt=3089,train.2.txt = 2262 double d[2262]; int probfeature=6; //样本特征维数 prob.y=new double[prob.l]; svm_parameter param; //svm参数设置 param.svm_type = C_SVC; param.kernel_type = RBF; param.degree = 3; param.gamma = 0.0001; param.coef0 = 0; param.nu = 0.5; param.cache_size = 100; param.C = 10; param.eps = 1e-5; param.p = 0.1; param.shrinking = 1; param.probability = 0; param.nr_weight = 0; param.weight_label = NULL; param.weight = NULL; //分类 if(param.gamma == 0) param.gamma = 0.5; //gamma for poly/rbf/sigmoid svm_node *x_space = new svm_node[(probfeature+1) * prob.l]; //样本特征存储空间 prob.x = new svm_node *[prob.l]; //每一个X指向一个样本 //数据填充开始 inFile.open("train.2.txt"); //打开训练数据文件 for(int i=0;i<prob.l;i++)//prob.l 总样本数 { /**/ float fvalue; int cn,cn2; char ch; inFile>>cn; outFile<<cn<<" "; for (int j=0;j<probfeature;j++) { inFile>>cn2>>ch>>fvalue; if(fvalue!=0.0) { x_space[(probfeature+1)*i+j].index=j+1; x_space[(probfeature+1)*i+j].value=fvalue; } outFile<<cn2<<ch<<fvalue<<" "; } x_space[(probfeature+1)*i+probfeature].index=-1; prob.x[i]=&x_space[(probfeature+1)*i]; prob.y[i] = cn; outFile<<prob.y[i]<<endl; // if (i<2000) //类别标签,两类的时候 //{ // prob.y[i]=1; // outFile<<"1"<<endl; //} // else //{ // prob.y[i]=-1; // outFile<<"-1"<<endl; //} } outFile.close(); inFile.close(); //关闭文件 //数据填充结束 // build model & classify svm_model *model = svm_train(&prob, ¶m); //开始训练 int test_num=1109; //test.1.txt = 4000; test.2.txt = 1109 inFile1.open("test.2.txt"); svm_node x[7]; //定义一个测试样本 double d2[1109]; int right=0; for(int i1=0;i1<test_num;i1++) { float fvalue; int cn,cn2; char ch; inFile1>>cn; outFile1<<cn<<" "; for (int j=0;j<probfeature;j++) { inFile1>>cn2>>ch>>fvalue; //cout<<"fvalue: "<<fixed<<fvalue<<endl; if(fvalue!=0.0) { x[j].index=j+1; x[j].value=fvalue; //cout<<x[j].index<<" "<<x[j].value<<endl; } outFile1<<cn2<<ch<<fvalue<<" "; } x[7].index=-1;////////////********************为什么要多一个值,而且还是空的*****************?????////// d2[i1]=svm_predict(model,x); //cout<<"cn: "<<cn<<" d2[i1]: "<<d2[i1]<<" "<<endl; outFile1<<d2[i1]<<endl; if(d2[i1] == cn) right++; //if(cn==1&&d2[i1]==1)//当2类的时候,判断分类 // right++; //if(cn==0&&d2[i1]==-1) // right++; } inFile1.close(); //outFile1.close(); x[0].index=1; x[0].value = 0.2; x[1].index=2; x[1].value = 0.2; x[2].index=3; x[2].value = 0.2; x[3].index=4; x[3].value = 0.2; cout<<"svm_predict(model,x): "<<svm_predict(model,x)<<endl; svm_destroy_model(model); delete[] x_space; delete[] prob.x; delete[] prob.y; cout<<"accuracy: "<<right<<"/"<<test_num<<" "<<(float)right/(float)test_num<<endl; }