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