LESSON 9.1 随机森林回归器的实现
目錄
三 隨機(jī)森林RandomForest
??1 RamdomForestRegressor的實(shí)現(xiàn)
??2 隨機(jī)森林回歸器的參數(shù)
???2.1 弱分類(lèi)器結(jié)構(gòu)
???2.2 弱分類(lèi)器數(shù)量
???2.3 弱分類(lèi)器訓(xùn)練的數(shù)據(jù)
???2.4 其他參數(shù)
四 增量學(xué)習(xí):隨機(jī)森林處理巨量數(shù)據(jù)
??1 普通學(xué)習(xí)vs增量學(xué)習(xí)
??2 增量學(xué)習(xí)在Kaggle數(shù)據(jù)上的應(yīng)用
五 原理進(jìn)階:Bagging方法6大面試熱點(diǎn)問(wèn)題
六 隨機(jī)森林的參數(shù)空間與自動(dòng)優(yōu)化
三 隨機(jī)森林RandomForest
隨機(jī)森林是機(jī)器學(xué)習(xí)領(lǐng)域最常用的算法之一,其算法構(gòu)筑過(guò)程非常簡(jiǎn)單:從提供的數(shù)據(jù)中隨機(jī)抽樣出不同的子集,用于建立多棵不同的決策樹(shù),并按照Bagging的規(guī)則對(duì)單棵決策樹(shù)的結(jié)果進(jìn)行集成(回歸則平均,分類(lèi)則少數(shù)服從多數(shù))。只要你充分掌握了決策樹(shù)的各項(xiàng)屬性和參數(shù),隨機(jī)森林的大部分內(nèi)容都相當(dāng)容易理解。
雖然原理上很簡(jiǎn)單,但隨機(jī)森林的學(xué)習(xí)能力異常強(qiáng)大、算法復(fù)雜度高、又具備一定的抗過(guò)擬合能力,是從根本上來(lái)說(shuō)比單棵決策樹(shù)更優(yōu)越的算法。即便在深入了解機(jī)器學(xué)習(xí)的各種技巧之后,它依然是我們能夠使用的最強(qiáng)大的算法之一。原理如此簡(jiǎn)單、還如此強(qiáng)大的算法在機(jī)器學(xué)習(xí)的世界中是不常見(jiàn)的。在機(jī)器學(xué)習(xí)競(jìng)賽當(dāng)中,隨機(jī)森林往往是我們?cè)谥行⌒蛿?shù)據(jù)上會(huì)嘗試的第一個(gè)算法。
在sklearn中,隨機(jī)森林可以實(shí)現(xiàn)回歸也可以實(shí)現(xiàn)分類(lèi)。隨機(jī)森林回歸器由類(lèi)sklearn.ensemble.RandomForestRegressor實(shí)現(xiàn),隨機(jī)森林分類(lèi)器則有類(lèi)sklearn.ensemble.RandomForestClassifier實(shí)現(xiàn)。我們可以像調(diào)用邏輯回歸、決策樹(shù)等其他sklearn中的算法一樣,使用“實(shí)例化、fit、predict/score”三部曲來(lái)使用隨機(jī)森林,同時(shí)我們也可以使用sklearn中的交叉驗(yàn)證方法來(lái)實(shí)現(xiàn)隨機(jī)森林。其中回歸森林的默認(rèn)評(píng)估指標(biāo)為R2,分類(lèi)森林的默認(rèn)評(píng)估指標(biāo)為準(zhǔn)確率。
class?sklearn.ensemble.RandomForestRegressor(n_estimators=100, *, criterion='squared_error', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, ccp_alpha=0.0, max_samples=None)
class?sklearn.ensemble.RandomForestClassifier(n_estimators=100, *, criterion='gini', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, class_weight=None, ccp_alpha=0.0, max_samples=None)
不難發(fā)現(xiàn),隨機(jī)森林回歸器和分類(lèi)器的參數(shù)高度一致,因此我們只需要講解其中一個(gè)類(lèi)即可。任意集成算法在發(fā)源時(shí)都是回歸類(lèi)算法,因此我們的重點(diǎn)將會(huì)放在回歸類(lèi)算法上。隨機(jī)森林有大量的參數(shù),幸運(yùn)的是,隨機(jī)森林中所有參數(shù)都有默認(rèn)值,因此即便我們不學(xué)習(xí)任何參數(shù),也可以調(diào)用隨機(jī)森林算法。我們先來(lái)建一片森林看看吧:
1 RandomForestRegressor的實(shí)現(xiàn)?
import matplotlib.pyplot as plt from sklearn.ensemble import RandomForestRegressor as RFR from sklearn.tree import DecisionTreeRegressor as DTR from sklearn.model_selection import cross_validate, KFold #這里我們不再使用cross_val_score,轉(zhuǎn)而使用能夠輸出訓(xùn)練集分?jǐn)?shù)的cross_validate #決策樹(shù)本身就是非常容易過(guò)擬合的算法,而集成模型的參數(shù)量/復(fù)雜度很難支持大規(guī)模網(wǎng)格搜索 #因此對(duì)于隨機(jī)森林來(lái)說(shuō),一定要關(guān)注算法的過(guò)擬合情況data = pd.read_csv('/Users/zhucan/Desktop/train_encode.csv',index_col=0) data.head()結(jié)果:?
data.shape #(1460, 81)X = data.iloc[:,:-1] y = data.iloc[:,-1]y #注意,y的類(lèi)型是整數(shù)型,并且y的均值很大,可想而知整體的MSE一定會(huì)很大 #0 208500 #1 181500 #2 223500 #3 140000 #4 250000 # ... #1455 175000 #1456 210000 #1457 266500 #1458 142125 #1459 147500 #Name: SalePrice, Length: 1460, dtype: int64y.mean() #180921.19589041095X.shape #(1460, 80)X.columns.tolist() #['Id', # '住宅類(lèi)型', # '住宅區(qū)域', # '街道接觸面積(英尺)', # '住宅面積', # '街道路面狀況', # '巷子路面狀況',...]與sklearn中其他回歸算法一樣,隨機(jī)森林的默認(rèn)評(píng)估指標(biāo)是R2,但在機(jī)器學(xué)習(xí)競(jìng)賽、甚至實(shí)際使用時(shí),我們很少使用損失以外的指標(biāo)對(duì)回歸類(lèi)算法進(jìn)行評(píng)估。對(duì)回歸類(lèi)算法而言,最常見(jiàn)的損失就是MSE。
reg_f = RFR() #實(shí)例化隨機(jī)森林 reg_t = DTR() #實(shí)例化決策樹(shù) cv = KFold(n_splits=5,shuffle=True,random_state=1412) #實(shí)例化交叉驗(yàn)證方式result_t = cross_validate(reg_t #要進(jìn)行交叉驗(yàn)證的評(píng)估器,X,y #數(shù)據(jù),cv=cv #交叉驗(yàn)證模式,scoring="neg_mean_squared_error" #評(píng)估指標(biāo),sklearn中默認(rèn)為負(fù),負(fù)的程度越深模型越糟糕,return_train_score=True #是否返回訓(xùn)練分?jǐn)?shù),verbose=True #是否打印進(jìn)程,n_jobs=-1 #線程數(shù)) #[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers. #[Parallel(n_jobs=-1)]: Done 2 out of 5 | elapsed: 1.1s remaining: 1.6s #[Parallel(n_jobs=-1)]: Done 5 out of 5 | elapsed: 1.1s finished result_f = cross_validate(reg_f,X,y,cv=cv,scoring="neg_mean_squared_error",return_train_score=True,verbose=True,n_jobs=-1) #[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers. #[Parallel(n_jobs=-1)]: Done 2 out of 5 | elapsed: 1.4s remaining: 2.1s #[Parallel(n_jobs=-1)]: Done 5 out of 5 | elapsed: 2.1s finished '''建立了100顆樹(shù),但由于樹(shù)是并行增長(zhǎng)的,所以建立只會(huì)比決策樹(shù)慢一點(diǎn),隨著數(shù)據(jù)量增長(zhǎng), 隨機(jī)森林會(huì)越來(lái)越慢'''result_t #超級(jí)過(guò)擬合 # {'fit_time': array([0.03513908, 0.02617216, 0.02826715, 0.03085804, 0.03072166]), # 'score_time': array([0.00184107, 0.00152969, 0.00140595, 0.00212121, 0.00243092]), # 'test_score': array([-1.32676659e+09, -3.30251909e+09, -1.57903793e+09, -1.50256213e+09, # -1.57774956e+09]), # 'train_score': array([-0., -0., -0., -0., -0.])}result_f #訓(xùn)練集和測(cè)試在交叉驗(yàn)證上的分?jǐn)?shù)差異更小,因此森林的過(guò)擬合程度沒(méi)有決策樹(shù)高 # {'fit_time': array([1.30783272, 1.37094092, 1.34987903, 1.40098619, 1.32293487]), # 'score_time': array([0.00880313, 0.00958204, 0.00925899, 0.00892091, 0.00915027]), # 'test_score': array([-7.78513095e+08, -2.03928947e+09, -7.46760247e+08, -4.73092198e+08, # -8.86053174e+08]), # 'train_score': array([-1.22052661e+08, -1.04873049e+08, -1.37851525e+08, -1.30651561e+08, # -1.26205314e+08])}在集成學(xué)習(xí)中,我們衡量回歸類(lèi)算法的指標(biāo)一般是RMSE(根均方誤差),也就是MSE開(kāi)根號(hào)后的結(jié)果。現(xiàn)實(shí)數(shù)據(jù)的標(biāo)簽往往數(shù)字巨大、數(shù)據(jù)量龐雜,MSE作為平方結(jié)果會(huì)放大現(xiàn)實(shí)數(shù)據(jù)上的誤差(例如隨機(jī)森林結(jié)果中得到的,7?1087?108等結(jié)果),因此我們會(huì)對(duì)平房結(jié)果開(kāi)根號(hào),讓回歸類(lèi)算法的評(píng)估指標(biāo)在數(shù)值上不要過(guò)于夸張。同樣的,方差作為平方結(jié)果,在現(xiàn)實(shí)數(shù)據(jù)上也會(huì)太大,因此如果可以,我們使用標(biāo)準(zhǔn)差進(jìn)行模型穩(wěn)定性的衡量。
trainRMSE_f = abs(result_f["train_score"])**0.5 testRMSE_f = abs(result_f["test_score"])**0.5 trainRMSE_t = abs(result_t["train_score"])**0.5 testRMSE_t = abs(result_t["test_score"])**0.5trainRMSE_f.mean() #10949.819569879735 testRMSE_f.mean() #30452.218280217272 trainRMSE_f.std() #方差數(shù)額太大,使用標(biāo)準(zhǔn)差 #373.26874603409686#默認(rèn)值下隨機(jī)森林的RMSE與標(biāo)準(zhǔn)差std xaxis = range(1,6) plt.figure(figsize=(8,6),dpi=80) #RMSE plt.plot(xaxis,trainRMSE_f,color="green",label = "RandomForestTrain") plt.plot(xaxis,testRMSE_f,color="green",linestyle="--",label = "RandomForestTest") plt.plot(xaxis,trainRMSE_t,color="orange",label = "DecisionTreeTrain") plt.plot(xaxis,testRMSE_t,color="orange",linestyle="--",label = "DecisionTreeTest") plt.xticks([1,2,3,4,5]) plt.xlabel("CVcounts",fontsize=16) plt.ylabel("RMSE",fontsize=16) plt.legend() plt.show()結(jié)果:
- 橫坐標(biāo):交叉驗(yàn)證次數(shù)
- 縱坐標(biāo):RMSE數(shù)值
從圖像來(lái)看,森林與決策樹(shù)都處于過(guò)擬合狀態(tài),不過(guò)森林的過(guò)擬合程度較輕,決策樹(shù)的過(guò)擬合程度較強(qiáng)。兩個(gè)算法在訓(xùn)練集上的結(jié)果都比較優(yōu)秀,決策樹(shù)的可以完美學(xué)習(xí)訓(xùn)練集上的內(nèi)容,達(dá)到RMSE=0的程度,而隨機(jī)森林在訓(xùn)練集上的RMSE大約在1w上下徘徊,測(cè)試集上的結(jié)果則是隨機(jī)森林更占優(yōu)。可見(jiàn),與填寫(xiě)的參數(shù)無(wú)關(guān),隨機(jī)森林天生就是比決策樹(shù)更不容易過(guò)擬合、泛化能力更強(qiáng)的。?
2 隨機(jī)森林回歸器的參數(shù)
當(dāng)填寫(xiě)參數(shù)之后,隨機(jī)森林可以變得更強(qiáng)大。比起經(jīng)典機(jī)器學(xué)習(xí)算法邏輯回歸、嶺回歸等,隨機(jī)森林回歸器的參數(shù)數(shù)量較多,因此我們可以將隨機(jī)森林類(lèi)的參數(shù)分為如下4大類(lèi)別,其中標(biāo)注為綠色的是我們從未學(xué)過(guò)的、只與集成算法相關(guān)的參數(shù):
2.1 弱分類(lèi)器結(jié)構(gòu)
在集成算法當(dāng)中,控制單個(gè)弱評(píng)估器的結(jié)構(gòu)是一個(gè)重要的課題,因?yàn)閱蝹€(gè)弱評(píng)估器的復(fù)雜度/結(jié)果都會(huì)影響全局,其中單棵決策樹(shù)的結(jié)構(gòu)越復(fù)雜,集成算法的整體復(fù)雜度會(huì)更高,計(jì)算會(huì)更加緩慢、模型也會(huì)更加容易過(guò)擬合,因此集成算法中的弱評(píng)估器也需要被剪枝。隨機(jī)森林回歸器的弱評(píng)估器是回歸樹(shù),因此集成評(píng)估器中有大量的參數(shù)都與弱評(píng)估器回歸樹(shù)中的參數(shù)重合:
這些參數(shù)在隨機(jī)森林中的用法與默認(rèn)值與決策樹(shù)類(lèi)DecisionTreeRegressor中完全一致,專(zhuān)門(mén)用于對(duì)決策樹(shù)進(jìn)行剪枝、控制單個(gè)弱評(píng)估器的結(jié)構(gòu),考慮到大家在決策樹(shù)中已經(jīng)充分掌握這些參數(shù),我們不再對(duì)這些參數(shù)一一進(jìn)行詳細(xì)說(shuō)明了。在這里,我們重點(diǎn)復(fù)習(xí)一下以下兩部分參數(shù):
- 分枝標(biāo)準(zhǔn)與特征重要性
criterion與feature_importances_
與分類(lèi)樹(shù)中的信息熵/基尼系數(shù)不同,回歸樹(shù)中的criterion可以選擇"squared_error"(平方誤差),"absolute_error"(絕對(duì)誤差)以及"poisson"(泊松偏差)。對(duì)任意樣本𝑖而言,𝑦𝑖為真實(shí)標(biāo)簽,𝑦𝑖帽為預(yù)測(cè)標(biāo)簽,則各個(gè)criterion的表達(dá)式為:
其中平方誤差與絕對(duì)誤差是大家非常熟悉的概念,作為分枝標(biāo)準(zhǔn),平方誤差比絕對(duì)誤差更敏感(類(lèi)似于信息熵比基尼系數(shù)更敏感),并且在計(jì)算上平方誤差比絕對(duì)誤差快很多。泊松偏差則是適用于一個(gè)特殊場(chǎng)景的:當(dāng)需要預(yù)測(cè)的標(biāo)簽全部為正整數(shù)時(shí),標(biāo)簽的分布可以被認(rèn)為是類(lèi)似于泊松分布的。正整數(shù)預(yù)測(cè)在實(shí)際應(yīng)用中非常常見(jiàn),比如預(yù)測(cè)點(diǎn)擊量、預(yù)測(cè)客戶(hù)/離職人數(shù)、預(yù)測(cè)銷(xiāo)售量等。我們現(xiàn)在正在使用的數(shù)據(jù)(房?jī)r(jià)預(yù)測(cè)),也可能比較適合于泊松偏差。
另外,當(dāng)我們選擇不同的criterion之后,決策樹(shù)的feature_importances_也會(huì)隨之變化,因?yàn)樵趕klearn當(dāng)中,feature_importances_是特征對(duì)criterion下降量的總貢獻(xiàn)量,因此不同的criterion可能得到不同的特征重要性。(criterion和feature_importances_相連,feature_importances_是通過(guò)每一個(gè)特征貢獻(xiàn)的不純度下降量計(jì)算的)
對(duì)我們來(lái)說(shuō),選擇criterion的唯一指標(biāo)就是最終的交叉驗(yàn)證結(jié)果——無(wú)論理論是如何說(shuō)明的,我們只取令隨機(jī)森林的預(yù)測(cè)結(jié)果最好的criterion。
- 調(diào)節(jié)樹(shù)結(jié)構(gòu)來(lái)控制過(guò)擬合
max_depth
最粗獷的剪枝方式,從樹(shù)結(jié)構(gòu)層面來(lái)看,對(duì)隨機(jī)森林抗過(guò)擬合能力影響最大的參數(shù)。max_depth的默認(rèn)值為None,也就是不限深度。因此當(dāng)隨機(jī)森林表現(xiàn)為過(guò)擬合時(shí),選擇一個(gè)小的max_depth會(huì)很有效。
max_leaf_nodes與min_sample_split
比max_depth更精細(xì)的減枝方式,但限制葉子數(shù)量和分枝,既可以實(shí)現(xiàn)微調(diào),也可以實(shí)現(xiàn)大刀闊斧的剪枝。max_leaf_nodes的默認(rèn)值為None,即不限葉子數(shù)量。min_sample_split的默認(rèn)值為2,等同于不限制分枝。
min_impurity_decrease
最精細(xì)的減枝方式,可以根據(jù)不純度下降的程度減掉相應(yīng)的葉子。默認(rèn)值為0,因此是個(gè)相當(dāng)有空間的參數(shù)。
2.2 弱分類(lèi)器數(shù)量
n_estimators
n_estimators是森林中樹(shù)木的數(shù)量,即弱評(píng)估器的數(shù)量,在sklearn中默認(rèn)100,它是唯一一個(gè)對(duì)隨機(jī)森林而言必填的參數(shù)。n_estimators對(duì)隨機(jī)森林模型的精確程度、復(fù)雜度、學(xué)習(xí)能力、過(guò)擬合情況、需要的計(jì)算量和計(jì)算時(shí)間都有很大的影響,因此n_estimators往往是我們?cè)谡{(diào)整隨機(jī)森林時(shí)第一個(gè)需要確認(rèn)的參數(shù)。對(duì)單一決策樹(shù)而言,模型復(fù)雜度由樹(shù)結(jié)構(gòu)(樹(shù)深、樹(shù)寬、樹(shù)上的葉子數(shù)量等)與數(shù)據(jù)量(樣本量、特征量)決定,而對(duì)隨機(jī)森林而言,模型復(fù)雜度由森林中樹(shù)的數(shù)量、樹(shù)結(jié)構(gòu)與數(shù)據(jù)量決定,其中樹(shù)的數(shù)量越多,模型越復(fù)雜。
還記得講解決策樹(shù)與邏輯回歸時(shí)我們繪制的這張圖像么?當(dāng)模型復(fù)雜度上升時(shí),模型的泛化能力會(huì)先增加再下降(相對(duì)的泛化誤差會(huì)先下降再上升),我們需要找到模型泛化能力最佳的復(fù)雜度。在實(shí)際進(jìn)行訓(xùn)練時(shí),最佳復(fù)雜度往往是一個(gè)比較明顯的轉(zhuǎn)折點(diǎn),當(dāng)復(fù)雜度高于最佳復(fù)雜度時(shí),模型的泛化誤差要么開(kāi)始上升,要么不再下降。
對(duì)隨機(jī)森林而言,該圖像的橫坐標(biāo)可以被無(wú)縫切換為參數(shù)n_estimators上的值。當(dāng)n_estimators越大時(shí):
- 模型的復(fù)雜程度上升,泛化能先增強(qiáng)再減弱(或不變)
- 模型的學(xué)習(xí)能力越來(lái)越強(qiáng),在訓(xùn)練集上的分?jǐn)?shù)可能越來(lái)越高,過(guò)擬合風(fēng)險(xiǎn)越來(lái)越高
- 模型需要的算力和內(nèi)存越來(lái)越多
- 模型訓(xùn)練的時(shí)間會(huì)越來(lái)越長(zhǎng)
因此在調(diào)整n_estimators時(shí),我們總是渴望在模型效果與訓(xùn)練難度之間取得平衡,同時(shí)我們還需要使用交叉驗(yàn)證來(lái)隨時(shí)關(guān)注模型過(guò)擬合的情況。在sklearn現(xiàn)在的版本中,n_estimators的默認(rèn)值為100,個(gè)人電腦能夠容忍的n_estimators數(shù)量大約在200~1000左右。
def RMSE(cvresult,key):return (abs(cvresult[key])**0.5).mean()reg_f = RFR(n_estimators=3) cv = KFold(n_splits=5,shuffle=True,random_state=1412) result_f = cross_validate(reg_f,X,y,cv=cv,scoring="neg_mean_squared_error",return_train_score=True,verbose=True,n_jobs=-1) #[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers. #[Parallel(n_jobs=-1)]: Done 2 out of 5 | elapsed: 1.3s remaining: 1.9s #[Parallel(n_jobs=-1)]: Done 5 out of 5 | elapsed: 1.3s finished RMSE(result_f,"test_score") #35681.96994493137reg_f = RFR(n_estimators=100) cv = KFold(n_splits=5,shuffle=True,random_state=1412) result_f = cross_validate(reg_f,X,y,cv=cv,scoring="neg_mean_squared_error",return_train_score=True,verbose=True,n_jobs=-1) #[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers. #[Parallel(n_jobs=-1)]: Done 2 out of 5 | elapsed: 1.4s remaining: 2.1s #[Parallel(n_jobs=-1)]: Done 5 out of 5 | elapsed: 2.0s finished RMSE(result_f,"test_score") #30351.359534374766reg_f = RFR(n_estimators=500) cv = KFold(n_splits=5,shuffle=True,random_state=1412) result_f = cross_validate(reg_f,X,y,cv=cv,scoring="neg_mean_squared_error",return_train_score=True,verbose=True,n_jobs=-1) #[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers. #[Parallel(n_jobs=-1)]: Done 2 out of 5 | elapsed: 7.8s remaining: 11.8s #[Parallel(n_jobs=-1)]: Done 5 out of 5 | elapsed: 7.9s finished RMSE(result_f,"test_score") #30290.45615417552隨機(jī)森林bagging生成的樹(shù)都是獨(dú)立并行計(jì)算的,所以時(shí)間不會(huì)成倍增加?
總結(jié):
?2.3 弱分類(lèi)器訓(xùn)練的數(shù)據(jù)
還記得決策樹(shù)是如何分枝的嗎?對(duì)每個(gè)特征決策樹(shù)都會(huì)找到不純度下降程度最大的節(jié)點(diǎn)進(jìn)行分枝,因此原則上來(lái)說(shuō),只要給出數(shù)據(jù)一致、并且不對(duì)決策樹(shù)進(jìn)行減枝的話(huà),決策樹(shù)的結(jié)構(gòu)一定是完全相同的。對(duì)集成算法來(lái)說(shuō),平均多棵相同的決策樹(shù)的結(jié)果并沒(méi)有意義,因此集成算法中每棵樹(shù)必然是不同的樹(shù),Bagging算法是依賴(lài)于隨機(jī)抽樣數(shù)據(jù)來(lái)實(shí)現(xiàn)這一點(diǎn)的。
隨機(jī)森林會(huì)從提供的數(shù)據(jù)中隨機(jī)抽樣出不同的子集,用于建立多棵不同的決策樹(shù),最終再按照Bagging的規(guī)則對(duì)眾多決策樹(shù)的結(jié)果進(jìn)行集成。因此在隨機(jī)森林回歸器的參數(shù)當(dāng)中,有數(shù)個(gè)關(guān)于數(shù)據(jù)隨機(jī)抽樣的參數(shù)。
- 樣本的隨機(jī)抽樣
bootstrap,oob_score,max_samples
bootstrap參數(shù)的輸入為布爾值,默認(rèn)True,控制是否在每次建立決策樹(shù)之前對(duì)數(shù)據(jù)進(jìn)行隨機(jī)抽樣。如果設(shè)置為False,則表示每次都使用全部樣本進(jìn)行建樹(shù),如果為T(mén)rue,則隨機(jī)抽樣建樹(shù)。從語(yǔ)言的意義上來(lái)看,bootstrap可以指代任意類(lèi)型的隨機(jī)抽樣,但在隨機(jī)森林中它特指有放回隨機(jī)抽樣技術(shù)。
如下圖所示,在一個(gè)含有m個(gè)樣本的原始訓(xùn)練集中,我們進(jìn)行隨機(jī)采樣。每次采樣一個(gè)樣本,并在抽取下一個(gè)樣本之前將該樣本放回原始訓(xùn)練集,也就是說(shuō)下次采樣時(shí)這個(gè)樣本依然可能被采集到,這樣采集max_samples次,最終得到max_samples個(gè)樣本組成的自助集。
自助集就是抽取出來(lái)的數(shù)據(jù)集。
通常來(lái)說(shuō),max_samples是等于m的(行業(yè)慣例),也就是抽樣數(shù)據(jù)集的大小與原始數(shù)據(jù)集一致,但是如果原始數(shù)據(jù)集太大、或者太小,我們也可以自由調(diào)整max_samples的大小。由于是隨機(jī)采樣,這樣每次的自助集和原始數(shù)據(jù)集不同,和其他的采樣集也是不同的。這樣我們就可以自由創(chuàng)造取之不盡用之不竭,并且互不相同的自助集,用這些自助集來(lái)訓(xùn)練我們的弱分類(lèi)器,我們的弱分類(lèi)器自然也就各不相同了。
然而有放回抽樣也會(huì)有自己的問(wèn)題。由于是有放回,一些樣本可能在同一個(gè)自助集中出現(xiàn)多次,而其他一些卻可能被忽略。當(dāng)抽樣次數(shù)足夠多、且原始數(shù)據(jù)集足夠大時(shí),自助集大約平均會(huì)包含全數(shù)據(jù)的63%,這個(gè)數(shù)字是有數(shù)學(xué)依據(jù)的。因?yàn)樵趍ax_samples次抽樣中,一個(gè)樣本被抽到某個(gè)自助集中的概率為:
這個(gè)式子是怎么來(lái)的呢?對(duì)于任意一個(gè)樣本而言:
一次抽樣時(shí)抽到該樣本的概率為1/m
一次抽樣時(shí)抽不到該樣本的概率為1?1/m
總共抽樣max_samples次,一次也沒(méi)有抽到該樣本的概率就是
因此1減去該概率,就是一個(gè)樣本在抽樣中一定會(huì)被抽到某個(gè)自助集的概率。 當(dāng)m剛好等于max_samples時(shí),公式可以被修改為:?
這明顯是一個(gè)經(jīng)典的極限問(wèn)題,由洛必達(dá)法則(L'H?pital's rule)我們可知:當(dāng)m足夠大時(shí)(接近極限時(shí)),這個(gè)概率收斂于1-(1/e),其中e是自然常數(shù),整體概率約等于0.632。因此,會(huì)有約37%的訓(xùn)練數(shù)據(jù)被浪費(fèi)掉,沒(méi)有參與建模,這些數(shù)據(jù)被稱(chēng)為袋外數(shù)據(jù)(out of bag data,簡(jiǎn)寫(xiě)為oob)。在實(shí)際使用隨機(jī)森林時(shí),袋外數(shù)據(jù)常常被我們當(dāng)做驗(yàn)證集使用,所以我們或許可以不做交叉驗(yàn)證、不分割數(shù)據(jù)集,而只依賴(lài)于袋外數(shù)據(jù)來(lái)測(cè)試我們的模型即可。當(dāng)然,這也不是絕對(duì)的,當(dāng)樹(shù)的數(shù)量n_estimators不足,或者max_samples太小時(shí),很可能就沒(méi)有數(shù)據(jù)掉落在袋外,自然也有無(wú)法使用oob數(shù)據(jù)來(lái)作為驗(yàn)證集了。
在隨機(jī)森林回歸器中,當(dāng)boostrap=True時(shí),我們可以使用參數(shù)oob_score和max_samples,其中:
oob_score控制是否使用袋外數(shù)據(jù)進(jìn)行驗(yàn)證,輸入為布爾值,默認(rèn)為False,如果希望使用袋外數(shù)據(jù)進(jìn)行驗(yàn)證,修改為T(mén)rue即可。(數(shù)據(jù)量特別大的時(shí)候,可以修改為T(mén)rue)
max_samples表示自助集的大小,可以輸入整數(shù)、浮點(diǎn)數(shù)或None,默認(rèn)為None。
輸入整數(shù)m,則代表每次從全數(shù)據(jù)集中有放回抽樣m個(gè)樣本
輸入浮點(diǎn)數(shù)f,則表示每次從全數(shù)據(jù)集中有放回抽樣f*全數(shù)據(jù)量個(gè)樣本
輸入None,則表示每次抽樣都抽取與全數(shù)據(jù)集一致的樣本量(X.shape[0])
在使用袋外數(shù)據(jù)時(shí),我們可以用隨機(jī)森林的另一個(gè)重要屬性:oob_score_來(lái)查看我們的在袋外數(shù)據(jù)上測(cè)試的結(jié)果,遺憾的是我們無(wú)法調(diào)整oob_score_輸出的評(píng)估指標(biāo),它默認(rèn)是R2。
reg = RFR(n_estimators=20, bootstrap=True #進(jìn)行隨機(jī)抽樣, oob_score=True #按袋外數(shù)據(jù)進(jìn)行驗(yàn)證, max_samples=500).fit(X,y) #重要屬性oob_score_ reg.oob_score_ #在袋外數(shù)據(jù)上的R2為83% #0.8379331878464579reg = RFR(n_estimators=20, bootstrap=False, oob_score=True, max_samples=500).fit(X,y) #直接無(wú)法運(yùn)行,因?yàn)閎oostrap=False時(shí)oob_score分?jǐn)?shù)根本不存在reg = RFR(n_estimators=20, bootstrap=True #允許抽樣, oob_score=False #但不進(jìn)行計(jì)算, max_samples=500).fit(X,y) reg.oob_score_ #雖然可以訓(xùn)練,但oob_score_無(wú)法被調(diào)用- 特征的隨機(jī)抽樣
max_features
數(shù)據(jù)抽樣還有另一個(gè)維度:對(duì)特征的抽樣。在學(xué)習(xí)決策樹(shù)時(shí),我們已經(jīng)學(xué)習(xí)過(guò)對(duì)特征進(jìn)行抽樣的參數(shù)max_features,在隨機(jī)森林中max_features的用法與決策樹(shù)中完全一致,其輸入也與決策樹(shù)完全一致:
輸入整數(shù),表示每次分枝時(shí)隨機(jī)抽取max_features個(gè)特征
輸入浮點(diǎn)數(shù),表示每次分枝時(shí)抽取round(max_features * n_features)個(gè)特征
輸入"auto"或者None,表示每次分枝時(shí)使用全部特征n_features
輸入"sqrt",表示每次分枝時(shí)使用sqrt(n_features)
輸入"log2",表示每次分枝時(shí)使用log2(n_features)
結(jié)果:
不難發(fā)現(xiàn),sqrt(n_features)和log2(n_features)都會(huì)返回一個(gè)比原始特征量小很多的數(shù),但一般情況下log2返回的值比sqrt返回的值更小,因此如果我們想要樹(shù)之間的差異更大,我們可以設(shè)置模式為log2。在實(shí)際使用時(shí),我們往往會(huì)先使用上述的文字輸入,觀察模型的結(jié)果,然后再在有效的范圍附近進(jìn)行網(wǎng)格搜索。
需要注意的是,無(wú)論對(duì)數(shù)據(jù)進(jìn)行怎樣的抽樣,我們能夠控制的都只是建立單棵樹(shù)時(shí)的數(shù)據(jù)而已。在總數(shù)據(jù)量有限的情況下,單棵樹(shù)使用的數(shù)據(jù)量越大,每一棵樹(shù)使用的數(shù)據(jù)就會(huì)越相似,每棵樹(shù)的結(jié)構(gòu)也就會(huì)越相似,bagging的效果難以發(fā)揮、模型也很容易變得過(guò)擬合。因此,當(dāng)數(shù)據(jù)量足夠時(shí),我們往往會(huì)消減單棵樹(shù)使用的數(shù)據(jù)量。
- 隨機(jī)抽樣的模式
random_state
在決策樹(shù)當(dāng)中,我們已經(jīng)學(xué)習(xí)過(guò)控制隨機(jī)模式的參數(shù)random_state,這個(gè)參數(shù)是“隨機(jī)數(shù)種子”,它控制決策樹(shù)當(dāng)中多個(gè)具有隨機(jī)性的流程。在sklearn實(shí)現(xiàn)的隨機(jī)森林當(dāng)中,決策樹(shù)上也存在眾多有隨機(jī)性的流程:
- 「強(qiáng)制」隨機(jī)抽取每棵樹(shù)建立時(shí)分枝用的特征,抽取的數(shù)量可由參數(shù)max_features決定
- 「強(qiáng)制」隨機(jī)排序每棵樹(shù)分枝時(shí)所用的特征(工業(yè)上不可能一個(gè)一個(gè)算)
- 「可選」隨機(jī)抽取每棵樹(shù)建立時(shí)訓(xùn)練用的樣本,抽取的比例可由參數(shù)max_samples決定
因此每次使用隨機(jī)森林類(lèi)時(shí),我們建立的集成算法都是不同的,在同一個(gè)數(shù)據(jù)集上多次建樹(shù)自然也會(huì)產(chǎn)生不同的模型結(jié)果。因此在工程部署和教學(xué)當(dāng)中,我們?cè)诮?shù)的第一步總是會(huì)先設(shè)置隨機(jī)數(shù)種子為一個(gè)固定值,讓算法固定下來(lái)。在設(shè)置的時(shí)候,需要注意兩個(gè)問(wèn)題:
1、不同庫(kù)中的隨機(jī)數(shù)種子遵循不同的規(guī)則,對(duì)不同庫(kù)中的隨機(jī)數(shù)種子給與相同的數(shù)字,也不會(huì)得到相同的結(jié)果
import pandas as pd import random list_ = [1,2,3,4,5] list_p = pd.Series(list_) list_p #0 1 #1 2 #2 3 #3 4 #4 5 #dtype: int64#random中的隨機(jī)抽樣 random.seed(1) random.sample(list_,k=3) #[2, 1, 5]#pandas中的隨機(jī)抽樣 list_p.sample(n=3,random_state=1).values #array([3, 2, 5])同樣的,sklearn中的隨機(jī)抽樣、numpy中的隨機(jī)抽樣、cuda中的隨機(jī)抽樣在相同的隨機(jī)數(shù)種子數(shù)值下,都會(huì)得到不同的結(jié)果。
2、如何選擇最佳隨機(jī)數(shù)種子?
當(dāng)數(shù)據(jù)樣本量足夠大的時(shí)候(數(shù)萬(wàn)),變換隨機(jī)數(shù)種子幾乎不會(huì)對(duì)模型的泛化能力有影響,因此在數(shù)據(jù)量巨大的情況下,我們可以隨意設(shè)置任意的數(shù)值。
當(dāng)數(shù)據(jù)量較小的時(shí)候,我們可以把隨機(jī)數(shù)種子當(dāng)做參數(shù)進(jìn)行調(diào)整,但前提是必須依賴(lài)于交叉驗(yàn)證的結(jié)果。選擇交叉驗(yàn)證結(jié)果中均值最高、方差最低的隨機(jī)數(shù)種子,以找到泛化能力最強(qiáng)大的隨機(jī)模式。
?2.4 其他參數(shù)
我們已經(jīng)了解過(guò)前三個(gè)參數(shù)。需要稍微說(shuō)明一下verbose參數(shù)。隨機(jī)森林的verbose參數(shù)打印的是建樹(shù)過(guò)程,但只有在樹(shù)的數(shù)量眾多、建模耗時(shí)很長(zhǎng)時(shí),verbose才會(huì)打印建樹(shù)的具體過(guò)程,否則它只會(huì)打印出一行兩簡(jiǎn)單的報(bào)告。這些參數(shù)中需要重點(diǎn)說(shuō)明的是warm_start。warm_start是控制增量學(xué)習(xí)的參數(shù),默認(rèn)為False,該參數(shù)可以幫助隨機(jī)森林處理巨量數(shù)據(jù),解決圍繞隨機(jī)森林的眾多關(guān)鍵問(wèn)題。我們將在之后的章節(jié)中重點(diǎn)講解warm_start的應(yīng)用。
總結(jié)
以上是生活随笔為你收集整理的LESSON 9.1 随机森林回归器的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 李宏毅深度学习——Why Deep?
- 下一篇: Lesson 3.张量的广播和科学运算