Visual Studio 2013使用Libsvm训练数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/AUTO1993/article/details/72081797

Visual Studio 2013使用Libsvm训练数据

最近在做周志华《机器学习》上面的习题时,需要使用linsvm库对西瓜数据集使用线性核和高斯核进行训练,比较其支持向量的差别,下面就简单的介绍一下,训练的过程。

在使用libsvm之前我们需要去官网下载最新的版本libsvm-3.22 libSVM的下载地址:http://www.csie.ntu.edu.tw/~cjlin/libsvm/

下载解压后文件如下:


新建VS2013工程,将上面下载文件中的 svm.cpp和svm.h添加到新建的工程中:


环境准备就这么简单,现在就可以开始编写代码文件main.cpp,读取数据文件,然后训练svm,下面是西瓜数据集3.0α 

0.697 0.460 1 
0.774 0.376 1 
0.634 0.264 1 
0.608 0.318 1 
0.556 0.215 1 
0.403 0.237 1 
0.481 0.149 1 
0.437 0.211 1 
0.666 0.091 0 
0.243 0.267 0 
0.245 0.057 0 
0.343 0.099 0 
0.639 0.161 0 
0.657 0.198 0 
0.360 0.370 0 
0.593 0.042 0 
0.719 0.103 0
main.cpp的完整代码如下:

#include<iostream>
#include<fstream>
#include<vector>
#include"svm.h"
#define PropertyNum 2  //数据集单个样本的属性个数,即特征值得个数
#define ModelSavePath "svm.xml"//模型文件保存路径名称

class ML_SVM
{
public:
	ML_SVM(const std::string &train_data_path)
	{
		TrainDataFilename = train_data_path;
	};
	void Train();
	void Predict();	
public:
	svm_model *svmModel;
private:
	void setParam();
	void readTrainData();
private:
	std::string TrainDataFilename;
	std::vector<svm_node*>data;
	std::vector<float>label;
	svm_parameter param;
	svm_problem prob;
	int SampleNum;
};

void ML_SVM::readTrainData()
{
	std::fstream Data;
	Data.open(TrainDataFilename);
	std::cout << "train data read begin..." << std::endl;
	SampleNum = 0;
	while (!Data.eof())
	{
		/*PropertyNum表示属性个数,即特征的维度*/
		svm_node* features = new svm_node[PropertyNum + 1];//因为需要结束标记,因此申请空间时特征维度+1 
		/*libSVM的数据格式:Label ,1:value 2:value ….*/
		for (int k = 0; k < PropertyNum; k++)
		{
		double value = 0;
		Data >> value;
		features[k].index = k + 1;//标号,从1开始  
		features[k].value = value;//特征值,属性值  
		}
		features[PropertyNum].index = -1;//结束标记  
		data.push_back(features);
		/*读标签*/
		double labelTemp; Data >> labelTemp;
		label.push_back(labelTemp);
		SampleNum++;
	}
	std::cout << "the number of train data is " << SampleNum << std::endl;
	std::cout << "train data read end" << std::endl;
	Data.close();
}

void ML_SVM::setParam()
{
	param.svm_type = C_SVC;
	param.kernel_type = LINEAR;
	param.degree = 3;
	param.gamma = 0.5;
	param.coef0 = 0;
	param.nu = 0.5;
	param.cache_size = 40;
	param.C = 1;
	param.eps = 1e-3;
	param.p = 0.1;
	param.shrinking = 1;
	param.nr_weight = 0;
	param.weight = NULL;
	param.weight_label = NULL;

}

void  ML_SVM::Train()
{
	/*加载训练数据*/
	readTrainData();
	prob.l = SampleNum;//训练样本个数 
	prob.x = new svm_node *[prob.l];//训练数据train data(features of all the training samples); 
	prob.y = new double[prob.l];//训练数据标签data label(label of all the training samples); 
	for (int i = 0; i < SampleNum; i++)
	{
		prob.x[i] = data[i];
		prob.y[i] = label[i];
	}
	/*设置训练参数*/
	setParam();
	/*开始训练SVM*/
	std::cout << "start training..." << std::endl;
	svmModel = svm_train(&prob, ¶m);
	svm_save_model(ModelSavePath, svmModel);
	std::cout << "model save done!" << std::endl;
}

void ML_SVM::Predict()
{

}

int main()
{
	ML_SVM svm("trainData.txt");
	svm.Train();
	int total_SV= svm.svmModel->l;;//支持向量的个数;
	 
	std::cout << "the total sv is " << total_SV<< std::endl;
	svm_node** sv; sv = svm.svmModel->SV;
	printf("每个类的支持向量机的个数: %d  %d\n", svm.svmModel->nSV[0], svm.svmModel->nSV[1]);	
	return 0;
}

下面是训练结束后生成的svm.xml文件的内容:
线性核训练文件内容如下:

svm_type c_svc
kernel_type linear
nr_class 2
total_sv 16
rho 1.1789
label 1 0
probA 2.03635
probB -0.172627
nr_sv 8 8
SV
1 1:0.697 2:0.46 
1 1:0.774 2:0.376 
1 1:0.634 2:0.264 
1 1:0.608 2:0.318 
1 1:0.556 2:0.215 
1 1:0.403 2:0.237 
1 1:0.481 2:0.149 
1 1:0.437 2:0.211 
-1 1:0.666 2:0.091 
-1 1:0.243 2:0.267 
-1 1:0.343 2:0.099 
-1 1:0.639 2:0.161 
-1 1:0.657 2:0.198 
-1 1:0.36 2:0.37 
-1 1:0.593 2:0.042 
-1 1:0.719 2:0.103 
高斯核训练文件内容如下:

svm_type c_svc
kernel_type rbf
gamma 0.5
nr_class 2
total_sv 16
rho 0.856587
label 1 0
probA 2.02543
probB -0.183112
nr_sv 8 8
SV
1 1:0.697 2:0.46 
1 1:0.774 2:0.376 
1 1:0.634 2:0.264 
1 1:0.608 2:0.318 
1 1:0.556 2:0.215 
1 1:0.403 2:0.237 
1 1:0.481 2:0.149 
1 1:0.437 2:0.211 
-1 1:0.666 2:0.091 
-1 1:0.243 2:0.267 
-1 1:0.343 2:0.099 
-1 1:0.639 2:0.161 
-1 1:0.657 2:0.198 
-1 1:0.36 2:0.37 
-1 1:0.593 2:0.042 
-1 1:0.719 2:0.103 

/**********svm 训练文件参数说明*****************

svm_type c_svc//所选择的svm类型,默认为c_svc

kernel_type rbf//训练采用的核函数类型,此处为RBF核

gamma 0.0769231//RBF核的参数γ

nr_class 2//类别数,此处为两分类问题

total_sv 132//支持向量总个数

rho 0.424462//判决函数的偏置项b

label 1 -1//原始文件中的类别标识

nr_sv 64 68//每个类的支持向量机的个数

SV//以下为各个类的权系数及相应的支持向量


***********************************/

从上面可以看出两种核函数训练得到的支持向量是一样的。和某博客给出的习题答案是一致的。

参考资料:

http://blog.csdn.net/zy_zhengyang/article/details/45009431

http://blog.csdn.net/u014691453/article/details/40393137

http://blog.csdn.net/lhanchao/article/details/53367532




猜你喜欢

转载自blog.csdn.net/AUTO1993/article/details/72081797