用Python進行梯度提升算法的參數調整
引言
或許之前你都是把梯度提升算法(Gradient Boosting Model)作為一個“黑箱”來用,那么現在我們就要把這個黑箱打開來看,里面到底裝著什么玩意兒。
提升算法(Boosting)在處理偏差-方差權衡的問題上表現優越,和裝袋算法(Bagging)僅僅注重控制方差不同,提升算法在控制偏差和方差的問題上往往更加有效。在這里,我們提供一個對梯度提升算法的透徹理解,希望他能讓你在處理這一問題上更加胸有成竹。
這篇文章我們將會用Python語言實踐梯度提升算法,并通過調整參數來獲得更加可信的結果。
提升算法的機制
提升算法是一個序列型的集成學習方法,它通過把一系列弱學習器集成為強學習器來提升它的預測精度,對于第t次要訓練的弱學習器,它會更加重視之前第t-1次預測錯誤的樣本,相反給預測正確的樣本更低的權重,我們用圖來描述一下:
- 圖一:生成的第一個弱分類器
- 所有的樣本擁有相同的權重(用大小表示)。
- 決策邊界成功預測了2個+樣本和5個-樣本。
- 圖二:生成的第二個弱分類器
- 在圖一中被正確分類的樣本給予了一個更小的權重,而錯分類樣本權重更大。
- 這個分類器更加重視那些權重大的樣本并把它們正確分類,但是會造成其他樣本的錯分類。 </ul> </li> </ul>
- 決策樹參數:單獨影響每個弱學習器(決策樹)的參數
- 提升算法參數:影響提升算法運行的參數
- 其他參數:整個模型中的其他參數
- 分支最小樣本量 :一個節點想要繼續分支所需要的最小樣本數。
- 葉節點最小樣本量 :一個節點要劃為葉節點所需最小樣本數,與上一個參數相對應。
- 最小葉節點相對權重 :和上一個參數類似,只不過按照權重的定義轉變為分數的形式。
- 樹最大深度 :樹的層次,樹越深越有過擬合的風險。
- 最大葉節點量 :葉節點的最大數目,和樹最大深度可以相互替代。
- 最大特征子集量 :選擇最優特征進行分支的時候,特征子集的最大數目,可以根據這個數目在特征全集中隨機抽樣。
- 生成初始模型
- 從1開始循環迭代
2.1 根據上一個運行的結果更新權重
2.2 用調整過的樣本子集重新擬合模型
2.3 對樣本全集做預測
2.4 結合預測和學習率來更新輸出結果 - 生成最終結果
這是一個非常樸素的梯度提升算法框架,我們剛才討論的哪些參數僅僅是影響2.2這一環節里的弱學習器模型擬合。 - 學習率 :這個參數是2.4中針對預測的結果計算的學習率。梯度提升算法就是通過對初始模型進行一次次的調整來實現的,學習率就是衡量每次調整幅度的一個參數。這個參數值越小,迭代出的結果往往越好,但所需要的迭代次數越多,計算成本也越大。
- 弱學習器數量 :就是生成的所有的弱學習器的數目,也就是第2步當中的迭代次數,當然不是越多越好,因為提升算法也會有過擬合的風險。
- 樣本子集所占比重 :用來訓練弱學習器的樣本子集占樣本總體的比重,一般都是隨機抽樣以降低方差,默認是選擇總體80%的樣本來訓練。
- 先選擇一個相對較高的 學習率 ,通常就是默認值0.1但是一般0.05到0.2范圍內的數值都是可以嘗試使用的。
- 在學習率確定的情況下,進一步確定要訓練的 弱學習器數量 ,應該在40到70棵決策樹之間,當然選擇的時候還要根據電腦的性能量力而行。
- 決定好學習率和弱學習器數目后,調整 決策樹參數 ,我們可以選擇不同的參數來定義每一棵決策樹的形式,下面也會有范例。
- 如果這樣訓練的模型精度不夠理想,降低當前的學習率、訓練更多的弱學習器。
- 調整 樹最大深度 和 分支最小樣本量 。
- 調整 葉節點最小樣本量 。
- 調整 最大特征子集量 。
- 分支最小樣本量 :1200
- 葉節點最小樣本量 :60
- 樹最大深度 :9
- 最大特征子集量 :7
- 樣本子集所占比重 :85%
圖三也是一樣的,這個過程會循環多次直到最后,然后把所有的弱學習器基于他們的準確性賦予權重,并最終集成為強學習器。
梯度提升算法的參數
梯度提升算法的參數可以被分為三類:
決策樹參數
下面是對決策樹參數的詳細介紹,在這里我們用的是Python的scikit-learn包,或許和R語言的一些包不同,但是他們蘊含的思想是一致的。
在定義下面兩類參數之前,我們先來看一下一個二分類問題的梯度提升算法框架:
提升算法參數
其他參數
諸如 損失函數(loss) 、 隨機數種子(random_state) 等參數,不在本文調整的參數范圍內,大多是采用默認狀態。
模型擬合與參數調整
我們用的是從Data Hackathon 3.x AV hackathon下載的數據,在預處理以后,我們在Python中載入要用的包并導入數據。
我們先定義一個函數來幫助我們創建梯度提升算法模型并實施交叉驗證。
我們首先創建一個基準模型,在這里我們選擇AUC作為預測標準,如果你有幸擬合了一個好的基準模型,那你就不用進行參數調整了。下圖是擬合的結果:
所以平均下來的交叉驗證得分是0.8319,我們要讓模型表現得更好一點。
參數調整的典型方法
事實上,我們很難找到一個最佳的學習率參數,因為往往小一點的學習率會訓練更多的弱學習器從而使得集成起來的學習器表現優越,但是這樣也會導致過度擬合的問題,而且對于個人用的電腦來說,計算成本太大。
下面的參數調整的思路要能夠謹記于心:
調整弱學習器數量
首先先看一下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是最優值。這樣我們就獲得了所有的調整后的決策樹參數。最后看一下我們的調參結果:
調整學習率
現在我們的任務是重新降低學習率,尋找一個低于默認值0.1的學習率并成比例地增加弱學習器的數量,當然這個時候弱學習器的數目已經不再是一開始調整后那個最優值了,但是新的參數值會是一個很好的基準。
當樹增多的時候,交叉驗證尋找最優值的計算成本會更大。為了讓你對模型表現有個直觀的把握,我計算了接下來每次調試后模型的 private leaderboard得分 ,這個數據是不開源的,所以你沒有辦法復制,但是它對你理解有幫助。
首先我們降低學習率到0.05,弱學習器數量增加到120個:
private leaderboard得分:0.844139
學習率降低到0.01,弱學習器數量增加到600個:
private leaderboard得分:0.848145
學習率降低到0.005,弱學習器數量增加到1200個:
private leaderboard得分:0.848112
可以看到得分降低了一點點,我們再做一次調整,只把弱學習器數量增加到1500個:
private leaderboard得分:0.848747
到此為止,我們可以看到得分由0.844到0.849,可以視為是比較顯著的變化。所以最終我們確定的學習率為0.005,弱學習器數量為1500,當然這個計算成本是很高的。
結語
本文基于優化梯度提升算法模型,分為三個部分:首先介紹了提升算法的思想,接下來討論了梯度提升算法的參數分類,最后是模型擬合和參數調整,并結合Python予以示例。
來自:http://www.jianshu.com/p/f9b070e42b0e