1、CvTrees相关函数解析
1.1 CvRTParams函数
CvRTParams( int max_depth,
int min_sample_count,
float regression_accuracy,
bool use_surrogates,
int max_categories,
const float* priors,
bool calc_var_importance,
int nactive_vars,
int max_num_of_trees_in_the_forest,
float forest_accuracy,
int termcrit_type );
参数解析:
(1)int max_depth:表示决策树的深度,该值的大小严重影响拟合的效果。
(2)int min_sample_count:表示决策树节点的最小样本数,如果节点的样本数小于该值,则该节点不再分叉,一般该值为样本总数的1%。
(3)float regression_accuracy:表示终止构建回归树的一个条件,回归树的响应值的精度a如果达到该值,则无需再分叉。该值不能小于0,否则报错。
(4)bool use_surrogates:表示是否使用替代分叉节点,false表示不使用替代分叉节点。
(5)int max_categories:表示特征属性为类的形式的最大类的数量。
(6)const float* priors:表示决策树的特征属性的先验概率。
(7)bool calc_var_importance:表示是否计算特征属性的重要程度。
(8)int nactive_vars,:表示用于寻找最佳分叉属性的每个节点的随机特征属性的数量,如果该值设置为0,则表示该值为样本的全部特征属性的平方根。
(9)int max_num_of_trees_in_the_forest:表示森林中决策树的最大数量,也就是最大迭代次数,因为每迭代一次,就会得到一颗决策树。通常来说,决策树越多,预测越准确,但决策树的数量达到一定程度之后,准确度的增长会减小,甚至区域不变。另一方面,预测时间是与决策树的数量呈线性关系的。
(10)float forest_accuracy:表示OOB误差的精度要求。
(11)int termcricER以决策树达到max_num_of_trees_in_the_forest为终止条件;CV_TERMCRIT_EPS以精度到达forest_accuracy为终止条件;CV_TERMCRIT_ITER|CV_TERMCRIT_EPS为任一条件达到即终止。
1.2 训练函数train
virtual bool train( const CvMat* trainData,
int tflag,
const CvMat* responses,
const CvMat* varIdx=0,
const CvMat* sampleIdx=0,
const CvMat* varType=0,
const CvMat* missingDataMask=0,
CvRTParams params=CvRTParams() );
参数解析:
(1)const CvMat* trainData:训练样本数据,必须为32FC1类型的矩阵形式。
(2)int tflag:训练数据的特征属性类型,如果为CV_ROW_SAMPLE,表示样本是以行的形式存储的,即_train_data矩阵的每一行为一个样本;如果为CV_COLSAMPLE,表示样本是以列的形式存储的。
(3)const CvMat* responses:样本的结果,即响应值,该值必须是32SC1或32FC1类型的一维矩阵(即矢量)的形式,并且元素的数量必须与训练样本数据_train_data的样本数一致
(4)const CvMat* varIdx=0:标识感兴趣的特征属性,即真正用于训练的那些特征属性,该值的形式与sample_idx的变量相似
(5)const CvMat* sampleIdx=0:标识感兴趣的样本,即真正用于训练的样本,该值必须是一维矩阵的形式,即矢量的形式,并且类型必须是8UC1、8SU1或者32SUC1。
(6)const CvMat* varType=0:特征属性的形式,是类的形式,还是数值的形式,用掩码的形式来表现,0表示为数值的形式,1表示为类的形式。该值必须是一维矩阵,并且元素的数量必须是真正用于训练的那些特征属性的数量加1,多余的一个元素表示的是响应的形式,即是分类树,还是回归树。
(7)const CvMat* missingDataMask=0:缺失的特征属性,用掩码的形式表现对应的特征属性,0表示没有缺失,而且必须与_train_data的矩阵尺寸大小一致。
(8)CvRTParams params=CvRTParams():构建随机森林的参数。
2、调用opencv的类CvRTrees做回归
#include <QCoreApplication>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/ml/ml.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//训练样本
double trainingData[28][2] = {{210.4,3},{240.0,3},{300.0,4},{153.4,3},{138.0,3},
{194.0,4},{189.0,3},{126.8,3},{132.0,2},{260.9,4},
{176.7,3},{160.4,3},{389.0,3},{145.8,3},{160.0,3},
{141.6,2},{198.5,4},{142.7,3},{149.4,3},{200.0,3},
{447.8,5},{230.0,4},{123.6,3},{303.1,4},{188.8,2},
{196.2,4},{110.0,3},{252.6,3}};
CvMat trainingDataCvMat = cvMat(28,2,CV_32FC1,trainingData);
//样本响应值
float response[28] = {399900,369000,539900,314900,212000,
239999,329999,259900,299900,499998,
252900,242900,573900,464500,329900,
232000,299900,198999,242500,347000,
699900,449900,199900,599000,255000,
259900,249900,469000};
CvMat responseCvMat = cvMat(28,1,CV_32FC1,response);
//设置参数
CvRTParams params = CvRTParams(10,//1决策树深度
2,//2决策树节点的最小样本数
0,//3终止构建回归树的精度条件
false,//4是否使用代替分叉节点
16,//5特征属性为类的形式的最大的类的数量
0,//6决策树的特征属性的先验概率
true,//7表示是否计算特征属性的重要程度
0,//8用于寻找最佳分叉属性的每个节点的随机特征属性的数量,如果为0,则该值为样本的全部特征属性的平方根
100,//9森林中决策树的最大数量
0,//10 OOB误差的精度要求
CV_TERMCRIT_ITER//11随机森林构建的终止条件
);
//CvRTrees rtrees;
CvRTrees* rtrees = new CvRTrees;
rtrees->train(&trainingDataCvMat,//1
CV_ROW_SAMPLE,//2
&responseCvMat,//3
NULL,//4
NULL,//5
NULL,//6
NULL,//7
params//8
);
//test
double sampleData[2] = {201.5,3};
Mat sampleMat(2,1,CV_32FC1,sampleData);
float r = rtrees->predict(sampleMat);
cout<<endl<<"result: "<<r<<endl;
return a.exec();
}
最终的输出值为252900。
3、调用opencv的类CvRTrees做分类
#include <QCoreApplication>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/ml/ml.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//samples
double trainingData[28][2] = {{210.4,3},{240.0,3},{300.0,4},{153.4,3},{138.0,3},
{194.0,4},{189.0,3},{126.8,3},{132.0,2},{260.9,4},
{176.7,3},{160.4,3},{389.0,3},{145.8,3},{160.0,3},
{141.6,2},{198.5,4},{142.7,3},{149.4,3},{200.0,3},
{447.8,5},{230.0,4},{123.6,3},{303.1,4},{188.8,2},
{196.2,4},{110.0,3},{252.6,3}};
CvMat trainingDataCvMat = cvMat(28,2,CV_32FC1,trainingData);
float response[28] = {1,1,1,0,0,
0,0,0,0,1,
0,0,1,0,0,
0,0,0,0,1,
1,1,0,1,0,
0,0,1};
CvMat responseCvMat = cvMat(28,1,CV_32FC1,response);
Mat var_type = Mat(2 + 1, 1, CV_8U );
var_type.setTo(Scalar(CV_VAR_NUMERICAL) );
var_type.at<uchar>(2, 0) = CV_VAR_CATEGORICAL;
CvMat * var_type1 = var_type;
//train
CvRTParams params = CvRTParams(10,//1决策树深度
2,//2决策树节点的最小样本数
0,//3终止构建回归树的精度条件
false,//4是否使用代替分叉节点
16,//5特征属性为类的形式的最大的类的数量
0,//6决策树的特征属性的先验概率
false,//7表示是否计算特征属性的重要程度
0,//8用于寻找最佳分叉属性的每个节点的随机特征属性的数量,如果为0,则该值为样本的全部特征属性的平方根
100,//9森林中决策树的最大数量
0.01f,//10 OOB误差的精度要求
CV_TERMCRIT_ITER//11随机森林构建的终止条件
);
//CvRTrees rtrees;
CvRTrees* rtrees = new CvRTrees;
rtrees->train(&trainingDataCvMat,//1
CV_ROW_SAMPLE,//2
&responseCvMat,//3
NULL,//4
NULL,//5
var_type1,//6
NULL,//7
params//8
);
//test
double sampleData[2] = {201.5,3};
Mat sampleMat(2,1,CV_32FC1,sampleData);
float r = rtrees->predict(sampleMat);
cout<<endl<<"result: "<<r<<endl;
return a.exec();
}