机器学习常见算法

1.朴素贝叶斯:

在使用时,有一个前提假设:各特征独立。在用贝叶斯公式之前,最好先看下全概率公式。用c表示类别,f表示特征。则贝叶斯课表示为:

             p(c|f_{1}f_{2}...f_{n})=\frac{p(f_{1}f_{2}...f_{n}|c)p(c)}{p(f_{1}f_{2}...f_{n})}=\frac{p(f_{1}|c)p(f_{2}|c)...p(f_{n}|c)p(c)}{p(f_{1})p(f_{2})...p(f_{n})}

在计算时,记得要拉普拉斯平滑,具体公式看西瓜书。还可以看看数据挖掘领域十大经典算法之—朴素贝叶斯算法机器学习之朴素贝叶斯(NB)分类算法与Python实现

OpenCV下的NormalBayesClassifier(训练的时间太长,不太好用):

void main()
{
	Mat classes;
	Mat trainingData;

	Mat trainingImage;
	Mat trainingLables;

	string imgname;
	ifstream fin("C:/Users/Administrator/Desktop/num/0/zero.txt");//C:/Users/Administrator/Desktop/num/0/0.txt
	while (getline(fin, imgname))
	{
		imgname = "C:/Users/Administrator/Desktop/num/0/" + imgname;//C:/Users/Administrator/Desktop/num/0/
		Mat img = imread(imgname,0);
		img = img.reshape(1, 1);
		trainingImage.push_back(img);
		trainingLables.push_back(0);
	}
	cout << "loading 0---" << endl;
	string imgname_2;
	ifstream fin_2("C:/Users/Administrator/Desktop/num/1/one.txt");//C:/Users/Administrator/Desktop/num/1/1.txt
	while (getline(fin_2, imgname_2))
	{
		imgname_2 = "C:/Users/Administrator/Desktop/num/1/" + imgname_2;//C:/Users/Administrator/Desktop/num/1/
		Mat img = imread(imgname_2,0);
		img = img.reshape(1, 1);
		trainingImage.push_back(img);
		trainingLables.push_back(1);
	}
	cout << "loading 1---" << endl;
	Mat(trainingImage).copyTo(trainingData);
	trainingData.convertTo(trainingData,CV_32FC1);
	Mat(trainingLables).copyTo(classes);
	/*classes.convertTo(classes,CV_32FC1);*/

	Ptr<NormalBayesClassifier> Nb= NormalBayesClassifier::create();
	cout << "trainging---" << endl;
	Nb->train(trainingData, cv::ml::ROW_SAMPLE, classes);
	//Nb->save("Nb.xml");
	cout << "finish---save model" << endl;



	Mat classes_test;
	Mat trainingData_test;

	Mat trainingImage_test;
	Mat trainingLables_test;

	string imgname_test;
	ifstream fin_test("C:/Users/Administrator/Desktop/num/0/zero.txt");//C:/Users/Administrator/Desktop/num/test/0/0.txt
	while (getline(fin_test, imgname_test))
	{
		imgname_test = "C:/Users/Administrator/Desktop/num/0/" + imgname_test;
		Mat img = imread(imgname_test,0);
		img = img.reshape(1, 1);
		trainingImage_test.push_back(img);
		trainingLables_test.push_back(0);
	}

	string imgname_2_test;
	ifstream fin_2_test("C:/Users/Administrator/Desktop/num/1/one.txt");//C:/Users/Administrator/Desktop/num/test/1/1.txt
	while (getline(fin_2_test, imgname_2_test))
	{
		imgname_2_test = "C:/Users/Administrator/Desktop/num/1/" + imgname_2_test;
		Mat img = imread(imgname_2_test,0);
		img = img.reshape(1, 1);
		trainingImage_test.push_back(img);
		trainingLables_test.push_back(1);
	}

	Mat(trainingImage_test).copyTo(trainingData_test);
	trainingData_test.convertTo(trainingData_test, CV_32FC1);
	Mat(trainingLables_test).copyTo(classes_test);
	Mat re;
	Mat prob;
	Mat res;

	Nb->predictProb(trainingData_test, re,prob);
	cout<<"re:" <<endl<< re << endl;
	cout <<"prob:"<<endl<<prob << endl;
	waitKey(0);
}

期间报错的主要原因都是:训练时或者测试时未正确读取图片。这种算法不太好,训练耗时太长。问题参考了:Python图像处理(12):贝叶斯分类器在opencv3中实现机器学习之:利用正态贝叶斯分类练习

2.KNN:

knn既可以用于分类,也可以用于回归。knn的基本步骤就是计算距离,排序,选择距离最小的K个点,找那K个点里找label次数最多的那个点即为所分的得类。推荐算法用的比较多。

OpenCV下的KNN:

void main()
{
	Mat classes;
	Mat trainingData;

	Mat trainingImage;
	Mat trainingLables;

	string imgname;
	ifstream fin("C:/Users/Administrator/Desktop/num/0/0.txt");//C:/Users/Administrator/Desktop/num/0/0.txt
	while (getline(fin, imgname))
	{
		imgname = "C:/Users/Administrator/Desktop/num/0/" + imgname;//C:/Users/Administrator/Desktop/num/0/
		Mat img = imread(imgname,0);
		if (!img.data)
		{
			cout << "no img" << endl;
			break;
		}
		img = img.reshape(1, 1);
		trainingImage.push_back(img);
		trainingLables.push_back(0);
	}
	cout << "loading 0---" << endl;
	string imgname_2;
	ifstream fin_2("C:/Users/Administrator/Desktop/num/1/1.txt");//C:/Users/Administrator/Desktop/num/1/1.txt
	while (getline(fin_2, imgname_2))
	{
		imgname_2 = "C:/Users/Administrator/Desktop/num/1/" + imgname_2;//C:/Users/Administrator/Desktop/num/1/
		Mat img = imread(imgname_2,0);
		if (!img.data)
		{
			cout << "no img" << endl;
			break;
		}
		img = img.reshape(1, 1);
		trainingImage.push_back(img);
		trainingLables.push_back(1);
	}
	cout << "loading 1---" << endl;
	Mat(trainingImage).copyTo(trainingData);
	trainingData.convertTo(trainingData,CV_32FC1);
	Mat(trainingLables).copyTo(classes);
	classes.convertTo(classes,CV_32FC1);
	cout << trainingData.cols << endl;
	Ptr<KNearest> knn= KNearest::create();
	knn->setDefaultK(4);
	knn->setIsClassifier(true);
	knn->setAlgorithmType(cv::ml::KNearest::BRUTE_FORCE);
	cout << "trainging---" << endl;
	knn->train(trainingData, cv::ml::ROW_SAMPLE, classes);
	//knn->save("knn.xml");
	cout << "finish---save model" << endl;

	Mat classes_test;
	Mat trainingData_test;

	Mat trainingImage_test;
	Mat trainingLables_test;

	string imgname_test;
	ifstream fin_test("C:/Users/Administrator/Desktop/num/test/0/0.txt");//C:/Users/Administrator/Desktop/num/0/zero.txt
	while (getline(fin_test, imgname_test))
	{
		imgname_test = "C:/Users/Administrator/Desktop/num/test/0/" + imgname_test;
		Mat img = imread(imgname_test,0);
		img = img.reshape(1, 1);
		cout << "--" << img.size() << endl;
		if (!img.data)
		{
			cout << "no img" << endl;
			break;
		}
		trainingImage_test.push_back(img);
		trainingLables_test.push_back(0);
	}

	string imgname_2_test;
	ifstream fin_2_test("C:/Users/Administrator/Desktop/num/test/1/1.txt");//C:/Users/Administrator/Desktop/num/1/one.txt
	while (getline(fin_2_test, imgname_2_test))
	{
		imgname_2_test = "C:/Users/Administrator/Desktop/num/test/1/" + imgname_2_test;
		Mat img = imread(imgname_2_test,0);
		if (!img.data)
		{
			cout << "no img" << endl;
			break;
		}
		img = img.reshape(1, 1);
		cout << "--" << img.size() << endl;
		trainingImage_test.push_back(img);
		trainingLables_test.push_back(1);
	}

	Mat(trainingImage_test).copyTo(trainingData_test);
	trainingData_test.convertTo(trainingData_test, CV_32FC1);
	Mat(trainingLables_test).copyTo(classes_test);
	classes_test.convertTo(classes_test,CV_32FC1);
	Mat re;
	knn->predict(trainingData_test,re);
	cout<<calculateAccuracyPercent(classes_test,re)<<endl;
	waitKey(0);
}

调试过程中报错原因有:1.最后Mat的类型(train和test的要一致),2.是否正确读取到图片。主要参考了:在opencv3中的机器学习算法 OpenCV3.3中 K-最近邻法(KNN)接口简介及使用

3.LogisticRegression:

OpenCV中的LogisticRegression(LogisticRegression):

训练:

void main()
{
	Mat classes;
	Mat trainingData;

	Mat trainingImage;
	Mat trainingLables;

	string imgname;
	ifstream fin("C:/Users/Administrator/Desktop/num/0/0.txt");
	while (getline(fin, imgname))
	{
		imgname = "C:/Users/Administrator/Desktop/num/0/" + imgname;
		Mat img = imread(imgname);
		img = img.reshape(1, 1);
		trainingImage.push_back(img);
		trainingLables.push_back(0);
	}
	cout << "loading 0---" << endl;
	string imgname_2;
	ifstream fin_2("C:/Users/Administrator/Desktop/num/1/1.txt");
	while (getline(fin_2, imgname_2))
	{
		imgname_2 = "C:/Users/Administrator/Desktop/num/1/" + imgname_2;
		Mat img = imread(imgname_2);
		img = img.reshape(1, 1);
		trainingImage.push_back(img);
		trainingLables.push_back(1);
	}
	cout << "loading 1---" << endl;
	Mat(trainingImage).copyTo(trainingData);
	trainingData.convertTo(trainingData,CV_32FC1);
	Mat(trainingLables).copyTo(classes);
	classes.convertTo(classes,CV_32FC1);

	Ptr<LogisticRegression> lr= LogisticRegression::create();
	lr->setLearningRate(0.0001);
	lr->setIterations(100);
	lr->setRegularization(cv::ml::LogisticRegression::REG_DISABLE);
	lr->setTrainMethod(cv::ml::LogisticRegression::MINI_BATCH);
	lr->setMiniBatchSize(1);
	cout << "trainging---" << endl;
	lr->train(trainingData, cv::ml::ROW_SAMPLE, classes);
	lr->save("lr.xml");
	cout << "finish---save model" << endl;
	waitKey(0);
}

调试过程中报错:

OpenCV Error: Bad argument (data must be of floating type) in cv::ml::LogisticRe
gressionImpl::predict, file F:\OpenCV3.3\opencv\sources\modules\ml\src\lr.cpp, l
ine 250

是因为类型不是CV_32FC1,但是convertTo后还是出错。原因在于直接写成了src.reshape(1, 1);,改成src=src.reshape(1, 1);就不会报错了。

测试:

static float calculateAccuracyPercent(const Mat &original, const Mat &predicted)
{
	return 100 * (float)countNonZero(original == predicted) / predicted.rows;
}

void main()
{
	
	Mat src = imread("C:/Users/Administrator/Desktop/num/1/1.bmp");
	src=src.reshape(1, 1);
	src.convertTo(src,CV_32FC1);
	Ptr<LogisticRegression> lr = LogisticRegression::load("lr.xml");
	Mat re;
	float t = 0;
	t=lr->predict(src,re);
	cout << re << endl;
	cout << "t:" << t << endl;
	Mat label;
	label.push_back(1);
	cout << label<<endl;
	cout << label.size() << endl;
	cout << re.size() << endl;
	cout << calculateAccuracyPercent(label, re) << endl;
}

测试过程报错:

OpenCV Error: Sizes of input arguments do not match (The operation is neither 'a
rray op array' (where arrays have the same size and the same type), nor 'array o
p scalar', nor 'scalar op array') in cv::compare, file F:\OpenCV3.3\opencv\sourc
es\modules\core\src\arithm.cpp, line 1256

是因为这句:label.convertTo(label,CV_32FC1);,删掉之后就可以了(目前并不知道为什么这句会导致报错)。

批量测试:

void main()
{

	Mat classes;
	Mat trainingData;

	Mat trainingImage;
	Mat trainingLables;

	string imgname;
	ifstream fin("C:/Users/Administrator/Desktop/num/test/0/0.txt");
	while (getline(fin, imgname))
	{
		imgname = "C:/Users/Administrator/Desktop/num/test/0/" + imgname;
		Mat img = imread(imgname);
		img = img.reshape(1, 1);
		trainingImage.push_back(img);
		trainingLables.push_back(0);
	}

	string imgname_2;
	ifstream fin_2("C:/Users/Administrator/Desktop/num/test/1/1.txt");
	while (getline(fin_2, imgname_2))
	{
		imgname_2 = "C:/Users/Administrator/Desktop/num/test/1/" + imgname_2;
		Mat img = imread(imgname_2);
		img = img.reshape(1, 1);
		trainingImage.push_back(img);
		trainingLables.push_back(1);
	}
	
	Mat(trainingImage).copyTo(trainingData);
	trainingData.convertTo(trainingData, CV_32FC1);
	Mat(trainingLables).copyTo(classes);
	Ptr<LogisticRegression> lr = LogisticRegression::load("lr.xml");
	Mat re;
	lr->predict(trainingData,re);
	cout<<"acc:"<<calculateAccuracyPercent(classes, re)<<"%"<< endl;
}

4.DTrees:

OpenCV下的DTrees:

void main()
{
	Mat classes;
	Mat trainingData;

	Mat trainingImage;
	Mat trainingLables;

	string imgname;
	ifstream fin("C:/Users/Administrator/Desktop/num/0/0.txt");//C:/Users/Administrator/Desktop/num/0/0.txt
	while (getline(fin, imgname))
	{
		imgname = "C:/Users/Administrator/Desktop/num/0/" + imgname;//C:/Users/Administrator/Desktop/num/0/
		Mat img = imread(imgname,0);
		if (!img.data)
		{
			cout << "no img" << endl;
			break;
		}
		img = img.reshape(1, 1);
		trainingImage.push_back(img);
		trainingLables.push_back(0);
	}
	cout << "loading 0---" << endl;
	string imgname_2;
	ifstream fin_2("C:/Users/Administrator/Desktop/num/1/1.txt");//C:/Users/Administrator/Desktop/num/1/1.txt
	while (getline(fin_2, imgname_2))
	{
		imgname_2 = "C:/Users/Administrator/Desktop/num/1/" + imgname_2;//C:/Users/Administrator/Desktop/num/1/
		Mat img = imread(imgname_2,0);
		if (!img.data)
		{
			cout << "no img" << endl;
			break;
		}
		img = img.reshape(1, 1);
		trainingImage.push_back(img);
		trainingLables.push_back(1);
	}
	cout << "loading 1---" << endl;
	Mat(trainingImage).copyTo(trainingData);
	trainingData.convertTo(trainingData,CV_32FC1);
	Mat(trainingLables).copyTo(classes);
	classes.convertTo(classes,CV_32FC1);
	
	Ptr<DTrees> dtree= DTrees::create();
	dtree->setMaxCategories(4);
	dtree->setMaxDepth(10);
	dtree->setMinSampleCount(10);
	dtree->setCVFolds(0);
	dtree->setUseSurrogates(false);
	dtree->setUse1SERule(false);
	dtree->setTruncatePrunedTree(false);
	dtree->setRegressionAccuracy(0);
	dtree->setPriors(cv::Mat());
	
	cout << "trainging---" << endl;
	dtree->train(trainingData, cv::ml::ROW_SAMPLE, classes);
	//knn->save("knn.xml");
	cout << "finish---save model" << endl;

	Mat classes_test;
	Mat trainingData_test;

	Mat trainingImage_test;
	Mat trainingLables_test;

	string imgname_test;
	ifstream fin_test("C:/Users/Administrator/Desktop/num/test/0/0.txt");//C:/Users/Administrator/Desktop/num/0/zero.txt
	while (getline(fin_test, imgname_test))
	{
		imgname_test = "C:/Users/Administrator/Desktop/num/test/0/" + imgname_test;
		Mat img = imread(imgname_test,0);
		img = img.reshape(1, 1);
		cout << "--" << img.size() << endl;
		if (!img.data)
		{
			cout << "no img" << endl;
			break;
		}
		trainingImage_test.push_back(img);
		trainingLables_test.push_back(0);
	}

	string imgname_2_test;
	ifstream fin_2_test("C:/Users/Administrator/Desktop/num/test/1/1.txt");//C:/Users/Administrator/Desktop/num/1/one.txt
	while (getline(fin_2_test, imgname_2_test))
	{
		imgname_2_test = "C:/Users/Administrator/Desktop/num/test/1/" + imgname_2_test;
		Mat img = imread(imgname_2_test,0);
		if (!img.data)
		{
			cout << "no img" << endl;
			break;
		}
		img = img.reshape(1, 1);
		cout << "--" << img.size() << endl;
		trainingImage_test.push_back(img);
		trainingLables_test.push_back(1);
	}

	Mat(trainingImage_test).copyTo(trainingData_test);
	trainingData_test.convertTo(trainingData_test, CV_32FC1);
	Mat(trainingLables_test).copyTo(classes_test);
	classes_test.convertTo(classes_test,CV_32FC1);
	Mat re;
	dtree->predict(trainingData_test,re);
	cout<<calculateAccuracyPercent(classes_test,re)<<endl;
	waitKey(0);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值