OpenCV:使用 随机森林与GBDT
??????? 隨機(jī)森林顧名思義,是用隨機(jī)的方式建立一個(gè)森林。簡(jiǎn)單來(lái)說(shuō),隨機(jī)森林就是由多棵CART(Classification And Regression Tree)構(gòu)成的。對(duì)于每棵樹,它們使用的訓(xùn)練集是從總的訓(xùn)練集中有放回采樣出來(lái)的,這意味著,總的訓(xùn)練集中的有些樣本可能多次出現(xiàn)在一棵樹的訓(xùn)練集中,也可能從未出現(xiàn)在一棵樹的訓(xùn)練集中。在訓(xùn)練每棵樹的節(jié)點(diǎn)時(shí),使用的特征是從所有特征中按照一定比例隨機(jī)地?zé)o放回的抽取的,根據(jù)Leo Breiman的建議,假設(shè)總的特征數(shù)量為M,這個(gè)比例可以是sqrt(M),1/2sqrt(M),2sqrt(M)。
?
???????隨機(jī)性來(lái)源:特征選擇的隨機(jī)性、自舉重采樣的隨機(jī)性。
?????? 隨機(jī)森林在多類識(shí)別上有足夠的優(yōu)點(diǎn):隨機(jī)森林可以作為天然的多類分類器,通過(guò)其學(xué)習(xí)特性進(jìn)行bag弱分類器,不需要SVM類似的頂層多類訓(xùn)練;隨機(jī)森林在訓(xùn)練的同時(shí)使用隨機(jī)采樣和特征選擇,因此并不需要特別的剪枝,可以防止過(guò)擬合;并由于隨機(jī)森林使用決策樹,在本質(zhì)上等同于布爾邏輯,理論上可以表達(dá)任意復(fù)雜的布爾函數(shù),有強(qiáng)大的可擴(kuò)充特性,因此隨機(jī)森林在處理多樣本問(wèn)題上看似是無(wú)邊界的,并容易實(shí)現(xiàn)在線學(xué)習(xí)方式-通過(guò)在線分裂葉子節(jié)點(diǎn)或者增加生成樹等方式。
??????? 其他描述可參考:http://www.cnblogs.com/hrlnw/p/3850459.html
??????? 或者此描述:https://www.cnblogs.com/maybe2030/p/4585705.html
??????? 隨機(jī)森林在生成過(guò)程中,使用了模型平均,致力于降低集合模型的方差,能夠獲取到內(nèi)部生成誤差的一種無(wú)偏估計(jì)/It generates an internal unbiased estimate of the generalization error as the forest building progresses。且理論證明,隨機(jī)森林的弱分類器的個(gè)數(shù)越多,分類器逐漸逼近理論模型的準(zhǔn)確度極限。
??????? 在 ? do we need hundreds of classifiers to solve real world classification problem 論文中,對(duì)不使用DNN的傳統(tǒng)分類器,十幾個(gè)族的各個(gè)分類器在多個(gè)數(shù)據(jù)集上進(jìn)行評(píng)測(cè),得到了排名第一的效果。
?
一、OpenCV的RTrees:
1. RTrees參數(shù),參考鏈接:http://blog.csdn.net/pi9nc/article/details/12197731
?
| CvRTParams | 定義R.T.訓(xùn)練用參數(shù),CvDTreeParams的擴(kuò)展子類,但并不用到CvDTreeParams(單一決策樹)所需的所有參數(shù)。比如說(shuō),R.T.通常不需要剪枝,因此剪枝參數(shù)就不被用到。 max_depth?:單棵樹所可能達(dá)到的最大深度 min_sample_count:? 樹節(jié)點(diǎn)持續(xù)分裂的最小樣本數(shù)量,也就是說(shuō),小于這個(gè)數(shù)節(jié)點(diǎn)就不持續(xù)分裂,變成葉子。 regression_accuracy: 回歸樹的終止條件,如果所有節(jié)點(diǎn)的精度都達(dá)到要求就停止 use_surrogates? :是否使用代理分裂。通常都是false,在有缺損數(shù)據(jù)或計(jì)算變量重要性的場(chǎng)合為true,比如,變量是色彩,而圖片中有一部分區(qū)域因?yàn)楣庹帐侨诘?br /> max_categories? :將所有可能取值聚類到有限類,以保證計(jì)算速度。樹會(huì)以次優(yōu)分裂(suboptimal split)的形式生長(zhǎng)。只對(duì)2種取值以上的樹有意義 priors : 優(yōu)先級(jí)設(shè)置,設(shè)定某些你尤其關(guān)心的類或值,使訓(xùn)練過(guò)程更關(guān)注它們的分類或回歸精度。通常不設(shè)置 calc_var_importance : 設(shè)置是否需要獲取變量的重要值,一般設(shè)置true nactive_vars : 樹的每個(gè)節(jié)點(diǎn)隨機(jī)選擇變量的數(shù)量,根據(jù)這些變量尋找最佳分裂。如果設(shè)置0值,則自動(dòng)取變量總和的平方根 max_num_of_trees_in_the_forest:? R.T.中可能存在的樹的最大數(shù)量 forest_accuracy : 準(zhǔn)確率(作為終止條件) termcrit_type? :終止條件設(shè)置 ? —?CV_TERMCRIT_ITER? 以樹的數(shù)目為終止條件,max_num_of_trees_in_the_forest生效 ? –?CV_TERMCRIT_EPS? 以準(zhǔn)確率為終止條件,forest_accuracy生效 ? —?CV_TERMCRIT_ITER | CV_TERMCRIT_EPS? 兩者同時(shí)作為終止條件 |
| CvRTrees::train | 訓(xùn)練R.T. return bool : 訓(xùn)練是否成功 train_data : 訓(xùn)練數(shù)據(jù):樣本(一個(gè)樣本由固定數(shù)量的多個(gè)變量定義),以Mat的形式存儲(chǔ),以列或行排列,必須是CV_32FC1格式(Float格式!) tflag? trainData的排列結(jié)構(gòu) ? —?CV_ROW_SAMPLE? 行排列 ? —?CV_COL_SAMPLE? 列排列 responses? :訓(xùn)練數(shù)據(jù):樣本的值(輸出),以一維Mat的形式存儲(chǔ),對(duì)應(yīng)trainData,必須是CV_32FC1或CV_32SC1格式。對(duì)于分類問(wèn)題,responses是類標(biāo)簽;對(duì)于回歸問(wèn)題,responses是需要逼近的函數(shù)取值 var_idx? :定義感興趣的變量,變量中的某些,傳null表示全部 sample_idx? :定義感興趣的樣本,樣本中的某些,傳null表示全部 var_type? :定義responses的類型 ? —?CV_VAR_CATEGORICAL?分類標(biāo)簽 ? —?CV_VAR_ORDERED(CV_VAR_NUMERICAL)數(shù)值,用于回歸問(wèn)題 missing_mask? :定義缺失數(shù)據(jù),和train_data一樣大的8位Mat params : CvRTParams定義的訓(xùn)練參數(shù) |
| CvRTrees::train | 訓(xùn)練R.T.(簡(jiǎn)短版的train函數(shù)) return bool? 訓(xùn)練是否成功 data??訓(xùn)練數(shù)據(jù):CvMLData格式,可從外部.csv格式的文件讀入,內(nèi)部以Mat形式存儲(chǔ),也是類似的value / responses / missing mask。 params?CvRTParams定義的訓(xùn)練參數(shù) |
| CvRTrees:predict | 對(duì)一組輸入樣本進(jìn)行預(yù)測(cè)(分類或回歸) return double? 預(yù)測(cè)結(jié)果 sample? 輸入樣本,格式同CvRTrees::train的train_data missing_mask? 定義缺失數(shù)據(jù) |
?
2. ? 訓(xùn)練過(guò)程
?
Training
?????? RF屬于Bagging類模型,因此大體訓(xùn)練過(guò)程和Bagging類似,關(guān)鍵在于樣本的隨機(jī)選取避免模型的overfitting問(wèn)題。RF中的每棵決策樹是分開(kāi)訓(xùn)練的,彼此之間并無(wú)關(guān)聯(lián)。對(duì)于每棵決策樹,訓(xùn)練之前形成一個(gè)樣本子集,在這個(gè)子集中有些樣本可能出現(xiàn)多次,而另一些可能一次都沒(méi)出現(xiàn)。接下去,就是循序決策樹訓(xùn)練算法的,針對(duì)這個(gè)樣本子集的單棵決策樹訓(xùn)練。
單棵決策樹的生成大致遵循以下過(guò)程:
1)隨機(jī)生成樣本子集;
2)分裂當(dāng)前節(jié)點(diǎn)為左右節(jié)點(diǎn),比較所有可選分裂,選取最優(yōu)者;
3)重復(fù)2)直至達(dá)到最大節(jié)點(diǎn)深度,或當(dāng)前節(jié)點(diǎn)分類精度達(dá)到要求。
這一過(guò)程是貪婪的。
當(dāng)然對(duì)于不同的應(yīng)用場(chǎng)合,訓(xùn)練過(guò)程中,會(huì)有細(xì)節(jié)上的差別,比如樣本子集的生成過(guò)程、以及最優(yōu)分割的定義。 ??
?
二.? 使用OpenCV隨機(jī)森林
1. 所使用的代碼:
//訓(xùn)練過(guò)程——閾值、迭代次數(shù)、輸出響應(yīng) //訓(xùn)練參數(shù)存儲(chǔ)為XML newrtrees.xml //注意事項(xiàng): 此代碼的內(nèi)存錯(cuò)誤我并沒(méi)有解決,而使用GBDTree!已解決! //注意事項(xiàng): CvRTrees* forest = new CvRTrees; 使用是錯(cuò)誤的,無(wú)法完成初始化,應(yīng)該修改為:CvRTrees* forest = new CvRTrees(); int CPalmRecog::rTreesTrain(LabeledFeatrureArrayI &trainData) {int NumSample = trainData.size();int NUMBER_OF_TRAINING_SAMPLES = NumSample;int ATTRIBUTES_PER_SAMPLE = FeatureLenG;//定義訓(xùn)練數(shù)據(jù)與標(biāo)簽矩陣 cv::Mat training_data =cv::Mat(NUMBER_OF_TRAINING_SAMPLES, ATTRIBUTES_PER_SAMPLE, CV_32FC1);cv::Mat training_classifications =cv::Mat(NUMBER_OF_TRAINING_SAMPLES, 1, CV_32FC1);//Copy 數(shù)據(jù)和標(biāo)簽 到訓(xùn)練數(shù)據(jù)!for (int i = 0; i< NUMBER_OF_TRAINING_SAMPLES; i++) {for (int idx = 0; idx < ATTRIBUTES_PER_SAMPLE; ++idx){//轉(zhuǎn)化為char類型training_data.at<float>(i,idx) = trainData[i].second[idx];}training_classifications.at<float>(i, 0) = trainData[i].first;//類別標(biāo)簽!}//1. RF參數(shù)!//正好15類////float priors[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};CvRTParams Params(15, 10, 0.01f, true,//false,15, 0, true,4,1000, 0.01f,//CV_TERMCRIT_ITER);//最大類別數(shù)設(shè)置為8//設(shè)置為64顆樹如何?CV_TERMCRIT_EPS );//2. 隨機(jī)森林訓(xùn)練 .SVM SVMS;// CvSVM SVMs;CvRTrees* forest = new CvRTrees();//CvRTrees* forest = new CvRTrees;CvMat* var_importance = 0;forest->train(training_data,//已經(jīng)填充數(shù)據(jù)CV_ROW_SAMPLE,//CV_COL_SAMPLE,//CV_ROW_SAMPLE,training_classifications,//已經(jīng)初始化,應(yīng)該沒(méi)有什么問(wèn)題!!!cv::Mat(), cv::Mat(), cv::Mat(), cv::Mat(),Params);//3. Test,不需要嗎?//4. 保存參數(shù)到XML文件forest->save("Out/rtrees.xml");return 1; }
2.注意事項(xiàng)
對(duì)于網(wǎng)上copy的代碼!
比如此行代碼:
CvRTrees* forest = new CvRTrees();//CvRTrees* forest = new CvRTrees;使用GBTrees和RTrees的存儲(chǔ)空間不太一樣,使用RTrees得到89MB的森林XML文件,而GBTrees只獲得了433KB的文件,精度上應(yīng)該有些差別。
梯度提升樹使用了殘差學(xué)習(xí)的方法,每一層學(xué)習(xí)的是上一層的函數(shù),類似于反饋模型,使用了較少的參數(shù),因此泛化性能也相應(yīng)地降低。
?
3.測(cè)試結(jié)果
全部測(cè)試,錯(cuò)誤率如下:Class (digit 0) false postives 0 (0%)Class (digit 1) false postives 9 (1.07527%)Class (digit 2) false postives 1 (0.119474%)Class (digit 3) false postives 0 (0%)Class (digit 4) false postives 0 (0%)Class (digit 5) false postives 0 (0%)Class (digit 6) false postives 0 (0%)Class (digit 7) false postives 0 (0%)Class (digit 8) false postives 0 (0%)Class (digit 9) false postives 1 (0.119474%)Class (digit 10) false postives 1 (0.119474%)Class (digit 11) false postives 0 (0%)Class (digit 12) false postives 0 (0%)Class (digit 13) false postives 0 (0%)Class (digit 14) false postives 0 (0%)錯(cuò)誤率:12/836?*100%?=?1.435%
?
二、GBDT
參考文章:機(jī)器學(xué)習(xí)中的算法——決策樹模型組合之隨機(jī)森林與GBDT
??????? 原始的Boost算法是在算法開(kāi)始的時(shí)候,為每一個(gè)樣本賦上一個(gè)權(quán)重值,初始的時(shí)候,大家都是一樣重要的。在每一步訓(xùn)練中得到的模型,會(huì)使得數(shù)據(jù)點(diǎn)的估計(jì)有對(duì)有錯(cuò),我們就在每一步結(jié)束后,增加分錯(cuò)的點(diǎn)的權(quán)重,減少分對(duì)的點(diǎn)的權(quán)重,這樣使得某些點(diǎn)如果老是被分錯(cuò),那么就會(huì)被“嚴(yán)重關(guān)注”,也就被賦上一個(gè)很高的權(quán)重。然后等進(jìn)行了N次迭代(由用戶指定),將會(huì)得到N個(gè)簡(jiǎn)單的分類器(basic learner),然后我們將它們組合起來(lái)(比如說(shuō)可以對(duì)它們進(jìn)行加權(quán)、或者讓它們進(jìn)行投票等),得到一個(gè)最終的模型。
??????? 而Gradient Boost與傳統(tǒng)的Boost的區(qū)別是,每一次的計(jì)算是為了減少上一次的殘差(residual),而為了消除殘差,我們可以在殘差減少的梯度(Gradient)方向上建立一個(gè)新的模型。所以說(shuō),在Gradient Boost中,每個(gè)新的模型的簡(jiǎn)歷是為了使得之前模型的殘差往梯度方向減少,與傳統(tǒng)Boost對(duì)正確、錯(cuò)誤的樣本進(jìn)行加權(quán)有著很大的區(qū)別。
?????? OpenCV可以直接使用GBDT,方法與隨機(jī)森林相同,在相同的準(zhǔn)確率下生成的模型要小很多,同時(shí)這意味著泛化能力變差。
?
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的OpenCV:使用 随机森林与GBDT的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: VTK初始化New返回Null问题
- 下一篇: VR: AR和VR演进哲学