SVM实验报告Word文件下载.docx
《SVM实验报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《SVM实验报告Word文件下载.docx(11页珍藏版)》请在冰豆网上搜索。
//指向一个存储内容为指针的数组
};
其中svm_node的结构体定义如下:
structsvm_node//用来存储输入空间中的单个特征
intindex;
//输入空间序号,假设输入空间数为m
doublevalue;
//该输入空间的值
所以,prob也可以说是问题的指针,它指向样本数据的类别和输入向量,在内存中的具体结构图如下:
图1.1LIBSVM训练时,样本数据在内存中的存放结构
只需在内存中申请n*(m+1)*sizeof(structsvm_node)大小的空间,并在里面填入每个样本的每个输入空间的值,即可在程序中完成prob参数的设置。
参数param,是svm_parameter数据结构,具体结构定义如下:
structsvm_parameter//训练参数
intsvm_type;
//SVM类型,
intkernel_type;
//核函数类型
intdegree;
/*forpoly*/
doublegamma;
/*forpoly/rbf/sigmoid*/
doublecoef0;
/*forpoly/sigmoid*/
/*thesearefortrainingonly*/
doublecache_size;
/*inMB制定训练所需要的内存*/
doubleeps;
/*stoppingcriteria*/
doubleC;
/*forC_SVC,EPSILON_SVRandNU_SVR,惩罚因子*/
intnr_weight;
/*forC_SVC权重的数目*/
int*weight_label;
/*forC_SVC权重,元素个数由nr_weight决定*/
double*weight;
/*forC_SVC*/
doublenu;
/*forNU_SVC,ONE_CLASS,andNU_SVR*/
doublep;
/*forEPSILON_SVR*/
intshrinking;
/*usetheshrinkingheuristics指明训练过程是否使用压缩*/
intprobability;
/*doprobabilityestimates指明是否要做概率估计*/
}
其中,SVM类型和核函数类型如下:
enum{C_SVC,NU_SVC,ONE_CLASS,EPSILON_SVR,NU_SVR};
/*svm_type*/
enum{LINEAR,POLY,RBF,SIGMOID,PRECOMPUTED};
/*kernel_type*/
只需申请一个svm_parameter结构体,并按实际需要设定SVM类型、核函数和各种参数的值即可完成参数param的设置。
设定完这两个参数,就可以直接在程序中调用训练函数进行训练了,该其函数返回一个structsvm_model*SVM模型的指针,可以使用svm_save_model(constchar*model_file_name,conststructsvm_model*model)函数,把这个模型保存在磁盘中。
至此,训练函数的移植已经完成。
(2)doublesvm_predict(conststructsvm_model*model,conststructsvm_node*x);
参数model,是一个SVM模型的指针,可以使用函数structsvm_model*svm_load_model(constchar*model_file_name),导入训练时保存好的SVM模型,此函数返回一个SVM模型的指针,可以直接赋值给变量model。
参数x,是conststructsvm_node结构体的指针,本意是一个输入空间的指针,但实际上,该函数执行的时候,是从参数x处计算输入空间,直到遇到单个样本数据结束标记-1才结束,也就是说,该函数运算了单个样本中的所有输入空间数据。
因此,在调用此函数时,必须先把预测样本的数据按图3.4中的固定格式写入内存中。
另外,该函数只能预测一个样本的值,本文需要对图像中的所有像数点预测,就要使用for循环反复调用。
该函数返回一个double类型,指明被预测数据属于哪个类。
面对两分类问题的时候,通常使用+1代表正样本,即类1;
-1代表负样本,即类2。
最后根据返回的double值就可以知道预测数据的类别了。
三、算法源代码及注释说明
1、需要在工程中添加头文件svm.h和源文件svm.cpp
2、自己编写的源代码(C++实现)(共230行):
#include"
svm.h"
#include<
iostream>
list>
iterator>
vector>
string>
ctime>
usingnamespacestd;
#ifdefWIN32
#pragmawarning(disable:
45144786)
#endif
svm_parameterparam;
svm_problemprob;
svm_model*svmModel;
list<
svm_node*>
xList;
double>
yList;
constintMAX=10;
constintnTstTimes=10;
vector<
int>
predictvalue;
realvalue;
inttrainNum=0;
//设置参数
voidsetParam()
param.svm_type=C_SVC;
param.kernel_type=RBF;
param.degree=3;
param.gamma=0.5;
param.coef0=0;
param.nu=0.5;
param.cache_size=40;
param.C=500;
param.eps=1e-3;
param.p=0.1;
param.shrinking=1;
//param.probability=0;
param.nr_weight=0;
param.weight=NULL;
param.weight_label=NULL;
voidtrain(char*filePath)
FILE*fp;
intk;
intline=0;
inttemp;
if((fp=fopen(filePath,"
rt"
))==NULL)
return;
while
(1)
{
svm_node*features=newsvm_node[85+1];
for(k=0;
k<
85;
k++)
{
fscanf(fp,"
%d"
&
temp);
features[k].index=k+1;
features[k].value=temp/(MAX*1.0);
}
features[85].index=-1;
fscanf(fp,"
xList.push_back(features);
yList.push_back(temp);
line++;
trainNum=line;
if(feof(fp))
break;
}
setParam();
prob.l=line;
prob.x=newsvm_node*[prob.l];
//对应的特征向量
prob.y=newdouble[prob.l];
//放的是值
intindex=0;
while(!
xList.empty())
prob.x[index]=xList.front();
prob.y[index]=yList.front();
xList.pop_front();
yList.pop_front();
index++;
//std:
:
cout<
<
prob.l<
"
listend\n"
;
svmModel=svm_train(&
prob,&
param);
\n"
over\n"
//保存model
svm_save_model("
model.txt"
svmModel);
//释放空间
deleteprob.y;
delete[]prob.x;
svm_free_and_destroy_model(&
svmModel);
voidpredict(char*filePath)
svm_model*svmModel=svm_load_model("
);
FILE*fp;
svm_node*input=newsvm_node[85+1];
for(intk=0;
input[k].index=k+1;
input[k].value=temp/(MAX*1.0);
input[85].index=-1;
intpredictValue=svm_predict(svmModel,input);
predictvalue.push_back(predictValue);
cout<
predictValue<
endl;
voidwriteValue(vector<
&
v,stringfilePath)
FILE*pfile=fopen("
filePath"
"
wb"
vector<
iteratoriter=v.begin();
char*c=newchar[2];
for(;
iter!
=v.end();
++iter)
c[1]='
\n'
if(*iter==0)
c[0]='
0'
else
c[0]='
1'
fwrite(c,1,2,pfile);
fclose(pfile);
deletec;
boolgetRealValue()
if((fp=fopen("
tictgts2000.txt"
returnfalse;
realvalue.push_back(temp);
returntrue;
doublegetAccuracy()
if(!
getRealValue())
return0.0;
intcounter=0;
intcounter1=0;
for(inti=0;
i<
realvalue.size();
i++)
if(realvalue.at(i)==predictvalue.at(i))
counter++;
//测试正确的个数
if(realvalue.at(i)==1)
counter1++;
//cout<
realvalue.size()<
//目标值为1的记录测试真确的个数
returncounter*1.0/realvalue.size();
intmain()
clock_tt1,t2,t3;
cout<
请稍等待..."
t1=clock();
train("
ticdata2000.txt"
//训练
t2=clock();
predict("
ticeval2000.txt"
//预测
t3=clock();
writeValue(predictvalue,"
result.txt"
//将预测值写入到文件
doubleaccuracy=getAccuracy();
//得到正确率
训练数据共:
trainNum<
条记录"
测试数据共:
训练的时间:
1.0*(t2-t1)/nTstTimes<
ms"
预测的时间:
1.0*(t3-t2)/nTstTimes<
测试正确率为:
accuracy*100<
%"
return0;
四、算法获得的模型
1、模型说明
改算法svm(支持向量机)用两个核心函数,第一个是structsvm_model*svm_train(conststructsvm_problem*prob,conststructsvm_parameter*param),设定好参数之后,运行改函数,该函数返回一个structsvm_model*SVM模型的指针,可以使用svm_save_model(constchar*model_file_name,conststructsvm_model*model)函数,把这个模型保存在磁盘中。
第二个是doublesvm_predict(conststructsvm_model*model,conststructsvm_node*x);
2、查看模型
我们可以查看源文中的model.txt文件。
以下是部分内容:
svm_typec_svc
kernel_typerbf
gamma0.5
nr_class2
total_sv1333
rho-2.12543
label01
nr_sv995338
SV
10.736583147298251:
3.92:
0.23:
0.34:
0.25:
0.96:
0.27:
0.28:
09:
0.510:
0.711:
0.212:
013:
014:
0.315:
0.616:
017:
0.418:
0.519:
020:
021:
022:
0.423:
0.124:
0.525:
026:
0.127:
0.428:
0.529:
030:
0.631:
0.332:
0.833:
034:
0.135:
0.936:
037:
0.438:
0.339:
0.340:
041:
042:
0.343:
0.544:
045:
046:
047:
0.648:
049:
050:
051:
052:
053:
054:
055:
056:
057:
058:
059:
060:
061:
062:
063:
064:
065:
066:
067:
068:
0.169:
070:
071:
072:
073:
074:
075:
076:
077:
078:
079:
080:
081:
082:
083:
084:
085:
0
8.406931039506561:
1.12:
0.35:
0.36:
0.37:
0.58:
0.210:
012:
0.213:
0.214:
0.215:
0.220:
0.323:
0.324:
0.325:
0.126:
0.227:
0.128:
0.429:
0.230:
031:
0.932:
0.633:
0.134:
0.235:
0.636:
0.337:
0.238:
0.141:
0.443:
0.744:
0.245:
048:
0.360:
0.166:
069:
0.181:
6.8681275878434911:
12:
0.13:
0.44:
0.17:
0.48:
0.19:
0.410:
0.112:
0.417:
0.318:
0.319:
0.923:
024:
025:
0.326:
027:
0.628:
029:
0.234:
0.536:
0.437:
038:
0.240:
0.241:
0.242:
0.843:
5001:
3.32:
0.24:
0.86:
0.611:
0.313:
0.314:
0.415:
0.316:
0.117:
0.120:
0.121:
0.224:
0.425:
0.228:
0.130:
0.531:
0.432:
0.335:
0.736:
0.237:
0.338:
0.439:
0.344:
五、实验结果