boosting和随机森林在内部使用了决策树,所以继承了树的很多有用性质。
在监督学习领域,有一种想法就是从很多弱分类器重学习得到一个强分类器。boosting算法,也叫AdaBoosting。
注:
Boosting意为加强、提升,也就是说将弱分类器提升为强分类器。而我们常听到的AdaBoost是Boosting发展到后来最为代表性的一类。所谓AdaBoost,即Adaptive Boosting,是指弱分类器根据学习的结果反馈Adaptively调整假设的错误率,所以也不需要任何的先验知识就可以自主训练。Breiman在他的论文里赞扬AdaBoost是最好的off-the-shelf方法。
boosting算法的主要特征是在训练过程中,这个代价将会更新,使得后来的弱分类器更加关注与前面的分类器没有分对的数据点。算法如下:
OpenCV2中有四种类型的boosting。
Boost::DISCRETE
Boost::REAL
Boost::LOGIT
Boost::GENTLE
实践发现,real和gentle的效果最好。
real利用了置信区间预测,在标签数据上有很好的性能。
gentle对外围数据赋予较小的值,所以在处理回归问题上效果很好。
opencv boost算法只能用于二分类问题。
boosting算法训练了T个弱分类,这些弱分类器很简单,大多数情况下,他们只是包含了一次分裂或仅有的几次分裂。adaboost训练时输入的特征向量是
xi
,向量的类别标签是
yi
,y的取值为1或者-1。
首先就是初始化数据样本的权值来告分类器将一个数据点分类错误的代价是多少。boosting算法的主要特征是在训练过程中,这个代价将会更新,使得后来的弱分类器更加关注与前面的分类器没有分对的数据点。
boosting的代码与决策树的代码很相似,但是除了决策树的参数,他还有自己的控制参数。
测试代码:
// OpenCV.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <opencv2/core/core.hpp>
#include <opencv2/ml/ml.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//训练样本
float trainingData[42][2]={ {40, 55},{35, 35},{55, 15},{45, 25},{10, 10},{15, 15},{40, 10},
{30, 15},{30, 50},{100, 20},{45, 65},{20, 35},{80, 20},{90, 5},
{95, 35},{80, 65},{15, 55},{25, 65},{85, 35},{85, 55},{95, 70},
{105, 50},{115, 65},{110, 25},{120, 45},{15, 45},
{55, 30},{60, 65},{95, 60},{25, 40},{75, 45},{105, 35},{65, 10},
{50, 50},{40, 35},{70, 55},{80, 30},{95, 45},{60, 20},{70, 30},
{65, 45},{85, 40} };
Mat trainingDataMat(42, 2, CV_32FC1, trainingData);
//训练样本的响应值
float responses[42] = {'R','R','R','R','R','R','R','R','R','R','R','R','R','R','R','R',
'R','R','R','R','R','R','R','R','R','R',
'B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B' };
Mat responsesMat(42, 1, CV_32FC1, responses);
float priors[2] = {1, 1}; //先验概率
CvBoostParams params( CvBoost::REAL, // boost_type
10, // weak_count
0.95, // weight_trim_rate
15, // max_depth
false, // use_surrogates
priors // priors
);
CvBoost boost;
boost.train ( trainingDataMat,
CV_ROW_SAMPLE,
responsesMat,
Mat(),
Mat(),
Mat(),
Mat(),
params
);
//预测样本
float myData[2] = {55, 25};
Mat myDataMat(2, 1, CV_32FC1, myData);
double r = boost.predict( myDataMat );
cout<<endl<<"result: "<<(char)r<<endl;
getchar();
return 0;
}
要记住:每一个弱分类器使用的是stump算法,单决策树。