習(xí)三大算法詳解:Bagging、Boosting與Stacking原理對(duì)比)
別忘了點(diǎn)“在看”呀今天這篇是寫給我們自己人看的做機(jī)器學(xué)習(xí)這一行如果你問(wèn)一個(gè)從業(yè)者“你在真實(shí)項(xiàng)目里最常用哪個(gè)模型”回答大概率不是某個(gè)花哨的深度學(xué)習(xí)網(wǎng)絡(luò)而是一句平淡的“調(diào)個(gè)梯度提升樹或者跑個(gè)隨機(jī)森林”。這兩個(gè)東西都屬于集成算法Ensemble Learning。圈里有人喜歡用“三個(gè)臭皮匠頂個(gè)諸葛亮”來(lái)解釋它也有人管它叫“集成學(xué)習(xí)大法好”但我覺(jué)得最傳神的說(shuō)法還是那句七個(gè)葫蘆一條心。什么意思呢單個(gè)葫蘆娃打架各有各的本事但也各有各的短板可一旦七個(gè)兄弟擰成一股繩連妖怪都得繞著走。集成算法就是這個(gè)套路多個(gè)弱學(xué)習(xí)器weak learner各自為戰(zhàn)最后通過(guò)投票、加權(quán)、疊加等方式統(tǒng)一決策硬生生把“一般般”變成“很能打”。這篇文章不聊花架子直接拆解集成算法里的三種主流玩法——Bagging、Boosting、Stacking——把它們的原理、流程、參數(shù)直覺(jué)、工程坑位一次說(shuō)透。適合正在學(xué)機(jī)器學(xué)習(xí)基礎(chǔ)、準(zhǔn)備做項(xiàng)目實(shí)戰(zhàn)的新手也適合已經(jīng)用過(guò)隨機(jī)森林或XGBoost但一直沒(méi)把底層邏輯理順的老手。1. 集成算法的整體設(shè)計(jì)思路1.1 為什么單個(gè)模型總有種“力不從心”的感覺(jué)在聊集成之前先想清楚一個(gè)問(wèn)題一個(gè)模型為什么會(huì)有誤差機(jī)器學(xué)習(xí)里有個(gè)經(jīng)典的偏差-方差分解Bias-Variance Decomposition可以把模型的泛化誤差拆成三塊偏差Bias、方差Variance和不可避免的噪聲Noise。偏差大說(shuō)明模型太簡(jiǎn)單對(duì)訓(xùn)練數(shù)據(jù)的擬合能力不足典型的欠擬合。方差大說(shuō)明模型太敏感訓(xùn)練數(shù)據(jù)稍微抖一下預(yù)測(cè)結(jié)果就劇烈波動(dòng)典型的過(guò)擬合。噪聲是數(shù)據(jù)本身自帶的任何模型都沒(méi)辦法消除。單個(gè)模型的問(wèn)題在于你很難同時(shí)把偏差和方差都?jí)旱煤艿?。拿決策樹舉例樹很淺偏差大、欠擬合樹很深方差大、過(guò)擬合。你調(diào)參調(diào)到半夜無(wú)非就是在“偏差”和“方差”之間找個(gè)能接受的平衡點(diǎn)。但是單個(gè)模型的容量有限平衡點(diǎn)附近的能力上限就在那里。那怎么辦呢?fù)Q個(gè)思路——既然一個(gè)模型搞不定那就別讓它單打獨(dú)斗了。多訓(xùn)練幾個(gè)模型讓它們互相彌補(bǔ)、互相糾錯(cuò)從統(tǒng)計(jì)上把誤差攤薄。這就是集成算法最底層的動(dòng)機(jī)。我自己的理解是集成學(xué)習(xí)本質(zhì)上是在用“模型數(shù)量的冗余”換取“預(yù)測(cè)結(jié)果的穩(wěn)定”這種思路在工業(yè)界特別好使因?yàn)楣こ躺夏銢](méi)法保證拿到的是完美數(shù)據(jù)但你總能擠出時(shí)間多跑幾個(gè)模型。1.2 集成起效果的兩個(gè)必要條件準(zhǔn)一點(diǎn)散一點(diǎn)不是隨便把幾個(gè)模型堆在一起就能變強(qiáng)的。葫蘆七兄弟能打勝仗是因?yàn)槊總€(gè)人都有自己的絕活而不是七個(gè)一模一樣的葫蘆娃復(fù)制粘貼。集成算法有效必須同時(shí)滿足兩個(gè)條件第一基學(xué)習(xí)器的準(zhǔn)確率至少要高于隨機(jī)猜測(cè)。哪怕只是比瞎蒙好一點(diǎn)點(diǎn)這個(gè)基學(xué)習(xí)器就有貢獻(xiàn)價(jià)值。第二基學(xué)習(xí)器之間要有足夠的差異性。如果所有模型犯的錯(cuò)都一樣投票的時(shí)候錯(cuò)的一邊還是錯(cuò)的那邊集成就沒(méi)有意義了。這兩句話看似簡(jiǎn)單其實(shí)是后面所有技術(shù)細(xì)節(jié)的出發(fā)點(diǎn)。Bagging通過(guò)樣本擾動(dòng)制造差異性Boosting通過(guò)樣本權(quán)重制造差異性Stacking通過(guò)模型結(jié)構(gòu)差異制造差異性。你看三兄弟的分岔路從這里就開始了。理解了“準(zhǔn)一點(diǎn)散一點(diǎn)”再看任何集成方法的設(shè)計(jì)都不會(huì)覺(jué)得突兀。1.3 三條主流路線的性格差異集成算法發(fā)展到現(xiàn)在主流路線就三條打分如下路線代表算法串行/并行核心目標(biāo)一句話性格Bagging隨機(jī)森林并行降方差各干各的最后投票老大哥風(fēng)格BoostingAdaBoost、GBDT、XGBoost串行降偏差后一個(gè)盯著前一個(gè)的錯(cuò)連環(huán)糾錯(cuò)Stacking模型融合層級(jí)組合優(yōu)勢(shì)讓聰明人集體開會(huì)再請(qǐng)個(gè)高管拍板接下來(lái)三章我分別展開講。2. Bagging各打各的最后投票2.1 自助采樣法每個(gè)模型看到的“世界”都不太一樣Bagging的全稱是Bootstrap Aggregating直譯過(guò)來(lái)就是“自助采樣聚合”。這里的關(guān)鍵詞是“自助采樣”Bootstrap Sampling。什么叫自助采樣給你一個(gè)包含N個(gè)樣本的訓(xùn)練集每次從里面隨機(jī)抽1個(gè)樣本抽完放回去再抽下一個(gè)。重復(fù)N次得到一個(gè)新的訓(xùn)練集。因?yàn)槭怯蟹呕爻闃有掠?xùn)練集里可能有重復(fù)樣本有些原樣本則一次都沒(méi)出現(xiàn)。數(shù)學(xué)上有一個(gè)經(jīng)典結(jié)論當(dāng)N足夠大時(shí)每個(gè)新訓(xùn)練集大約包含原數(shù)據(jù)集63.2%的不重復(fù)樣本剩下約36.8%的樣本是沒(méi)被抽中的。那些沒(méi)被抽中的樣本有個(gè)專門的名字叫“包外樣本”O(jiān)ut-of-Bag簡(jiǎn)稱OOB它們可以天然地當(dāng)作驗(yàn)證集來(lái)用不需要額外劃分驗(yàn)證數(shù)據(jù)這算是Bagging附帶贈(zèng)送的一個(gè)大福利。在每個(gè)基學(xué)習(xí)器的訓(xùn)練中用一份通過(guò)自助采樣得到的“副本”數(shù)據(jù)來(lái)訓(xùn)練。因?yàn)槊糠莞北镜臄?shù)據(jù)分布都略有差異基學(xué)習(xí)器之間就自然而然地產(chǎn)生了差異性。最后回歸任務(wù)對(duì)所有基學(xué)習(xí)器的輸出取平均分類任務(wù)做多數(shù)投票或者對(duì)各類別概率求平均再取最大。就這么簡(jiǎn)單粗暴。2.2 為什么Bagging能降低方差如果你手頭有一組獨(dú)立同分布的隨機(jī)變量每個(gè)變量的方差都是σ2那它們的平均值方差就是σ2/k。只要k足夠大平均值的波動(dòng)會(huì)越來(lái)越小。這就是統(tǒng)計(jì)學(xué)里的基本事實(shí)也是Bagging降方差的理論根基。但這里有一個(gè)容易誤導(dǎo)人的地方Bagging里的基學(xué)習(xí)器并不是真正獨(dú)立的因?yàn)樗鼈兌紒?lái)自同一份原始數(shù)據(jù)的自助采樣副本而且底層的模型同質(zhì)比如都是決策樹所以它們之間其實(shí)存在正相關(guān)性。那降方差的效果就要打折扣。相關(guān)系數(shù)ρ越高集成的方差下降越有限。所以Bagging的效果上限很大程度上取決于你能不能把基學(xué)習(xí)器之間的相關(guān)性壓下去。而這正是隨機(jī)森林Random Forest做得最漂亮的地方。2.3 隨機(jī)森林的“雙重隨機(jī)”隨機(jī)森林在Bagging的基礎(chǔ)上加了第二重隨機(jī)性不僅在樣本層面做自助采樣在特征層面也做了隨機(jī)選擇。具體來(lái)說(shuō)每次分裂決策樹的一個(gè)節(jié)點(diǎn)時(shí)不是從全部m個(gè)特征里找最優(yōu)分裂特征而是先從全部特征中隨機(jī)抽出k個(gè)特征k通常取根號(hào)m或log2m再在這k個(gè)候選特征里挑選最優(yōu)分裂。這一手非常聰明。如果只用樣本擾動(dòng)遇到特征特別強(qiáng)的場(chǎng)景所有樹都會(huì)優(yōu)先用那一個(gè)強(qiáng)特征分裂樹與樹之間長(zhǎng)得差不多相關(guān)性很高集成的方差下降效果就被削弱了。加了特征隨機(jī)之后即便最強(qiáng)特征還在大部分樹也不一定能選中它分裂時(shí)被迫使用其他特征樹與樹之間的差異就大了。實(shí)踐里隨機(jī)森林往往是決策樹Bagging的一個(gè)顯著升級(jí)版深層原因就在這里。2.4 為什么Bagging的最佳搭檔是決策樹細(xì)想一下Bagging對(duì)基學(xué)習(xí)器的要求是“高方差、低偏差”。什么意思呢基學(xué)習(xí)器得足夠敏感數(shù)據(jù)一擾動(dòng)學(xué)習(xí)器輸出的變化要比較明顯否則集成根本產(chǎn)生不了多樣性。而決策樹天然就有這個(gè)脾氣樹一深還原訓(xùn)練數(shù)據(jù)還原得特別徹底方差很高但對(duì)訓(xùn)練集的擬合能力也強(qiáng)偏差很低。如果換成線性模型或者KNN這種穩(wěn)定模型你換一份自助采樣副本它學(xué)出來(lái)的模型可能幾乎沒(méi)變化那Bagging就白搞了。所以實(shí)際工程中Bagging的基學(xué)習(xí)器基本默認(rèn)決策樹尤其是CART樹。這不是巧合是性質(zhì)匹配。實(shí)操中還有一個(gè)非常值得關(guān)注的點(diǎn)如果用Bagging可以讓每棵樹長(zhǎng)得非常深甚至不剪枝讓它充分?jǐn)M合訓(xùn)練集把那個(gè)“高方差”的性格發(fā)揮出來(lái)然后靠集成去平抑方差。這跟Boosting恰好相反后面我會(huì)講到。2.5 包外樣本評(píng)估與實(shí)戰(zhàn)心得我之前在某圖像處理Demo項(xiàng)目里想快速評(píng)估隨機(jī)森林的效果但又不想額外劃分驗(yàn)證集就用了OOB評(píng)估。具體做法訓(xùn)練過(guò)程中記錄每個(gè)樣本是否被某棵樹的自助采樣副本包含。對(duì)樣本x只用那些沒(méi)有在訓(xùn)練時(shí)見(jiàn)過(guò)x的樹對(duì)x做預(yù)測(cè)最后集成起來(lái)作為OOB預(yù)測(cè)。這個(gè)OOB誤差和交叉驗(yàn)證誤差高度接近但成本低很多。實(shí)際操作里直接用random forest框架的話一個(gè)參數(shù)oob_score設(shè)為True就能拿到OOB分?jǐn)?shù)。這個(gè)指標(biāo)特別適合做超參數(shù)粗篩比如快速比較樹的數(shù)量、最大特征數(shù)哪個(gè)設(shè)置更好。用OOB先粗篩一把確定一個(gè)候選區(qū)間再拿交叉驗(yàn)證精調(diào)比每一步都跑交叉驗(yàn)證省了不知道多少時(shí)間。3. Boosting連環(huán)糾錯(cuò)步步為營(yíng)3.1 Boosting和Bagging最大的區(qū)別Boosting跟Bagging走了完全相反的路Bagging并行建樹Boosting串行建樹Bagging追求降低方差Boosting追求降低偏差。Boosting的基本流程是先用初始數(shù)據(jù)訓(xùn)練一個(gè)弱學(xué)習(xí)器然后根據(jù)當(dāng)前學(xué)習(xí)器的表現(xiàn)調(diào)整訓(xùn)練樣本的權(quán)重或目標(biāo)值讓下一個(gè)基學(xué)習(xí)器更關(guān)注之前做錯(cuò)的樣本。如此反復(fù)迭代最后把所有基學(xué)習(xí)器加權(quán)組合起來(lái)。這個(gè)思想可以概括成一句話后一個(gè)模型站在前一個(gè)模型的肩膀上專挑前一個(gè)的軟肋打。所以你最終得到的不是一個(gè)各管一攤的團(tuán)隊(duì)而是一個(gè)糾錯(cuò)鏈條所有模型合在一起共同逼近一個(gè)更準(zhǔn)確的函數(shù)形態(tài)。3.2 AdaBoost從“改權(quán)重”開始的經(jīng)典版本AdaBoostAdaptive Boosting自適應(yīng)提升是最早的Boosting算法之一拿到的目標(biāo)不是直接預(yù)測(cè)而是“讓模型把注意力放在錯(cuò)得最多的樣本上”。它的核心流程分三步第一步給每個(gè)訓(xùn)練樣本初始化一個(gè)權(quán)重通常都是1/N。第二步用當(dāng)前帶權(quán)樣本訓(xùn)練一個(gè)基學(xué)習(xí)器計(jì)算它在訓(xùn)練集上的加權(quán)錯(cuò)誤率ε。根據(jù)錯(cuò)誤率計(jì)算這個(gè)學(xué)習(xí)器的權(quán)重α公式為α0.5×ln((1-ε)/ε)。這個(gè)權(quán)重表示“這個(gè)學(xué)習(xí)器說(shuō)話的分量”。第三步根據(jù)模型是否正確預(yù)測(cè)每個(gè)樣本更新樣本權(quán)重。被分錯(cuò)的樣本權(quán)重乘上e^α分對(duì)的乘上e^(-α)最后歸一化。簡(jiǎn)單說(shuō)錯(cuò)得越多的樣本下一輪在樣本里占的比例越大。迭代T輪后得到T個(gè)基學(xué)習(xí)器及其權(quán)重α。集成預(yù)測(cè)時(shí)每個(gè)基學(xué)習(xí)器按α加權(quán)投票。AdaBoost訓(xùn)練到后期樣本權(quán)重的分布會(huì)變得非常極端——那些極難分類的樣本權(quán)重會(huì)累積得非??鋸堖@既是它抗不過(guò)噪聲的原因也是后面改進(jìn)版本要解決的問(wèn)題。3.3 換個(gè)角度看AdaBoost加性模型如果只看AdaBoost的步驟覺(jué)得像某種啟發(fā)式的權(quán)重調(diào)整。但從宏觀視角看AdaBoost是典型的加性模型Additive Model最終模型是一堆基學(xué)習(xí)器的加權(quán)和。它本質(zhì)上是在做函數(shù)空間上的梯度下降優(yōu)化的損失函數(shù)是指數(shù)損失L(y,f(x))e^(-yf(x))。這個(gè)角度非常關(guān)鍵因?yàn)樗苯右隽薌BDT的核心邏輯既然Boosting是在做函數(shù)空間梯度下降那能不能不限定損失函數(shù)任意給定一個(gè)可導(dǎo)損失都用梯度下降的方式去擬合一個(gè)弱學(xué)習(xí)器呢答案是能這就有了Gradient Boosting。3.4 GBDT用負(fù)梯度做“偽殘差”GBDTGradient Boosting Decision Tree的訓(xùn)練思路和AdaBoost看起來(lái)很不一樣但其實(shí)一脈相承。每一輪迭代中我們不是修改樣本權(quán)重而是根據(jù)當(dāng)前集成模型對(duì)每個(gè)樣本的預(yù)測(cè)值計(jì)算損失函數(shù)關(guān)于預(yù)測(cè)值的負(fù)梯度然后用一棵決策樹去擬合這個(gè)負(fù)梯度。當(dāng)損失函數(shù)取平方損失時(shí)這個(gè)負(fù)梯度恰好等于真實(shí)值減預(yù)測(cè)值也就是殘差。所以對(duì)平方損失而言GBDT每輪就是在擬合殘差。但換成其他損失函數(shù)比如對(duì)數(shù)損失、Huber損失負(fù)梯度就不是殘差那么簡(jiǎn)單了。所以業(yè)界管它叫“偽殘差”。所有框架的負(fù)面效果都一樣每輪新訓(xùn)練一棵樹讓整體的預(yù)測(cè)沿著損失下降最快的方向前進(jìn)這是FLOW的求導(dǎo)思想在函數(shù)空間的應(yīng)用。實(shí)際操作中還有個(gè)要記得的點(diǎn)GBDT通常用一個(gè)較小的學(xué)習(xí)率η比如0.01到0.1來(lái)縮放每一棵樹的貢獻(xiàn)即新模型舊模型η×當(dāng)前樹。這不是為了好玩而是為了給后面的迭代留出空間。如果學(xué)習(xí)率太大前面幾輪就把損失壓到很低后面繼續(xù)糾錯(cuò)的空間被壓縮很容易過(guò)擬合。這個(gè)小細(xì)節(jié)我踩過(guò)很多次坑后面在“參數(shù)直覺(jué)”里細(xì)說(shuō)。3.5 樹模型在Boosting里的角色差異在Bagging里我們鼓勵(lì)樹長(zhǎng)得深讓方差爆發(fā)出來(lái)。但在Boosting里基學(xué)習(xí)器恰恰要用“弱”的——所以實(shí)際工程里GBDT的樹一般都很淺常用的max_depth是3到8。這里面的道理是Boosting的核心是靠大量弱學(xué)習(xí)器一點(diǎn)點(diǎn)糾偏每一步走小一點(diǎn)方向更精一點(diǎn)樹太深單棵樹擬合能力太強(qiáng)前面幾輪就把訓(xùn)練集擬合得七七八八后面要么過(guò)擬合要么把噪聲也學(xué)進(jìn)去了。所以我自己在調(diào)GBDT類模型包括XGBoost、LightGBM時(shí)習(xí)慣性先把max_depth調(diào)小然后通過(guò)控制n_estimators和學(xué)習(xí)率來(lái)整體平衡擬合能力。樹的數(shù)量不是越多越好也不是越少越好得看著驗(yàn)證集曲線決定。但是如果你發(fā)現(xiàn)驗(yàn)證集提升非常緩慢先別急著堆樹看看是不是學(xué)習(xí)率設(shè)置得太小了。注意Boosting系模型對(duì)數(shù)據(jù)中的異常值非常敏感。原因很簡(jiǎn)單每一輪迭代都會(huì)把權(quán)重或梯度集中在“難擬合”的樣本上如果這個(gè)難擬合的樣本本身是噪聲那Boosting就是在強(qiáng)行記住垃圾信息。使用前一定要做異常值篩查至少也要用對(duì)異常值不太敏感的損失函數(shù)比如Huber損失。4. Stacking讓聰明人開完會(huì)高管拍板4.1 什么是Stacking如果說(shuō)Bagging和Boosting解決的是“同一類模型的集成”問(wèn)題那Stacking解決的是“不同類模型怎么融合”的問(wèn)題。它的思路很直白先用多個(gè)異構(gòu)的基學(xué)習(xí)器比如邏輯回歸、KNN、決策樹、SVM在訓(xùn)練集上分別訓(xùn)練每個(gè)基模型都對(duì)樣本產(chǎn)生一個(gè)預(yù)測(cè)結(jié)果然后把這些預(yù)測(cè)結(jié)果作為新的特征拼接成一個(gè)“次級(jí)訓(xùn)練集”再用一個(gè)元學(xué)習(xí)器meta-learner在這個(gè)次級(jí)訓(xùn)練集上訓(xùn)練學(xué)習(xí)“不同基模型的結(jié)果如何組合最優(yōu)”。聽(tīng)起來(lái)就像開一個(gè)評(píng)審會(huì)各個(gè)基模型是不同領(lǐng)域的專家每個(gè)專家先獨(dú)立給意見(jiàn)最后有一個(gè)高管元學(xué)習(xí)器綜合所有人的意見(jiàn)做最終決策。這個(gè)高管不關(guān)心原始特征是什么只看每個(gè)專家的意見(jiàn)。所以Stacking的核心是“組合權(quán)重的學(xué)習(xí)”。4.2 為什么要用交叉驗(yàn)證來(lái)生成“次級(jí)訓(xùn)練集”這是Stacking里最容易被初學(xué)者踩爆的坑。如果你讓基模型在全部訓(xùn)練集上訓(xùn)練然后用它對(duì)訓(xùn)練集本身做預(yù)測(cè)把預(yù)測(cè)結(jié)果當(dāng)作次級(jí)特征去訓(xùn)練元學(xué)習(xí)器那必然會(huì)發(fā)生嚴(yán)重的過(guò)擬合。因?yàn)榛P鸵呀?jīng)在訓(xùn)練集上“見(jiàn)過(guò)”這些樣本了預(yù)測(cè)結(jié)果里帶著大量“背答案”的信息元學(xué)習(xí)器學(xué)到的規(guī)律在真實(shí)數(shù)據(jù)上根本不成立。解決辦法就是K折交叉驗(yàn)證。以5折為例把訓(xùn)練集分成5份每次拿4份訓(xùn)練基模型對(duì)剩下1份做預(yù)測(cè)。重復(fù)5次每個(gè)樣本都會(huì)得到一次“模型在沒(méi)看過(guò)它的情況下”的預(yù)測(cè)結(jié)果。把這些跨折預(yù)測(cè)拼接起來(lái)作為次級(jí)訓(xùn)練集的特征。測(cè)試集呢方法是用同一個(gè)基模型在每個(gè)折上訓(xùn)練出的5個(gè)版本分別對(duì)測(cè)試集做預(yù)測(cè)取平均作為測(cè)試集的次級(jí)特征。這個(gè)方法多出一大塊訓(xùn)練開銷——每個(gè)基模型要訓(xùn)練K次而不是1次。但沒(méi)辦法這屬于“保命操作”不做數(shù)據(jù)就泄露模型上線就翻車。我在某跨平臺(tái)系統(tǒng)里親眼見(jiàn)過(guò)一個(gè)讓人欲哭無(wú)淚的場(chǎng)景某同事圖省事用全量訓(xùn)練集擬合基模型后直接在訓(xùn)練集上生成次級(jí)特征訓(xùn)練集上元模型分?jǐn)?shù)漂亮得不行上線后效果直接崩盤一夜之間從90分變60分。后來(lái)改成5折交叉驗(yàn)證生成特征才恢復(fù)正常。4.3 基模型的多樣性和元學(xué)習(xí)器的選擇Stacking要想效果好基模型之間的差異性非常重要。如果你把五個(gè)一模一樣的邏輯回歸放在一起Stacking那跟單個(gè)邏輯回歸沒(méi)什么區(qū)別。實(shí)際操作中我會(huì)刻意選擇不同類型的模型比如線性模型邏輯回歸、嶺回歸、非線性核模型SVM、樹模型隨機(jī)森林、GBDT、近鄰模型KNN、以及簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)MLP。讓每一個(gè)模型從不同的角度觀察數(shù)據(jù)元學(xué)習(xí)器才有可學(xué)習(xí)的素材。元學(xué)習(xí)器本身不建議太復(fù)雜。因?yàn)榇渭?jí)特征維度通常不高基模型個(gè)數(shù)個(gè)到幾十個(gè)而且基模型的預(yù)測(cè)結(jié)果之間可能存在較強(qiáng)的相關(guān)性。元學(xué)習(xí)器用簡(jiǎn)單的邏輯回歸或線性模型比較穩(wěn)妥目的是學(xué)習(xí)組合權(quán)重而不是再一次引入大量非線性變換。如果有人把元學(xué)習(xí)器也搞成一個(gè)很強(qiáng)的GBDT很容易在次級(jí)特征上過(guò)擬合。另外有個(gè)實(shí)操細(xì)節(jié)Stacking里基模型的預(yù)測(cè)結(jié)果最好確保是概率值而不是硬類別標(biāo)簽。硬標(biāo)簽只有0和1信息量太低而且容易丟失各個(gè)模型內(nèi)部對(duì)不確定性的度量概率值比如某樣本屬于正類的概率是0.73保留了更多信息元學(xué)習(xí)器可以更好地捕捉模型的置信度。分類任務(wù)中這一點(diǎn)非常關(guān)鍵。4.4 Stacking的時(shí)間成本大家得有個(gè)心理準(zhǔn)備Stacking的時(shí)間成本大概是單獨(dú)訓(xùn)練一個(gè)模型的好幾倍具體取決于基模型數(shù)量和交叉驗(yàn)證折數(shù)。假設(shè)你選5個(gè)基模型、5折交叉驗(yàn)證那實(shí)際訓(xùn)練次數(shù)就是5×525次訓(xùn)練再加元學(xué)習(xí)器1次總計(jì)26次。還要考慮每次訓(xùn)練的時(shí)間可能是單模型的數(shù)倍。在時(shí)間預(yù)算緊張的工業(yè)環(huán)境里Stacking通常不是首選除非單模型已經(jīng)壓不動(dòng)了或者你手頭有充足的計(jì)算資源。我個(gè)人的經(jīng)驗(yàn)是Stacking比較適合放在比賽沖刺階段或上線前的最終模型融合階段不適合放在日常實(shí)驗(yàn)迭代中。日常迭代用單個(gè)強(qiáng)模型比如LightGBM快速試錯(cuò)最后確定幾個(gè)差異性較大的強(qiáng)模型做Stacking。這個(gè)順序反過(guò)來(lái)就會(huì)讓自己陷入“洗不完的試錯(cuò)循環(huán)”。5. 三種集成方案橫向?qū)Ρ?.1 關(guān)鍵維度對(duì)照維度BaggingBoostingStacking基學(xué)習(xí)器同質(zhì)通常是決策樹同質(zhì)通常是淺決策樹異質(zhì)多種模型訓(xùn)練方式并行串行層級(jí)主要降低方差偏差組合誤差對(duì)噪聲敏感度較低很高中等訓(xùn)練成本中中高高可解釋性尚可特征重要性尚可特征重要性較差最常用場(chǎng)景高方差數(shù)據(jù)特征多結(jié)構(gòu)化表格數(shù)據(jù)比賽沖刺、精度極限5.2 如何根據(jù)項(xiàng)目選型如果你是做結(jié)構(gòu)化表格數(shù)據(jù)、特征里有大量數(shù)值和類別變量目標(biāo)是最小化預(yù)測(cè)誤差那Boosting系尤其是LightGBM或XGBoost通常是默認(rèn)首選我踩過(guò)的大部分表格類項(xiàng)目最后都是這倆在撐場(chǎng)子。如果數(shù)據(jù)噪聲比較大特征維度很高而且你比較關(guān)注訓(xùn)練穩(wěn)定性那隨機(jī)森林這類Bagging方案往往比單棵決策樹好得多而且不容易過(guò)擬合。如果你已經(jīng)是多輪比賽老兵對(duì)粗糙度不敏感那就考慮Stacking收尾。這三種方案不是互斥的。事實(shí)上很多成熟方案是“兩層套娃”底層用隨機(jī)森林上層再做Boosting或者先用Boosting跑出一個(gè)強(qiáng)模型再和別的模型做Stacking。集成算法本來(lái)就是用來(lái)靈活組合的不用拘泥于“只能用某一種”。6. 工程實(shí)戰(zhàn)中的坑位與排查清單6.1 特征擾動(dòng)與樣本擾動(dòng)的邊界提到Bagging大家容易忽略一個(gè)點(diǎn)Bagging里的基學(xué)習(xí)器不僅可以用樣本擾動(dòng)還可以用特征擾動(dòng)。隨機(jī)森林同時(shí)用了兩者。但在某些場(chǎng)景里樣本擾動(dòng)帶來(lái)的收益已經(jīng)很小比如樣本量非常大、采樣后每份子集長(zhǎng)得差不多這時(shí)候可以試試加大特征擾動(dòng)從全部特征變成隨機(jī)抽一部分特征訓(xùn)練每棵樹。我這里說(shuō)一個(gè)不太常見(jiàn)的做法每棵樹隨機(jī)用80%的特征訓(xùn)練會(huì)比固定用全部特征更容易制造多樣且對(duì)缺失特征的魯棒性也更好。6.2 Boosting類模型訓(xùn)練時(shí)的經(jīng)典報(bào)錯(cuò)與對(duì)策我在實(shí)際項(xiàng)目中遇到過(guò)幾個(gè)很典型的Boosting報(bào)錯(cuò)列一下排查思路損失不降訓(xùn)練集上誤差率始終居高不下。先查學(xué)習(xí)率是不是太大或太小。學(xué)習(xí)率太大模型在迭代過(guò)程中震蕩不收斂學(xué)習(xí)率太小迭代步數(shù)不夠還沒(méi)到極小值就結(jié)束了。我一般從0.05到0.1起步結(jié)合早停機(jī)制動(dòng)態(tài)決定迭代輪數(shù)。驗(yàn)證集上比訓(xùn)練集差一大截。這通常是過(guò)擬合的信號(hào)。除了調(diào)小最大深度外還要查一下是否加足了正則化參數(shù)葉子節(jié)點(diǎn)權(quán)重、L1/L2正則。XGBoost和LightGBM都有對(duì)應(yīng)的正則項(xiàng)別只用默認(rèn)值。特征重要性畸變個(gè)別類別型特征被瘋狂使用。檢查類別特征的處理方式分箱切分過(guò)細(xì)容易導(dǎo)致模型抓住噪聲。換成學(xué)習(xí)率更低、迭代更多的方式可能會(huì)改善。6.3 Stacking里的“時(shí)間放大器”問(wèn)題Stacking有一個(gè)特別坑的工程問(wèn)題如果你用5個(gè)基模型、5折交叉驗(yàn)證那相當(dāng)于把單模型訓(xùn)練成本乘以25。如果每個(gè)基模型訓(xùn)練本來(lái)就要1小時(shí)Stacking一套跑下來(lái)將近一天再加上調(diào)參迭代一不留神就變成“訓(xùn)練一周、崩潰一秒”。我建議在進(jìn)入Stacking之前先對(duì)每個(gè)基模型做嚴(yán)格的時(shí)間預(yù)算評(píng)估能并行就并行多個(gè)基模型可以并發(fā)訓(xùn)練實(shí)在不行就減少折數(shù)到3折或者選更輕量的基模型比如用邏輯回歸替換深度網(wǎng)絡(luò)。6.4 別忘了做加權(quán)平均這個(gè)“窮人版集成”最后分享一個(gè)壓箱底的經(jīng)驗(yàn)在考慮上復(fù)雜Stacking之前先試試加權(quán)平均集成。這是一個(gè)成本極低但效果往往出乎意料的方法把兩個(gè)或三個(gè)強(qiáng)模型的概率預(yù)測(cè)或回歸預(yù)測(cè)值做加權(quán)平均權(quán)重用驗(yàn)證集搜索。做這個(gè)操作大概只需要10分鐘有時(shí)候效果已經(jīng)能逼近完整的Stacking。因?yàn)楹芏嗷P椭g的誤差確實(shí)存在互補(bǔ)性一個(gè)簡(jiǎn)單的線性融合就足以把漲點(diǎn)收進(jìn)口袋。我自己在好幾個(gè)項(xiàng)目里的體會(huì)是集成算法的價(jià)值不在于多花哨而在于“把不同模型的優(yōu)點(diǎn)組合起來(lái)”。好比你帶團(tuán)隊(duì)每個(gè)組員都未必是全方位的頂尖高手但只要各有所長(zhǎng)、相互信任、目標(biāo)一致最后做出的成績(jī)一定比任何一個(gè)人單兵作戰(zhàn)都好。七個(gè)葫蘆娃能贏靠的不是某一個(gè)娃的神力而是七個(gè)人一條心。做模型也是這個(gè)道理。從最小可用起步先用單模型跑通基線再上Bagging或Boosting看看增益最后再考慮Stacking。每一步都記錄訓(xùn)練時(shí)間和驗(yàn)證集分?jǐn)?shù)清晰知道自己每一步在干嘛踩坑也踩得明明白白。集成學(xué)習(xí)這條路真不復(fù)雜貴在把基礎(chǔ)原理想透再動(dòng)手。