VS2017+OpenCV4.5.5 SVM-鸢尾花分类

支持向量机(SVM)
支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM还包括核技巧,这使它成为实质上的非线性分类器。SVM的的学习策略就是间隔最大化,可形式化为一个求解凸二次规划的问题,也等价于正则化的合页损失函数的最小化问题。SVM的的学习算法就是求解凸二次规划的最优化算法。

SVM算法原理
SVM学习的基本原理是求解能够正确划分训练数据集并且几何间隔最大的分离超平面。
如图,样本数据集是二维的,分散在平面上,需要找到一条直线将数据集分割开。可以分开的直线有很多,我们要找到其中泛化能力最好,鲁棒性最强的直线。如果是在三维空间中,则需要找到一个平面;如果是超过三维以上的维数,则需要找到一个超平面。
在这里插入图片描述
测试用例

鸢尾花数据集下载:http://download.tensorflow.org/data/iris_training.csv

#include<iostream>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/ml/ml.hpp>

using namespace std;
using namespace cv;
using namespace cv::ml;

int main(int argc, char *argv[])
{
    
    
	//训练样本:花萼长、花萼宽、花瓣长、花瓣宽
	int sample_num = 0;
	int data_dim = 0;
	char str1[36], str2[36], str3[36];
	FILE *fp;
	fp = fopen("D:\\download\\iris_training.csv", "r");
	fscanf(fp, "%d,%d,%s,%s,%s", &sample_num, &data_dim, &str1, &str2, &str3);
	Mat trainDataMat = cv::Mat::zeros(sample_num, data_dim, CV_32FC1);
	Mat labelsMat = cv::Mat::zeros(sample_num, 1, CV_32SC1);
	int cnt = 0;
	while (1) {
    
    
		fscanf(fp, "%f,%f,%f,%f,%d", &trainDataMat.ptr<float>(cnt)[0], &trainDataMat.ptr<float>(cnt)[1], &trainDataMat.ptr<float>(cnt)[2], &trainDataMat.ptr<float>(cnt)[3], &labelsMat.ptr<int>(cnt)[0]);
		cnt++;
		if (cnt == sample_num)
		{
    
    
			break;
		}
	}
	fclose(fp);
	//创建SVM分类器
	Ptr<SVM> svm_model = SVM::create();
	svm_model->setType(SVM::C_SVC);
	svm_model->setC(10.0);
	svm_model->setKernel(SVM::RBF);
	svm_model->setGamma( 8.0);
	svm_model->setTermCriteria(TermCriteria(cv::TermCriteria::EPS, 100, FLT_EPSILON));

	//创建TrainData并进行训练
	Ptr<TrainData> tData = TrainData::create(trainDataMat, ROW_SAMPLE, labelsMat);
	svm_model->train(tData);

	float myData[4] = {
    
     6.1,2.7,5.3,2.3 };// {6.7, 3.1, 4.7, 1.5};//测试样本
	Mat myDataMat(1, 4, CV_32FC1, myData);

	// 利用训练好的分类器进行测试样本预测
	int res = svm_model->predict(myDataMat);

	cout << endl << "The result is :  " << res << endl;
	svm_model.release();
	return 0;
}

测试结果:2

猜你喜欢

转载自blog.csdn.net/zfjBIT/article/details/128118655