2025年機(jī)器學(xué)習(xí)實(shí)戰(zhàn)隨機(jī)森林算法深度解析與應(yīng)用_第1頁
2025年機(jī)器學(xué)習(xí)實(shí)戰(zhàn)隨機(jī)森林算法深度解析與應(yīng)用_第2頁
2025年機(jī)器學(xué)習(xí)實(shí)戰(zhàn)隨機(jī)森林算法深度解析與應(yīng)用_第3頁
2025年機(jī)器學(xué)習(xí)實(shí)戰(zhàn)隨機(jī)森林算法深度解析與應(yīng)用_第4頁
2025年機(jī)器學(xué)習(xí)實(shí)戰(zhàn)隨機(jī)森林算法深度解析與應(yīng)用_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

隨機(jī)森林試驗(yàn)匯報(bào)輸入:訓(xùn)練數(shù)據(jù)集D,停止訓(xùn)練條件A,對(duì)于每一個(gè)可能的劃分值a,根據(jù)大于a及小于等于a將訓(xùn)練數(shù)據(jù)集分成D1,D2兩(2)在所有可能特征A以及其所有可能劃分點(diǎn)a中,選擇gini系數(shù)最小的特征及切分值,將D1和D2分配到左右兩個(gè)子節(jié)點(diǎn)去。(3)對(duì)左右節(jié)點(diǎn)分別遞歸的調(diào)用(1),(2),直到滿足一定條件為止。RF在每次構(gòu)造一棵決策樹時(shí),先隨機(jī)的有放回的從訓(xùn)練集中抽取(60%)或n(sizeof將一種N分類問題轉(zhuǎn)化為N個(gè)二分類問題。轉(zhuǎn)化措施是:構(gòu)造N棵二叉擬合樹,這里假設(shè)N為26,然后我們給N棵二叉樹依次標(biāo)號(hào)為1,2,3...26。1號(hào)樹的成果對(duì)應(yīng)于該條記錄是不是屬于第一類,是則輸出1,否則輸出0.2號(hào)樹的成果對(duì)應(yīng)于該條記錄是不是屬于第二類,是則1否則0,依此類推。這樣,我們的26棵二叉樹的成果就對(duì)應(yīng)了26個(gè)下標(biāo)。例如對(duì)于某條記錄,這26個(gè)二叉樹的成果按序號(hào)排列為(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,..1,0],那么這條記錄的分類應(yīng)當(dāng)為25。要將一種26維的0,1序列變回我們將上面的26棵分別對(duì)26個(gè)索引做與否判斷的二分類樹視為一種整體,在多線程的環(huán)境下,2.將訓(xùn)練集分割為輸入trainIn,輸出trainOut[sampleln,transformSampleOut]=TakeSample(trai//CartTree數(shù)組寄存著26棵二分類樹CartTree[category]=TrainCartTree(sampleln,transftransformTestOut[i1][category]+=predict(CartTree[category],tes6.遍歷transformTrainOut[],將其每一行的最大值的下標(biāo)作為該行記錄的索引值。1.決策樹在這里,我們每一次26分類是由26棵CART共同完畢的,CART的costfun2.隨機(jī)森林a.隨機(jī)森林每次循環(huán)的訓(xùn)練集采樣為原訓(xùn)練集的0.5.b.對(duì)于森林中每一棵決策樹每一次分割點(diǎn)的選用,對(duì)屬性進(jìn)行了打亂抽樣,抽樣數(shù)為25,即每次分割只在25個(gè)屬性中尋找最合適的值。并且對(duì)于每個(gè)選用的屬性,我們進(jìn)行了行采樣。即假如這個(gè)屬性所擁有的屬性值數(shù)不小于30,我們選用其中30個(gè)作為分割候選,假如不不小于30,則所有納入分割候選。五.代碼詳解1.訓(xùn)練集/測(cè)試集的讀入a.在dataDefine.h中定義了:訓(xùn)練集記錄條數(shù)transetNum測(cè)試集記錄條數(shù)testsetNum分類類型數(shù)typesNum而在main.cpp中,我們申明了全局變量doubletestin[testsetNum]{numparadoubletestOut{testsetNuml;trainIn用于裝載訓(xùn)練集輸入,trainOut用于裝載訓(xùn)練集的輸出(這里trainOut是二維數(shù)組是出于模型假如泛化,那么輸出值不一定只有一種的狀況,在本次試驗(yàn)中并未派上什么真正用場(chǎng),可以將trainOut看作一種一般一維數(shù)組)。trainID用于裝載訓(xùn)練集中每一行的第一列ID號(hào)。testIn,testID則對(duì)應(yīng)測(cè)試集的輸入和ID號(hào)。這里注意,沒有testOut的原因是測(cè)試集的成果理論上應(yīng)當(dāng)是不存在的。然后通過自己編寫的讀入函數(shù)讀入測(cè)試集合訓(xùn)練集,這個(gè)函數(shù)將分別裝載我們?cè)谇懊嫣岬降膖rainIn、trainOut、trainID、testIn、testID。這個(gè)函數(shù)使用的fstream逐行讀入的措施,這里不做詳述。2.訓(xùn)練集輸出轉(zhuǎn)化為對(duì)應(yīng)的26維01數(shù)組transformOut[typesNum]在dataDefine.h中,我們定義了分類類別數(shù)typesNum:WdefinetypesNum26//26類型數(shù)量在main.cpp中,我們定義了全局變量transformOut[typesNum]這里的transformOut是用于儲(chǔ)存將trainOut每行的值映射為一行對(duì)應(yīng)的26維01序列后所這里面的對(duì)應(yīng)關(guān)系是:例如trainOut[10]中的值是13那么transformOut[10][13]=1,transformOut[10][除13外其他列]=0;假如值是14,那么14列為1,其他列為0,行號(hào)代表的是它們對(duì)應(yīng)的是第幾條記錄:trainOut[10]和transformOut[10]都表達(dá)的是第10行的分類值為某個(gè)值,只是體現(xiàn)方式不一樣。前者用數(shù)字表達(dá),后者將對(duì)應(yīng)下標(biāo)的值置1表達(dá)。voidindexTransform(inttransformreslltypesNum+1),doubleogresl[1)://將原始輸出轉(zhuǎn)化為轉(zhuǎn)化型輸出在在main.cpp中,我們構(gòu)建了doubletrainInPerTime[perTimeNum][numparadoubletrainInPerTimeT1[perTimeNum][numdoubletrainInPerTimeT2[perTimeNum][numparamedoubletrainInPerTimeT3[perTimeNum][numparametres-2];doubletrainInPerTimeT4[perTimeNum][numparametres-2];inttransformOutPerTimeT1[perTimeinttransformOutPerTimeT2[inttransformOutinttransformOutdoubletransformTestOutT1[testsetNum][typesNum+1]={0};doubletransformTestOutT2[testsetNum][typesNum+1]=(0);doubletransformTestOutT3[testsetNum][typesNum+1]=(0);TransformOutPerTime代表的是與trainlnperTime對(duì)應(yīng)的轉(zhuǎn)換輸出transformtestOut是承接本支線程的所有CART樹的決策值之和的構(gòu)造,這與算法思緒是對(duì)應(yīng)的,我們我們可以看出,這幾種變量都是只有最終的TX有區(qū)別,實(shí)際上,反復(fù)的創(chuàng)立相似的變量只是為了以這里使用的是C++11的<thread>庫(kù),簡(jiǎn)樸好用。每一種線程的隨機(jī)森林框架定義在main.cpp的 這個(gè)函數(shù)采用循環(huán)的方式,每次循環(huán),對(duì)訓(xùn)練集及對(duì)應(yīng)轉(zhuǎn)換輸出進(jìn)行打亂后采樣,然后輸入TRAIN(traininPerTime_,transformOutPerTime_,transformTesTRAIN(traininPerTime_,transformOutPerTime_,transformTes中進(jìn)行一輪決策樹的訓(xùn)練,這一輪訓(xùn)練將會(huì)生成26棵CART樹,對(duì)應(yīng)26個(gè)分類值。這里輸入的參數(shù)Tree就是我們所用的決策樹容器,這里注意,我們一種線程中只需要公用一種決策樹構(gòu)造即足夠了.在訓(xùn)練完畢后,我們用累加訓(xùn)練成果。由于26棵CART樹才能完整的等價(jià)于一棵26分類樹,因此我們將構(gòu)建這26棵CART樹的過程當(dāng)作是一種整體。這個(gè)過程由函數(shù)TRAIN(trainnPerTime_,transformOutPerTime_,transformTesTRAIN(trainnPerTime_,transformOutPerTime_,transformTes實(shí)現(xiàn)。它的輸入依次是本輪的訓(xùn)練輸入(通過了下采樣,隨機(jī)森林規(guī)定的),對(duì)應(yīng)的轉(zhuǎn)換訓(xùn)練輸出,以及一種決策樹容器Tree。決策樹的定義我們將在下文中描述。這個(gè)函數(shù)有一種棧stack<int>trace;//用于追蹤樹的遍歷過程,這里我們假并且有一種從1:26的循環(huán)的是一種先序的遍歷次序。當(dāng)循環(huán)完畢后,將會(huì)計(jì)算本輪的轉(zhuǎn)換輸出成果的變更://testresPerTime[i][typesN]=TputeRes(test5.每科CART樹的構(gòu)造CART樹的數(shù)據(jù)構(gòu)造如下:trainIntrainOut對(duì)應(yīng)于輸入該樹的輸入輸出集,Nodes表達(dá)的是節(jié)點(diǎn)序列,在這里我們的樹的構(gòu)造使用的是數(shù)組,且樹的節(jié)點(diǎn)間的索引是通過索引值維護(hù)的,這顆樹非常緊密(假如只看NODES是看不出節(jié)點(diǎn)間的層級(jí)關(guān)系的)。它有如下組員函數(shù):boolgetPartition(intindex,//doublecomputeNodeGini(intindex);//初始化樹//對(duì)于每個(gè)節(jié)點(diǎn)的一些操作voidgetNodeAttr(vector<int>selectedColvoidcomputeNodeValue(int;getNodeSequence(node1[)本來是用來輸出節(jié)點(diǎn)參數(shù)的,這里不做詳述initialize用于初始化決策樹。getNodeAttr用于得到某一節(jié)點(diǎn)的備選屬性分割值computePerNodeGini用于計(jì)算某一節(jié)點(diǎn)的GINI值,這在停止節(jié)點(diǎn)分割時(shí)有用computeNodeValue是用于計(jì)算某一葉子節(jié)點(diǎn)的擬合值的。我們?cè)僬f一下Nodes節(jié)點(diǎn),它的構(gòu)造如下Attrbutes[selectedColumns]是用于寄存候選的分割值的容器其他變量的功能見圖片中的文字注釋這里我們用datalndex寄存對(duì)應(yīng)記錄所在索引的措施取代了直接寄存記錄,這里是一種巨大的改善,將程序的執(zhí)行速度提高了至少10倍。在構(gòu)造一棵決策樹時(shí),當(dāng)train函數(shù)對(duì)應(yīng)的trace棧的棧頂非空時(shí),我們會(huì)不停的取出棧頂元素,對(duì)其操作,Index指的是節(jié)點(diǎn)所在的索引值,container用于寄存這個(gè)節(jié)點(diǎn)的左右葉子索引,由于樹的構(gòu)建是由外部棧維護(hù)的,因此這個(gè)container是必不可少的,在目前節(jié)點(diǎn)分割完畢后,我們會(huì)將這個(gè)節(jié)點(diǎn)的索引值出棧,假如container[0]的值不是-1,我們會(huì)將container[0].container[1]入棧。建樹的對(duì)應(yīng)模//樹的初始化(插入頭節(jié)點(diǎn))完成后,正式開始決策樹的構(gòu)建(*Tree).getPartition(curren//判斷當(dāng)前節(jié)點(diǎn)是否成功分割下面再重點(diǎn)說一下函數(shù):這個(gè)函數(shù)是單棵決策樹構(gòu)造的關(guān)鍵,調(diào)用這個(gè)函數(shù),假如目前節(jié)點(diǎn)的Gini值已經(jīng)為0,那么這個(gè)函數(shù)會(huì)計(jì)算目前節(jié)點(diǎn)的擬合值:ifif(Nodes[index]gini==0||Nodes[index]layer>=MaxLayerNfor(inti=0;i<Nodes[index].datalndex.size結(jié)束條件是gini==0|1層數(shù)等于10selectedColumns列。然后調(diào)用getNodeAttr(s,index)獲取目前節(jié)點(diǎn)的備選分割值,這里的s是抽取的屬性的列號(hào)的集合。在得到備選的屬性分割值后,將進(jìn)入循環(huán),尋找最優(yōu)分割點(diǎn)for(cursor=Nodes[index].attributes{).begin);cursor!=Nodes[index]attributeslj].end?;++temp_ginicomputeGini(index,6.最終止果計(jì)算在main函數(shù)中,我們將四個(gè)線程所得的transformOutT相加,最終遍歷取每一行最大值的下標(biāo),即可得到最終止果。1.應(yīng)用了數(shù)組+棧建樹取代了一般的函數(shù)遞歸建樹,加緊了建樹速度。2.在傳遞每個(gè)節(jié)點(diǎn)的節(jié)點(diǎn)數(shù)據(jù)集時(shí),使用了傳遞數(shù)據(jù)集的索引而非數(shù)據(jù)自身,這樣做的好處是,本來假如傳遞一條數(shù)據(jù)需要復(fù)制617個(gè)double類型的數(shù)量,而目前只需要傳遞一種Int型的索引,這種快了617倍的數(shù)據(jù)集傳遞方式使程序運(yùn)行效率提高了10倍以上。3.在每個(gè)屬性中選擇備選分割值的時(shí)候,采用了一種下采樣的方略。即:假如該節(jié)點(diǎn)的數(shù)據(jù)集大小不不小于某一數(shù)值,則將這個(gè)數(shù)據(jù)集的這個(gè)屬性的所有值都納入候選分割值列表。不過假如不小于了這個(gè)閥值,則將屬性所對(duì)應(yīng)的列進(jìn)行排序后再進(jìn)行等間距采樣得到樣本數(shù)等于閾值的子集作為候選分割集。代碼詳見getPartition().這樣做的好處是需要計(jì)算的分割gini值大大減少了(本人取的采樣閾值時(shí)100,相比原數(shù)據(jù)集,樣本空間縮小了盡30倍),這里也再一次加速了程序運(yùn)行。不過這個(gè)優(yōu)化隨機(jī)而來的一種問題是:有也許每次分割都不是最佳分割。4.使用了C++11的<thread>庫(kù)進(jìn)行了并行實(shí)現(xiàn),開出4個(gè)線程,程序相比單線程加速了4倍。七.并行實(shí)現(xiàn)C++1l<thread>庫(kù)創(chuàng)立線程,為每個(gè)線程賦予獨(dú)立的數(shù)據(jù)容器,并將隨機(jī)森林提成等量的4部分(由于我使用的是4個(gè)線程)。即,每個(gè)線程中執(zhí)行的函數(shù)承擔(dān)1/4規(guī)模的隨機(jī)森林的構(gòu)造,實(shí)現(xiàn)代碼如intmaininThread(inttransfomOutPerTimeIlypesSNum+11.doubletrainnPerTime

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論