用Python進行梯度提升演算法的參數調整
引言
或許之前你都是把梯度提升演算法(Gradient Boosting Model)作為一個「黑箱」來用,那麼現在我們就要把這個黑箱打開來看,裡面到底裝著什麼玩意兒。
提升演算法(Boosting)在處理偏差-方差權衡的問題上表現優越,和裝袋演算法(Bagging)僅僅注重控制方差不同,提升演算法在控制偏差和方差的問題上往往更加有效。在這裡,我們提供一個對梯度提升演算法的透徹理解,希望他能讓你在處理這一問題上更加胸有成竹。
這篇文章我們將會用Python語言實踐梯度提升演算法,並通過調整參數來獲得更加可信的結果。
提升演算法的機制
提升演算法是一個序列型的集成學習方法,它通過把一系列弱學習器集成為強學習器來提升它的預測精度,對於第t次要訓練的弱學習器,它會更加重視之前第t-1次預測錯誤的樣本,相反給預測正確的樣本更低的權重,我們用圖來描述一下:
- 圖一:生成的第一個弱分類器
- 所有的樣本擁有相同的權重(用大小表示)。
- 決策邊界成功預測了2個+樣本和5個-樣本。
- 圖二:生成的第二個弱分類器
- 在圖一中被正確分類的樣本給予了一個更小的權重,而錯分類樣本權重更大。
- 這個分類器更加重視那些權重大的樣本並把它們正確分類,但是會造成其他樣本的錯分類。
圖三也是一樣的,這個過程會循環多次直到最後,然後把所有的弱學習器基於他們的準確性賦予權重,並最終集成為強學習器。
梯度提升演算法的參數
梯度提升演算法的參數可以被分為三類:
- 決策樹參數:單獨影響每個弱學習器(決策樹)的參數
- 提升演算法參數:影響提升演算法運行的參數
- 其他參數:整個模型中的其他參數
決策樹參數
下面是對決策樹參數的詳細介紹,在這裡我們用的是Python的scikit-learn包,或許和R語言的一些包不同,但是他們蘊含的思想是一致的。
- 分支最小樣本量:一個節點想要繼續分支所需要的最小樣本數。
- 葉節點最小樣本量:一個節點要劃為葉節點所需最小樣本數,與上一個參數相對應。
- 最小葉節點相對權重:和上一個參數類似,只不過按照權重的定義轉變為分數的形式。
- 樹最大深度:樹的層次,樹越深越有過擬合的風險。
- 最大葉節點量:葉節點的最大數目,和樹最大深度可以相互替代。
- 最大特徵子集量:選擇最優特徵進行分支的時候,特徵子集的最大數目,可以根據這個數目在特徵全集中隨機抽樣。
在定義下面兩類參數之前,我們先來看一下一個二分類問題的梯度提升演算法框架:
- 生成初始模型
- 從1開始循環迭代2.1 根據上一個運行的結果更新權重2.2 用調整過的樣本子集重新擬合模型
2.3 對樣本全集做預測
2.4 結合預測和學習率來更新輸出結果 - 生成最終結果這是一個非常樸素的梯度提升演算法框架,我們剛才討論的哪些參數僅僅是影響2.2這一環節里的弱學習器模型擬合。
提升演算法參數
- 學習率:這個參數是2.4中針對預測的結果計算的學習率。梯度提升演算法就是通過對初始模型進行一次次的調整來實現的,學習率就是衡量每次調整幅度的一個參數。這個參數值越小,迭代出的結果往往越好,但所需要的迭代次數越多,計算成本也越大。
- 弱學習器數量:就是生成的所有的弱學習器的數目,也就是第2步當中的迭代次數,當然不是越多越好,因為提升演算法也會有過擬合的風險。
- 樣本子集所佔比重:用來訓練弱學習器的樣本子集占樣本總體的比重,一般都是隨機抽樣以降低方差,默認是選擇總體80%的樣本來訓練。
其他參數
諸如損失函數(loss)、隨機數種子(random_state)等參數,不在本文調整的參數範圍內,大多是採用默認狀態。
模型擬合與參數調整
我們用的是從Data Hackathon 3.x AV hackathon下載的數據,在預處理以後,我們在Python中載入要用的包並導入數據。
我們先定義一個函數來幫助我們創建梯度提升演算法模型並實施交叉驗證。我們首先創建一個基準模型,在這裡我們選擇AUC作為預測標準,如果你有幸擬合了一個好的基準模型,那你就不用進行參數調整了。下圖是擬合的結果:
所以平均下來的交叉驗證得分是0.8319,我們要讓模型表現得更好一點。
參數調整的典型方法
事實上,我們很難找到一個最佳的學習率參數,因為往往小一點的學習率會訓練更多的弱學習器從而使得集成起來的學習器表現優越,但是這樣也會導致過度擬合的問題,而且對於個人用的電腦來說,計算成本太大。
下面的參數調整的思路要能夠謹記於心:- 先選擇一個相對較高的學習率,通常就是默認值0.1但是一般0.05到0.2範圍內的數值都是可以嘗試使用的。
- 在學習率確定的情況下,進一步確定要訓練的弱學習器數量,應該在40到70棵決策樹之間,當然選擇的時候還要根據電腦的性能量力而行。
- 決定好學習率和弱學習器數目後,調整決策樹參數,我們可以選擇不同的參數來定義每一棵決策樹的形式,下面也會有範例。
- 如果這樣訓練的模型精度不夠理想,降低當前的學習率、訓練更多的弱學習器。
調整弱學習器數量
首先先看一下Python默認的一些參數值:分支最小樣本量=500;葉節點最小樣本量=50;樹最大深度=8; 樣本子集所佔比重=0.8;最大特徵子集量=特徵總數平方根。這些默認參數值我們要在接下來的步驟中調整。我們現在要做的是基於以上這些默認值和默認的0.1學習率來決定弱學習器數量,我們用網格搜索(grid search)的方法,以10為步長,在20到80之間測試弱學習器的最優數量。
輸出結果顯示,我們確定60個弱學習器時得分最高,這個結果恰巧比較合理。但是情況往往不都是如此:如果最終結果顯示大概在20左右,那麼我們應該降低學習率到0.05;如果顯示超過80(在80的時候得分最高),那麼我們應該調高學習率。最後再調整弱學習器數量,直到進入合理區間。
調整決策樹參數
確定好弱學習器數量之後,現實情況下常用的調參思路為:
- 調整樹最大深度和分支最小樣本量。
- 調整葉節點最小樣本量。
- 調整最大特徵子集量。
當然上述調參順序是慎重決定的,應該先調整那些有更大影響的參數。注意:接下來的網格搜索可能每次會花費15~30分鐘甚至更長的時間,在實戰中,你可以根據你的計算機情況合理選擇步長和範圍。
首先我們以2為步長在5到15之間選擇樹最大深度,以200為步長在200到1000內選擇分支最小樣本量,這些都是基於我本人的經驗和直覺,現實中你也可以選擇更大的範圍更小的步長。
從運行結果來看,選擇深度為9、分支最小樣本量為1000時得分最高,而1000是我們所選範圍的上界,所以真實的最優值可能在1000以上,理論上應該擴大範圍繼續尋找最優值。我們以200為步長在大於1000的範圍內確定分支最小樣本量,在30到70的範圍內以10為步長確定葉節點最小樣本量。
最終我們得到了分支最小樣本量為1200,葉節點最小樣本量為60。這個時候我們階段性回顧一下,看之前的調參效果。如果你對比了基準模型和新模型的特徵重要程度,你會發現我們已經能夠從更多的特徵中獲其價值,現在的模型已經學會把凝視在前幾個特徵的目光分散到後面的特徵。現在我們再來調整最後的決策樹參數--最大特徵量。調整方式為以2為步長從7到19。最終結果顯示最優值是7,這也是演算法默認的平方根,所以這一參數的默認值就是最好的。當然,你也可以選擇更小的值來測,畢竟7同時是我們所選的範圍下界,但我選擇安於現狀。接下來我們調整子集所佔比重,候選值為0.6、0.7、0.75、0.8、0.85、0.9。從結果來看,0.85是最優值。這樣我們就獲得了所有的調整後的決策樹參數。最後看一下我們的調參結果:
- 分支最小樣本量:1200
- 葉節點最小樣本量:60
- 樹最大深度:9
- 最大特徵子集量:7
- 樣本子集所佔比重:85%
調整學習率
現在我們的任務是重新降低學習率,尋找一個低於默認值0.1的學習率並成比例地增加弱學習器的數量,當然這個時候弱學習器的數目已經不再是一開始調整後那個最優值了,但是新的參數值會是一個很好的基準。
當樹增多的時候,交叉驗證尋找最優值的計算成本會更大。為了讓你對模型表現有個直觀的把握,我計算了接下來每次調試後模型的private leaderboard得分,這個數據是不開源的,所以你沒有辦法複製,但是它對你理解有幫助。首先我們降低學習率到0.05,弱學習器數量增加到120個:到此為止,我們可以看到得分由0.844到0.849,可以視為是比較顯著的變化。所以最終我們確定的學習率為0.005,弱學習器數量為1500,當然這個計算成本是很高的。
結語
本文基於優化梯度提升演算法模型,分為三個部分:首先介紹了提升演算法的思想,接下來討論了梯度提升演算法的參數分類,最後是模型擬合和參數調整,並結合Python予以示例。關於詳細的代碼等資料可以去作者的GitHub(https://github.com/aarshayj/AnalyticsVidhya/tree/master/Articles/ParameterTuningGBMwith_Example)上尋找。
原文作者:Aarshay Jain
譯者:Teacup
原文鏈接:Complete Guide to Parameter Tuning in Gradient Boosting (GBM) in Python推薦閱讀:
※大數據是回事么?(2016年最新大數據公司全局圖)
※哪些蘋果用戶還會購買下一代產品?讓機器學習帶你精準定位
※獨立DSP未來預測(上)——數字營銷2017職業雞湯
※新浪為什麼解決不了訪問量暴漲的衝擊,因而屢次癱瘓?
TAG:大数据 |