資料來源:http://www.cnblogs.com/jasonfreak/p/5657196.html
ps:他/她寫的好好
《機器學習》 周志華:第二章偏差與方差,第八章
0. 前言
sklearn提供了sklearn.ensemble庫,其中包括隨機森林模型(分類)。但之前使用這個模型的時候,要么使用默認參數,要么將調參的工作丟給調參算法(grid search等)。今天想來深究一下到底是如何選擇參數,如何進行調參。
學會調參是進行集成學習工作的前提。參數可分為兩種,一種是影響模型在訓練集上的准確度或影響防止過擬合能力的參數;另一種不影響這兩者的其他參數。模型的准確度由其在訓練集上的准確度及其防止過擬合的能力所共同決定,所以在調參時,我們主要對第一種參數進行調整,最終達到的效果是:模型在訓練集上的准確度和防止過擬合能力的平衡。
1. 集成學習是什么
集成學習通過構建並結合多個學習器來完成學習任務。 集成學習的一般結構:先產生一組“個體學習器”(individual learner),然后再用某種策略將它們結合起來。個體學習器通常有一個現有的學習算法從訓練數據產生,此時集成中只包含同種類型的個體學習器,比如“決策樹集成”,此時的集合里全部都是決策樹。同質集成中的個體學習器稱為“基學習器”(base learner),相應的學習算法成為“基學習算法”(base learning algorithm)。
因為集成學習通過對多個“弱學習器”進行結合,可以獲得比單一學習器更加顯著的泛化性能,所以集成學習的很多理論研究是針對弱學習器的。因此“基學習器”有時會被直接稱之為弱學習器或者弱模型,通常來說弱模型是偏差高(在訓練集上准確度低)方差小(防止過擬合能力強)的模型。
在驗證集成學習可以獲得更好的泛化性能過程中有一個重要的前提假設就是:基學習器的誤差相互獨立。而在現實任務中,基學習器不可能相互獨立。所以其准確性和多樣性本身就存在沖突,比如准確性很高就容易產生過擬合現象。所以如何產生“好而不同”的個體學習器,是集成學習研究的核心。
根據個體學習器的生成方式,目前的集成學習方法大致分為兩類:
a:個體學習器之間存在強依賴關系、必須串行生成的序列化方法:代表為boosting
b:個體學習器之間不存在強依賴關系、可以同時生成的並行化方法:代表為bagging和隨機森林
本文主要關注第二類。
注意,並不是所有集成學習框架中的基模型都是弱模型。bagging中的基模型為強模型(偏差低方差高),boosting中的基模型為弱模型。
2. 偏差與方差
廣義的偏差(bias)描述的是預測值和真實值之間的差異,方差(variance)描述距的是預測值作為隨機變量的離散程度。《Understanding the Bias-Variance Tradeoff》當中有一副圖形象地向我們展示了偏差和方差的關系:
2.1 偏差
模型的偏差是一個相對來說簡單的概念:訓練出來的模型在訓練集上的准確度。偏差度量了學習算法的期望預測與真實結果的偏離程度,刻畫了學習算法的本身你和能力。
2.2 方差
我們認為方差越大的模型越容易過擬合:假設有兩個訓練集A和B,經過A訓練的模型Fa與經過B訓練的模型Fb差異很大,這意味着Fa在類A的樣本集合上有更好的性能,而Fb反之,這便是我們所說的過擬合現象。方差度量了同樣大小的訓練集的變動導致的學習性能的變化,即刻畫了數據擾動所造成的影響。
2.3 泛化性能
根據偏差-方差分解說明(《機器學習(周志華)第44頁),泛化性能是由學習算法的能力、數據的充分性以及學習任務本身的難度共同決定的。給定的學習任務,為了取得良好的性能,需要使偏差較小(充分擬合數據),方差較小(數據擾動產生影響小)。
我認為書中第46頁一段話能解釋什么樣的參數是我們所需要能得到最優泛化性能的,摘錄如下“一般來講,偏差與方差是有沖突的,稱為偏差-方差窘境(bias-varince dilemma)。 給定學習任務,假定我們能控制學習算法的訓練程度,則在訓練不足時,學習器的擬合能力不夠強, 訓練數據的擾動不足以使學習器產生顯著變化,此時偏差主導了泛化錯誤率;隨着訓練程度的加深,學習器的擬合能力逐漸增強,訓練數據發生的擾動漸漸能被學習器學到,方差逐漸主導了泛化錯誤率;在訓練程度充足后,學習器的擬合能力已非常強,訓練數據發生的輕微擾動都會導致學習器發生顯著變化,若訓練數據自身的、非全局的特性被學習器學習到了,則將發生過擬合。”
對於bagging來說,,整體模型的期望近似於基模型的期望,這也就意味着整體模型的偏差和基模型的偏差近似。同時,整體模型的方差小於等於基模型的方差(當相關性為1時取等號),隨着基模型數(m)的增多,整體模型的方差減少,從而防止過擬合的能力增強,模型的准確度得到提高。但是,模型的准確度一定會無限逼近於1嗎?並不一定,當基模型數增加到一定程度時,方差公式第二項的改變對整體方差的作用很小,防止過擬合的能力達到極限,這便是准確度的極限了。另外,在此我們還知道了為什么bagging中的基模型一定要為強模型,否則就會導致整體模型的偏差度低,即准確度低。
3. Random Forest
Random Forest是Bagging的一個擴展變體。RF在以決策樹為基學習器構建Bagging的基礎上,進一步在決策樹的訓練過程中引入了隨機屬性選擇。即在樹的內部節點分裂過程中,不再是將所有特征,而是隨機抽樣一部分特征納入分裂的候選項。這樣一來,基模型之間的相關性降低,從而在方差公式中,繼續導致整體方差仍是減少。
在sklearn.ensemble庫中,我們可以找到Random Forest分類和回歸的實現:RandomForestClassifier和RandomForestRegression。本文主要關注分類。
回顧上文,參數可分為兩種,一種是影響模型在訓練集上的准確度或影響防止過擬合能力的參數;另一種不影響這兩者的其他參數。所以調參的步驟如下:
a:我們的目標是找到第一種參數,確定對目標是正影響還是負影響和影響的大小
b:通過某些策略提高訓練效率
c:訓練過程的檢測
對於a,我們可以把模型的參數分為4類:目標類、性能類、效率類和附加類。下表詳細地展示了RF中這4個模型參數的意義:
注:下表是直接從http://www.cnblogs.com/jasonfreak/p/5657196.html 中copy過來的,所以包含其他三種模型,不過真的好贊~~~
參數 | 類型 | RandomForestClassifier | RandomForestRegressor | GradientBoostingClassifier | GradientBoostingRegressor |
loss | 目標 | 損失函數 ● exponential:模型等同AdaBoost ★ deviance:和Logistic Regression的損失函數一致 |
損失函數 ● exponential:模型等同AdaBoost ★ deviance:和Logistic Regression的損失函數一致 |
||
alpha | 目標 | 損失函數為huber或quantile的時,alpha為損失函數中的參數 | 損失函數為huber或quantile的時,alpha為損失函數中的參數 | ||
class_weight | 目標 | 類別的權值 |
|||
n_estimators | 性能 | 子模型的數量 ● int:個數 ★ 10:默認值 |
子模型的數量 ● int:個數 ★ 10:默認值 |
子模型的數量 ● int:個數 ★ 100:默認值 |
子模型的數量 ● int:個數 ★ 100:默認值 |
learning_rate | 性能 | 學習率(縮減) | 學習率(縮減) | ||
criterion | 性能 | 判斷節點是否繼續分裂采用的計算方法 ● entropy ★ gini |
判斷節點是否繼續分裂采用的計算方法 ★ mse |
||
max_features | 性能 | 節點分裂時參與判斷的最大特征數 ● int:個數 ● float:占所有特征的百分比 ★ auto:所有特征數的開方 ● sqrt:所有特征數的開方 ● log2:所有特征數的log2值 ● None:等於所有特征數 |
節點分裂時參與判斷的最大特征數 ● int:個數 ● float:占所有特征的百分比 ★ auto:所有特征數的開方 ● sqrt:所有特征數的開方 ● log2:所有特征數的log2值 ● None:等於所有特征數 |
節點分裂時參與判斷的最大特征數 ● int:個數 ● float:占所有特征的百分比 ● auto:所有特征數的開方 ● sqrt:所有特征數的開方 ● log2:所有特征數的log2值 ★ None:等於所有特征數 |
節點分裂時參與判斷的最大特征數 ● int:個數 ● float:占所有特征的百分比 ● auto:所有特征數的開方 ● sqrt:所有特征數的開方 ● log2:所有特征數的log2值 ★ None:等於所有特征數 |
max_depth | 性能 | 最大深度,如果max_leaf_nodes參數指定,則忽略 ● int:深度 ★ None:樹會生長到所有葉子都分到一個類,或者某節點所代表的樣本數已小於min_samples_split |
最大深度,如果max_leaf_nodes參數指定,則忽略 ● int:深度 ★ None:樹會生長到所有葉子都分到一個類,或者某節點所代表的樣本數已小於min_samples_split |
最大深度,如果max_leaf_nodes參數指定,則忽略 ● int:深度 ★ 3:默認值 |
最大深度,如果max_leaf_nodes參數指定,則忽略 ● int:深度 ★ 3:默認值 |
min_samples_split | 性能 | 分裂所需的最小樣本數 ● int:樣本數 ★ 2:默認值 |
分裂所需的最小樣本數 ● int:樣本數 ★ 2:默認值 |
分裂所需的最小樣本數 ● int:樣本數 ★ 2:默認值 |
分裂所需的最小樣本數 ● int:樣本數 ★ 2:默認值 |
min_samples_leaf | 性能 | 葉節點最小樣本數 ● int:樣本數 ★ 1:默認值 |
葉節點最小樣本數 ● int:樣本數 ★ 1:默認值 |
葉節點最小樣本數 ● int:樣本數 ★ 1:默認值 |
葉節點最小樣本數 ● int:樣本數 ★ 1:默認值 |
min_weight_fraction_leaf | 性能 | 葉節點最小樣本權重總值 ● float:權重總值 ★ 0:默認值 |
葉節點最小樣本權重總值 ● float:權重總值 ★ 0:默認值 |
葉節點最小樣本權重總值 ● float:權重總值 ★ 0:默認值 |
葉節點最小樣本權重總值 ● float:權重總值 ★ 0:默認值 |
max_leaf_nodes | 性能 | 最大葉節點數 ● int:個數 ★ None:不限制葉節點數 |
最大葉節點數 ● int:個數 ★ None:不限制葉節點數 |
最大葉節點數 ● int:個數 ★ None:不限制葉節點數 |
最大葉節點數 ● int:個數 ★ None:不限制葉節點數 |
bootstrap | 性能 | 是否bootstrap對樣本抽樣 ● False:子模型的樣本一致,子模型間強相關 ★ True:默認值 |
是否bootstrap對樣本抽樣 ● False:子模型的樣本一致,子模型間強相關 ★ True:默認值 |
||
subsample | 性能 | 子采樣率 ● float:采樣率 ★ 1.0:默認值 |
子采樣率 ● float:采樣率 ★ 1.0:默認值 |
||
init | 性能 | 初始子模型 | 初始子模型 | ||
n_jobs | 效率 | 並行數 ● int:個數 ● -1:跟CPU核數一致 ★ 1:默認值 |
並行數 ● int:個數 ● -1:跟CPU核數一致 ★ 1:默認值 |
||
warm_start | 效率 | 是否熱啟動,如果是,則下一次訓練是以追加樹的形式進行 ● bool:熱啟動 ★ False:默認值 |
是否熱啟動,如果是,則下一次訓練是以追加樹的形式進行 ● bool:熱啟動 ★ False:默認值 |
是否熱啟動,如果是,則下一次訓練是以追加樹的形式進行 ● bool:熱啟動 ★ False:默認值 |
是否熱啟動,如果是,則下一次訓練是以追加樹的形式進行 ● bool:熱啟動 ★ False:默認值 |
presort | 效率 |
|
是否預排序,預排序可以加速查找最佳分裂點,對於稀疏數據不管用 ● Bool ★ auto:非稀疏數據則預排序,若稀疏數據則不預排序 |
是否預排序,預排序可以加速查找最佳分裂點,對於稀疏數據不管用 ● Bool ★ auto:非稀疏數據則預排序,若稀疏數據則不預排序 |
|
oob_score | 附加 | 是否計算袋外得分 ★ False:默認值 |
是否計算袋外得分 ★ False:默認值 |
||
random_state | 附加 | 隨機器對象 | 隨機器對象 | 隨機器對象 | 隨機器對象 |
verbose | 附加 | 日志冗長度 ● int:冗長度 ★ 0:不輸出訓練過程 ● 1:偶爾輸出 ● >1:對每個子模型都輸出 |
日志冗長度 ● int:冗長度 ★ 0:不輸出訓練過程 ● 1:偶爾輸出 ● >1:對每個子模型都輸出 |
日志冗長度 ● int:冗長度 ★ 0:不輸出訓練過程 ● 1:偶爾輸出 ● >1:對每個子模型都輸出 |
日志冗長度 ● int:冗長度 ★ 0:不輸出訓練過程 ● 1:偶爾輸出 ● >1:對每個子模型都輸出 |
上述第一種影響准確度的參數又可分為兩類:過程影響類及子模型影響類。在子模型不變的前提下,某些參數可以通過改變訓練的過程,從而影響模型的性能,諸如:“子模型數”(n_estimators)、“學習率”(learning_rate)等。還可以通過改變子模型性能來影響整體模型的性能,諸如:“最大樹深度”(max_depth)、“分裂條件”(criterion)等。現在可以進一步明確目標了,RF基學習器都擁有較低的偏差,整體模型的訓練過程旨在降低方差,故其需要較少的子模型(n_estimators默認值為10)且子模型不為弱模型(max_depth的默認值為None),同時,降低子模型間的相關度可以起到減少整體模型的方差的效果(max_features的默認值為auto)。
下一步就是調參。
調參在http://www.cnblogs.com/jasonfreak/p/5720137.html中寫的非常詳細,我在具體操作后再來補充說明。