RandomForest随机森林总括,基于opencv的RandomForest随机森林

 

2.OpenCV函数施用

OpenCV提供了随便森林的相关类和函数。具体选用方法如下:

(1)首先使用Cv昂科拉TParams定义本人的参数,其格式如下

 

 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)

 

抢先58%参数描述都在http://docs.opencv.org/modules/ml/doc/random\_trees.html上面有,说一下没有描述的几个参数的意义

bool use_surrogates:是或不是采取代理,指的是,假诺当前的测试样本贫乏某个特点,不过在脚下节点上的分类or回归特征正是贫乏的这些天性,那么这些样本就无可奈何继续本着树向下走了,达不到叶子节点的话,就没有预测输出,那种情况下,能够应用最近节点上面包车型大巴全数子节点中的叶子节点预测输出的平均值,作为那么些样本的预测输出。

const
float*priors:先验知识,那一个指的是,能够依照各类项目样本数量的先验分布,对其进展加权。比如:借使一共有3类,第壹类样本占全体磨练集的五分四,其他两类各占一成,那么那几个数据集里面包车型的士多寡就很不平均,借使每类的样本都加权的话,即使把拥有样本都预测成第3类,那么准确率也有五分之四,那明摆着是不创立的,由此大家供给增强后两类的权重,使得后两类的归类正确率也不会太低。

float regression_accuracy:回归树的停下条件,若是当前节点上有所样本的真实值和预测值之间的差小于这么些数值时,结束生产那么些节点,并将其作为叶子节点。

新兴发现那些参数在决策树里面有分解,英文表明在这边http://docs.opencv.org/modules/ml/doc/decision\_trees.html\#cvdtreeparams

切切实实事例如下,网上找了个外人的例子,自个儿改成了足以读取MNIST数据同时做分类的方式,如下:

 

图片 1

#include <cv.h>       // opencv general include file
#include <ml.h>          // opencv machine learning include file
#include <stdio.h>

using namespace cv; // OpenCV API is in the C++ "cv" namespace

/******************************************************************************/
// global definitions (for speed and ease of use)
//手写体数字识别

#define NUMBER_OF_TRAINING_SAMPLES 60000
#define ATTRIBUTES_PER_SAMPLE 784
#define NUMBER_OF_TESTING_SAMPLES 10000

#define NUMBER_OF_CLASSES 10

// N.B. classes are integer handwritten digits in range 0-9

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

// loads the sample database from file (which is a CSV text file)

inline void revertInt(int&x)
{
    x=((x&0x000000ff)<<24)|((x&0x0000ff00)<<8)|((x&0x00ff0000)>>8)|((x&0xff000000)>>24);
};

int read_data_from_csv(const char* samplePath,const char* labelPath, Mat data, Mat classes,
                       int n_samples )
{
    FILE* sampleFile=fopen(samplePath,"rb");
    FILE* labelFile=fopen(labelPath,"rb");
    int mbs=0,number=0,col=0,row=0;
    fread(&mbs,4,1,sampleFile);
    fread(&number,4,1,sampleFile);
    fread(&row,4,1,sampleFile);
    fread(&col,4,1,sampleFile);
    revertInt(mbs);
    revertInt(number);
    revertInt(row);
    revertInt(col);
    fread(&mbs,4,1,labelFile);
    fread(&number,4,1,labelFile);
    revertInt(mbs);
    revertInt(number);
    unsigned char temp;
    for(int line = 0; line < n_samples; line++)
    {
        // for each attribute on the line in the file
        for(int attribute = 0; attribute < (ATTRIBUTES_PER_SAMPLE + 1); attribute++)
        {
            if (attribute < ATTRIBUTES_PER_SAMPLE)
            {
                // first 64 elements (0-63) in each line are the attributes
                fread(&temp,1,1,sampleFile);
                //fscanf(f, "%f,", &tmp);
                data.at<float>(line, attribute) = static_cast<float>(temp);
                // printf("%f,", data.at<float>(line, attribute));
            }
            else if (attribute == ATTRIBUTES_PER_SAMPLE)
            {
                // attribute 65 is the class label {0 ... 9}
                fread(&temp,1,1,labelFile);
                //fscanf(f, "%f,", &tmp);
                classes.at<float>(line, 0) = static_cast<float>(temp);
                // printf("%f\n", classes.at<float>(line, 0));
            }
        }
    }
    fclose(sampleFile);
    fclose(labelFile);
    return 1; // all OK
}

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

int main( int argc, char** argv )
{

    for (int i=0; i< argc; i++)
        std::cout<<argv[i]<<std::endl;

    // lets just check the version first
    printf ("OpenCV version %s (%d.%d.%d)\n",
            CV_VERSION,
            CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION);

    //定义训练数据与标签矩阵
    Mat training_data = Mat(NUMBER_OF_TRAINING_SAMPLES, ATTRIBUTES_PER_SAMPLE, CV_32FC1);
    Mat training_classifications = Mat(NUMBER_OF_TRAINING_SAMPLES, 1, CV_32FC1);

    //定义测试数据矩阵与标签
    Mat testing_data = Mat(NUMBER_OF_TESTING_SAMPLES, ATTRIBUTES_PER_SAMPLE, CV_32FC1);
    Mat testing_classifications = Mat(NUMBER_OF_TESTING_SAMPLES, 1, CV_32FC1);

    // define all the attributes as numerical
    // alternatives are CV_VAR_CATEGORICAL or CV_VAR_ORDERED(=CV_VAR_NUMERICAL)
    // that can be assigned on a per attribute basis

    Mat var_type = Mat(ATTRIBUTES_PER_SAMPLE + 1, 1, CV_8U );
    var_type.setTo(Scalar(CV_VAR_NUMERICAL) ); // all inputs are numerical

    // this is a classification problem (i.e. predict a discrete number of class
    // outputs) so reset the last (+1) output var_type element to CV_VAR_CATEGORICAL

    var_type.at<uchar>(ATTRIBUTES_PER_SAMPLE, 0) = CV_VAR_CATEGORICAL;

    double result; // value returned from a prediction

    //加载训练数据集和测试数据集
    if (read_data_from_csv(argv[1],argv[2], training_data, training_classifications, NUMBER_OF_TRAINING_SAMPLES) &&
            read_data_from_csv(argv[3],argv[4], testing_data, testing_classifications, NUMBER_OF_TESTING_SAMPLES))
    {
      /********************************步骤1:定义初始化Random Trees的参数******************************/
        float priors[] = {1,1,1,1,1,1,1,1,1,1};  // weights of each classification for classes
        CvRTParams params = CvRTParams(20, // max depth
                                       50, // min sample count
                                       0, // regression accuracy: N/A here
                                       false, // compute surrogate split, no missing data
                                       15, // max number of categories (use sub-optimal algorithm for larger numbers)
                                       priors, // the array of priors
                                       false,  // calculate variable importance
                                       50,       // number of variables randomly selected at node and used to find the best split(s).
                                       100,     // max number of trees in the forest
                                       0.01f,                // forest accuracy
                                       CV_TERMCRIT_ITER |    CV_TERMCRIT_EPS // termination cirteria
                                      );

        /****************************步骤2:训练 Random Decision Forest(RDF)分类器*********************/
        printf( "\nUsing training database: %s\n\n", argv[1]);
        CvRTrees* rtree = new CvRTrees;
        bool train_result=rtree->train(training_data, CV_ROW_SAMPLE, training_classifications,
                     Mat(), Mat(), var_type, Mat(), params);
//        float train_error=rtree->get_train_error();
//        printf("train error:%f\n",train_error);
        // perform classifier testing and report results
        Mat test_sample;
        int correct_class = 0;
        int wrong_class = 0;
        int false_positives [NUMBER_OF_CLASSES] = {0,0,0,0,0,0,0,0,0,0};

        printf( "\nUsing testing database: %s\n\n", argv[2]);

        for (int tsample = 0; tsample < NUMBER_OF_TESTING_SAMPLES; tsample++)
        {

            // extract a row from the testing matrix
            test_sample = testing_data.row(tsample);
        /********************************步骤3:预测*********************************************/
            result = rtree->predict(test_sample, Mat());

            printf("Testing Sample %i -> class result (digit %d)\n", tsample, (int) result);

            // if the prediction and the (true) testing classification are the same
            // (N.B. openCV uses a floating point decision tree implementation!)
            if (fabs(result - testing_classifications.at<float>(tsample, 0))
                    >= FLT_EPSILON)
            {
                // if they differ more than floating point error => wrong class
                wrong_class++;
                false_positives[(int) result]++;
            }
            else
            {
                // otherwise correct
                correct_class++;
            }
        }

        printf( "\nResults on the testing database: %s\n"
                "\tCorrect classification: %d (%g%%)\n"
                "\tWrong classifications: %d (%g%%)\n",
                argv[2],
                correct_class, (double) correct_class*100/NUMBER_OF_TESTING_SAMPLES,
                wrong_class, (double) wrong_class*100/NUMBER_OF_TESTING_SAMPLES);

        for (int i = 0; i < NUMBER_OF_CLASSES; i++)
        {
            printf( "\tClass (digit %d) false postives     %d (%g%%)\n", i,
                    false_positives[i],
                    (double) false_positives[i]*100/NUMBER_OF_TESTING_SAMPLES);
        }

        // all matrix memory free by destructors

        // all OK : main returns 0
        return 0;
    }

    // not OK : main returns -1
    return -1;
}

图片 2

 

MNIST样本得以在这几个网址http://yann.lecun.com/exdb/mnist/下载,改一下路径可以直接跑的。

3.什么样协调统一筹划随机森林程序

突发性现有的库不能够满足供给,就需求协调统一筹划三个分类器算法,这一部分讲一下哪些统一筹划协调的私下森林分类器,代码完结就不贴了,因为在工作中用到了,由此比较灵活。

第二,要有三个RandomForest类,里面保存整个树要求的局地参数,包罗但不压制:磨炼样本数量、测试样本数量、特征维数、每个节点随机提取的表征维数、CACR-VT树的多寡、树的最大深度、体全面量(要是是分类难点)、一些悬停条件、指向全部树的指针,指向训练集和测试集的指针,指向磨炼集label的指针等。还要有局地函数,至少要有train和predict吧。train里面一贯调用每棵树的train方法即可,predict同理,但要对每棵树的预测输出做拍卖,获得森林的预计输出。

 

协理,要有一个sample类,那个类可不是用来储存操练集和对应label的,那是因为,每棵树、每一种节点都有谈得来的范本集和,假若你的储存每一种样本集和的话,必要的内部存款和储蓄器实在是太过巨大了,假使样本数量为M,特征维数为N,则整个陶冶集大小为M×N,而每棵树的每层都有诸如此类多种本,树的深度为D,共有S棵树的话,则须要仓库储存M×N×D×S的蕴藏空间。那事实上是太大了。由此,每一个节点操练时用到的磨炼样本和特色,大家都用序号数组来替代,sample类正是干那个的。sample的函数基本要求五个就行,第三个是从现有磨炼集有放回的随机抽取2个新的陶冶集,当然,只含有样本的序号。第二个函数是从现有的特征中无放回的肆意抽取一定数额的特点,同理,也是特色序号即可。

下一场,要求一个Tree类,代表每棵树,里面保存树的局地参数以及3个对准全体节点的指针。

末段,必要二个Node类,代表树的各类节点。

 

急需证实的是,保存树的格局得以是最常见的数组,也可是是vector。Node的保留方法同理,不过个人不建议用链表的点子,在先后设计以及函数处理上太劳顿,可是在省空间上并不曾太多的展示。

当前先写那样多,最终那有些本人还会再扩张一些。

 

 

 

1.随机山林原理介绍

自由森林,指的是采取多棵树对样本实行练习并预测的一种分类器。该分类器最早由LeoBreiman和阿代le
Cutler提议,并被登记成了商标。一言以蔽之,随机森林便是由多棵CAHavalT(Classification
And Regression
Tree)构成的。对于每棵树,它们选择的教练集是从总的演习集中有放回采集样品出来的,这表示,总的磨练集中的有点样本只怕多次并发在一棵树的练习集中,也可能没有出现在一棵树的教练集中。在练习每棵树的节点时,使用的特征是从全部特征中听从一定比例随机地无放回的抽取的,依据LeoBreiman的建议,若是总的特征数据为M,这么些比例能够是sqrt(M),百分之五十sqrt(M),2sqrt(M)。

所以,随机森林的教练进程能够计算如下:

(1)给定练习集S,测试集T,特征维数F。明确参数:使用到的CA昂CoraT的数量t,每棵树的深度d,种种节点使用到的性格数据f,终止条件:节点上至少样本数s,节点上最少的新闻增益m

对于第1-t棵树,i=1-t:

(2)从S中有放回的抽取大小和S一样的练习集S(i),作为根节点的范本,从根节点早先演习

(3)借使当前节点上实现终止条件,则设置当前节点为叶子节点,假如是分类难点,该叶子节点的前瞻输出为当下节点样本集合中数据最多的那一类c(j),可能率p为c(j)占当前样本集的比重;假诺是回归难题,预测输出为当前节点样本集各种样本值的平均值。然后继续陶冶别的节点。假若当前节点没有高达终止条件,则从F维特征中无放回的随意选取f维特征。利用那f维特征,寻找分类功用最棒的一维特征k及其阈值th,当前节点上样本第k维特征小于th的样本被分割到左节点,别的的被分割到右节点。继续磨练别的节点。有关分类效果的鉴定标准在末端会讲。

(4)重复(2)(3)直到全体节点都练习过了照旧被标记为叶子节点。

(5)重复(2),(3),(4)直到全数CAKugaT都被演习过。

运用任意森林的猜测进程如下:

对于第1-t棵树,i=1-t:

(1)从眼下树的根节点伊始,依照当前节点的阈值th,判断是进入左节点(<th)依旧进入右节点(>=th),直到抵达,有些叶子节点,并出口预测值。

(2)重复执行(1)直到全数t棵树都输出了预测值。假诺是分类难题,则输出为具有树中预测可能率总和最大的那一个类,即对各类c(j)的p举办累计;若是是回归难点,则输出为全数树的输出的平均值。

注:有关分类效果的考核评议标准,因为运用的是CACR-VT,由此选取的也是CAPRADOT的评议标准,和C3.0,C4.5都不相同等。

对此分类难点(将有些样本划分到某一类),相当于离散变量难题,CA宝马7系T使用Gini值作为评判标准。定义为Gini=1-∑(P(i)*P(i)),P(i)为近日节点上多少集中第i类样本的比重。例如:分为2类,当前节点上有玖拾2个样本,属于第叁类的样书有柒11个,属于第③类的样本有三贰十二个,则Gini=1-0.7×07-0.3×03=0.42,能够见见,种类分布越平均,Gini值越大,类分布越不均匀,Gini值越小。在搜寻最棒的分类特征和阈值时,评判标准为:argmax(Gini-GiniLeft-GiniRight),即寻找最好的特征f和阈值th,使伏贴前节点的Gini值减去左子节点的Gini和右子节点的Gini值最大。

对于回归难点,相对更为简约,直白动用argmax(Var-VarLeft-VarRight)作为评判标准,即时下节点演习集的方差Var减去减去左子节点的方差VarLeft和右子节点的方差VarRight值最大。**

 

RandomForest随机森林计算

1.随机森林原理介绍

随便森林,指的是选用多棵树对样本实行演习并估摸的一种分类器。该分类器最早由LeoBreiman和Adele
Cutler提议,并被注册成了商标。一言以蔽之,随机森林正是由多棵CART(Classification
And Regression
Tree)构成的。对于每棵树,它们采纳的教练集是从总的练习集中有放回采集样品出来的,那意味,总的演习集中的多少样本恐怕数次产出在一棵树的磨炼集中,也或者没有出现在一棵树的磨炼集中。在练习每棵树的节点时,使用的特征是从全体特征中依据一定比重随机地无放回的抽取的,依据LeoBreiman的建议,借使总的特征数据为M,这几个比重能够是sqrt(M),二分之一sqrt(M),2sqrt(M)。

之所以,随机森林的演练进程能够总计如下:

(1)给定磨练集S,测试集T,特征维数F。鲜明参数:使用到的CA冠道T的数量t,每棵树的深度d,种种节点使用到的风味数据f,终止条件:节点上至少样本数s,节点上最少的音讯增益m

对于第1-t棵树,i=1-t:

(2)从S中有放回的抽取大小和S一样的练习集S(i),作为根节点的范本,从根节点开头磨炼

(3)要是当前节点上达成终止条件,则设置当前节点为叶子节点,若是是分类难点,该叶子节点的推断输出为近期节点样本集合中数据最多的那一类c(j),可能率p为c(j)占当前样本集的比重;假诺是回归难点,预测输出为近期节点样本集各种样本值的平均值。然后继续陶冶别的节点。借使当前节点没有高达终止条件,则从F维特征中无放回的妄动采取f维特征。利用这f维特征,寻找分类功效最佳的一维特征k及其阈值th,当前节点上样本第k维特征小于th的范本被分割到左节点,其他的被分割到右节点。继续磨炼其余节点。有关分类效能的评议标准在末端会讲。

(4)重复(2)(3)直到全数节点都练习过了或许被标记为叶子节点。

(5)重复(2),(3),(4)直到全部CAPAJEROT都被教练过。

采取任意森林的预测过程如下:

对于第1-t棵树,i=1-t:

(2)重复执行(1)直到全部t棵树都输出了预测值。如若是分类难点,则输出为全部树中预测可能率总和最大的那多少个类,即对各样c(j)的p实行累计;倘若是回归难题,则输出为全部树的出口的平均值。

注:有关分类作用的评比标准,因为运用的是CA奇骏T,由此接纳的也是CA奥迪Q7T的机械标准,和C3.0,C4.5都差异等。

对此分类难题(将有些样本划分到某一类),也正是离散变量难点,CA中华VT使用Gini值作为评判标准。定义为Gini=1-∑(P(i)*P(i)),P(i)为当前节点上多少集中第i类样本的比重。例如:分为2类,当前节点上有九十两个样本,属于第壹类的范本有七贰十一个,属于第三类的样书有2七个,则Gini=1-0.7×07-0.3×03=0.42,能够看看,系列分布越平均,Gini值越大,类分布越不均匀,Gini值越小。在寻找最好的分类特征和阈值时,评判标准为:argmax(Gini-GiniLeft-GiniRight),即寻找最棒的特征f和阈值th,使稳妥前节点的Gini值减去左子节点的Gini和右子节点的Gini值最大。

对于回归难题,绝对更为简便易行,直白接纳argmax(Var-VarLeft-VarRight)作为裁判标准,即此时此刻节点陶冶集的方差Var减去减去左子节点的方差VarLeft和右子节点的方差VarRight值最大。**

2.OpenCV函数选择

OpenCV提供了任性森林的相关类和函数。具体运用方法如下:

(1)首先采纳CvLX570TParams定义本人的参数,其格式如下

CvRTParams::CvRTParams(intmax_depth,intmin_sample_count,floatregression_accuracy,booluse_surrogates,intmax_categories,constfloat*
priors,boolcalc_var_importance,intnactive_vars,intmax_num_of_trees_in_the_forest,floatforest_accuracy,inttermcrit_type)

大部参数描述都在http://docs.opencv.org/modules/ml/doc/random\_trees.html上面有,说一下没有描述的几个参数的意义

booluse_surrogates:是或不是利用代理,指的是,假使当前的测试样本缺少有个别特点,不过在脚下节点上的归类or回归特征便是缺少的那一个特点,那么这几个样本就无可怎么着继续本着树向下走了,达不到叶子节点的话,就从未有过预测输出,那种状态下,能够运用近年来节点上边包车型大巴全数子节点中的叶子节点预测输出的平均值,作为那么些样本的前瞻输出。

const
float*priors:先验知识,那么些指的是,能够依照种种项目样本数量的先验分布,对其进展加权。比如:要是一共有3类,第3类样本占总体练习集的4/5,其他两类各占一成,那么那一个数据集里面包车型大巴数额就很不平均,假如每类的样书都加权的话,固然把具备样本都预测成第3类,那么准确率也有五分四,那明摆着是不创造的,因而我们供给进步后两类的权重,使得后两类的归类正确率也不会太低。

floatregression_accuracy:回归树的终止条件,假设当前节点上具有样本的真实值和预测值之间的差小于这几个数值时,结束生产那些节点,并将其当作叶子节点。

新生发觉这个参数在决策树里面有表明,英文表达在此间http://docs.opencv.org/modules/ml/doc/decision\_trees.html\#cvdtreeparams

现实事例如下,网上找了个外人的例证,自身改成了能够读取MNIST数据同时做分类的款式,如下:

😉

#include <cv.h>//opencv general include file

#include <ml.h>//opencv machine learning include file

#include <stdio.h>

usingnamespacecv;//OpenCV API is in the C++ “cv” namespace

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

//global definitions (for speed and ease of use)

//手写体数字识别

#defineNUMBER_OF_TRAINING_SAMPLES 60000

#defineATTRIBUTES_PER_SAMPLE 784

#defineNUMBER_OF_TESTING_SAMPLES 10000

#defineNUMBER_OF_CLASSES 10

//N.B. classes are integer handwritten digits in range 0-9

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

//loads the sample database from file (which is a CSV text file)

inlinevoidrevertInt(int&x)

{

x=((x&0x000000ff)<<24)|((x&0x0000ff00)<<8)|((x&0x00ff0000)>>8)|((x&0xff000000)>>24);

};

intread_data_from_csv(constchar* samplePath,constchar*labelPath,
Mat data, Mat classes,

intn_samples )

{

FILE* sampleFile=fopen(samplePath,”rb”);

FILE* labelFile=fopen(labelPath,”rb”);

intmbs=0,number=0,col=0,row=0;

fread(&mbs,4,1,sampleFile);

fread(&number,4,1,sampleFile);

fread(&row,4,1,sampleFile);

fread(&col,4,1,sampleFile);

revertInt(mbs);

revertInt(number);

revertInt(row);

revertInt(col);

fread(&mbs,4,1,labelFile);

fread(&number,4,1,labelFile);

revertInt(mbs);

revertInt(number);

unsignedchartemp;

for(intline =0; line < n_samples; line++)

{

//for each attribute on the line in the file

for(intattribute =0; attribute < (ATTRIBUTES_PER_SAMPLE +1);
attribute++)

{

if(attribute <ATTRIBUTES_PER_SAMPLE)

{

//first 64 elements (0-63) in each line are the attributes

fread(&temp,1,1,sampleFile);

//fscanf(f, “%f,”, &tmp);

data.at<float>(line, attribute) = static_cast<float>(temp);

//printf(“%f,”, data.at<float>(line, attribute));

}

elseif(attribute ==ATTRIBUTES_PER_SAMPLE)

{

//attribute 65 is the class label {0 … 9}

fread(&temp,1,1,labelFile);

//fscanf(f, “%f,”, &tmp);

classes.at<float>(line,0) = static_cast<float>(temp);

//printf(“%f\n”, classes.at<float>(line, 0));

}

}

}

fclose(sampleFile);

fclose(labelFile);

return1;//all OK

}

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

intmain(intargc,char**argv )

{

for(inti=0; i< argc; i++)

std::cout<<argv[i]<<std::endl;

//lets just check the version first

printf (“OpenCV version %s (%d.%d.%d)\n”,

CV_VERSION,

CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION);

//定义陶冶多少与标签矩阵

Mat training_data =Mat(NUMBER_OF_TRAINING_SAMPLES,
ATTRIBUTES_PER_SAMPLE, CV_32FC1);

Mat training_classifications= Mat(NUMBER_OF_TRAINING_SAMPLES,1,
CV_32FC1);

//定义测试数据矩阵与标签

Mat testing_data =Mat(NUMBER_OF_TESTING_SAMPLES,
ATTRIBUTES_PER_SAMPLE, CV_32FC1);

Mat testing_classifications= Mat(NUMBER_OF_TESTING_SAMPLES,1,
CV_32FC1);

//define all the attributes as numerical

//alternatives are CV_VAR_CATEGORICAL or
CV_VAR_ORDERED(=CV_VAR_NUMERICAL)

//that can be assigned on a per attribute basis

Mat var_type= Mat(ATTRIBUTES_PER_SAMPLE +1,1, CV_8U );

var_type.setTo(Scalar(CV_VAR_NUMERICAL) );//all inputs are numerical

//this is a classification problem (i.e. predict a discrete number of
class

//outputs) so reset the last (+1) output var_type element to
CV_VAR_CATEGORICAL

var_type.at<uchar>(ATTRIBUTES_PER_SAMPLE,0)
=CV_VAR_CATEGORICAL;

doubleresult;//value returned from a prediction

//加载陶冶数据集和测试数据集

if(read_data_from_csv(argv[1],argv[2], training_data,
training_classifications, NUMBER_OF_TRAINING_SAMPLES) &&

read_data_from_csv(argv[3],argv[4], testing_data,
testing_classifications, NUMBER_OF_TESTING_SAMPLES))

{

/********************************步骤1:定义开始化Random
Trees的参数******************************/

floatpriors[] = {1,1,1,1,1,1,1,1,1,1};//weights of each classification
for classes

CvRTParamsparams= CvRTParams(20,//max depth

50,//min sample count

0,//regression accuracy: N/A here

false,//compute surrogate split, no missing data

15,//max number of categories (use sub-optimal algorithm for larger
numbers)

priors,//the array of priors

false,//calculate variable importance

50,//number of variables randomly selected at node and used to find the
best split(s).

100,//max number of trees in the forest

0.01f,//forest accuracy

CV_TERMCRIT_ITER |    CV_TERMCRIT_EPS//termination cirteria

);

/****************************步骤2:训练
Random Decision
Forest(RDF)分类器*********************/

printf(“\nUsing training database: %s\n\n”, argv[1]);

CvRTrees* rtree =newCvRTrees;

booltrain_result=rtree->train(training_data, CV_ROW_SAMPLE,
training_classifications,

Mat(), Mat(), var_type, Mat(),params);

//float train_error=rtree->get_train_error();

//printf(“train error:%f\n”,train_error);

//perform classifier testing and report results

Mat test_sample;

intcorrect_class =0;

intwrong_class =0;

intfalse_positives [NUMBER_OF_CLASSES] = {0,0,0,0,0,0,0,0,0,0};

printf(“\nUsing testing database: %s\n\n”, argv[2]);

for(inttsample =0; tsample < NUMBER_OF_TESTING_SAMPLES; tsample++)

{

//extract a row from the testing matrix

test_sample =testing_data.row(tsample);

/********************************步骤3:预测*********************************************/

result= rtree->predict(test_sample, Mat());

printf(“Testing Sample %i -> class result (digit %d)\n”, tsample,
(int) result);

//if the prediction and the (true) testing classification are the same

//(N.B. openCV uses a floating point decision tree implementation!)

if(fabs(result – testing_classifications.at<float>(tsample,0))

>=FLT_EPSILON)

{

//if they differ more than floating point error => wrong class

wrong_class++;

false_positives[(int) result]++;

}

else

{

//otherwise correct

correct_class++;

}

}

printf(“\nResults on the testing database: %s\n”

“\tCorrect classification: %d (%g%%)\n”

“\tWrong classifications: %d (%g%%)\n”,

argv[2],

correct_class, (double)
correct_class*100/NUMBER_OF_TESTING_SAMPLES,

wrong_class, (double) wrong_class*100/NUMBER_OF_TESTING_SAMPLES);

for(inti =0; i < NUMBER_OF_CLASSES; i++)

{

printf(“\tClass (digit %d) false postives    %d (%g%%)\n”, i,

false_positives[i],

(double) false_positives[i]*100/NUMBER_OF_TESTING_SAMPLES);

}

//all matrix memory free by destructors

//all OK : main returns 0

return0;

}

//not OK : main returns -1

return-1;

}

MNIST样本能够在那几个网址http://yann.lecun.com/exdb/mnist/下载,改一下路径可以直接跑的。

3.怎么样团结设计随机森林程序

突发性现有的库不能满足必要,就须求协调安顿2个分类器算法,那有个别讲一下什么样布置本身的妄动森林分类器,代码达成就不贴了,因为在工作中用到了,因而比较灵敏。

先是,要有1个RandomForest类,里面保存整个树需求的一部分参数,包蕴但不压制:练习样本数量、测试样本数量、特征维数、每一种节点随机提取的性状维数、CALacrosseT树的数据、树的最大深度、种类数量(倘使是分类难点)、一些停歇条件、指向全数树的指针,指向操练集和测试集的指针,指向练习集label的指针等。还要有一些函数,至少要有train和predict吧。train里面一贯调用每棵树的train方法即可,predict同理,但要对每棵树的展望输出做拍卖,获得森林的前瞻输出。

说不上,要有二个sample类,那些类可不是用来储存演习集和对应label的,那是因为,每棵树、每一种节点都有协调的样书集和,假若你的贮存每一个样本集和的话,必要的内存实在是太过巨大了,要是样本数量为M,特征维数为N,则整个练习集大小为M×N,而每棵树的每层都有这么两种本,树的纵深为D,共有S棵树的话,则供给仓库储存M×N×D×S的储存空间。那实则是太大了。因而,各个节点演习时用到的磨练样本和脾性,我们都用序号数组来代表,sample类正是干这一个的。sample的函数基本须要多个就行,第⑥个是从现有训练集有放回的肆意抽取1个新的操练集,当然,只含有样本的序号。第四个函数是从现有的特点中无放回的自由抽取一定数额的天性,同理,也是特点序号即可。

下一场,要求3个Tree类,代表每棵树,里面保存树的一对参数以及一个针对性全部节点的指针。

最终,须要一个Node类,代表树的各种节点。

必要表明的是,保存树的办法能够是最平时的数组,也但是是vector。Node的保留方法同理,但是个人不建议用链表的法门,在先后设计以及函数处理上太费事,不过在省空间上并不曾太多的反映。

近日先写这么多,最终这有的自个儿还会再扩充一些。

相关文章