转载 libsvm vc 移植 实现多类分类
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;
}

浙公网安备 33010602011771号